Skip to content

[Air #1709] feat: /arch-save takes a next task, /arch-init starts on it - #1710

Open
waleedkadous wants to merge 6 commits into
mainfrom
builder/air-1709
Open

waleedkadous wants to merge 6 commits into
mainfrom
builder/air-1709

Conversation

@waleedkadous

@waleedkadous waleedkadous commented Sep 19, 2026

Copy link
Copy Markdown
Contributor

Summary

/arch-save now accepts a free-text next task, persists it in the state file's banner, and /arch-init starts on it as the first action of the resumed session — so an owner who already knows what the refreshed architect should do first says it once, at the moment they direct the refresh, instead of watching for the re-init to land and typing it again.

/arch-save file and spawn that issue        save, clear, re-init, then start on that
/arch-save main file and spawn that issue   explicit name still accepted
/arch-save                                  unchanged: save, clear, re-init, wait

Closes #1709

What Changed

Docs-only feature — both halves are skill documents, so the shipped SKILL.md text is the implementation.

arch-save/SKILL.md

  • argument-hint advertises the next task; the intro shows all three invocation forms.
  • Step 1 becomes "Resolve your name, then split off the next task": afx whoami first, then the three-rule split (empty → no task; first token == whoami name → name + remainder; otherwise → whole string is the task).
  • Step 3 gains a next-task block: write # ⏭ NEXT TASK (owner-directed at save, <ISO>): <text> directly after the ⭐ THIS /clear IS INTENTIONAL line, verbatim; new text replaces an existing line, no text preserves one.
  • The state-block template carries the line, marked OPTIONAL.

arch-init/SKILL.md

  • Old step 3 splits into 3 (orient — now reporting Next task from the owner at save time: <text>), 4 (start on it, delete the line, log the pickup), 5 (then follow the state file).
  • The "Saving your state" section gains one sentence so it does not contradict the new step 4.

All four copies of each skill (.claude / .codex × instance / skeleton) are byte-identical.

Key Decisions

  1. afx whoami now runs unconditionally, where it previously ran only when $ARGUMENTS was empty. Rule 2 of the split compares the first token against the whoami name, so the name must be known before the arguments can be parsed. Consequence: the non-zero-exit branch could no longer be an unconditional STOP, or /arch-save main would break whenever whoami was down. Written as: no name yet → a single validating token is still accepted as one, anything else stops and asks. That preserves both the back-compat path and the never-default-to-main guard (afx send: detectCurrentBuilderId silently falls back to bare worktree name on state.db read failure → builder messages misroute to main #1094).

  2. The line lives in the banner, not in a dated log entry. /arch-init reads the banner plus the most recent dated section; the banner is the half unambiguously read first, and it already holds the ⭐ THIS /clear IS INTENTIONAL resume instructions.

  3. A next task is an instruction, not a pre-spent approval. It carries the owner's authority the way any owner message does, with the standard limits unchanged — it never by itself approves a porch gate, merges, releases, or restarts Tower. If the next task is such an act, /arch-init prepares it and asks for the word live.

  4. Verbatim, with the reason attached. The context writing the line down is the one about to be destroyed, so a paraphrase is unrecoverable — that "why" travels with the rule in the doc.

  5. No text preserves an existing line rather than clearing it: a surviving NEXT TASK means the previous cycle never came back to pick it up, so dropping it silently would lose an owner instruction nothing else is holding.

Scope note: the issue named codev/roles/architect.md as a candidate for consistency edits. Grepping both trees found it does not mention /arch-save at all, so it needed no change. The other hits (builder-refresh frontmatter, agent-farm.md:514, tower-client.ts:797, reset/{constants,self}.ts) are all about the delayed send and clear/re-entry ordering, not the argument contract — left alone. The 1307-* spec/plan/review are historical artifacts, not living docs.

Test Plan

  • Unit tests added — packages/codev/src/agent-farm/__tests__/air-1709-next-task.test.ts (18 assertions)
  • Build passes — pnpm --filter @cluesmith/codev build
  • All tests pass — 307 files, 6175 passed / 48 skipped, exit 0; porch's own build + tests checks green

The new test pins every acceptance criterion in the issue: the three invocation forms, the three split rules, back-compat, the verbatim rule, replace-vs-preserve, the template line, the orient label, orient→next-task→state-file ordering, the not-a-pre-spent-approval limits, and delete-plus-log-the-pickup.

CMAP Review

gemini=APPROVE, codex=APPROVE, claude=APPROVE — all HIGH confidence.

Gemini and codex found nothing. Claude approved with four observations; each was verified against the files before acting. Three are applied in the follow-up commit:

Finding Action
The doc never said the next-task text survives the "which architect are you?" stop (whoami down + multi-token arguments) Applied — one sentence; the answer supplies the name, $ARGUMENTS already supplied the task
/arch-init frontmatter still says "an explicit name argument overrides"; the pair now resolves identity by different rules, unacknowledged in /arch-save Applied — /arch-save now states the asymmetry and why (/arch-init takes no next task, so any argument there is unambiguously a name)
A test regex pinned a hard line wrap (/\*\*first\n\s+action…/) and would fail on a pure reflow Applied — relaxed to \s+
Four-copy parity for arch-save duplicates spec-1307-arch-save-skill.test.ts:41 Confirmed and kept deliberately, now noted in the test header — both skills of one feature should fail together

The fourth finding went to the architect, who ruled: add the guard. The explicit-name override had narrowed — previously any non-empty $ARGUMENTS was the name, now only a first token equal to whoami's (or a lone validating token when whoami fails). The uncovered case was whoami answering with the wrong architect: /arch-save tower from a session whoami calls main would write to main's state file with no argument-level override. That is the #1094 failure class.

arch-save step 1 now carries, after the split: first token validates as a name, differs from whoami's, and codev/state/<token>.md exists → STOP and ask which architect you are, write nothing.

The existence check is what keeps it narrow. merge 1660 and review Amr's PR pass straight through; only a first word that is a live sibling's name stops, and it costs one clarification.

(Aside: the agy/gemini lane returned a clean VERDICT block on a --type pr review here — the known "agy consult broken for --type" issue did not reproduce.)

Review Notes

Two things worth a look:

packages/codev/skeleton/ is build-generated from codev-skeleton/ and gitignored — not touched.

🤖 Generated with Claude Code

waleedkadous and others added 3 commits September 19, 2026 07:32
An owner who already knows what the refreshed session should do first had
nowhere to put that instruction: /arch-save saved, cleared and re-inited, and
the architect came back oriented but idle, waiting to be told again.

/arch-save now takes the next task as free text. Argument resolution runs
`afx whoami` first (unconditionally now — the split compares the first token
against the resolved name), then: empty $ARGUMENTS means no next task; a first
token matching the whoami name is the name, with the remainder as the task; any
other leading token makes the whole of $ARGUMENTS the task. /arch-save and
/arch-save <name> are unchanged.

The task is written verbatim into the state file's banner as a NEXT TASK line,
directly after the intentional-clear line. New text replaces an existing line;
no text preserves one, since a surviving line means the previous cycle never
resumed to pick it up.

/arch-init reports it in the orient block and starts on it as the first action
of the resumed session, then deletes the line and logs the pickup so a second
re-init cannot re-run it. The standard limits are unchanged: a next task naming
a gate, merge, release or Tower restart produces a prepared request for the
word, not the act — a saved instruction is an instruction, not a pre-spent
approval.

All four copies of each skill stay byte-identical; the new test guards that for
arch-init too, which spec-1134 does not (it compares only .claude).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@waleedkadous

Copy link
Copy Markdown
Contributor Author

Thank you — this is a clean, careful implementation of #1709, and the thread's two recorded decisions (whoami runs unconditionally; the line lives in the banner, not the log) are exactly the right calls.

Architect check against the issue's prescribed design, item by item:

  • Argument split — whoami-first, empty → no task, leading-name → strip, else whole text is the task; the whoami-down fallback (single validating token still accepted, otherwise stop) keeps /arch-save main working without reopening the afx send: detectCurrentBuilderId silently falls back to bare worktree name on state.db read failure → builder messages misroute to main #1094 default-to-main hole. ✅
  • Banner line — placed directly under the ⭐ line, verbatim with newlines collapsed, new-replaces / empty-preserves, template updated and marked optional. ✅
  • Pickup in /arch-init — reported in the orient block, started first, standard gate/merge/release/restart limits restated as "an instruction, not a pre-spent approval", then delete + log. ✅
  • Copies — all eight byte-identical across .claude/.codex × instance/skeleton; argument-hint updated; the only other prose mentioning the cycle (agent-farm.md's delayed-send note) needs no change. ✅
  • Tests — the four-copy parity guard for both skills closes the gap the spec-1134 test left for .codex. Good catch.

No changes requested from my side. Waiting on the CMAP verdicts and CI, then I'll take it to the owner for the merge word.

waleedkadous and others added 3 commits September 19, 2026 07:43
All three reviewers approved; claude raised four points, three of which are
cheap and additive.

- The next task survives the "which architect are you?" stop. whoami down plus
  multi-token arguments falls through both split rules to STOP, which was the
  right outcome but left it unsaid that the task text is still in hand — an
  implementer could reasonably make the owner retype it.
- /arch-save and /arch-init now resolve a name by different rules, and
  /arch-save says so. /arch-init takes no next task, so any argument there is
  unambiguously a name and overrides whoami outright; here the first token is
  weighed against whoami instead. Notes that a whoami reporting the wrong
  architect cannot be overridden by argument alone, and to stop rather than
  save into an unverified name.
- Test nit: one regex pinned a hard line wrap and would have failed on a pure
  reflow with no semantic change.
- Recorded that spec-1307 already covers four-copy parity for arch-save; the
  duplicate stays so both skills of one feature fail together.

Claude's remaining finding — that the explicit-name override is narrower than
before — is the issue's prescribed rules 3 and 4, so it goes to the architect
rather than into this commit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…tect

Architect's ruling on the CMAP finding that the explicit-name override had
narrowed: add the guard rather than leave the rules as prescribed.

In arch-save step 1, after the split — if the first token validates as a name,
differs from the name whoami reported, and codev/state/<token>.md exists, STOP
and ask which architect you are, writing nothing.

whoami can be wrong (#1094), and without this rule 3 buries a real name-override
inside next-task text and saves to whoami's file. The existence check keeps it
narrow: a task that merely opens with a word shaped like a name passes through
untouched unless a state file for that name actually exists, so the only cost is
one clarification when the first word is a live sibling's name.

Rewriting the paragraph's closing sentence invalidated an assertion from the
previous commit; re-pinned to the new wording, which now points at the guard.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

/arch-save: accept a next-task instruction and have /arch-init start on it after the refresh

1 participant