@cluesmith/codev 3.3.4 → 3.3.5

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 (96) hide show
  1. package/dashboard-dist/assets/index-BuflRUi6.js +220 -0
  2. package/dashboard-dist/assets/index-BuflRUi6.js.map +1 -0
  3. package/dashboard-dist/assets/index-r3bZzLmX.css +32 -0
  4. package/dashboard-dist/index.html +2 -2
  5. package/dist/agent-farm/commands/send.d.ts +3 -2
  6. package/dist/agent-farm/commands/send.d.ts.map +1 -1
  7. package/dist/agent-farm/commands/send.js +24 -5
  8. package/dist/agent-farm/commands/send.js.map +1 -1
  9. package/dist/agent-farm/commands/spawn-worktree.d.ts.map +1 -1
  10. package/dist/agent-farm/commands/spawn-worktree.js +12 -2
  11. package/dist/agent-farm/commands/spawn-worktree.js.map +1 -1
  12. package/dist/agent-farm/servers/decisions/file.d.ts +50 -0
  13. package/dist/agent-farm/servers/decisions/file.d.ts.map +1 -0
  14. package/dist/agent-farm/servers/decisions/file.js +146 -0
  15. package/dist/agent-farm/servers/decisions/file.js.map +1 -0
  16. package/dist/agent-farm/servers/decisions/grammar.d.ts +36 -0
  17. package/dist/agent-farm/servers/decisions/grammar.d.ts.map +1 -0
  18. package/dist/agent-farm/servers/decisions/grammar.js +109 -0
  19. package/dist/agent-farm/servers/decisions/grammar.js.map +1 -0
  20. package/dist/agent-farm/servers/decisions/notice.d.ts +11 -0
  21. package/dist/agent-farm/servers/decisions/notice.d.ts.map +1 -0
  22. package/dist/agent-farm/servers/decisions/notice.js +18 -0
  23. package/dist/agent-farm/servers/decisions/notice.js.map +1 -0
  24. package/dist/agent-farm/servers/decisions/parse.d.ts +36 -0
  25. package/dist/agent-farm/servers/decisions/parse.d.ts.map +1 -0
  26. package/dist/agent-farm/servers/decisions/parse.js +308 -0
  27. package/dist/agent-farm/servers/decisions/parse.js.map +1 -0
  28. package/dist/agent-farm/servers/decisions/routes.d.ts +17 -0
  29. package/dist/agent-farm/servers/decisions/routes.d.ts.map +1 -0
  30. package/dist/agent-farm/servers/decisions/routes.js +160 -0
  31. package/dist/agent-farm/servers/decisions/routes.js.map +1 -0
  32. package/dist/agent-farm/servers/decisions/splice.d.ts +26 -0
  33. package/dist/agent-farm/servers/decisions/splice.d.ts.map +1 -0
  34. package/dist/agent-farm/servers/decisions/splice.js +120 -0
  35. package/dist/agent-farm/servers/decisions/splice.js.map +1 -0
  36. package/dist/agent-farm/servers/decisions/stamp.d.ts +4 -0
  37. package/dist/agent-farm/servers/decisions/stamp.d.ts.map +1 -0
  38. package/dist/agent-farm/servers/decisions/stamp.js +171 -0
  39. package/dist/agent-farm/servers/decisions/stamp.js.map +1 -0
  40. package/dist/agent-farm/servers/overview.d.ts +4 -3
  41. package/dist/agent-farm/servers/overview.d.ts.map +1 -1
  42. package/dist/agent-farm/servers/overview.js +51 -24
  43. package/dist/agent-farm/servers/overview.js.map +1 -1
  44. package/dist/agent-farm/servers/tower-routes.d.ts.map +1 -1
  45. package/dist/agent-farm/servers/tower-routes.js +63 -5
  46. package/dist/agent-farm/servers/tower-routes.js.map +1 -1
  47. package/dist/agent-farm/utils/message-format.d.ts +8 -0
  48. package/dist/agent-farm/utils/message-format.d.ts.map +1 -1
  49. package/dist/agent-farm/utils/message-format.js +16 -0
  50. package/dist/agent-farm/utils/message-format.js.map +1 -1
  51. package/dist/commands/consult/index.d.ts +20 -1
  52. package/dist/commands/consult/index.d.ts.map +1 -1
  53. package/dist/commands/consult/index.js +56 -2
  54. package/dist/commands/consult/index.js.map +1 -1
  55. package/dist/commands/porch/checks.d.ts +7 -1
  56. package/dist/commands/porch/checks.d.ts.map +1 -1
  57. package/dist/commands/porch/checks.js +77 -14
  58. package/dist/commands/porch/checks.js.map +1 -1
  59. package/dist/commands/porch/index.d.ts +38 -1
  60. package/dist/commands/porch/index.d.ts.map +1 -1
  61. package/dist/commands/porch/index.js +79 -43
  62. package/dist/commands/porch/index.js.map +1 -1
  63. package/dist/commands/porch/protocol.d.ts +4 -3
  64. package/dist/commands/porch/protocol.d.ts.map +1 -1
  65. package/dist/commands/porch/protocol.js +32 -5
  66. package/dist/commands/porch/protocol.js.map +1 -1
  67. package/dist/commands/porch/types.d.ts +2 -0
  68. package/dist/commands/porch/types.d.ts.map +1 -1
  69. package/dist/lib/agent-env.d.ts +10 -1
  70. package/dist/lib/agent-env.d.ts.map +1 -1
  71. package/dist/lib/agent-env.js +12 -1
  72. package/dist/lib/agent-env.js.map +1 -1
  73. package/dist/lib/config.d.ts +8 -0
  74. package/dist/lib/config.d.ts.map +1 -1
  75. package/dist/lib/config.js.map +1 -1
  76. package/package.json +4 -4
  77. package/skeleton/.claude/skills/afx/SKILL.md +15 -0
  78. package/skeleton/.claude/skills/arch-init/SKILL.md +56 -9
  79. package/skeleton/.claude/skills/arch-save/SKILL.md +100 -9
  80. package/skeleton/.claude/skills/consult/SKILL.md +9 -0
  81. package/skeleton/.claude/skills/porch/SKILL.md +18 -0
  82. package/skeleton/.codex/skills/afx/SKILL.md +15 -0
  83. package/skeleton/.codex/skills/arch-init/SKILL.md +56 -9
  84. package/skeleton/.codex/skills/arch-save/SKILL.md +100 -9
  85. package/skeleton/.codex/skills/consult/SKILL.md +9 -0
  86. package/skeleton/.codex/skills/porch/SKILL.md +18 -0
  87. package/skeleton/protocol-schema.json +6 -0
  88. package/skeleton/protocols/maintain/protocol.md +5 -0
  89. package/skeleton/protocols/pir/prompts/review.md +0 -1
  90. package/skeleton/protocols/protocol-schema.json +6 -0
  91. package/skeleton/resources/commands/agent-farm.md +44 -0
  92. package/skeleton/resources/commands/consult.md +9 -2
  93. package/skeleton/templates/cheatsheet.md +1 -1
  94. package/dashboard-dist/assets/index-DZf6pNPE.js +0 -199
  95. package/dashboard-dist/assets/index-DZf6pNPE.js.map +0 -1
  96. package/dashboard-dist/assets/index-DnYLy5C_.css +0 -32
