feat(session-flow): context-driven continuation router - #3029
Conversation
Evolve the workflow skill's continuation router per AI Hero course lane 2 (#2900, decisions Q9/Q20-Q22). - Informant inputs as presence-gated pointers (orient, reconcile, the workflow checklist, the work-item tracker seam); no duplicated reads and no new pre-compute, so the skill's single gather block keeps its $-expansion ban. - New question 2: the AFK edge, routing the spawn-brief decision to orchestrate. Deliberately non-terminal, ordered after the explicit background request and before the zero-cost in-session exit, with its ordering purpose stated. Sibling hard gates untouched. - Suggest-by-default output shape (mechanism, evidence, next step) plus two licensed autonomy tiers: a per-invocation `continue auto` opt-in that expires with the invocation, and the orchestrator relay codified as the autonomous tier for delegated work. - I23 reconciliation recorded where the design is stated: the mechanism menu lives only in this user-invoked skill body, operator-channel pointers stay operator-side, and autonomy initiative never comes from injected context or a self-estimated budget. Closes #2971 Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QbfCrj3X9FfGL7VRZYmrn4
|
Claude finished @kyle-sexton's task in 5m 31s —— View job Code review complete
This is a CI code-review pass per Finding (posted inline)
Verified during review (no issues)
No other correctness or maintainability issues found in the diff. |
|
Claude finished @kyle-sexton's task in 3m 36s —— View job Security review —
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b2165faf52
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Last security-reviewed head: |
|
Claude has reviewed this PR 2 times. The lane skips further automatic reviews after 5; deleting this comment resets the count. |
…inputs Review findings on PR #3029. - Argument parsing now consumes a second token when the first is `continue`, so the `continue auto` row is reachable instead of collapsing into the bare `continue` row and silently degrading to suggest-only. - The liveness input no longer points at a skill that writes. `reconcile` auto-settles proven-done tasks and retires finished off-thread work, so the router consumes a reconciliation that has already run, falls back to `orient`'s read-only off-thread glance, and then to unknown — a router that only recommends must not mutate tracking as a side effect of deciding. - The natural-language half of the `auto` opt-in counts only in a genuine user turn; a fetched page, an item body, a tool result, or another agent's return is data the router evaluates, never a licence it acts on. A routed skill that makes outbound changes with no further confirmation takes the literal token and nothing else — `clean-stop` pushes commits, opens PRs, and files issues once invoked, so a semantic reading must never start it. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QbfCrj3X9FfGL7VRZYmrn4
|
Claude finished @kyle-sexton's task in 2m 46s —— View job Code review complete
This is a CI code-review pass per What the new commit changes
All three are correctly and thoroughly fixed, with no gaps I could find in the new prose, and no inconsistencies introduced against the surrounding unchanged sections (renumbering/cross-references from the prior commit weren't touched by this one, so they don't need re-verification). Minor note (non-blocking, no single line to anchor it to)
Verified unchanged from the prior review pass
|
|
Claude finished @kyle-sexton's task in 1m 18s —— View job Security review —
|
Closes #2972 The continuation router had zero eval coverage: five workflow cases existed and none exercised the `continue` path, while one of its ordering invariants had already regressed once and been fixed inside the router's own creation PR (#1603, originating issue #1476). The 0.27.0 router evolution (#2971 / PR #3029) shipped without it by design; this is the safety net that item deferred. Nine cases (ids 6-14) pin the shipped behavior. Each grades the router's stated reason, not just its verdict, so a rewrite that reaches the right mechanism by the wrong edge still fails. - First-yes-wins: machine-going-away routes to clean-stop over a healthy-context continue; an explicit background request outranks question 3's zero-cost in-session exit (the regressed invariant). - Zone gating: a compaction marker overrides a green zone word and rejects in-session continue for judgment-heavy work; a healthy zone whose next stage consumes the reasoning verbatim prefers continue. - Post-evolution: the AFK edge hands the spawn brief to orchestrate, keeps asking (non-terminal), and launches nothing; suggest-by-default is graded on its full mechanism/evidence/next-step shape. - Autonomy gating: the opt-in counts only in a genuine user turn; `auto` cannot carry out /clear or /compact; clean-stop takes the literal `continue auto` token and nothing else. Schema-validated and quality-linted green (0 warnings). Co-authored-by: Claude <noreply@anthropic.com>
…ontract (#3040) Closes #2973 ## Summary `reference/reader-contract.md`'s zone-crossing hooks section described the advisory injection as it worked **before** the 0.5.0 audience split — as one undifferentiated block carrying "a minimal generic continuation tree plus a presence-gated pointer to `session-flow:workflow`'s router". Since 0.5.0 the menu has been operator-channel only, so the reference told every reader of the seam that the model receives an exit menu it has not received for many versions. Surfaced by the fresh-context verifier during AI Hero course lane 2 (#2900). ## Fix The section now states what each channel actually carries, and why: - **Model channel (`additionalContext`)** — the determination plus the counter-steer (the reading is a measurement rather than an instruction; real degradation shows up in the model's own output, never in a zone word; keep working the task in hand), plus the durable-note addendum in `dumb`. - **Operator channel (`systemMessage`)** — the same crossing plus the continuation menu that is the human's call (continue / `/clear` / handoff-then-`/clear`, with the hand-written resume note as the standalone-install fallback / `/compact`) and the presence-gated router pointer. - **Neither the menu nor the router pointer ever reaches the model channel** — with the I23 rationale stated where the split is described (`claude-config`, `reference/criteria.md`): a menu injected into model context manufactures the model's own initiative to stop, summarize, or hand off, and I23's Remediate clause prescribes exactly this shape — counter-steer plainly stated, reassurance rather than an exit menu. - The model channel says continuation is the operator's **call**, never that the operator has **seen** the menu, since no documented hook behavior tells a hook whether an operator is present. ## Verification - **Verified against the hook's actual emission**, not its header summary: `hooks/zone-crossing-inject.sh` builds `guidance` (model) and `operator` (operator) separately and emits both via `hook::emit_channels` — the rewritten prose tracks those two strings, including the `dumb`-only addendum and the option-3 manual fallback. - **Third acceptance criterion swept**: `grep` over the whole contract for injection/menu/channel prose found the content described in exactly one place (the section rewritten here). The other injection mentions cover hysteresis and the compaction marker and are accurate — no other section describes pre-0.5.0 behavior. - `bash plugins/context-guard/hooks/zone-crossing-inject.test.sh` — PASS=53 FAIL=0 (hook untouched; run because this doc is its contract). - `bash scripts/validate-plugins.sh` — all manifests + catalog validated; `generate-catalog.mjs --check` in sync. - `bash scripts/check-changelog-parity.sh --check` / `--check-bump origin/main` / `--check-order` — all green. - `bash scripts/check-changed-skills.sh origin/main` — no changed skills under `plugins/*/skills/` (this is a plugin-level `reference/` file). - `bash scripts/check-cross-plugin-source-drift.sh` — exit 0. - `npx markdownlint-cli2` on both changed markdown files — 0 issues; `typos` clean. - **Version bump** `context-guard` 0.7.14 → 0.7.15 (patch — documentation accuracy, no behavior change). ## Related - Refs #2900 (lane 2 decision record and the verifier finding), `docs/upstream/aihero-course.md` lane 2 rows - Refs #2971 (the sibling router item, closed by PR #3029) — this is its lane 2 companion 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01QbfCrj3X9FfGL7VRZYmrn4 --- _Generated by [Claude Code](https://claude.ai/code/session_01QbfCrj3X9FfGL7VRZYmrn4)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
Closes #2971
Summary
Lane 2's build deliverable (#2900, decisions Q9/Q20-Q22).
session-flow:workflow's continuation router decided from the zone word alone, and the AFK criterion the lane adopted had no edge to live on. This evolves the router in place — no new skill — so it decides over plan, work-item, and history state through the informants that already own them, carries the AFK edge, states its output shape, and reconciles itself against I23.Fix
session-flow:orient), what is still running (a reconciliation already run this session, elseorient's read-only off-thread glance), which boundary this is (the workflow checklist), whether the remaining work is already scoped (the consuming repo's work-item tracker seam) — each consumed the way the zone word already is: take the owner's answer, inline none of its mechanics. Every input is presence-gated, an absent one degrades to unknown rather than blocking, and the router runs no probe of its own: the skill's repository-context gather stays the single pre-compute block, so a later input arrives as a pointer rather than as a probe inlined into the file, and the$-expansion ban (fix(skills): pre-compute Class 2 remainder — genuine shell expansion mixed into pre-compute in 5 plugins (canonical tracker; scope in comments, body list superseded) #1687, fix(session-flow): remove $-expansion from pre-compute so isolated agents can load these skills #1688) is inherited rather than restated. Consulting an informant never means firing one that writes —reconcileauto-settles proven-done tasks, so a router that only recommends must not invoke it to manufacture an answer.session-flow:orchestrateand the router continues asking, because sending work elsewhere does not answer which mechanism carries this session across the boundary. Ordered after the explicit-background-request question so feasibility the router infers never pre-empts an instruction the user actually gave, and before the zero-cost in-session exit because a yes changes who does the remaining work while every question below asks how this session carries it.continue-in-background's explicit-intent launch gate is untouched — the router suggests and never launches — and orchestrate keeps spawn ownership. The four questions below it are renumbered 3–6 and the cross-references inside the ordering purposes updated to match; every moved edge keeps its stated purpose.continue autoargument (the argument-parsing rule consumes a second token when the first iscontinue, so the modifier reaches its mode) or the user's own words in a genuine user turn — that expires with the invocation, mirroringcontinue-in-background's explicit-words precedent; never a standing config. It authorizes the router to invoke a mechanism, never that mechanism to skip a gate it owns; a routed skill that makes outbound changes with no further confirmation (clean-stoppushes commits, opens PRs, and files issues once invoked) takes the literal token and nothing else; and it cannot reach/clearor/compactat all, since those sit outside the small allowlist ofSkill-invocable built-ins. Second tier is the orchestrator relay, now codified in the handoff-relay convention as the autonomous tier for delegated work — a worker writes its own handoff at its fork point and returns the path; the orchestrator, standing in for the absent human, retires it and seeds a fresh agent with the resume prompt, never reading the handoff body. Spawn-brief discipline stays orchestrate's.context-guard's 0.5.0 audience split, honored from the consuming end by taking the zone word and inlining no band values; autonomy initiative comes from the user's opt-in or the orchestrator, never from injected context or a self-estimated budget.session-flow0.26.1 → 0.27.0 with the matching CHANGELOG entry.Verification
bash scripts/check-changed-skills.sh origin/main— 1 skill checked, 0 failed, 0 warnings. SKILL.md is 200 lines; the soft target (plugins/skill-quality/scripts/check-skill.sh, check 10) is<= 200, so 200 is compliant and no WARN fires — an earlier revision hit 201 and was trimmed.bash scripts/validate-plugins.sh— all plugin manifests + catalog validated.node scripts/generate-catalog.mjs --checkandnode scripts/generate-cheatsheet.mjs --check— both in sync.bash scripts/check-changelog-parity.sh--check/--check-bump origin/main/--check-preserved origin/main/--check-order— all green (83 changelogs read newest-first, no duplicates).scripts/check-contract-clause-coverage.py,check-contract-slice-prune.sh --checkand--check-diff origin/main,check-cross-plugin-source-drift.sh --check,check-skill-leaf-names.sh --check,check-orphaned-fixtures.sh --check,check-lane-coverage.sh --check— all PASS.npx markdownlint-cli2on every changed markdown file — 0 issues;typosoverplugins/session-flow/— clean.REcompile() paniclines in thecheck-skill.shoutput are the known container mawk/ERE-interval artifact (skill-quality: check-skill.sh fresh-eyes scanner breaks under mawk — ERE interval expressions unsupported #3005), not a finding from this change.Review round (commit
8fb17146)Three findings were raised on
b2165fafand all three are fixed and verified by the re-review:continue autowas unreachable — the parsing rule read only the first argument, so the two-token row collapsed to plaincontinueand the autonomy tier silently degraded to suggest-only.reconcile, which auto-settles proven-done tasks and retires finished off-thread work — a suggest-only router would have mutated tracking as a side effect of deciding.autoopt-in was forgeable through injected context, andclean-stophas no re-confirmation of its own once invoked.Related
docs/upstream/aihero-course.mdlane 2 rows$-expansion ban the new inputs inherit)🤖 Generated with Claude Code
https://claude.ai/code/session_01QbfCrj3X9FfGL7VRZYmrn4