feat(implementation): enforce capability-tier model bindings at the dispatch seam - #1711
Conversation
…ispatch seam Add implementer and phase-verifier plugin agents whose model frontmatter structurally binds the strong capability tier's current alias, route implement-dispatch's worker and phase-verifier dispatches through them, and ride the same surface from /work-items:work's fix re-dispatches — so a fast-tier orchestrator root no longer silently runs implementers at orchestrator strength via the default model inheritance. Tier definitions stay order-defined and family-agnostic per the loop-lane convention §3; the alias binding lives only at the dispatch seam. The loop-lane worker-lane paste-block admonition reduces to overrides-only (frontier for security surfaces, haiku for mechanical pulls), and the Models section's self-diagnosis now records the structural enforcement. Frontmatter model values and the resolution order (env, parameter, frontmatter, inherit) verified against https://code.claude.com/docs/en/sub-agents on 2026-07-26. Closes #1649 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VRSgwJ7RN4vPZt4oJAADHy
Independent fresh-context verification surfaced six findings; all fixed: state the phase-verifier's tool cage as what it enforces rather than "read-only" (Bash can write, per the named-agent bar); drop the effort pins and record the session-relative upward-override duty so a session above the strong tier is never pinned down (frontmatter binds a floor); give the /work-items:work PR-monitor and post-green review-pass dispatches explicit per-invocation tier models (reviewer never weaker than implementer); presence-gate the no-admonition-needed claim on the implementation plugin being installed; grant the implementer web research and disclose both tool cages; correct the Models-section enumeration to name the merge lane's retained opus binding; add the inherit-value nuance to every CLAUDE_CODE_SUBAGENT_MODEL claim; and register both frontmatter binding sites in the plugin philosophy's dated tier table. Refs #1649 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VRSgwJ7RN4vPZt4oJAADHy
…patch seam The implementer and phase-verifier agents bound model but left effort to inherit from the session, so an orchestrator that lowered effort for its own bookkeeping still silently lowered it for the phase implementation and its acceptance verdict — the same inheritance hole the model binding closes, one field over. Both now set effort: high, matching every other named agent in this marketplace. Frontmatter model and effort fields and the env, parameter, frontmatter, inherit resolution order re-verified against https://code.claude.com/docs/en/sub-agents on 2026-07-27; the two in-tree verification dates move to that date. Refs #1649 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VRSgwJ7RN4vPZt4oJAADHy
…claims Verifier findings on the dispatch-seam binding. phase-verifier carried maxTurns: 30. A turn cap stops a subagent with no error, so a verifier whose audit outgrows the cap returns a truncated report that an orchestrator consumes as a verdict — silently downgrading the very gate this seam exists to make structural. The cap is removed (an audit's length is set by the diff, and the tool cage already bars mutation) and the agent is contracted to return INCONCLUSIVE naming what it could not reach, never a partial PASS. implementer's cage prose claimed nested dispatch outright; the harness withholds Agent from a subagent at the spawn-depth limit whatever the tools list says, so the grant is now stated as conditional with the doc citation. PLUGIN-PHILOSOPHY read as if the two new agents were the whole alias-pin recheck list. They are the dispatch seam, not the registry: the recheck trigger covers every agent-frontmatter model value in the repo, now pointed at a grep rather than a restated list that would drift. maxTurns semantics and the depth-limit Agent withholding verified against https://code.claude.com/docs/en/sub-agents on 2026-07-27. Refs #1649 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VRSgwJ7RN4vPZt4oJAADHy
Second verifier round on the dispatch-seam binding. INCONCLUSIVE was a one-sided contract: phase-verifier promised to return it, and nothing consumed it. implement-dispatch's phase-boundary clause now states the orchestrator's action — the phase stays unmarked, a fresh verifier is re-dispatched against the gap the return named, and a second inconclusive return on the same criteria escalates as a divergence. Three claims were overstated. The sub-agents page defines maxTurns as the maximum turns before the subagent stops; that a stop carries no failure signal is applied inference, and the CHANGELOG now labels it as such instead of carrying it under the verification stamp. The same entry said "unlike this marketplace's review agents" when discovery's agents cap too, and gave a verdict-rendering rationale that covers only the verifier — the implementer's uncapped surface is now stated on its own terms, with the brief's scope fence named as its control. implementer's depth-limit note dropped "silently" for the behavior the page actually documents. Refs #1649 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VRSgwJ7RN4vPZt4oJAADHy
|
Claude finished @kyle-sexton's task in 3m 47s —— View job PR Review
SummaryThis PR converts the tier-enforcement admonition in CorrectnessAgent frontmatter bindings — correct.
Tool cage for
Audit surface — enumerable. The Version bumps — correct. Minor Observations1. "Leave effort at its default" may confuse readers of the Models section.
This applies to lane roots (the 2.
3. The contract that prevents a partial-pass return is expressed in the body text, not in a tool restriction. An agent could technically return a misleading verdict. This is the expected state — there is no mechanism to enforce the output shape of a free-form response — and the INCONCLUSIVE contract is the right design given that constraint. Worth being aware of when reading verifier returns: the orchestrator should treat any return that does not include per-criterion verdicts for every criterion as implicitly INCONCLUSIVE. VerdictPASS. The design is correct, internally consistent, and well-aligned with the loop-lane convention §3 and plugin philosophy. The structural binding replaces a human-memory obligation with a harness-enforced floor, and the INCONCLUSIVE path prevents a truncated audit from reading as a verdict. No blocking issues found. |
|
Claude finished @kyle-sexton's task in 3m 36s —— View job Security Review — PR #1711
ScopeReviewed the 11 files changed in this PR only, per the security-review brief. No GitHub Actions workflow files are in scope. Static analysis concerns (unpinned actions, dangerous triggers, permission widening) deferred to zizmor's lane. Overall verdictNo CRITICAL or IMPORTANT vulnerabilities found. This PR is a net security improvement: it closes a previously-open gap (silent model downgrade by root-session inheritance) and introduces an explicit Two design-level observations are noted below as SUGGESTION, both arising from the inherent limits of instruction-based tool cages in Claude Code agents rather than from mistakes in this diff. SUGGESTION — phase-verifier's Bash inclusion means its "cage" is not a structural write restrictionConfidence: HIGH — the limitation is confirmed by the codebase's own philosophy doc. The Its body then says: "Your tool cage deliberately bars Edit/Write and agent spawning; Bash remains available for inspection (diffs, greps, read-only checks), and mutating state through it is outside your contract — a verifier that touches the artifact it grades has voided its verdict." The safety claim in the final clause ("a verifier that touches the artifact it grades has voided its verdict") is behaviorally true but structurally unenforced:
The philosophy doc captures the limit correctly; the This is not a defect introduced by this PR — it is an inherent Claude Code platform constraint for Bash-capable agents. However, since this PR is the one that creates and publishes the agent definition, it's the right place to flag it. The independence guarantee the verifier provides is behavioral, not structural. No fix is required, but a future hardening pass could consider whether a read-only inspection path (no Bash, or a sandboxed shell with no write permissions) is achievable for the verifier surface. SUGGESTION —
|
| Surface | Disposition |
|---|---|
Argument parsing (--wave-cap <N>) |
Floor/ceiling arithmetic described instruction-level; controls concurrency only, not security boundaries. Fractional and < 1 inputs explicitly bounded. |
Shell snippets in work/SKILL.md |
Template/instructional form (LLM-interpreted, not exec'd directly); tracker IDs come from the provider adapter's validated output. No shell injection surface exposed by this diff. |
Plugin manifest changes (plugin.json) |
Version bumps only; no new dependencies, no new mcpServers, no new bin/ entries. |
| INCONCLUSIVE return token | Correctly closes the truncated-audit-as-verdict gap. Orchestrator re-dispatch on INCONCLUSIVE and escalation on second INCONCLUSIVE are both specified. |
implementer tool list (Agent included) |
Nested spawn depth limited by platform; acknowledged in the agent body. Not introduced by this PR's security surface. |
CLAUDE_CODE_SUBAGENT_MODEL: inherit carve-out |
Correctly excluded from the "outranks" statement ("set to anything but inherit"). No logic error. |
| Cross-vendor advisor path | Presence-gated correctly; fallback to same-vendor fresh-context agent is the stated default. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9d466ccb6a
ℹ️ 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".
…t to assigned briefs
The worker's STOP list treated an absent worktree path as an omission to refuse
on, unconditionally. That contradicted this same file's own description ("its
assigned or self-provisioned worktree") and the dispatch contract it composes:
under worker-side provisioning the orchestrator deliberately dispatches the first
phase before the worktree exists, and materializing it is the worker's mandated
first step. As written, every first phase of an autonomous run would STOP before
performing the step the brief assigns it.
The requirement now attaches to the assigned-worktree brief, where a path is the
only way the worker learns where to edit. A provisioning brief supplies the
branch and the provisioning instructions instead, and the worker discovers the
path and returns it. The refusal is preserved where it belongs: a brief carrying
neither an assigned path nor provisioning instructions still STOPs.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0134vdV1jXJhzpSmeT7y5B8N
|
Claude encountered an error after 0s —— View job I'll analyze this and get back to you. |
|
Claude encountered an error after 0s —— View job I'll analyze this and get back to you. |
|
Claude finished @kyle-sexton's task in 2m 25s —— View job PR Review
SummaryThis review covers the updated PR state as of commit Codex P1 Finding — ResolvedThe Codex reviewer flagged that The fix in
The catch-all STOP for a brief carrying neither is preserved, so the safety invariant is maintained. The distinction is correct against the dispatch contract in BlockingNone. The PR is structurally correct and the P1 regression has been addressed. Minor — CHANGELOG gap for the worktree-path fixCommit A one-line addition under 0.10.0 "Changed" (or "Fixed") is sufficient:
Carry-forward observations from the prior review (still open)1. "Leave effort at its default" ambiguity —
This applies to lane-root invocations, but it appears in the same Models section that introduces the structural seam. A reader who notices that 2. The override caveat lives in Both observations are non-blocking suggestions; the enforcement mechanism introduced by this PR is correct as-is. VerdictPASS. The structural tier enforcement is sound, the Codex P1 regression is correctly fixed, and the INCONCLUSIVE/re-dispatch chain is complete. The only action item is a CHANGELOG entry for the worktree-path scoping fix. |
|
Claude finished @kyle-sexton's task in 4m 3s —— View job Security Review — PR #1711
ScopeReviewed the 11 changed files in this PR. This re-review follows a No GitHub Actions workflow files are in scope. Static analysis concerns (unpinned actions, dangerous triggers, permission-widening) deferred to zizmor's lane. Overall verdictNo new CRITICAL or IMPORTANT vulnerabilities found. The two SUGGESTION findings from the 2026-07-28 security review carry forward unaddressed — they are correctly described as inherent platform constraints rather than defects in this diff. One new SUGGESTION is reported below. SUGGESTION —
|
| Surface | Disposition |
|---|---|
| Merge content from origin/main | Six merged commits (bb0efe6, 3fcc50e, 8bd86e3, 326a8e6, c9879fb, 8a926ac, a09efd7) touch unrelated plugins; none intersect the 11 PR files. No new security surface. |
03587cd (worktree-path fix merged from main) |
Scopes the worktree-path STOP to assigned-worktree briefs only. Correctness fix; reduces erroneous STOP paths. No security regression. |
implementer model/effort frontmatter binding |
Correctly aliases rather than pinning a dated model ID. No trust boundary change. |
phase-verifier INCONCLUSIVE contract |
Orchestrator re-dispatch on second inconclusive is specified; no new silent-PASS surface beyond what prior review noted. |
| Brief scope fence (ALLOWED/FORBIDDEN) | Instruction-enforced only; no new structural mechanism. Pre-existing design constraint, not introduced by this PR. |
|
Claude finished @kyle-sexton's task in 2m 37s —— View job PR Review
Codex P1 Finding — AddressedThe Codex P1 comment flagged that It was resolved by commit
No action needed. The Codex finding is closed. ReviewThe 2026-07-28 Claude review was comprehensive and remains accurate for the core substance of the PR. This pass covers the complete diff independently, with particular attention to the changes introduced after that review. Structural binding — correct. Both Worker-side provisioning path — correct (post-fix). The STOP condition is now "neither assigned path nor provisioning instructions," which is the correct predicate. Autonomous first-phase dispatch correctly reaches provisioning before it would ever evaluate a path requirement.
INCONCLUSIVE chain — complete.
Version bumps — Most recent merge commit ( VerdictPASS. The Codex P1 finding was valid and has been resolved. The tier enforcement lands structurally at the dispatch seam as intended, the INCONCLUSIVE path is fully wired, and the worker-side provisioning distinction is correct. No blocking issues found. |
|
Claude finished @kyle-sexton's task in 2m 59s —— View job Security Review — PR #1711
ScopeReviewed the 11 changed files in this PR at HEAD No GitHub Actions workflow files are in scope. Static analysis concerns deferred to zizmor's lane. Overall verdictNo new CRITICAL or IMPORTANT vulnerabilities found. The three SUGGESTION findings from the prior reviews carry forward unaddressed; they are correctly characterized as inherent platform constraints rather than defects in this diff. All are confirmed against the current tree. Carry-forward findings confirmed at HEADSUGGESTION 1 —
SUGGESTION 2 — The override caveat appears in SUGGESTION 3 —
Other surfaces reviewed and found clean for this re-review
|
…hapes, record the review boundary (#1712) ## What Three loop-lane convention notes, all in `docs/conventions/loop-lane/README.md`, batched because they touch the same document. **#1655 — pin the "`/loop` runs the prompt fresh, not the session" distinction.** A relaunch is the only context reset a loop lane gets; the note records that and points at the authoritative surface in `claude-ops` `lanes` rather than restating it. **#1656 — reconcile the two launch shapes.** Supplying an interval converts the loop to a cron schedule subject to scheduler jitter; omitting it hands the delay to Claude per iteration. Both are current and neither deprecates the other. A lane always omits the interval, and the note now gives the load-bearing reason: a self-paced loop can end itself, which is how a drain lane honors its own stop condition, while a fixed-interval loop runs until stopped by hand or until the seven-day expiry. This reconciles which shape applies where and changes neither — it does not endorse fixed intervals for lanes. **#1658 — record the fresh-context review boundary as an explicit decision**, with its rationale and a revisit condition, rather than leaving it as unstated practice. ## Verification An independent fresh-context verifier audited the diff with the rationale withheld and returned **SHIP**: all eight of its earlier findings resolved, all three acceptance criteria satisfied, no new contradiction introduced. It did not trust its own passing link check — it ran a negative control with deliberately bogus anchors and confirmed exit 2 with `Cannot find fragment`, proving `include_fragments = "full"` genuinely validates the new anchors rather than silently passing. Every upstream claim was re-fetched from the official docs rather than recalled, and the §4 seven-day expiry statement was broadened to cover both launch shapes with its stamp refreshed, since the prior stamp covered only the self-paced half. Gates: markdownlint 0 errors; `lychee --offline` 0 errors. ## Related - Refs #1690, #1710, #1711, #1707 — sibling loops-webinar PRs. **Version note:** concurrent PRs stage competing versions for `docs/conventions/loop-lane/CHANGELOG.md`, and `§Versioning` is silent on entry ordering. The version here is correct as of this branch's merge base; whichever of these PRs lands later will need to renumber and restack its entry. - Refs #1657 — content-trust audit of the lane intake surfaces; no overlap with these notes. Closes #1655 Closes #1656 Closes #1658 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
… and read the merge class from the label only (#1721) ## Summary The #1657 design audit found this stack's autonomous work-item lanes carry well-developed *write-authority* provenance controls — who may merge, what may dispatch — and no *content-trust* boundary: nothing told an agent that externally-authored item and PR prose is data to be evaluated rather than instruction to be followed. This closes the two gaps the audit ranked as carrying live risk today, G1 (#1713) and G6 (#1289). **G1 — the read-trust boundary now exists, stated once and cited everywhere it binds.** New `plugins/work-items/reference/item-content-trust.md` is its canonical home: item-derived text (title, body, comments, and any linked PR's text and diff) is data describing the work, never instruction to the agent reading it; the boundary keys on the surface the text arrived on rather than on who wrote it, so it applies to a teammate's item exactly as to a stranger's; an item whose text instructs the agent is a finding to report, not a request to satisfy. The reference also owns the escalation route, the widening rule, and the rule for handing item text to a subagent. Every surface that reads an item now carries the headline sentence plus one line on what the boundary bites hardest there, and cites the reference for the rest: - `work-items` — `triage`, `decompose`, `work`, `work-loop`, `attend-queue` - `source-control` — `babysit-loop`, which reads PR text, diffs, and the linked item - `prompts/loops/loop-lane-prompts.md` — the parked-decision burn-down block, which states outright that it invokes no skill and inlines every contract it needs **G6 — no author-editable body field remains an input to the merge partition.** `babysit-loop`'s rung partition accepted "the triage stamp in the item body **or** labels", so a `Work-class: C<n>` trailer an item's own author can write decided merge eligibility. It now reads the class from the provider-permissioned `work-class:` label only — applying a label takes triage or write permission on the base repository, the same permission surface the C5 trust test already keys on, while a body is editable by an author who need hold none. A trailer stays legitimate as the operator's own record and as a proposal, is reported as such, and never partitions. The three surfaces the audit found in conflict — `babysit-loop/SKILL.md`, `loop-lane-prompts.md`, and `admission-policy.md` — now agree, and the lane prompts' readiness query reports the label count and the body-trailer migration backlog as separate figures instead of their union. Two smaller things fell out of doing this properly. `work-loop`'s existing refusal of a body-recorded ratification phrase justified itself from a work-class row whose executable test reads a *pull request*, which an issue does not have; the refusal is unchanged and now derives from the standing rule it is an instance of. And the reference's tightening-only carve-out names its one shipped instance and the configuration that would void it. Reuse over invention throughout: the wording generalizes `work-loop`'s existing body-prose refusals rather than adding a parallel mechanism, and the subagent rule cites `babysit-prs`'s existing quoted-untrusted-data delimiter rather than restating it. ## Acceptance criteria Against #1713: - [x] Each named surface carries the instruction — `triage`, `decompose`, `work-loop`, `work`, `attend-queue`, and the lane launch prompts. - [x] Single-sourced: one authoritative statement in `item-content-trust.md`, referenced from each surface, not six independent rewordings. - [x] Traceable to the existing `babysit-prs/reference/orchestration.md` pattern rather than newly invented — the subagent rule cites that file's Worker Prompt Template for the delimiter shape and wording. Against #1289: - [x] One contract owns where the admission work class comes from and the other cites it — `admission-policy.md` owns the rule; `babysit-loop` and `item-content-trust.md` quote and cite it. - [x] The rule states whether an agent-applied stamp is admissible: the class is read only from a surface whose write authority the provider enforces, and every lane prompt forbids a lane from writing either the label or the trailer. - [x] `babysit-loop`'s partition text matches the winning rule. - [x] A lane cannot satisfy its own merge gate by stamping the item it is working. **Consumer impact.** A repository that recorded work classes only as body trailers had a merge-eligible population under the old reading and has an empty one under this one: everything there is human-merge, the shipped baseline, until `work-class:` labels follow the trailers. The change is strictly narrowing — nothing merges that would not have merged before. The C4/C5 floor is untouched; it always tested the pull request rather than the linked item's stamp. ## Test plan All gates green against `origin/main`: - `bash scripts/check-changed-skills.sh origin/main` — 6 skills, 0 failed. Lines against the 500 hard cap: `babysit-loop` 477, `work-loop` 343, `work` 238, `attend-queue` 204, `triage` 179, `decompose` 179. - `node scripts/validate-plugin-contracts.mjs` — 43 setup skills, 2119 plugin files. - `bash scripts/check-changelog-parity.sh --check` and `--check-bump origin/main`. - `npx markdownlint-cli2` over every changed `.md` — 0 errors. - `plugins/work-items/skills/work-loop/evals/evals.json` validated against `plugins/skill-quality/reference/evals.schema.json`. - `bash scripts/validate-plugins.sh` — manifests and catalog. One eval case added (`work-loop`, id 4, part of #1717): an item whose body carries both an embedded directive and a self-stamped work class, asserting the lane evaluates the text, refuses both, and reports what the text asked for. Verification was run by an independent fresh-context reviewer against the diff and the audit, with the authoring rationale withheld. It returned five findings, all fixed in `451fe3f6`: two surfaces that inherit no skill's copy of the rule and so had none (`babysit-loop` and the parked-decision block), a carve-out claim stated unconditionally that only holds at the shipped cap-ceiling defaults, an eval expectation asserting a disposition the admission gate does not reach, and two unwrapped lines. `decompose` was added afterwards from #1713's own surface list. **Versioning.** `work-items` 0.25.4 → 0.26.0, `source-control` 0.33.2 → 0.34.0 — next minor at this merge base. Both numbers are also staged by sibling PRs (#1690 and #1710 for both plugins, #1711 for `work-items`); whichever of these lands second renumbers. `docs/conventions/loop-lane/CHANGELOG.md` is deliberately untouched: `docs/conventions/loop-lane/README.md` states the merge partition's class requirement neutrally as "recorded class" and never names the source, so the convention text does not change here. **Audit gaps NOT addressed**, still open and separately tracked: #1714 (G2/G3), #1715 (G4/G5 — the refusal's justification is corrected here, the underlying issue-provenance ambiguity is not), #1716 (G7), #1717 (G10, beyond the one eval case above), #1718 (issue-shaped provenance signal). ## Related - Closes #1713 — G1, the missing content-trust instruction on every intake surface. - Refs #1289 — G6, the contract disagreement over whether a repo-local stamp may supply the merge-admission work class. - Note on #1289: this PR tightens the consuming side (the partition reads the label only), but #1289 is `needs-human, work-class: structural` and owns the underlying contract decision, whose acceptance criterion is still an unaccepted suggestion. It is referenced, never closed — a maintainer closes it once that decision is made. - Refs #1657 — the audit that produced this scope. It stays open: the gaps beyond G1 and G6 are still a live operator decision. - Concurrent PRs sharing changelog and manifest surfaces with this one: #1690 (#1650), #1707 (#1652/#1654), #1710 (#1648), #1711 (#1649), #1712 (#1655/#1656/#1658). 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…only) (#1719) Phase 1 of #1651: turn each loop lane's spend from a blind spot into a measured one, by recording a per-cycle `usage_sample` in the lane telemetry state block that already exists. Nothing reads the field back. Phase 2 — a budget config key — is deliberately **not** designed here, and no threshold, cap, warning, pause, backoff, pacing change, or merge-rung change derives from the sampled value. ## The signal, and why it is not a token count The issue title says "token usage". This ships **window-percentage** usage instead, because no token count is readable at a lane's cycle boundary. What each lane actually records is the reading its rate-limit guard step already took that cycle: - **Field:** `rate_limits.five_hour.used_percentage` / `rate_limits.seven_day.used_percentage` - **Produced by:** `plugins/rate-limit-guard/scripts/statusline-tee.sh`, which selects `rate_limits` out of the status-line stdin payload and atomically rewrites `~/.claude/rate-limit-guard/rate-limits.json` - **Doc:** <https://code.claude.com/docs/en/statusline> — `used_percentage` is 0–100, `resets_at` is Unix epoch seconds, and `rate_limits` appears only for Claude.ai subscribers after the session's first API response, with each window independently absent. Re-verified 2026-07-28; no drift. Because the guard step already holds this value, the invariant costs a write, not an observation. **Why not tokens.** `context_window.total_input_tokens` / `total_output_tokens` are documented as token counts *currently in the context window, from the most recent API response* — cumulative session totals only before Claude Code v2.1.132. The `/usage`, `/goal`, and `/workflows` figures the issue cites are interactive displays, not values a skill body can parse at a cycle step. **One signal does exist, and is recorded as deferred rather than denied.** `cost.total_cost_usd` is documented as the session's client-side accumulated cost, resetting on `/clear` — machine-readable and session-scoped, so it *would* attribute to a single lane. The tee does not forward it. Widening the tee is a `rate-limit-guard` change (its own bump plus a reader-contract amendment) and is out of scope for a measure-only item, so this PR records it as the deferred candidate with its trigger rather than claiming no signal exists. ## Caveats, re-derived rather than inherited The issue's acceptance criterion names "approximate, machine-local". Both are recorded, but attributed to what they actually describe: - **Approximate** was a `/usage` caveat and does not hold for `used_percentage`, which the status-line schema documents without qualification. The real bound is the guard's staleness rule, so the sample is described as a snapshot no fresher than that rule allows. - **Machine-local** describes the *tee file* — last-writer-wins, no account identifier — not the reading, which is account-scope. The two are now stated separately. - **Disclosed gap:** the tee refreshes only while an interactive session renders a status line, and a lane is by construction a `claude --bg` session. An unattended lane with no interactive window open samples `null` every cycle. An empty sample therefore means *unobserved*, never zero. This is stated rather than glossed, because the framing "the reading is already in hand" otherwise hides it. ## Scope - Extends the existing `#502` durable-state block in both loop lanes — no second telemetry mechanism. `plugins/claude-ops/skills/lanes/scripts/telemetry-upsert.sh` is body-opaque and validates no schema, so it needs no change; nothing else in the repo parses the state block. - The schema tag stays `@1`: the added key is additive-optional and no reader validates the shape. - The attended `attend-queue` lane is unaffected — §4 binds loop lanes, and that lane holds no durable-state block. - `plugins/autonomy/reference/` is untouched. That tree holds the OTLP telemetry contract, not the lane state-block shape; the shape lives in the loop-lane convention and the two lane bodies. ## Versioning — renumbered as predicted The competing numbers this PR's table anticipated all landed first, so every version here was re-derived against `origin/main` at merge time rather than against this branch's original merge base: | File | Now | Superseded by what landed | |---|---|---| | `docs/conventions/loop-lane/CHANGELOG.md` | `6.0.0` | #1690 took `4.0.0`, #1710 took `5.0.0` | | `plugins/source-control` | `0.39.0` | #1690 `0.35.0`, #1710 `0.36.0`, plus `0.37.0` and `0.38.0` landing mid-merge | | `plugins/work-items` | `0.29.0` | #1690 `0.27.0`, #1710 `0.28.0` | The loop-lane bump stays **major** on the convention's own discriminator — §4 states loop-layer invariants and this adds one every loop-lane body must carry. The competing minor reading (a field nothing reads back changes no behavior) is recorded in the entry per the established pattern. The convention entry was also moved back to the top of its changelog, where the merge had left it below the entries that landed ahead of it. `§Versioning` re-derivation trigger 2 is satisfied: the status-line claim was re-verified against its cited page and the stamp refreshed, recorded as a changelog entry. `rate-limit-guard`'s reader contract carries its own 2026-07-23 stamp on the same page; it is unchanged by this PR and its refresh belongs to that plugin's own bump. ## Composition with the two features that landed first Both lane bodies now carry three loop-layer features in one cycle step and one state block: the no-progress streak (#1648), the escalation record write (#1650), and this usage sample. Composing them pushed `babysit-loop`'s `SKILL.md` past the 500-line hard cap, so two things were tightened without changing any contract: - The usage-sample prose in **both** lane bodies keeps the field contract (the `at` semantics, every `null` rule, the delta's roll-over and first-cycle cases) and cites §4 for the single permitted readback, the preceding-interval delta, and the three bounding properties — all of which §4 already states in full. §4's own wording changed from "recorded alongside the sample in each lane body" to "held by citation from each lane body" to match. - `babysit-loop`'s telemetry upsert mechanics — the singleton lookup and the creation-race reconcile — moved to `reference/telemetry-upsert.md`, beside the `pre-escalation-dispatch.md` and `no-progress-detector.md` spokes already there. Still inlined in this plugin rather than invoked from `claude-ops`, for the same reason as before. ## Verification Gates green after the merge: `check-changed-skills.sh` (babysit-loop 486/500 and work-loop 451/500 against the hard 500-line cap, both re-measured with all three features composed), `check-changelog-parity.sh --check` and `--check-bump origin/main`, and markdownlint over every changed markdown file. No `evals.json` is touched. A fresh-context verifier audited the diff with the rationale withheld and traced the tee's producer and the live status-line doc independently. Its findings drove the cumulative-cost correction, the caveat re-attribution, the background-session disclosure, and the removal of a cited precedent that did not exist. Its remaining version-collision finding is the table above. ## Related - #1690 (#1650) — merged; took loop-lane `4.0.0` and both plugin bumps, and writes the escalation record into the same cycle step this PR extends - #1710 (#1648) — merged; took loop-lane `5.0.0` and both plugin bumps, and adds the no-progress streak to the same state block and cycle step - #1712 (#1655/#1656/#1658) — took loop-lane `3.1.0` - #1711 (#1649) — stages a `work-items` bump; still open - #1707 (#1652/#1654) — concurrent lane work, no file overlap - Phase 2 (`*_session_token_budget`) stays deferred until this sampling produces data, per the issue's own staging. Closes #1651 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
main landed work-items 0.29.0 while this branch was in review, so this branch's entry moves to 0.30.0 in both the changelog and the manifest, with both sides' entries retained. `implementation` 0.10.0 already sits above main's 0.9.2 and keeps its number. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TkLLDcB8Ht2tm3j688F5ZP
|
Claude finished @kyle-sexton's task in 2m 19s —— View job PR Review
SummaryThis review covers HEAD Version Conflict Resolution — CorrectMain landed
The resolution is correct. The CHANGELOG retains the full 0.29.0 entry from main and places the 0.30.0 entry on top of it, preserving the changelog's monotone ordering. Carry-forward Observations — Status UnchangedAll three non-blocking observations from prior reviews remain open: 1. "Leave effort at its default" scope is unstated —
This applies to lane-root invocations but sits in the same Models section that introduces the structural seam binding (where 2. Neither 3. CHANGELOG gap for the worktree-path scoping fix The 0.10.0 section describes the tier binding and dispatch cadence thoroughly but contains no explicit note that the VerdictPASS. The merge is clean, the version conflict resolution is correct, and the PR's structural enforcement mechanism is unchanged. All three carry-forward observations remain non-blocking suggestions. |
|
Claude finished @kyle-sexton's task in 2m 36s —— View job Security Review — PR #1711
ScopeReviewed the 11 changed files in this PR at HEAD No GitHub Actions workflow files are in scope. Static analysis concerns deferred to zizmor's lane. Overall verdictNo new CRITICAL or IMPORTANT vulnerabilities found. The three SUGGESTION findings from prior reviews all carry forward unaddressed; they are correctly characterized as inherent platform constraints rather than defects in this diff. All confirmed against the current tree. Carry-forward findings confirmed at HEADSUGGESTION 1 — Severity: SUGGESTION | Confidence: HIGH
No fix required by this PR; the limit is an inherent Claude Code platform constraint for Bash-capable agents. SUGGESTION 2 — Severity: SUGGESTION | Confidence: HIGH The override caveat appears in SUGGESTION 3 — Severity: SUGGESTION | Confidence: MEDIUM
The attack path requires attacker-controlled content to survive multiple LLM reasoning stages, making direct exploitation low-probability. The Other surfaces reviewed and found clean
|
What
Makes loop-lane model tiering actually take effect. The tiers were documented but nothing bound them
at the point of dispatch, so a lane's stated tier had no mechanism behind it — the binding lived only
in a paste-block admonition a human had to remember to honor.
The binding now lands structurally at the dispatch seam. Two agent definitions gain an explicit
model and effort pairing,
implement-dispatchandwork-items:workconsume it, and theper-dispatch admonition in
prompts/loops/loop-lane-prompts.mdis reduced accordingly — theenforcement is in the seam, not in a reminder.
Effort is bound alongside the model deliberately: tier is not only which model runs, it is also how
much reasoning depth the subtask gets, and binding one without the other leaves half the tier
unenforced.
docs/conventions/loop-lane/README.md§3 is respected throughout — tier definitions stayabstract, with no model family names in them. Only the seam names concrete models.
The verifier turn cap is removed from
phase-verifierrather than raised. A cap only moves thecliff, and the docs give no error signal an orchestrator could key off, so a truncated audit would
read like a verdict. In its place the agent contracts a positive
INCONCLUSIVEtoken, and theconsuming surfaces now state what to do when they receive one.
Verification
An independent fresh-context verifier audited the diff with the rationale withheld, across three
rounds. Verdict: PASS on all criteria. It ran the cited registry grep verbatim to confirm the
claim about agent model bindings was exhaustive rather than asserted, and it checked each
harness-behavior claim against the fetched
sub-agentspage rather than taking the author's word.Two claims were hedged as a result of that check: the depth-limit withholding is described as
inference rather than quotation, since the docs state "reports no error" for a different filter; and
the
maxTurnsrationale no longer presents an inferred half under a verification stamp.The one review finding on this PR — that requiring a worktree path in every brief would make a
self-provisioning worker STOP before its mandated first provisioning step — was fixed in 03587cd:
the path is now required of an assigned-worktree brief only, a self-provisioning brief is accepted
on branch name plus provisioning instructions with the path discovered and returned, and the
omission that genuinely must STOP (neither a path nor provisioning instructions) is stated
positively.
Gates green after the merge:
check-changed-skills.sh origin/main,check-changelog-parity.sh --check-bump origin/main, markdownlint over all changed markdown.Versioning
work-items0.30.0 —mainlanded 0.26.0 through 0.29.0 while this branch was in review, sothis branch's entry composes above them and both sides' changelog entries are retained.
implementation0.10.0 — already abovemain's 0.9.2, so it keeps its number.Related
the lane bodies and the loop-lane convention; this PR touches the dispatch seam, so the only
overlap was the
work-itemsversion line.Closes #1649
🤖 Generated with Claude Code