acstack 0.0.0-stage → 0.47.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/.claude-plugin/plugin.json +19 -0
  2. package/LICENSE +21 -0
  3. package/README.md +389 -2
  4. package/THIRD_PARTY_NOTICES +14 -0
  5. package/TROUBLESHOOTING.md +225 -0
  6. package/agents/codex/frontend-verifier.toml +352 -0
  7. package/agents/codex/task-checker.toml +345 -0
  8. package/agents/codex/task-executor.toml +157 -0
  9. package/agents/codex/test-writer.toml +149 -0
  10. package/agents/frontend-verifier.md +351 -0
  11. package/agents/task-checker.md +344 -0
  12. package/agents/task-executor.md +156 -0
  13. package/agents/test-writer.md +148 -0
  14. package/assets/playwriter-bridge/build-launcher.ps1 +32 -0
  15. package/assets/playwriter-bridge/doctor.ps1 +450 -0
  16. package/assets/playwriter-bridge/launcher-src.cs +131 -0
  17. package/assets/playwriter-bridge/opener.js +330 -0
  18. package/assets/playwriter-bridge/opener.ps1 +63 -0
  19. package/assets/playwriter-bridge/register-tasks.ps1 +328 -0
  20. package/assets/playwriter-bridge/relay.ps1 +50 -0
  21. package/assets/playwriter-bridge/stop.ps1 +125 -0
  22. package/assets/playwriter-bridge/sync.ps1 +271 -0
  23. package/assets/playwriter-bridge/tunnel.ps1 +325 -0
  24. package/assets/playwriter-bridge/vm-free-port.sh +166 -0
  25. package/assets/terminal-workspace/client-keybindings.md +87 -0
  26. package/assets/terminal-workspace/config.example.yaml +329 -0
  27. package/assets/terminal-workspace/setup.sh +4317 -0
  28. package/cli/README.md +47 -0
  29. package/cli/bin/acstack.js +3 -0
  30. package/cli/dist/index.js +25984 -0
  31. package/cli/dist/index.js.map +7 -0
  32. package/cli/package.json +59 -0
  33. package/docs/adr/0001-ste-writing-standard.md +16 -0
  34. package/docs/adr/0002-version-gate-not-auto-bump.md +35 -0
  35. package/docs/adr/0003-handoff-ack-command.md +19 -0
  36. package/docs/adr/0004-dev-setup-per-host.md +13 -0
  37. package/docs/adr/0005-two-orchestrators-per-host.md +25 -0
  38. package/docs/adr/0006-document-opener-service.md +89 -0
  39. package/docs/adr/0007-lead-check-reads-the-transcript.md +87 -0
  40. package/docs/adr/0008-cli-audits-skill-interviews.md +37 -0
  41. package/docs/adr/0009-verify-the-write-not-the-writer.md +51 -0
  42. package/docs/adr/0010-promote-dev-to-main-by-fast-forward.md +115 -0
  43. package/docs/adr/0011-node-header-is-the-edge-encoding.md +20 -0
  44. package/docs/adr/0012-node-kind-is-a-closed-set-of-five.md +31 -0
  45. package/docs/adr/0013-the-diagram-renderer-is-pure.md +23 -0
  46. package/docs/adr/0014-reading-a-node-hides-its-generated-diagram.md +29 -0
  47. package/docs/adr/0015-a-node-id-links-to-its-issue-through-an-anchor.md +37 -0
  48. package/docs/adr/0016-the-map-root-carries-no-status-of-its-own.md +21 -0
  49. package/docs/adr/0017-call-impeccable-copy-only-its-questions.md +13 -0
  50. package/docs/adr/index.md +17 -0
  51. package/docs/config-reference.md +572 -0
  52. package/docs/dev-setups.md +164 -0
  53. package/docs/migrate-0.8.md +28 -0
  54. package/docs/playwriter-bridge-windows.md +15 -0
  55. package/docs/terminal-workspace-keys.md +137 -0
  56. package/docs/terminal-workspace.md +1774 -0
  57. package/docs/workflows.md +309 -0
  58. package/hooks/ac-writing-style-reminder.sh +86 -0
  59. package/hooks/context-pressure.sh +583 -0
  60. package/hooks/hooks.json +50 -0
  61. package/hooks/session-start-handoff.sh +165 -0
  62. package/hooks/session-start.sh +214 -0
  63. package/orchestrator/AGENTS.md +532 -0
  64. package/output-styles/ac-writing-style.md +286 -0
  65. package/package.json +50 -4
  66. package/pi/agents/frontend-verifier.md +357 -0
  67. package/pi/agents/task-checker.md +348 -0
  68. package/pi/agents/task-executor.md +160 -0
  69. package/pi/agents/test-writer.md +154 -0
  70. package/pi/extension.ts +723 -0
  71. package/profiles/fullstack-python.yaml +29 -0
  72. package/profiles/node-typescript.yaml +23 -0
  73. package/profiles/python.yaml +24 -0
  74. package/skills/archive/SKILL.md +160 -0
  75. package/skills/bootstrap/SKILL.md +109 -0
  76. package/skills/bridge/HANDOFF.md +93 -0
  77. package/skills/bridge/SKILL-VM.md +292 -0
  78. package/skills/bridge/SKILL-WINDOWS.md +526 -0
  79. package/skills/bridge/SKILL.md +121 -0
  80. package/skills/browser-verify/SKILL.md +229 -0
  81. package/skills/code-review/SKILL.md +44 -0
  82. package/skills/commit/SKILL.md +106 -0
  83. package/skills/compact-and-continue/SKILL.md +241 -0
  84. package/skills/explore/SKILL.md +149 -0
  85. package/skills/grilling/SKILL.md +134 -0
  86. package/skills/handoff/SKILL.md +250 -0
  87. package/skills/handoff/launch-herdr.md +197 -0
  88. package/skills/handoff/launch-without-herdr.md +30 -0
  89. package/skills/handoff/lead-check.md +59 -0
  90. package/skills/handoff/outcomes.md +162 -0
  91. package/skills/handoff/running-agent.md +50 -0
  92. package/skills/handoff/watch.md +115 -0
  93. package/skills/host/SKILL.md +247 -0
  94. package/skills/host/detect-host.sh +297 -0
  95. package/skills/host/herdr.md +79 -0
  96. package/skills/host/install-herdr-block.sh +467 -0
  97. package/skills/host/install-orca.sh +512 -0
  98. package/skills/host/notes.md +97 -0
  99. package/skills/host/orca.md +160 -0
  100. package/skills/host/questions.md +163 -0
  101. package/skills/host/report.md +42 -0
  102. package/skills/implement/SKILL.md +230 -0
  103. package/skills/implement/decision-log.md +62 -0
  104. package/skills/implement/design-pass.md +32 -0
  105. package/skills/implement/relaxed-tdd.md +28 -0
  106. package/skills/map/SKILL.md +250 -0
  107. package/skills/map/frontend.md +227 -0
  108. package/skills/map/trackers/files.md +74 -0
  109. package/skills/map/trackers/github.md +180 -0
  110. package/skills/map/visuals.md +387 -0
  111. package/skills/new-worktree/SKILL.md +155 -0
  112. package/skills/new-worktree/detect-orchestrator.sh +328 -0
  113. package/skills/new-worktree/detect-orchestrator.test.sh +894 -0
  114. package/skills/new-worktree/herdr.md +84 -0
  115. package/skills/new-worktree/orca.md +101 -0
  116. package/skills/pre-commit-review/SKILL.md +242 -0
  117. package/skills/pre-commit-review/auto-fix.md +19 -0
  118. package/skills/pre-commit-review/interactive.md +35 -0
  119. package/skills/quick-fix/SKILL.md +125 -0
  120. package/skills/record-context/SKILL.md +106 -0
  121. package/skills/setup/SKILL.md +250 -0
  122. package/skills/setup/browser.md +123 -0
  123. package/skills/setup/design-review.md +97 -0
  124. package/skills/setup/first-run.md +114 -0
  125. package/skills/setup/report.md +68 -0
  126. package/skills/setup/row-fixes.md +196 -0
  127. package/skills/setup/terminal-workspace.md +153 -0
  128. package/skills/sync/SKILL.md +171 -0
  129. package/skills/teardown-worktree/SKILL.md +245 -0
  130. package/skills/teardown-worktree/detector.md +39 -0
  131. package/skills/teardown-worktree/herdr.md +113 -0
  132. package/skills/teardown-worktree/orca.md +61 -0
  133. package/skills/terminal-workspace/SKILL.md +249 -0
  134. package/skills/terminal-workspace/components.md +36 -0
  135. package/skills/terminal-workspace/config-choices.md +69 -0
  136. package/skills/terminal-workspace/emulator-keys.md +48 -0
  137. package/skills/terminal-workspace/headless-clipboard.md +175 -0
  138. package/skills/terminal-workspace/turn-off-and-update.md +104 -0
  139. package/skills/test-conventions/SKILL.md +59 -0
  140. package/skills/visual-docs/SKILL.md +246 -0
  141. package/skills/writing/SKILL.md +231 -0
  142. package/skills/writing/examples.md +153 -0
  143. package/skills/writing/vocabulary.md +96 -0
