
Park Thread
- 1 installs
- 3 repo stars
- Updated May 21, 2026
- ai-project-brain/project-brain
park-thread is a Claude Code skill that pauses or resumes a project-brain thread without archiving it, recording park metadata.
About
park-thread is a Claude Code skill in the project-brain pack that pauses or resumes an active thread without archiving it. Parking flips status to parked, preserves maturity, and records why it was paused; unpark reverses it and restores the preserved maturity. Developers use it to shelve a thread blocked on something external and bring it back later.
- Parks or resumes a project-brain thread without archiving it
- Captures parked_at, parked_by, and parked_reason metadata
- Moves the thread row between Active and Parked in thread-index.md
Park Thread by the numbers
- 1 all-time installs (skills.sh)
- Ranked #2,476 of 3,282 Productivity & Planning skills by installs in the Skillselion catalog
- Data as of Jul 7, 2026 (Skillselion catalog sync)
park-thread capabilities & compatibility
- Capabilities
- thread lifecycle · status management · notes organization
- Use cases
- planning · memory · project management
What park-thread says it does
Parking is the "alive but paused" state.
Parked threads stay at their original path and keep every byte of their content — only `status` and a small set of park metadata fields change.
npx skills add https://github.com/ai-project-brain/project-brain --skill park-threadAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1 |
|---|---|
| repo stars | ★ 3 |
| Last updated | May 21, 2026 |
| Repository | ai-project-brain/project-brain ↗ |
What it does
Pause or resume a project-brain thread, recording park metadata, without archiving it.
Who is it for?
Developers who want to shelve a blocked project-brain thread and resume it later.
Skip if: Archiving or deleting threads, or projects without a project-brain root.
When should I use this skill?
When the user says park this thread, pause this, shelve this for now, resume, or unpark.
What you get
A parked or resumed thread with correct status, preserved maturity, and updated index.
- updated thread status
- park metadata
- updated thread-index
By the numbers
- one script call parks or unparks
- 3 park metadata fields (parked_at, parked_by, parked_reason)
Files
park-thread
Parking is the "alive but paused" state. A thread gets parked when work is blocked on something external (a missing dependency, a decision elsewhere, a quarter-boundary wait), or when the author realizes the thread is not the right shape yet but does not want to discard it. Parked threads stay at their original path and keep every byte of their content — only status and a small set of park metadata fields change.
Unparking is the symmetric reverse: clear the park metadata, restore status: active, and restore the maturity value held at park time. The skill treats the two directions as one operation with a --unpark flag because they share every non-trivial step (resolve, validate, flip, re-sync index, commit) and the divergence is narrow.
When to invoke
- "Park this thread" / "pause this" / "shelve this for now"
- "I need to stop thinking about <slug> until <X>"
- "Unpark <slug>" / "resume this thread" / "pick this back up"
- When
current-state.mdis cluttered with threads the user isn't actively working, and they want to hide them without killing them - Before switching contexts for a long stretch and wanting to document why the thread was left
Inputs
| Name | Source | Required | Description |
|---|---|---|---|
thread_slug | user prompt or cwd inference | yes | Slug of the thread. Defaults to the thread whose directory contains cwd. |
mode | flag (--unpark) or inferred | yes | park or unpark. If flag is absent, infer from current thread status: active → park, parked → unpark. Mismatch is a refuse. |
reason | user prompt | cond. | Short "why paused". Required for park. 1–3 sentences; verbatim into parked_reason. |
unpark_trigger | user prompt | no | Optional for park. Free-form description of what would cause resumption (e.g. "after Q3 planning", "when ADP spec lands"). |
note | user prompt | no | Optional for unpark. A brief note appended to thread.md under a ## Park log heading to record the round-trip. |
--brain=<path> | user prompt or cwd inference | no | Absolute path to the brain root. Defaults to the nearest ancestor project-brain/ directory. |
--dry-run | boolean | no | Print the plan (status flip, park metadata, commit message) without performing any file writes, git mutations, or audit-log writes. See Process § Dry-run semantics. |
Prompt strategy: resolve thread_slug from cwd. Infer mode from current status; if ambiguous (e.g. skill invoked without context), ask the user to pick park-vs-unpark. For park, always prompt for reason even if the user supplied an inline reason in their original message — parked threads are often re-read weeks later and a one-word reason is rarely enough.
Preconditions
The skill refuses if any of these are not met.
1. Current working directory is inside a brain root (a project-brain/ directory containing CONVENTIONS.md) or an explicit --brain=<path> was given. 2. project-brain/threads/[thread_slug]/thread.md exists. 3. For park mode:
- Thread
statusisactive. Parking fromin-reviewis refused (close or merge the PR first); parking fromparkedis a no-op refuse; parking fromarchivedis refused. reasonis non-empty.
4. For unpark mode:
- Thread
statusisparked. parked_at,parked_by,parked_reasonare present in frontmatter (any missing means the thread was hand-edited into a bad state; refuse and route to manual fix orverify-tree).- The preserved
maturityvalue is one ofexploring | refining | locking.
5. Working tree has no uncommitted changes to project-brain/thread-index.md, project-brain/current-state.md, or the thread's thread.md. 6. parked_by is resolvable. If --by <email> is supplied, use it. Otherwise write the literal placeholder TODO@example.com into the parked_by frontmatter field and append a TODO note to the thread body reminding the user to fix it. No `git` invocation and no env-var read — rc4 keeps park-thread shell-free. Precondition always succeeds (placeholder is always available); it never refuses.
Process
### ⛔️ HARD CONSTRAINT — ONE TOOL CALL
>
Call `${PROJECT_BRAIN_PACK_ROOT}/scripts/park-thread.sh` ONCE. NoReadof thread.md, no pre-flight status check. The script reads frontmatter, determines park vs unpark (from the thread's currentstatusor--unparkflag), validates, mutates, rebuilds indexes.
>
Derive mode + reason/trigger from language. "Park this for now, waiting on X" →--reason='waiting on X'. "Pick this back up — X just landed" →--unpark --trigger='X landed'. Don't ask.
One call:
"${PROJECT_BRAIN_PACK_ROOT}/scripts/park-thread.sh" \
--brain=<absolute brain path> \
--slug=<thread_slug> \
--reason='<reason>' \ # park mode
[--unpark] \ # unpark mode (alternative)
[--trigger='<trigger>'] \ # optional unpark trigger description
[--by=<email>]Infer --slug from cwd. After success, echo the script's stdout in your response message verbatim — don't rely on the Bash tool's result card to display it; the user should see the script's output as part of your reply.
Dry-run semantics
When --dry-run is set:
1. Run all preconditions (steps 1–2 above), including brain-root existence, thread existence, status checks. Exit 1 if any fail. 2. Compute the full plan: print the mode (park or unpark), the frontmatter changes, any body append for unpark note, and the rebuild step. 3. Invoke `verify-tree --rebuild-index --dry-run` to surface any index-rebuild failures. If that fails, print the error and exit 1. 4. Write NOTHING to disk: neither frontmatter edits, nor body appends, nor the transcript. 5. Exit 0 if the plan would succeed end-to-end, exit 1 if any check failed, exit 2 on unexpected error.
Print the plan to stdout as a numbered list. When exiting 1, also print the failing precondition or rebuild error.
Side effects
Files written or modified
| Path (relative to brain root) | Operation | Mode | Notes |
|---|---|---|---|
threads/[slug]/thread.md | edit (frontmatter + optional body append) | both | Frontmatter flip; unpark optionally appends a ## Park log entry |
threads/[slug]/transcript.md | append | both | If transcript_logging=on (default) |
thread-index.md | regenerate | both | By verify-tree --rebuild-index from per-thread frontmatter |
current-state.md | regenerate | both | By verify-tree --rebuild-index from per-thread frontmatter |
No file moves. The thread directory stays at threads/[slug]/ in both directions. This is deliberate — parking is not archiving.
Git operations
None. This skill performs file operations only. The user runs git add and git commit themselves (§ Git deferred).
When --dry-run is set: NO side effects. Stdout output only.
External calls
None.
Outputs
User-facing summary. A short message with:
- The commit SHA.
- The new status (
parkedoractive) and the preserved (park) or restored (unpark) maturity. - For
park: the reason and unpark trigger, plus the suggestion "Runpark-thread --unpark [slug]when you're ready to resume." - For
unpark: a pointer to the## Park logentry (if written) and the suggestion "Continue withupdate-threadorpromote-thread-to-tree."
State passed forward.
thread_slug— unchanged.mode—parkorunpark(the one that ran).thread_status— resulting status (parkedoractive).preserved_maturity— the maturity value carried through (always present in both directions).parked_reason— present ifmode == park.
Verbosity contract
Reads verbosity from <brain>/config.yaml (env override: PROJECT_BRAIN_VERBOSITY). Defaults to terse.
- terse (default): one acknowledgement line naming the operation + thread, then
Done. - Example output:
Parking project-brain/threads/alpha/ (reason: blocked on ADP). Done. - normal: structured summary of frontmatter changes (status flip, metadata added/removed).
- verbose: full narration (pre-rc4 default). Use for debugging.
Frontmatter flips
| File | Field | Before | After | Mode |
|---|---|---|---|---|
threads/[slug]/thread.md | status | active | parked | park |
threads/[slug]/thread.md | parked_at | (absent) | <ISO-8601> | park |
threads/[slug]/thread.md | parked_by | (absent) | <email> | park |
threads/[slug]/thread.md | parked_reason | (absent) | <string> | park |
threads/[slug]/thread.md | unpark_trigger | (absent) | <string> (only if given) | park |
threads/[slug]/thread.md | status | parked | active | unpark |
threads/[slug]/thread.md | parked_at | <ISO-8601> | (removed) | unpark |
threads/[slug]/thread.md | parked_by | <email> | (removed) | unpark |
threads/[slug]/thread.md | parked_reason | <string> | (removed) | unpark |
threads/[slug]/thread.md | unpark_trigger | <string> or absent | (removed) | unpark |
maturity is never flipped by this skill in either direction. It is preserved across the park/unpark round-trip by design.
When --dry-run is set: no files are written; the frontmatter changes and any body appends are described in the plan output instead.
Postconditions
- Thread directory unchanged at
threads/[slug]/. Nothing moved, no content deleted. - On
park:status == parked, the four park metadata fields are populated, and the thread is visible under## Parkedinthread-index.md(autogenerated). - On
unpark:status == active, no park metadata present, and the thread is visible under## Activeinthread-index.md(autogenerated). maturityequals whatever it was pre-skill (park direction) or pre-park (unpark direction). The round-trip is lossless.thread-index.mdandcurrent-state.mdreflect the post-operation state of all threads (autogenerated).- Exactly one commit was added.
verify-treepasses on the thread.
Failure modes
| Failure | Cause | Response |
|---|---|---|
| Brain root not found | No project-brain/CONVENTIONS.md up the tree; no --brain given | refuse — prompt user to init-project-brain |
| Thread slug does not resolve | Typo; wrong cwd | refuse — list nearby slugs |
park on already-parked thread | Mode mismatch | refuse — suggest --unpark instead |
park on in-review thread | PR is live | refuse — tell user to close, merge, or discard the PR first |
park on archived thread | Terminal state | refuse — no action |
unpark on non-parked thread | Mode mismatch | refuse — report current status |
Missing park metadata on unpark | Hand-edited thread; frontmatter broken | refuse — suggest verify-tree and manual repair |
Empty reason on park | Slipped past prompt | re-prompt — reason is not optional |
(retired in rc4 — parked_by defaults to TODO@example.com when --by not supplied) | Git not configured | refuse — ask user to configure git |
| Uncommitted edits to unrelated paths | Conflict risk | refuse — ask user to stash or commit |
| Rebuild source-validation failure | Thread frontmatter schema violations | refuse — report violating thread; user must repair before retrying |
| Rebuild write failure | Filesystem / permissions issue | refuse — live index files unchanged (atomic); report error |
--dry-run plan shows a precondition failure | Any precondition failed during dry-run | skill exits 1 after printing the plan and the failing precondition. The plan is still useful: the user sees both what was intended and why it wouldn't work. |
Related skills
- Coordinates with:
update-thread,discard-thread— the three pre-promotion thread operations; mutually exclusive per invocation. - Blocks:
promote-thread-to-tree— will refuse on aparkedthread; unpark first. - Compatible with:
verify-tree— run after unpark to confirm the round-trip restored a clean state. - Mutually exclusive with: itself — cannot be re-invoked in the same mode without an interleaving flip (no-op refuse).
Asset dependencies
None. The skill edits existing frontmatter and index files; it does not create files from templates. The ## Park log heading in thread.md is created on-demand by unpark when a note is supplied.
Versioning
0.2.2 — Added --dry-run flag specification with full semantics contract, including exit codes 0/1/2 (2 reserved for unexpected errors).
0.2.0 — Stage 2 of v0.9.0: index-file updates moved to centralized verify-tree --rebuild-index final step; previous inline edits removed.
0.1.0 — initial draft. Minor bump if a pin/snooze variant is added (e.g. a "park until <date>" that auto-unparks). Major bump if the preservation semantics around maturity change (e.g. a rule that parking always resets maturity to refining on unpark).
Related skills
FAQ
Does parking move the thread?
No, the thread stays at its original threads/<slug>/ path; only status and park metadata change.
How is unpark different?
Unpark clears park metadata, restores status active, and restores the maturity held at park time.