@@ -46,12 +46,56 @@ name in a multi-architect workspace).
46
46
  (`codev/state/*.md`); never commit them. Builder `*_thread.md` files
47
47
  are the opposite: versioned, shipping with each builder PR.
48
48
 
49
- 3. **Confirm identity + orient, then follow the state file.** In one tight
50
- block, report: who you now are (name + one-line role from the banner, if
51
- present), the file you read, and the current-state / open-loops summary
52
- from the most recent dated section (or the file's leading content if it
53
- has no dated sections). Then carry out whatever the state file says to do
54
- on resume. Do not invent a new agenda — resume the one the state file
49
+ 3. **Confirm identity + orient.** In one tight block, report: who you now are
50
+ (name + one-line role from the banner, if present), the file you read, and
51
+ the current-state / open-loops summary from the most recent dated section
52
+ (or the file's leading content if it has no dated sections). If the banner
53
+ carries a `NEXT TASK` line, report both halves of it, as
54
+ `Next task from the owner at save time: <verbatim> → resolved: <gloss>`
55
+ (omit `→ resolved: …` when the line carries no `[resolved at save: …]` gloss).
56
+
57
+ 4. **Start on the next task, if the banner carries one.** It is the **first
58
+ action of the resumed session**, ahead of the general resume agenda — the
59
+ owner wrote it at save time precisely so it would not have to be typed
60
+ again once you came back. Begin it without waiting for a further prompt.
61
+ - It carries the owner's authority the way any owner message does, **with
62
+ the standard limits unchanged**. A next task never by itself approves a
63
+ porch gate, merges a PR, cuts a release, restarts Tower, or performs any
64
+ other act that needs a per-occasion word. If the next task *is* such an
65
+ act, prepare it and ask for the word live: a saved instruction is an
66
+ instruction, not a pre-spent approval.
67
+ - **The gloss carries the word — for the items it names, and only them.**
68
+ Items named in a `[resolved at save: …]` gloss are approved for the act
69
+ the owner's words name: "merge them all [resolved at save: PRs #1710,
70
+ #1712]" means merge #1710 and #1712 without asking again. The owner gave
71
+ the word at save time, and the saving session pinned it to those items.
72
+ This narrows the rule above; it does not remove it — and a line with no
73
+ gloss pre-approves nothing:
74
+ - The act must be the one the owner's words say. **A gloss never widens
75
+ the verb** — "merge" does not also approve a release.
76
+ - **Anything not in the gloss still needs the word live.** A PR that
77
+ appeared after the save, an item the gloss did not name, a gate the
78
+ words did not mention → prepare and ask, exactly as above.
79
+ - Porch gates are still relayed to the builder, never run by you: the
80
+ gloss lets you *relay* the approval without re-asking; it does not
81
+ change who runs `porch approve`.
82
+ - Ordinary verification still applies: an approved merge still waits for
83
+ green CI, and a gloss item you find already merged, closed, or changed
84
+ is reported, not forced.
85
+ - **A line marked `[carried over — …]` is orientation only.** Its gloss
86
+ was written by an earlier cycle and carries no word: ask for it before
87
+ any gated act.
88
+ - **This does not narrow the gate rule.** The human decision was explicit
89
+ at save time, and the gloss is its record. What the rule forbids —
90
+ inferring approval from a gate notification, from silence, or from an
91
+ agent's own judgment — stays forbidden; a gloss is none of those.
92
+ - **Once you have started, delete the `NEXT TASK` line from the banner**
93
+ and record the pickup as a log entry (`picked up next task: <verbatim>
94
+ → resolved: <gloss>`, omitting `→ resolved: …` when there was no gloss).
95
+ A second re-init, or the next `/arch-save`, must not re-run it.
96
+
97
+ 5. **Then follow the state file.** Carry out whatever it says to do on
98
+ resume. Do not invent a new agenda — resume the one the state file
55
99
  describes.
56
100
 
57
101
  ## Saving your state (and knowing when to `/clear`)
@@ -118,9 +162,12 @@ Do not repeat it, and do not prompt for it at any other time.
118
162
  **`/arch-save` packages this whole loop**, and is the preferred path when the
119
163
  owner directs a refresh: it stops your monitors, writes the pruned state file,
120
164
  clears, and schedules `/arch-init` to bring you back — in that order, which is
121
- the part that matters. The save discipline above is what it performs at its
122
- step 3, so this section remains the source of truth for *how to write the
123
- file*; `/arch-save` is the source of truth for *the sequence*. The manual path
165
+ the part that matters. It also accepts a **next task** as free text
166
+ (`/arch-save file and spawn that issue`), which it writes into the banner as a
167
+ `NEXT TASK` line for step 4 above to pick up. The save discipline above is
168
+ what it performs at its step 3, so this section remains the source of truth
169
+ for *how to write the file*; `/arch-save` is the source of truth for *the
170
+ sequence*. The manual path
124
171
  (save → human clears → `/arch-init`) stays valid and is the fallback when
125
172
  Tower is unavailable.
126
173
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: arch-save
3
3
  description: Save an architect's state, clear its context, and re-init automatically — the packaged save→clear→re-init refresh cycle. Use when the owner directs a context refresh, or says "/arch-save", "save and clear", "refresh your context". Runs on the owner's direction; an architect does not invoke it autonomously mid-task. Counterpart to /arch-init, which recovers the state this writes.
4
- argument-hint: "[name] (e.g. main; omit to auto-detect via afx whoami)"
4
+ argument-hint: "[name] [next task] (e.g. main; or: file and spawn that issue)"
5
5
  ---
6
6
 
7
7
  # /arch-save — save state, clear, and come back as yourself
@@ -9,7 +9,18 @@ argument-hint: "[name] (e.g. main; omit to auto-detect via afx whoami)"
9
9
  Long sessions accumulate stale context. This is the deliberate cure: you choose the
10
10
  moment, you choose what survives, and a fresh session resumes from what you wrote.
11
11
 
12
- `$ARGUMENTS` is the architect name (e.g. `main`). Omit it to auto-detect.
12
+ `$ARGUMENTS` carries the architect name, a **next task** for the session that comes back,
13
+ or both:
14
+
15
+ ```
16
+ /arch-save save, clear, re-init, then wait
17
+ /arch-save file and spawn that issue … and start on that first, unprompted
18
+ /arch-save main file and spawn that issue explicit name, then the next task
19
+ ```
20
+
21
+ The next task is how an owner who already knows what the refreshed session should do first
22
+ says so once, at the moment they direct the refresh, instead of watching for the re-init to
23
+ land and typing it again.
13
24
 
14
25
  ## When NOT to run this
15
26
 
@@ -28,20 +39,51 @@ action. A mid-task snapshot resumes into confusion.
28
39
  Do these in order. **The order is the feature** — step 3 must precede step 4, because the
29
40
  context that knows what to write is the one about to be destroyed.
30
41
 
31
- ### 1. Resolve your name
42
+ ### 1. Resolve your name, then split off the next task
32
43
 
33
- If `$ARGUMENTS` is non-empty, that is your name. Otherwise run `afx whoami` and use the
34
- reported `name` when `type: architect`.
44
+ **Always run `afx whoami` first**, whatever `$ARGUMENTS` holds — the split below cannot
45
+ tell a name from a task until it knows your name. The name rules are unchanged:
35
46
 
47
+ - `type: architect` → the reported `name` is yours.
36
48
  - `type: builder` → **STOP.** This terminal is a builder. Report the mismatch.
37
- - Non-zero exit → **STOP** and ask which architect you are. Do **not** guess, and do not
38
- default to `main` — writing another architect's state file is the exact failure
39
- `/arch-init` exists to prevent (#1094).
49
+ - Non-zero exit → you have no name yet. A single-token `$ARGUMENTS` that validates as a
50
+ name is still accepted as one; anything else → **STOP** and ask which architect you are.
51
+ Do **not** guess, and do not default to `main` — writing another architect's state file
52
+ is the exact failure `/arch-init` exists to prevent (#1094).
40
53
 
41
54
  **Validate the name before building any path**: `[a-z][a-z0-9-]*`, at most 64 characters.
42
55
  Reject slashes, `..`, uppercase, spaces. Never interpolate an unvalidated name into
43
56
  `codev/state/<name>.md`.
44
57
 
58
+ Then split `$ARGUMENTS`:
59
+
60
+ 1. `$ARGUMENTS` is empty → name from `afx whoami`, and there is no next task.
61
+ 2. The **first whitespace-separated token** equals the whoami name (or, when whoami could
62
+ not resolve one, is a single token that validates as a name) → that token is the name,
63
+ and the **remainder** is the next-task text, which may be empty.
64
+ 3. Otherwise → the **whole** of `$ARGUMENTS` is the next-task text, and the name comes
65
+ from `afx whoami`.
66
+
67
+ So `/arch-save` and `/arch-save main` behave exactly as they always have. The one
68
+ ambiguity — a next task whose first word happens to be your own architect name — is
69
+ accepted rather than worked around: lead with the explicit name
70
+ (`/arch-save main main is stalled, look at it`) to disambiguate.
71
+
72
+ **If you had to ask which architect you are, the next task still stands.** The answer
73
+ supplies the name; `$ARGUMENTS` already supplied the task. Do not make the owner retype it.
74
+
75
+ **Guard, applied after the split: a leading token that names a *different* architect stops
76
+ you.** If the first token validates as a name, differs from the name whoami reported, and
77
+ `codev/state/<token>.md` exists → **STOP and ask which architect you are. Write nothing.**
78
+ whoami can be wrong (#1094), and rule 3 would otherwise bury a real name-override inside
79
+ next-task text and save to whoami's file; a task that merely opens with a sibling's name is
80
+ the only case this costs, and it costs one clarification.
81
+
82
+ **This is not how `/arch-init` resolves a name**, and the asymmetry is deliberate:
83
+ `/arch-init` takes no next task, so any non-empty argument there is unambiguously a name
84
+ and overrides whoami outright. Here the first token is weighed *against* whoami, which is
85
+ why the guard above exists — never save into a name you did not verify.
86
+
45
87
  ### 2. Stop your own monitors
46
88
 
47
89
  Enumerate every monitor, watcher or background task you armed, and stop it.
@@ -75,6 +117,50 @@ first (`cp codev/state/<name>.md codev/state/.<name>.bak.md`) is cheap insurance
75
117
  **Content guardrails.** No secrets — tokens, keys, credentials. No transcript dumps, no
76
118
  raw tool output. Only: current focus, open loops, and what a fresh session needs to resume.
77
119
 
120
+ **Write the next task into the banner**, if step 1 produced one. Add a single line to the
121
+ banner block, directly after the `⭐ THIS /clear IS INTENTIONAL` line:
122
+
123
+ ```
124
+ # ⏭ NEXT TASK (owner-directed at save, 2026-09-19T02:10Z): file and spawn that issue
125
+ ```
126
+
127
+ - **Verbatim.** Collapse newlines to spaces; do not paraphrase, expand, or "helpfully"
128
+ plan it. Those are the owner's words, and the context writing them down is the one about
129
+ to be destroyed — this is the last moment at which a paraphrase can be caught.
130
+ - **New text replaces** any existing NEXT TASK line.
131
+ - **No new text preserves an existing one.** A NEXT TASK line still in the banner means the
132
+ previous cycle never came back to pick it up; dropping it silently would lose an owner
133
+ instruction that nothing else is holding. **Mark it carried over when you preserve it:**
134
+ append `[carried over — gloss orients only; re-confirm before acting]` to the line (once;
135
+ a line already marked stays as it is). A gloss carries the owner's word only for the
136
+ cycle that wrote it.
137
+
138
+ **Then resolve its referents — resolve, don't plan.** After the clear, "them" points at
139
+ nothing; this context is the only one that knows what the owner meant. So pin every
140
+ referent in the owner's words to a concrete, durable identifier, and append it to the same
141
+ line, after the verbatim text, as a `[resolved at save: …]` gloss:
142
+
143
+ ```
144
+ # ⏭ NEXT TASK (owner-directed at save, 2026-09-22T13:40Z): merge them all [resolved at save: PRs #1710, #1712, #1715]
145
+ ```
146
+
147
+ - **Every referent.** Pronouns and deictics — "them", "that issue", "his PR", "the failing
148
+ one" — become PR numbers, issue numbers, builder ids, branch names, file paths.
149
+ - **Resolution only.** The gloss names *what*, never *how*: no steps, no ordering, no
150
+ caveats, no "after CI is green". A gloss that contains a plan has overstepped; the
151
+ resumed session plans.
152
+ - **No referents → no gloss.** `/arch-save review PR #1712` needs nothing; write the line
153
+ as above without one. Never add an empty or redundant gloss.
154
+ - **Cannot resolve → do not clear.** If any referent is ambiguous or unknown to you,
155
+ **stop before step 4** and ask the owner which items are meant. Clearing with an
156
+ unresolved task destroys the only context that could have answered. This is the one
157
+ case where `/arch-save` may pause its own cycle — it is cheap, and the alternative is a
158
+ wrong merge. Tell the owner your monitors are already stopped (step 2), and on their
159
+ answer resume from here: write the gloss, then continue to step 4.
160
+
161
+ The gloss is more than orientation: `/arch-init` treats the items it names as approved for
162
+ the act the owner's words name, so it is how the owner's word survives the clear.
163
+
78
164
  Use the template at the end of this document.
79
165
 
80
166
  ### 4. Clear
@@ -160,12 +246,17 @@ literal text on the front of the next message never executes.
160
246
 
161
247
  The structure below comes from a live run of this cycle. Every element earns its place;
162
248
  keep them all, including a `MONITORS:` line even when the answer is "none armed" — an
163
- omitted monitor list is indistinguishable from a forgotten one.
249
+ omitted monitor list is indistinguishable from a forgotten one. The `NEXT TASK` line is the
250
+ single exception: it appears only when there is one.
164
251
 
165
252
  ```
166
253
  # <lane> architect — state (vNN, <date> ~HH:MM UTC — <milestone>, DELIBERATE /clear cycle)
167
254
  # ⭐ THIS /clear IS INTENTIONAL (owner-directed context refresh). On re-init: normal
168
255
  # /arch-init flow, then:
256
+ # ⏭ NEXT TASK (owner-directed at save, <ISO timestamp>): <the owner's words, verbatim> [resolved at save: <referents>]
257
+ # — OPTIONAL; present only when the save carried one. The `[resolved at save: …]` gloss
258
+ # is optional too: present only when the words had referents to resolve. /arch-init
259
+ # starts here before the agenda below, then deletes this line and logs the pickup.
169
260
  # 1. MONITORS: <what to stop if it is still firing, then what to re-arm> — watch target,
170
261
  # cadence, alert pattern. Self-test once before trusting alerts. ("none armed" is a
171
262
  # valid and complete answer.)
@@ -24,6 +24,15 @@ The `-m` / `--model` flag is **always required** except for `consult stats`.
24
24
  | `codex` | `gpt` | Thorough (~200-250s), shell exploration |
25
25
  | `claude` | `opus` | Agent SDK with tool use (~60-120s) |
26
26
 
27
+ ## Credentials and `.env`
28
+
29
+ `consult` loads `<workspace>/.env` and sets every key the shell does not already define, **credentials included**. Those override your stored login:
30
+
31
+ - claude: `CLAUDE_CODE_OAUTH_TOKEN` (or `ANTHROPIC_AUTH_TOKEN` / `ANTHROPIC_API_KEY`) beats the keychain login. When an OAuth token is set, the API keys are dropped.
32
+ - codex: `CODEX_API_KEY` beats the ChatGPT login. `OPENAI_API_KEY` is ignored.
33
+
34
+ Each SDK lane prints what it authenticates with, e.g. `[CLAUDE] auth: CLAUDE_CODE_OAUTH_TOKEN (from .env)`. If a review fails with a usage-limit or auth error while your own login works, check that line first. A key exported in the shell wins over `.env`.
35
+
27
36
  ## All flags
28
37
 
29
38
  ```
@@ -45,6 +45,7 @@ porch approve 42 pr --a-human-explicitly-approved-this
45
45
 
46
46
  ```bash
47
47
  porch pending # List all gates waiting for approval
48
+ porch pending --all # Include stale records on finished/advanced projects (hidden by default)
48
49
  ```
49
50
 
50
51
  ## Critical rules
@@ -55,6 +56,23 @@ porch pending # List all gates waiting for approval
55
56
  - `porch run` is for strict mode only — soft mode builders follow the protocol document manually
56
57
  - When running `porch approve` from the architect, use a subshell if you need worktree context: `(cd /path/to/worktree && porch approve ...)`
57
58
 
59
+ ## Check overrides and timeouts (`porch.checks`)
60
+
61
+ Override a protocol check per name in `.codev/config.json` under `porch.checks` instead of forking `protocol.json`. Each entry takes `command` (replace), `cwd` (replace), `timeout_ms` (replace), and/or `skip: true`:
62
+
63
+ ```jsonc
64
+ {
65
+ "porch": {
66
+ "checks": {
67
+ "tests": { "command": "uv run pytest", "timeout_ms": 900000 },
68
+ "e2e_tests": { "skip": true }
69
+ }
70
+ }
71
+ }
72
+ ```
73
+
74
+ A phase check is killed after 5 minutes unless it sets `timeout_ms` — in `protocol.json` or in its `porch.checks` override. On timeout porch kills the check's whole process tree.
75
+
58
76
  ## State storage
59
77
 
60
78
  Project state lives in `codev/projects/<id>-<name>/status.yaml`, managed automatically by porch. The status file tracks current phase, gate states, consultation results, and timestamps.
@@ -184,8 +184,23 @@ There is NO `afx tower restart` — use `afx tower stop && afx tower start`.
184
184
  ```bash
185
185
  afx workspace start # Start workspace for current project
186
186
  afx workspace stop # Stop workspace processes
187
+ afx workspace add-architect --name <name> # Add a named sibling architect terminal
188
+ afx workspace remove-architect <name> # Remove a sibling architect (cannot remove main)
189
+ afx workspace recover # Revive builders whose shellper died (e.g. after reboot)
187
190
  ```
188
191
 
192
+ **Recreating a dead architect** (its process died while Tower kept the registration):
193
+ re-add it under the SAME name, then re-init its identity:
194
+
195
+ ```bash
196
+ afx workspace add-architect --name <name>
197
+ afx send architect:<name> "/arch-init <name>"
198
+ ```
199
+
200
+ Builder-to-architect affinity survives the death (builders keep their Owner), so a
201
+ same-name re-add restores routing with no worktree impact and no builder disruption.
202
+ `afx workspace recover` revives builders only, not architects.
203
+
189
204
  `afx dash` is a deprecated alias — use `afx workspace` instead.
190
205
 
191
206
  ## afx cron
@@ -46,12 +46,56 @@ name in a multi-architect workspace).
46
46
  (`codev/state/*.md`); never commit them. Builder `*_thread.md` files
47
47
  are the opposite: versioned, shipping with each builder PR.
48
48
 
49
- 3. **Confirm identity + orient, then follow the state file.** In one tight
50
- block, report: who you now are (name + one-line role from the banner, if
51
- present), the file you read, and the current-state / open-loops summary
52
- from the most recent dated section (or the file's leading content if it
53
- has no dated sections). Then carry out whatever the state file says to do
54
- on resume. Do not invent a new agenda — resume the one the state file
49
+ 3. **Confirm identity + orient.** In one tight block, report: who you now are
50
+ (name + one-line role from the banner, if present), the file you read, and
51
+ the current-state / open-loops summary from the most recent dated section
52
+ (or the file's leading content if it has no dated sections). If the banner
53
+ carries a `NEXT TASK` line, report both halves of it, as
54
+ `Next task from the owner at save time: <verbatim> → resolved: <gloss>`
55
+ (omit `→ resolved: …` when the line carries no `[resolved at save: …]` gloss).
56
+
57
+ 4. **Start on the next task, if the banner carries one.** It is the **first
58
+ action of the resumed session**, ahead of the general resume agenda — the
59
+ owner wrote it at save time precisely so it would not have to be typed
60
+ again once you came back. Begin it without waiting for a further prompt.
61
+ - It carries the owner's authority the way any owner message does, **with
62
+ the standard limits unchanged**. A next task never by itself approves a
63
+ porch gate, merges a PR, cuts a release, restarts Tower, or performs any
64
+ other act that needs a per-occasion word. If the next task *is* such an
65
+ act, prepare it and ask for the word live: a saved instruction is an
66
+ instruction, not a pre-spent approval.
67
+ - **The gloss carries the word — for the items it names, and only them.**
68
+ Items named in a `[resolved at save: …]` gloss are approved for the act
69
+ the owner's words name: "merge them all [resolved at save: PRs #1710,
70
+ #1712]" means merge #1710 and #1712 without asking again. The owner gave
71
+ the word at save time, and the saving session pinned it to those items.
72
+ This narrows the rule above; it does not remove it — and a line with no
73
+ gloss pre-approves nothing:
74
+ - The act must be the one the owner's words say. **A gloss never widens
75
+ the verb** — "merge" does not also approve a release.
76
+ - **Anything not in the gloss still needs the word live.** A PR that
77
+ appeared after the save, an item the gloss did not name, a gate the
78
+ words did not mention → prepare and ask, exactly as above.
79
+ - Porch gates are still relayed to the builder, never run by you: the
80
+ gloss lets you *relay* the approval without re-asking; it does not
81
+ change who runs `porch approve`.
82
+ - Ordinary verification still applies: an approved merge still waits for
83
+ green CI, and a gloss item you find already merged, closed, or changed
84
+ is reported, not forced.
85
+ - **A line marked `[carried over — …]` is orientation only.** Its gloss
86
+ was written by an earlier cycle and carries no word: ask for it before
87
+ any gated act.
88
+ - **This does not narrow the gate rule.** The human decision was explicit
89
+ at save time, and the gloss is its record. What the rule forbids —
90
+ inferring approval from a gate notification, from silence, or from an
91
+ agent's own judgment — stays forbidden; a gloss is none of those.
92
+ - **Once you have started, delete the `NEXT TASK` line from the banner**
93
+ and record the pickup as a log entry (`picked up next task: <verbatim>
94
+ → resolved: <gloss>`, omitting `→ resolved: …` when there was no gloss).
95
+ A second re-init, or the next `/arch-save`, must not re-run it.
96
+
97
+ 5. **Then follow the state file.** Carry out whatever it says to do on
98
+ resume. Do not invent a new agenda — resume the one the state file
55
99
  describes.
56
100
 
57
101
  ## Saving your state (and knowing when to `/clear`)
@@ -118,9 +162,12 @@ Do not repeat it, and do not prompt for it at any other time.
118
162
  **`/arch-save` packages this whole loop**, and is the preferred path when the
119
163
  owner directs a refresh: it stops your monitors, writes the pruned state file,
120
164
  clears, and schedules `/arch-init` to bring you back — in that order, which is
121
- the part that matters. The save discipline above is what it performs at its
122
- step 3, so this section remains the source of truth for *how to write the
123
- file*; `/arch-save` is the source of truth for *the sequence*. The manual path
165
+ the part that matters. It also accepts a **next task** as free text
166
+ (`/arch-save file and spawn that issue`), which it writes into the banner as a
167
+ `NEXT TASK` line for step 4 above to pick up. The save discipline above is
168
+ what it performs at its step 3, so this section remains the source of truth
169
+ for *how to write the file*; `/arch-save` is the source of truth for *the
170
+ sequence*. The manual path
124
171
  (save → human clears → `/arch-init`) stays valid and is the fallback when
125
172
  Tower is unavailable.
126
173
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: arch-save
3
3
  description: Save an architect's state, clear its context, and re-init automatically — the packaged save→clear→re-init refresh cycle. Use when the owner directs a context refresh, or says "/arch-save", "save and clear", "refresh your context". Runs on the owner's direction; an architect does not invoke it autonomously mid-task. Counterpart to /arch-init, which recovers the state this writes.
4
- argument-hint: "[name] (e.g. main; omit to auto-detect via afx whoami)"
4
+ argument-hint: "[name] [next task] (e.g. main; or: file and spawn that issue)"
5
5
  ---
6
6
 
7
7
  # /arch-save — save state, clear, and come back as yourself
@@ -9,7 +9,18 @@ argument-hint: "[name] (e.g. main; omit to auto-detect via afx whoami)"
9
9
  Long sessions accumulate stale context. This is the deliberate cure: you choose the
10
10
  moment, you choose what survives, and a fresh session resumes from what you wrote.
11
11
 
12
- `$ARGUMENTS` is the architect name (e.g. `main`). Omit it to auto-detect.
12
+ `$ARGUMENTS` carries the architect name, a **next task** for the session that comes back,
13
+ or both:
14
+
15
+ ```
16
+ /arch-save save, clear, re-init, then wait
17
+ /arch-save file and spawn that issue … and start on that first, unprompted
18
+ /arch-save main file and spawn that issue explicit name, then the next task
19
+ ```
20
+
21
+ The next task is how an owner who already knows what the refreshed session should do first
22
+ says so once, at the moment they direct the refresh, instead of watching for the re-init to
23
+ land and typing it again.
13
24
 
14
25
  ## When NOT to run this
15
26
 
@@ -28,20 +39,51 @@ action. A mid-task snapshot resumes into confusion.
28
39
  Do these in order. **The order is the feature** — step 3 must precede step 4, because the
29
40
  context that knows what to write is the one about to be destroyed.
30
41
 
31
- ### 1. Resolve your name
42
+ ### 1. Resolve your name, then split off the next task
32
43
 
33
- If `$ARGUMENTS` is non-empty, that is your name. Otherwise run `afx whoami` and use the
34
- reported `name` when `type: architect`.
44
+ **Always run `afx whoami` first**, whatever `$ARGUMENTS` holds — the split below cannot
45
+ tell a name from a task until it knows your name. The name rules are unchanged:
35
46
 
47
+ - `type: architect` → the reported `name` is yours.
36
48
  - `type: builder` → **STOP.** This terminal is a builder. Report the mismatch.
37
- - Non-zero exit → **STOP** and ask which architect you are. Do **not** guess, and do not
38
- default to `main` — writing another architect's state file is the exact failure
39
- `/arch-init` exists to prevent (#1094).
49
+ - Non-zero exit → you have no name yet. A single-token `$ARGUMENTS` that validates as a
50
+ name is still accepted as one; anything else → **STOP** and ask which architect you are.
51
+ Do **not** guess, and do not default to `main` — writing another architect's state file
52
+ is the exact failure `/arch-init` exists to prevent (#1094).
40
53
 
41
54
  **Validate the name before building any path**: `[a-z][a-z0-9-]*`, at most 64 characters.
42
55
  Reject slashes, `..`, uppercase, spaces. Never interpolate an unvalidated name into
43
56
  `codev/state/<name>.md`.
44
57
 
58
+ Then split `$ARGUMENTS`:
59
+
60
+ 1. `$ARGUMENTS` is empty → name from `afx whoami`, and there is no next task.
61
+ 2. The **first whitespace-separated token** equals the whoami name (or, when whoami could
62
+ not resolve one, is a single token that validates as a name) → that token is the name,
63
+ and the **remainder** is the next-task text, which may be empty.
64
+ 3. Otherwise → the **whole** of `$ARGUMENTS` is the next-task text, and the name comes
65
+ from `afx whoami`.
66
+
67
+ So `/arch-save` and `/arch-save main` behave exactly as they always have. The one
68
+ ambiguity — a next task whose first word happens to be your own architect name — is
69
+ accepted rather than worked around: lead with the explicit name
70
+ (`/arch-save main main is stalled, look at it`) to disambiguate.
71
+
72
+ **If you had to ask which architect you are, the next task still stands.** The answer
73
+ supplies the name; `$ARGUMENTS` already supplied the task. Do not make the owner retype it.
74
+
75
+ **Guard, applied after the split: a leading token that names a *different* architect stops
76
+ you.** If the first token validates as a name, differs from the name whoami reported, and
77
+ `codev/state/<token>.md` exists → **STOP and ask which architect you are. Write nothing.**
78
+ whoami can be wrong (#1094), and rule 3 would otherwise bury a real name-override inside
79
+ next-task text and save to whoami's file; a task that merely opens with a sibling's name is
80
+ the only case this costs, and it costs one clarification.
81
+
82
+ **This is not how `/arch-init` resolves a name**, and the asymmetry is deliberate:
83
+ `/arch-init` takes no next task, so any non-empty argument there is unambiguously a name
84
+ and overrides whoami outright. Here the first token is weighed *against* whoami, which is
85
+ why the guard above exists — never save into a name you did not verify.
86
+
45
87
  ### 2. Stop your own monitors
46
88
 
47
89
  Enumerate every monitor, watcher or background task you armed, and stop it.
@@ -75,6 +117,50 @@ first (`cp codev/state/<name>.md codev/state/.<name>.bak.md`) is cheap insurance
75
117
  **Content guardrails.** No secrets — tokens, keys, credentials. No transcript dumps, no
76
118
  raw tool output. Only: current focus, open loops, and what a fresh session needs to resume.
77
119
 
120
+ **Write the next task into the banner**, if step 1 produced one. Add a single line to the
121
+ banner block, directly after the `⭐ THIS /clear IS INTENTIONAL` line:
122
+
123
+ ```
124
+ # ⏭ NEXT TASK (owner-directed at save, 2026-09-19T02:10Z): file and spawn that issue
125
+ ```
126
+
127
+ - **Verbatim.** Collapse newlines to spaces; do not paraphrase, expand, or "helpfully"
128
+ plan it. Those are the owner's words, and the context writing them down is the one about
129
+ to be destroyed — this is the last moment at which a paraphrase can be caught.
130
+ - **New text replaces** any existing NEXT TASK line.
131
+ - **No new text preserves an existing one.** A NEXT TASK line still in the banner means the
132
+ previous cycle never came back to pick it up; dropping it silently would lose an owner
133
+ instruction that nothing else is holding. **Mark it carried over when you preserve it:**
134
+ append `[carried over — gloss orients only; re-confirm before acting]` to the line (once;
135
+ a line already marked stays as it is). A gloss carries the owner's word only for the
136
+ cycle that wrote it.
137
+
138
+ **Then resolve its referents — resolve, don't plan.** After the clear, "them" points at
139
+ nothing; this context is the only one that knows what the owner meant. So pin every
140
+ referent in the owner's words to a concrete, durable identifier, and append it to the same
141
+ line, after the verbatim text, as a `[resolved at save: …]` gloss:
142
+
143
+ ```
144
+ # ⏭ NEXT TASK (owner-directed at save, 2026-09-22T13:40Z): merge them all [resolved at save: PRs #1710, #1712, #1715]
145
+ ```
146
+
147
+ - **Every referent.** Pronouns and deictics — "them", "that issue", "his PR", "the failing
148
+ one" — become PR numbers, issue numbers, builder ids, branch names, file paths.
149
+ - **Resolution only.** The gloss names *what*, never *how*: no steps, no ordering, no
150
+ caveats, no "after CI is green". A gloss that contains a plan has overstepped; the
151
+ resumed session plans.
152
+ - **No referents → no gloss.** `/arch-save review PR #1712` needs nothing; write the line
153
+ as above without one. Never add an empty or redundant gloss.
154
+ - **Cannot resolve → do not clear.** If any referent is ambiguous or unknown to you,
155
+ **stop before step 4** and ask the owner which items are meant. Clearing with an
156
+ unresolved task destroys the only context that could have answered. This is the one
157
+ case where `/arch-save` may pause its own cycle — it is cheap, and the alternative is a
158
+ wrong merge. Tell the owner your monitors are already stopped (step 2), and on their
159
+ answer resume from here: write the gloss, then continue to step 4.
160
+
161
+ The gloss is more than orientation: `/arch-init` treats the items it names as approved for
162
+ the act the owner's words name, so it is how the owner's word survives the clear.
163
+
78
164
  Use the template at the end of this document.
79
165
 
80
166
  ### 4. Clear
@@ -160,12 +246,17 @@ literal text on the front of the next message never executes.
160
246
 
161
247
  The structure below comes from a live run of this cycle. Every element earns its place;
162
248
  keep them all, including a `MONITORS:` line even when the answer is "none armed" — an
163
- omitted monitor list is indistinguishable from a forgotten one.
249
+ omitted monitor list is indistinguishable from a forgotten one. The `NEXT TASK` line is the
250
+ single exception: it appears only when there is one.
164
251
 
165
252
  ```
166
253
  # <lane> architect — state (vNN, <date> ~HH:MM UTC — <milestone>, DELIBERATE /clear cycle)
167
254
  # ⭐ THIS /clear IS INTENTIONAL (owner-directed context refresh). On re-init: normal
168
255
  # /arch-init flow, then:
256
+ # ⏭ NEXT TASK (owner-directed at save, <ISO timestamp>): <the owner's words, verbatim> [resolved at save: <referents>]
257
+ # — OPTIONAL; present only when the save carried one. The `[resolved at save: …]` gloss
258
+ # is optional too: present only when the words had referents to resolve. /arch-init
259
+ # starts here before the agenda below, then deletes this line and logs the pickup.
169
260
  # 1. MONITORS: <what to stop if it is still firing, then what to re-arm> — watch target,
170
261
  # cadence, alert pattern. Self-test once before trusting alerts. ("none armed" is a
171
262
  # valid and complete answer.)
@@ -24,6 +24,15 @@ The `-m` / `--model` flag is **always required** except for `consult stats`.
24
24
  | `codex` | `gpt` | Thorough (~200-250s), shell exploration |
25
25
  | `claude` | `opus` | Agent SDK with tool use (~60-120s) |
26
26
 
27
+ ## Credentials and `.env`
28
+
29
+ `consult` loads `<workspace>/.env` and sets every key the shell does not already define, **credentials included**. Those override your stored login:
30
+
31
+ - claude: `CLAUDE_CODE_OAUTH_TOKEN` (or `ANTHROPIC_AUTH_TOKEN` / `ANTHROPIC_API_KEY`) beats the keychain login. When an OAuth token is set, the API keys are dropped.
32
+ - codex: `CODEX_API_KEY` beats the ChatGPT login. `OPENAI_API_KEY` is ignored.
33
+
34
+ Each SDK lane prints what it authenticates with, e.g. `[CLAUDE] auth: CLAUDE_CODE_OAUTH_TOKEN (from .env)`. If a review fails with a usage-limit or auth error while your own login works, check that line first. A key exported in the shell wins over `.env`.
35
+
27
36
  ## All flags
28
37
 
29
38
  ```
@@ -45,6 +45,7 @@ porch approve 42 pr --a-human-explicitly-approved-this
45
45
 
46
46
  ```bash
47
47
  porch pending # List all gates waiting for approval
48
+ porch pending --all # Include stale records on finished/advanced projects (hidden by default)
48
49
  ```
49
50
 
50
51
  ## Critical rules
@@ -55,6 +56,23 @@ porch pending # List all gates waiting for approval
55
56
  - `porch run` is for strict mode only — soft mode builders follow the protocol document manually
56
57
  - When running `porch approve` from the architect, use a subshell if you need worktree context: `(cd /path/to/worktree && porch approve ...)`
57
58
 
59
+ ## Check overrides and timeouts (`porch.checks`)
60
+
61
+ Override a protocol check per name in `.codev/config.json` under `porch.checks` instead of forking `protocol.json`. Each entry takes `command` (replace), `cwd` (replace), `timeout_ms` (replace), and/or `skip: true`:
62
+
63
+ ```jsonc
64
+ {
65
+ "porch": {
66
+ "checks": {
67
+ "tests": { "command": "uv run pytest", "timeout_ms": 900000 },
68
+ "e2e_tests": { "skip": true }
69
+ }
70
+ }
71
+ }
72
+ ```
73
+
74
+ A phase check is killed after 5 minutes unless it sets `timeout_ms` — in `protocol.json` or in its `porch.checks` override. On timeout porch kills the check's whole process tree.
75
+
58
76
  ## State storage
59
77
 
60
78
  Project state lives in `codev/projects/<id>-<name>/status.yaml`, managed automatically by porch. The status file tracks current phase, gate states, consultation results, and timestamps.
@@ -215,6 +215,12 @@
215
215
  "type": "string",
216
216
  "description": "Human-readable description"
217
217
  },
218
+ "timeout_ms": {
219
+ "type": "integer",
220
+ "description": "Kill the check after this many milliseconds (default: 300000, i.e. 5 minutes)",
221
+ "minimum": 1,
222
+ "maximum": 2147483647
223
+ },
218
224
  "on_fail": {
219
225
  "type": "string",
220
226
  "enum": ["fail", "retry", "warn"],
@@ -7,6 +7,11 @@ Use it for dead code and unused dependencies, quarterly hygiene, pre-release cle
7
7
  keeping the governance docs honest — `arch.md`/`arch-critical.md`,
8
8
  `lessons-learned.md`/`lessons-critical.md`, and the `CLAUDE.md`↔`AGENTS.md` twins.
9
9
 
10
+ It is a scheduled, whole-repository run that a human asks for, scoped from the last run's base
11
+ commit. It is **not** the protocol for one targeted cleanup: a specific dead file, a drifted
12
+ document, or a stale section is an ordinary issue under BUGFIX (or AIR). Reaching for "a
13
+ MAINTAIN pass" to fix one thing misuses the since-marker and the audit discipline below.
14
+
10
15
  ## The state machine
11
16
 
12
17
  ```json
@@ -110,7 +110,6 @@ BRANCH="$(git branch --show-current)"
110
110
 
111
111
  export CODEV_PR_TITLE="$PR_TITLE"
112
112
  export CODEV_PR_BODY="$(cat codev/reviews/{{artifact_name}}.md)"
113
- export CODEV_PR_BASE=main
114
113
  export CODEV_PR_HEAD="$BRANCH"
115
114
 
116
115
  {{pr_create_command}}