@@ -0,0 +1,149 @@
1
+ ---
2
+ name: explore
3
+ description: Enter explore mode - a thinking partner for exploring ideas, investigating problems, and clarifying requirements. Invoke when the user signals they want to think rather than build – thinking out loud, weighing options, asking what if, or saying they are not ready to start yet. Explore mode never writes code, so do not invoke it on a request to build something; use implement, quick-fix or map for that.
4
+ ---
5
+
6
+ ## User input
7
+
8
+ ```text
9
+ $ARGUMENTS
10
+ ```
11
+
12
+ Enter explore mode.
13
+
14
+ Think deeply. Visualize freely. Follow the conversation wherever it goes.
15
+
16
+ **IMPORTANT**: Explore mode is for thinking, not implementing.
17
+
18
+ You may read files, search code, and investigate the codebase. You must NEVER write code or implement features. If the user asks you to implement something, remind them to exit explore mode first and map out the work with /acstack:map.
19
+
20
+ You MAY create ACStack artifacts (map nodes, specs, ADRs) if the user asks – that's capturing thinking, not implementing.
21
+
22
+ **This is a stance, not a workflow.** There are no fixed steps, no required sequence, no mandatory outputs. You're a thinking partner helping the user explore.
23
+
24
+ ---
25
+
26
+ ## The stance
27
+
28
+ - **Curious, not prescriptive** - Ask questions that emerge naturally. Don't follow a script
29
+ - **Open threads, not interrogations** - Surface multiple interesting directions. Let the user follow what resonates
30
+ - **Visual** - Use ASCII diagrams liberally when they'd help clarify thinking
31
+ - **Adaptive** - Follow interesting threads. Pivot when new information emerges
32
+ - **Patient** - Don't rush to conclusions. Let the shape of the problem emerge
33
+ - **Grounded** - Explore the actual codebase when relevant. Don't just theorize
34
+
35
+ ---
36
+
37
+ ## What you might do
38
+
39
+ Depending on what the user brings, you might:
40
+
41
+ **Explore the problem space**
42
+
43
+ - Ask clarifying questions that emerge from what they said
44
+ - Challenge assumptions
45
+ - Reframe the problem
46
+ - Find analogies
47
+
48
+ **Investigate the codebase**
49
+
50
+ - Map existing architecture relevant to the discussion
51
+ - Find integration points
52
+ - Identify patterns already in use
53
+ - Surface hidden complexity
54
+
55
+ **Compare options**
56
+
57
+ - Brainstorm multiple approaches
58
+ - Build comparison tables
59
+ - Sketch tradeoffs
60
+ - Recommend a path (if asked)
61
+
62
+ **Visualize**
63
+
64
+ ```
65
+ +---------------------------------------------+
66
+ | Use ASCII diagrams liberally |
67
+ +---------------------------------------------+
68
+ | |
69
+ | +--------+ +--------+ |
70
+ | | State |-------->| State | |
71
+ | | A | | B | |
72
+ | +--------+ +--------+ |
73
+ | |
74
+ | System diagrams, state machines, |
75
+ | data flows, architecture sketches, |
76
+ | dependency graphs, comparison tables |
77
+ +---------------------------------------------+
78
+ ```
79
+
80
+ **Surface risks and unknowns**
81
+
82
+ - Identify what could go wrong
83
+ - Find gaps in understanding
84
+ - Suggest spikes or investigations
85
+
86
+ ---
87
+
88
+ ## ACStack awareness
89
+
90
+ You have full context of the ACStack system. Use it naturally, don't force it.
91
+
92
+ ### Check for context
93
+
94
+ At the start, quickly check what exists – maps on the configured tracker
95
+ (`ls acstack/maps/` on the files backend) and living specs
96
+ (`~/.claude/acstack/bin/acstack list --specs --json`).
97
+
98
+ ### When no map exists
99
+
100
+ Think freely. When insights crystallize, you might offer:
101
+
102
+ - "This feels solid enough to start. Want me to chart it with /acstack:map?"
103
+ - Or keep exploring – no pressure to formalize
104
+
105
+ ### When a map exists
106
+
107
+ If the user mentions a map or you detect one is relevant:
108
+
109
+ 1. Orient with the packaging walk (`acstack node walk --map <name>`)
110
+ - On GitHub, `--map` refuses – pipe `gh issue list` into `--stdin` per the
111
+ map skill's `trackers/github.md`
112
+ 2. Reference them naturally in conversation
113
+ 3. Offer to capture when a decision lands:
114
+
115
+ | Insight Type | Where to Capture |
116
+ | -------------------------- | ---------------------------- |
117
+ | New requirement discovered | `specs/<domain>/spec.md` |
118
+ | Requirement changed | `specs/<domain>/spec.md` |
119
+ | Design decision made | an ADR via `record-context` |
120
+ | Term pinned down | glossary via `record-context` |
121
+ | New work identified | a map node (a small tracked-work record, if a map exists) |
122
+ | Assumption invalidated | Relevant artifact |
123
+
124
+ 4. The user decides – offer and move on. Don't pressure.
125
+
126
+ ---
127
+
128
+ ## What you don't have to do
129
+
130
+ - Follow a script
131
+ - Ask the same questions every time
132
+ - Produce a specific artifact
133
+ - Reach a conclusion
134
+ - Stay on topic if a tangent is valuable
135
+ - Be brief (this is thinking time)
136
+
137
+ ---
138
+
139
+ ## Guardrails
140
+
141
+ - **Don't implement** - Never write code or implement features
142
+ - **Don't fake understanding** - If something is unclear, dig deeper
143
+ - **Don't rush** - Discovery is thinking time, not task time
144
+ - **Don't force structure** - Let patterns emerge naturally
145
+ - **Don't auto-capture** - Offer to save insights. Don't just do it
146
+ - **Write for the reader** - Captured artifacts follow the `writing` skill
147
+ - **Do visualize** - A good diagram is worth many paragraphs
148
+ - **Do explore the codebase** - Ground discussions in reality
149
+ - **Do question assumptions** - Including the user's and your own
@@ -0,0 +1,134 @@
1
+ ---
2
+ name: grilling
3
+ description: Interview technique for settling open decisions in rounds. A round asks the whole frontier – every question whose prerequisites are settled – numbered, each with a recommended answer, then recomputes and repeats. Use whenever decisions need a human and requirements are foggy, with or without a map. Called by /acstack:map for charting and frontier work; also usable directly in conversation.
4
+ ---
5
+
6
+ # Grilling
7
+
8
+ Grilling settles open decisions by asking the user a whole round of questions
9
+ at once. One technique at two scales.
10
+
11
+ The frontier is the set of questions ready to ask – every open question with
12
+ settled prerequisites.
13
+
14
+ In conversation you work it out as you go. On a map – a stored graph of
15
+ question and work nodes – you ask the tracker for it. You limit it to `hitl`
16
+ nodes, meaning the ones a human must answer rather than an agent.
17
+
18
+ On the files backend:
19
+
20
+ `~/.claude/acstack/bin/acstack node frontier --map <name> --mode hitl`
21
+
22
+ The map skill's `trackers/` docs declare other backends. Same structure
23
+ either way – the only difference is whether the frontier outlives the
24
+ session.
25
+
26
+ ## The round
27
+
28
+ 1. **Compute the frontier.** Every question with settled prerequisites,
29
+ nothing else. Never ask a question whose answer depends on one still open.
30
+
31
+ 2. **Facts are your job, never the user's.** Skip a question that an
32
+ environment fact would answer. Dispatch parallel `Explore` subagents, one
33
+ per distinct place to look, not a fixed count. Fold what they find into
34
+ the round.
35
+
36
+ 3. **Run it before you ask it.** Check whether running something could answer
37
+ the question – behaviour, timing, output, or performance. If it could,
38
+ dispatch a subagent to build a throwaway prototype instead of asking the
39
+ user:
40
+ - The subagent builds it in `/tmp/acstack-proto/<node-id>/`, or
41
+ `/tmp/acstack-proto/<short-slug>/` with no map
42
+ - It imports repo code by absolute path, and never creates a prototype
43
+ file inside the repo
44
+ - It returns the answer and its evidence, then deletes the folder
45
+ - You record both on the node, or in the conversation with no map
46
+
47
+ Questions of taste, product, or preference still go to the user. No
48
+ prototype code is ever copied into the repo – the real build goes
49
+ through the normal TDD pipeline.
50
+
51
+ 4. **Number the questions.** Attach a recommended answer to each, with one
52
+ line of reasoning. A question you cannot recommend an answer for is usually
53
+ two questions.
54
+
55
+ 5. **Present the whole round at once** (see Presentation). One round, one
56
+ message. Never trickle questions one at a time.
57
+
58
+ 6. **Record each answer.** If no option matches, the reply itself is the
59
+ answer, never the nearest option.
60
+
61
+ 7. **Recompute the frontier.** Answers surface new questions and unblock old
62
+ ones. Derive the next round fresh. Never continue down a list planned in
63
+ advance.
64
+
65
+ ## Presentation
66
+
67
+ `workflow.grilling.questions` in `acstack/project.yaml` picks the mode:
68
+
69
+ | Value | Behaviour |
70
+ | ---------------- | ------------------------------------------------------------------------------------ |
71
+ | `tool` (default) | the host's question tool (AskUserQuestion on Claude Code), one call per round |
72
+ | `inline` | questions as prose in the reply – also what `tool` means on a host with no such tool |
73
+
74
+ **`tool` falls back to inline** for any round it cannot hold: more than 4
75
+ questions, or any question with no discrete options. Never split one round
76
+ across two tool calls – a round is the whole frontier, and splitting it
77
+ reintroduces the ordering the frontier exists to prevent. In tool mode, put
78
+ the recommended option first with "(Recommended)".
79
+
80
+ **Inline format**: numbered questions, options in a table, the recommended
81
+ option **bolded** with its one-line reason. Prose follows the `writing` skill.
82
+
83
+ Whichever mode runs, an open answer survives: if the user types something no
84
+ option covers, that text is the answer.
85
+
86
+ ## Stop condition
87
+
88
+ Stop when the frontier is empty, or the user signals stop ("stop", "done",
89
+ "proceed").
90
+
91
+ There is no question cap. Settled prerequisites already bound the
92
+ frontier, and provenance keeps it narrow. Every question hangs off the
93
+ answer that surfaced it, so nothing unrelated can join the round.
94
+
95
+ A cap would be a blunt proxy for a guarantee the frontier definition
96
+ provides.
97
+
98
+ ## On a map
99
+
100
+ When the questions are map nodes, each answer is a resolution – all through
101
+ the tracker's `update` and `create` operations:
102
+
103
+ 1. Append the answer to the node body under `## Answer`. Mark the node
104
+ resolved. On the files backend, one `acstack node update` call does both.
105
+
106
+ Write the answer per the `writing` skill.
107
+
108
+ 2. Create a node for each new question the answer surfaced, with `answers`
109
+ naming the node that surfaced it. Questions that can be stated precisely
110
+ are `open`; the rest are `fog`.
111
+
112
+ 3. Invoke the `record-context` skill for each resolution – it decides whether
113
+ the decision earns an ADR, a glossary term, both, or neither.
114
+
115
+ 4. Redraw the resolved node's own diagram to mark the path you chose, then
116
+ regenerate its parent's. The map skill's `visuals.md` holds the rules and
117
+ the command.
118
+
119
+ 5. Recompute the frontier with the tracker's query and present the next
120
+ round.
121
+
122
+ **Example** – the `## Answer` body of a node asking whether map nodes
123
+ belong in git:
124
+
125
+ ```markdown
126
+ ## Answer
127
+
128
+ Map nodes stay out of git. `acstack/maps/` goes in `.gitignore`, because a
129
+ node is working state that the map throws away once it clears.
130
+
131
+ The durable output is the living specs, the architecture decision records and
132
+ the glossary. The `record-context` skill extracts each one as a node
133
+ resolves, so nothing of lasting value leaves with the nodes.
134
+ ```
@@ -0,0 +1,250 @@
1
+ ---
2
+ name: handoff
3
+ description: Hand the current work to a visible agent – a new one running in its own pane, or one already running. Writes only what nothing on disk holds – the next action, decisions already made, blockers, file ownership – and references everything else. Invoke when the user asks to hand work over or to spin the work out to another agent, or when context pressure makes continuing in this session unwise. Keeping the work in this session across a context compaction is the compact-and-continue skill's job.
4
+ argument-hint: "[focus note – what the receiving agent must not lose]"
5
+ ---
6
+
7
+ ## User input
8
+
9
+ ```text
10
+ $ARGUMENTS
11
+ ```
12
+
13
+ Treat the argument as the focus for the receiving agent.
14
+
15
+ # Hand the work over
16
+
17
+ A handoff moves the current work to an agent a human can see – a named session
18
+ in a visible pane, or a session already running. To keep the work in THIS
19
+ session across a context compaction instead, use `compact-and-continue`.
20
+
21
+ ## Only the lead session runs this
22
+
23
+ An agent that another agent launched stops here. One Bash call tells you
24
+ whether you are one. Replace `<nonce>` with eight random hex characters, picked
25
+ fresh, and never with a value already used in this session:
26
+
27
+ <!-- lead-check: tests/test-skill-gates.sh extracts and runs the block below -->
28
+
29
+ ```bash
30
+ n=acstack-whoami-<nonce>
31
+ s="${CLAUDE_CODE_SESSION_ID:-none}"
32
+ p="${CLAUDE_CONFIG_DIR:-$HOME/.claude}/projects"
33
+ case "${PI_SESSION_FILE:-}" in
34
+ */run-[0-9]*/session.jsonl|*/forks/*.jsonl) echo "child: $PI_SESSION_FILE"; exit 0;;
35
+ ?*) [ -z "${CLAUDE_CODE_SESSION_ID:-}" ] && { echo "lead"; exit 0; };;
36
+ esac
37
+ for _ in $(seq 1 20); do
38
+ m=$(grep -lF "$n" "$p"/*/"$s"/subagents/agent-*.jsonl 2>/dev/null </dev/null | head -1)
39
+ [ -n "$m" ] && { echo "child: $m"; exit 0; }
40
+ grep -qF "$n" "$p"/*/"$s".jsonl 2>/dev/null </dev/null && { echo "lead"; exit 0; }
41
+ sleep 0.5
42
+ done
43
+ echo "lead"
44
+ ```
45
+
46
+ `lead` means carry on. `child: <path>` means stop, and tell whoever launched
47
+ you that this skill runs only in the lead session. Report your state upward
48
+ instead – in your final message, or through your host's agent-messaging tool
49
+ (`SendMessage` on Claude Code). The lead then hands off or compacts.
50
+
51
+ Read [`lead-check.md`](lead-check.md) before you change that command, or when
52
+ its answer looks wrong. It says why a child must stop, and what it checks.
53
+
54
+ ## First: is this yours to invoke?
55
+
56
+ If the user asked for a handoff, proceed. If you invoke it on your own
57
+ initiative, first read `workflow.handoff.self_invoke` from `acstack/project.yaml`.
58
+
59
+ If it is `false`, stop. Tell the user a handoff looks warranted and why. Ask
60
+ permission.
61
+
62
+ Unset means `true`.
63
+
64
+ ## Where the work goes
65
+
66
+ herdr is the terminal workspace manager some sessions run inside. Four terms
67
+ carry its vocabulary, defined once here.
68
+
69
+ A **herdr workspace** is a git worktree. A **herdr tab** is a session working
70
+ inside one.
71
+
72
+ A **pane** is the terminal rectangle a session occupies. An **agent** is a named
73
+ session herdr supervises.
74
+
75
+ One rule decides the destination:
76
+
77
+ | The work is | Goes to |
78
+ | -------------------------------------------- | ---------------------------------------------------------------- |
79
+ | a continuation of what this session is doing | a new **tab** in this workspace – same worktree, same files |
80
+ | genuinely separate, or runs in parallel | a new **worktree**, so a new **workspace**, with its own checkout |
81
+ | better suited to an agent already running | that agent, by message – no new pane at all |
82
+
83
+ Ambiguous cases go to the user. Do not guess. Without herdr there are no tabs
84
+ and no workspaces, so this table collapses to two cases – *Without herdr*, in
85
+ [`launch-without-herdr.md`](launch-without-herdr.md), gives that variant.
86
+
87
+ **Consider the agents already running before launching anything.** List live
88
+ sessions with `claude agents --json`, which works with no terminal attached.
89
+
90
+ Read [`running-agent.md`](running-agent.md) when the listing shows a live session.
91
+
92
+ ## The rule that governs the handoff
93
+
94
+ *Reference state. Never copy it.*
95
+
96
+ A handoff that restates the repo is a second copy of the repo, correct only at
97
+ the moment you write it. Anything the receiving agent can run a command to learn,
98
+ it should run the command.
99
+
100
+ | Do not write it down | The receiving agent gets it from |
101
+ | --------------------------- | --------------------------------------------------------------------------------- |
102
+ | Map state and reading order | `~/.claude/acstack/bin/acstack node walk --map <name>` (reading order of the map) |
103
+ | What can be worked next | `~/.claude/acstack/bin/acstack node frontier --map <name>` (what is workable now) |
104
+ | Files in flight | `git status --short` and `git diff` |
105
+ | Test baseline, last result | `.test-baseline`, then run the suite |
106
+ | What the code does | the living specs in `acstack/specs/` |
107
+
108
+ On GitHub, `--map` refuses – pipe `gh issue list` into `--stdin` per the
109
+ map skill's `trackers/github.md`.
110
+
111
+ The same applies to specs, architecture decision records, issues and commits.
112
+ Reference them by path or URL.
113
+
114
+ **You do not search the codebase for this.** Build the handoff from what is already
115
+ in context. If you are about to search source files, stop – the conversation holds it.
116
+
117
+ ## What only a handoff can carry
118
+
119
+ *Five things. Nothing on disk records them, so what you leave out disappears.*
120
+
121
+ 1. **Next action** – the single concrete thing to do first
122
+ 2. **Decisions made** – so nobody reopens and re-argues them
123
+ 3. **Open questions and blockers** – including anything waiting on the user
124
+ 4. **Agent-team file ownership** – each scope, its teammate, its non-overlapping
125
+ file set. Also name any shared file to touch only after the team finishes.
126
+ Nothing else records this
127
+
128
+ 5. **Suggested skills** – which skills the receiving agent should invoke, by name
129
+
130
+ Omit any that do not apply. Do not pad.
131
+
132
+ Prose follows the `writing` skill.
133
+
134
+ ## Redaction
135
+
136
+ *The handoff leaves the conversation and becomes another agent's prompt.*
137
+
138
+ Strip credentials, tokens, API keys, connection strings and personal data before
139
+ writing. Reference where a secret lives, not its value. This is not optional.
140
+
141
+ ## Write the handoff file
142
+
143
+ Write the handoff to the OS temporary directory, never the workspace – it is
144
+ conversation content, not project state, and must not be committable. Name it
145
+ `$TMPDIR/acstack-handoff-<slug>-<timestamp>.md` (`/tmp` when `$TMPDIR` holds
146
+ nothing), where `<slug>` names the work and `<timestamp>` stops two handoffs
147
+ colliding.
148
+
149
+ Its first line, above every heading, repeats the acknowledgement requirement
150
+ verbatim, with `<this-file>` replaced by the file's own path:
151
+
152
+ ```text
153
+ Acknowledge before any other tool call. Run ~/.claude/acstack/bin/acstack handoff ack accept --file <this-file> "<one-line reason>", or ack decline --file <this-file> "<one-line reason>". The command writes <this-file>.ack, which the sender watches.
154
+ ```
155
+
156
+ This temp file is not `acstack/HANDOFF.md`, the `compact-and-continue` anchor.
157
+ Never put this line into that anchor, which has to start with `---` frontmatter.
158
+
159
+ Head the rest with the same skeleton the `compact-and-continue` anchor uses. The
160
+ headings are Next action, Decisions made, Open questions and blockers,
161
+ Agent-team plan, Suggested skills, References. That skeleton is the five carried
162
+ items above, plus the commands from the reference table instead of copied state.
163
+
164
+ Drop any heading with nothing under it.
165
+
166
+ The launch prompt is a **single-line pointer at that file**, never the handoff
167
+ text itself. `herdr agent start` rejects newlines and tabs in its arguments.
168
+
169
+ ## Every prompt opens with an acknowledgement
170
+
171
+ Every handoff prompt asks for the command.
172
+
173
+ There are two prompts, because the two destinations must say different things.
174
+ Use the matching one verbatim, and substitute only the handoff file path.
175
+
176
+ Each one is a single line. `herdr agent start` rejects newlines and tabs in its
177
+ arguments. So the instruction and the pointer at the handoff file share that one
178
+ line.
179
+
180
+ **Fresh agent** – one launched for this handoff, into a new pane, worktree or
181
+ tab, or as a `--bg` session. Reading the handoff file is the one tool call
182
+ allowed before the ack command. Every other tool call – a command, an edit, a
183
+ subagent – leaves the acknowledgement still owed.
184
+
185
+ > Before any other tool call, acknowledge this handoff by running ~/.claude/acstack/bin/acstack handoff ack accept --file <handoff-file> "<one-line reason>", or ack decline --file <handoff-file> "<one-line reason>". You may read <handoff-file> first to judge whether the work suits you, and nothing else until the command has run – the sender watches for the file it writes and cannot report this work as yours until it exists. Then continue that work.
186
+
187
+ **Agent already running** – one reached by cross-session message. Its variant
188
+ of the opener is in [`running-agent.md`](running-agent.md).
189
+
190
+ The agent may investigate before it decides. Acknowledgement comes first, work
191
+ second. Never start the work and acknowledge later – by then the sender has
192
+ already had to guess.
193
+
194
+ ## Launch
195
+
196
+ Read [`watch.md`](watch.md) first, for the pre-launch snapshot, then one of:
197
+
198
+ - [`launch-herdr.md`](launch-herdr.md) – `HERDR_ENV` is `1`, a new worktree or tab
199
+ - [`launch-without-herdr.md`](launch-without-herdr.md) – `HERDR_ENV` is not `1`
200
+ - [`running-agent.md`](running-agent.md) – an agent already running
201
+
202
+ ## Watch for the acknowledgement
203
+
204
+ Do not eyeball transcripts. The CLI watches for you:
205
+
206
+ ```bash
207
+ ~/.claude/acstack/bin/acstack handoff watch --file <handoff-file> \
208
+ --session-id <id> --cwd <dir> --token <token> --turns <n>
209
+ ```
210
+
211
+ **Run the watcher in the background.** This session has stopped working on the
212
+ task, but it must not lock up. The user can keep talking to it while the handoff
213
+ lands, and the harness surfaces the watcher's exit on its own. Never sit in a
214
+ foreground wait.
215
+
216
+ [`watch.md`](watch.md) gives every flag, `--fresh` among them. When the watcher
217
+ exits, read [`outcomes.md`](outcomes.md) for what its result means.
218
+
219
+ ## Silence the context-pressure nudge
220
+
221
+ Once you finish the handoff, write the quiet marker. The context-pressure Stop
222
+ hook reads it and stays silent for the rest of this session. The work has
223
+ already moved on, so there is nothing left to nudge about:
224
+
225
+ ```bash
226
+ d="${ACSTACK_CONTEXT_PRESSURE_DIR:-${TMPDIR:-/tmp}/acstack-context-pressure}"
227
+ sid="${CLAUDE_CODE_SESSION_ID:-${PI_SESSION_ID:-}}"; [ -n "$sid" ] && mkdir -p "$d" && : > "$d/$sid.quiet" || true
228
+ ```
229
+
230
+ `CLAUDE_CODE_SESSION_ID` (`PI_SESSION_ID` on pi) is this session's own id. The
231
+ lead check at the top ruled out child sessions, so the marker lands where the hook looks.
232
+
233
+ If the variable holds nothing, skip this step and say so in the report. The hook
234
+ then keeps nudging, which is noisy but harmless.
235
+
236
+ ## Report
237
+
238
+ Always name the target, the handoff file path, and the next action the receiving
239
+ agent would take. The target is an agent name with its pane or workspace, or the
240
+ existing session.
241
+
242
+ Then say where the handoff stands, in the terms of [`outcomes.md`](outcomes.md).
243
+
244
+ - accepted
245
+ - declined on fit, and relaunched elsewhere
246
+ - declined on the merits, with the objection in enough of its own words to act on
247
+ - proceeding, unacknowledged – the target engaged, and you spent the nudge
248
+ - unacknowledged – read `outcomes.md` for `staleAck` before you report this
249
+
250
+ Never describe the work as owned by the target until the target has accepted it.