Skip to content

fix(entry-skills): close the handoff fences — six files render their arms wrong#550

Open
leeovery wants to merge 6 commits into
fix/test-teardown-rmsync-retriesfrom
fix/entry-handoff-fences
Open

fix(entry-skills): close the handoff fences — six files render their arms wrong#550
leeovery wants to merge 6 commits into
fix/test-teardown-rmsync-retriesfrom
fix/entry-handoff-fences

Conversation

@leeovery

Copy link
Copy Markdown
Owner

Summary

  • Found by a prose-test walker. Walking workflow-specification-entry, it had to guess whether a fenced block ends at the next fence (what markdown actually does) or at the next arm heading (what the author meant) — and recorded AMBIGUOUS rather than choosing silently.
  • Markdown pairs fences in order. A missing closing fence therefore makes the next arm's heading render inside the previous arm's code block, and that arm's own arguments render as plain prose outside any block. Since each arm instructs "invoke the skill with the next fenced block as its arguments", a session following the prose literally is handed the wrong text.
  • Six of eight entry skills affected: implementation, investigation, planning, review, scoping, specification. discussion and research close their blocks correctly — which is what shows this is an omission rather than a house style.

Enumerated across every invoke-skill.md before fixing any of them; the first sweep only matched bare ``` and missed ```bash openers, which under-reported the damage — the corrected pass found six files rather than four.

Test plan

  • Verified by re-parsing all eight files: no unclosed blocks, no headings inside a block.
  • npm test green: 1699 tests, 0 fail.
  • Diff is additions only — eleven closing fences, zero lines removed, no wording changed.

🤖 Generated with Claude Code

leeovery and others added 6 commits July 25, 2026 22:09
…arms wrong

Found by a prose-test walker, which had to guess whether a fenced block
ends at the next fence (what markdown does) or at the next arm heading
(what the author meant), and recorded the ambiguity rather than picking
silently.

Markdown pairs fences in order, so a missing closing fence makes the
next arm's heading render *inside* the previous arm's code block, and
that arm's own arguments render as plain prose. In
workflow-specification-entry every one of the four arms was mispaired.
Since each arm says "invoke the skill with the next fenced block as its
arguments", a session following it literally is handed the wrong text.

Six of eight entry skills were affected; discussion and research close
their blocks correctly, which is what shows this is an omission rather
than a house style. Additions only — eleven closing fences, no wording
touched.

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

Lee's call, and the right one: a log the agent writes is the same trust
problem relocated. A PostToolUse hook declared in the walker's own agent
frontmatter — so it fires for walkers and nothing else — appends every
tool call to .walk-actions.log in the world, excluded from the diff.

Proven necessary, not assumed. A diagnostic walker's world held the
agent row at `incorporated` plus the report file, so it had run
dispatch, stub, scan and incorporate; its transcript began at the fifth
step. Four cases came back INVALID today for that reason alone, none of
them a prose fault. Two attempts to fix it with wording — a stricter log
format, then moving to Opus — both failed, because a narrative composed
at the end is a recollection however it is instructed.

Evidence now splits by kind: recorded actions are the authority on what
was done, the transcript on what was reasoned (which arm, which guard,
what was emitted), and the recording wins any disagreement. INVALID WALK
keys off the actions, so a walker that did the work and described it
poorly is judged rather than discarded.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
smoke-boot-in-world asked for what it forbade: the act stopped right
after boot returned, while the assertions were about renderings that
only happen in the arms after that point. The act now covers the whole
of initialisation and the claims match what it reaches.

implementation-picks-first-task scripted one answer against a flow that
asks three — environment setup, then project skills, then linters — so
both runs halted at an unscripted question, in different places. Rather
than script the extra gates, the case is narrowed to stop once the
environment is settled: answering them writes project_skills and
discovered linters whose values depend on what the fake project happens
to contain, which no expected world can pin. The task pickup wants its
own case, against a fixture where those are already settled.

Both were found by the UNSCRIPTED QUESTION marker and by the world diff
doing exactly what they exist for.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…udge without a record

The PostToolUse hook never fired: its command was a relative path, and
the walker's cwd is the world directory, so it resolved to
<world>/tests/prose/lib/… and failed silently. Now resolved via
$CLAUDE_PROJECT_DIR, with a throwaway shell probe alongside it so one
run distinguishes "hooks don't fire here" from "my path was wrong".

Hardening from the same round: an absent action log is the harness
failing, not the walk. run.cjs assert now refuses to emit a prompt at
all in that case, and the orchestrator reports HARNESS ERROR — five
runs had reported INVALID instead, which reads like a test result and
buried the actual cause.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Agent-frontmatter hooks do not fire in this environment — proven with a
bare `echo` probe that produced nothing across a full run, so it was
never the relative-path theory. Hooks in settings.json would fire, but
for every tool call in the project rather than just a walker's.

The harness already writes each subagent's session to a JSONL
transcript, which is the same evidence and better scoped: lib/actions.cjs
extracts the ordered tool calls, and `assert` now requires
--transcript. The orchestrator passes the output_file the walker's
dispatch reports.

The hooks block, record-action.cjs and the action-log plumbing are gone
rather than left dormant.

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

Lee was right to push back on abandoning them. Frontmatter hooks in a
project subagent are gated on hasTrustDialogAccepted (v2.1.218+) and
fail silently when it is false — which it was for this repo, despite
onboarding having completed long ago. Nothing was wrong with the
config: the shape matched the documented example exactly, and a bare
echo probe proved the hooks simply never ran.

With trust accepted, the walker's own PostToolUse hook fires and
records every tool call to .walk-actions.log in the world. The
project-level settings.json hook is gone — it worked, but fired for
every tool call in the repo rather than just a walker's — and so is the
transcript-parsing fallback it was standing in for.

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.

1 participant