Skip to content

docs(autonomy): autonomous-runner design pack (WP7) - #676

Merged
kyle-sexton merged 15 commits into
mainfrom
docs/autonomy-runner-design-pack
Jul 20, 2026
Merged

docs(autonomy): autonomous-runner design pack (WP7)#676
kyle-sexton merged 15 commits into
mainfrom
docs/autonomy-runner-design-pack

Conversation

@kyle-sexton

@kyle-sexton kyle-sexton commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Summary

WP7 of the AI-adoption-ladder effort: the autonomous-runner design pack — the
architect-ready design contract the T4 charter graduates into, as a progressive-disclosure
hub (plugins/autonomy/reference/runner.md) with four leaves under reference/runner/.
Design only: zero build artifacts, the runner-execution home stays unborn, both T4 build
triggers are restated and neither is assumed fired.

  • Hub + seams (phase 1): T4 charter imported verbatim in substance (queue-contract split,
    both build triggers, self-run-primary substrate stance with the vendor-hosted
    human-merge-gate cap, inherited constraints, anti-goals) with an explicit no-build clause;
    the two-layer composition spine (normative shape in seam vocabulary; adopt-first binding
    stance with reimplement-the-pattern as the named fallback, no library pinned); the 8 seams
    as the spine's complete interface set, each citing its shipped owning contract or marked
    runner-new; envelope fields stop_reason / outcome / evidence / resume_handle
    resolved.
  • Lifecycle + escalation + topology (phase 2): linear state model
    leased → executing → verifying → disposing → (escalated | complete) with per-transition
    telemetry cited from the telemetry contract; thin per-item-PR launch disposition with the
    vendor-hosted cap restated on the disposition path; batched gated-merge serialization as a
    growth stage on its evidence trigger, binding a platform-native merge-queue facility, never
    reimplemented. Terminal-handoff escalation: four terminal outcomes (success never files
    escalation work), the two-family stop-criteria taxonomy (runner-owned / agent-signaled),
    the deterministic two-step mapping (stop reason → outcome → event class), two additively
    registered runner event classes (runner-needs-human, runner-cap-exceeded),
    contract-default severities for all eight classes on the notice/attention/urgent axis,
    the urgent stop-reason override, 72h/one-bump acknowledgment knobs, deferred mid-run
    interrupt, and four research gaps carried as UNVERIFIED. Topology: four ownership homes, the
    launch backend set (one free self-run L2 container-class backend; L3 deferred with C5
    dispatch blocked until bound, the floor cited from the work-classes cell; cloud backends
    advisory and vendor-hosted-capped), birth-time decisions USER-RESERVED.
  • Escalation-severity join + setup surface (phase 3): the security binding gains three
    genuinely additive optional keys beside an untouched escalation_routes
    escalation_severity (event class → severity), escalation_severity_routes (severity →
    route, personal-push legal at any tier, severity-first resolution with the per-event route
    as fallback), escalation_ack (staleness window, re-escalation cap). The event-class
    registry grows additively: escalation_routes keeps requiring only the six inherited
    guardrail classes (existing bindings validate unchanged) while the two runner classes are
    legal optional route keys. check-security-binding.mjs mirrors the shapes and adds the one
    semantic rule the schema cannot express (an unroutable severity-bound event class fails
    closed). SKILL.md gains the short runner note (427/500 lines), evals.json case 29 covers
    the slice, plugin 0.6.0 → 0.7.0, catalog regenerated.

Zero-build audit (phase 4)

Branch diff vs base: exactly 17 paths, all inside the four allowed surfaces (reference/ pack,
skills/setup/, the two READMEs, the plugin manifest) plus the PLAN's own phase tags. No new
.sh/.mjs/.py files. grep -rci 'git init\|create the repo' over reference/runner* = 0.
No sentence in the pack reads as a build commitment; birth-time decisions carry arbiter
USER-RESERVED.

Additivity proof (schema)

Full security-binding fixture sweep before/after: 10 pass / 92 reject → 11 pass / 95 reject
with zero flips among the 102 pre-WP7 fixtures — the delta is exactly the four new
escalation fixtures (valid binding passes; bad severity token, unroutable event class, and
non-positive ack values each reject with their own finding). A runner class bound through an
optional escalation_routes entry alone is routable, matching the escalation contract.

Near-duplicate audit

The pack cites the shipped contracts for every inherited obligation — matrix cells, isolation
ladder levels, queue/lease dispatch, telemetry emission and join attribute, return-accounting
capture, executor surface classes — and defines only runner-new content (envelope fields,
state model, stop-criteria taxonomy, severity mapping, ownership seams). The two deliberate
restatements are the stress-test F6 items: the vendor-hosted human-gate cap on the lifecycle
disposition path and on the topology cloud-backend path.

Gates

validate-plugins.sh, generate-catalog --check, validate-plugin-contracts.mjs (vendor
deny-list over reference/), run-plugin-tests.sh (all pass or skip),
claude plugin validate --strict, markdownlint, typos, lychee over the five-file pack
(66 links, 0 errors) — all green locally.

Related

No linked issue (the T4 charter decision node #244 is already closed; this package delivers
the design pack it chartered).

PLAN

ai-ladder-wp7-runner

Brief

TLDR

Runner design pack (T4 charter graduation): architect-ready design contract for the
autonomous-drain runner — spine shape + 8 seam specs, lifecycle state model, two-family
stop-criteria taxonomy with terminal-handoff escalation, matrix-derived backend set, and the
topology seam map. Design only: build stays gated on the T4 triggers; the runner-execution
home stays unborn.

Goal

When the T4 build trigger fires, /architect and the build start from a complete,
Boris-aligned design contract instead of a cold charter: every design decision T4 graduated
(composition spine, isolation backends, lifecycle depth, escalation UX, topology) is resolved
in contract vocabulary, every inherited constraint is imported unchanged, and nothing in the
package commits, implies, or starts a build before the trigger earns it.

Locked decisions

# Decision
D1 Scope: architect-ready design contract docs ONLY — charter import (T4 scope boundary, build triggers, substrate stance, inherited constraints, anti-goals) + the five design decisions T4 graduated (composition spine, multi-backend isolation, lifecycle depth, escalation UX, topology) resolved + seam specifications. Capability-distribution home. No code, no skeleton repo, no capability templates; runner-execution home stays unborn until the T4 build trigger fires (WP1 D1); empirical spine validation waits for the trigger.
D2 Composition spine, two-layer: normative contract fixes the spine SHAPE in seam vocabulary — minimal composable orchestration, pluggable sandbox-provider seam × pluggable agent-adapter seam, autonomous/interactive split, the 8 seams as its interface set (absorb discipline, no vendor names). Binding layer records adopt-first: adopt the qualifying spine library as a build-stage dependency, re-verified at trigger time (maintenance, license, seam fit); reimplement-the-pattern is the named fallback on failed re-verification.
D3 Isolation backends: the sandbox-provider seam is the normative requirement; the launch backend set derives from matrix coverage of trigger-admitted work — one free self-run L2 container-class backend (default-deny egress) at launch; an L3 backend is deferred with trigger = first C5-class work admitted to autonomous drain (fail-closed blocks C5 dispatch until an L3 binding exists); paid/cloud backends advisory + explicit opt-in.
D4 Lifecycle: full state model in the contract — lease-claim → execute in isolation → verification gates (matrix column) → disposition per merge policy → escalate or complete, every transition emitting telemetry per the telemetry contract. Launch disposition is thin: per-item PR through the platform's native flow. Batched gated merge serialization is a named growth stage with an evidence trigger (observed concurrent auto-merge collisions), binding to a platform-native merge-queue facility where one exists (availability verified at binding time); never reimplement a built-in.
D5 Escalation UX (WP5 D6 remainder, evidence: RESEARCH-escalation-observability.md): terminal-handoff at launch — every stop is a terminal state (success / gate-failed / needs-human / cap-exceeded); the runner files a human-gated work item carrying the evidence bundle (failure summary, run-transcript link, cost, trace link, session-resume handle; human takeover = resume the persisted session). Contract carries the two-family stop-criteria taxonomy: deterministic runner-owned (turn/budget/wall-clock caps, execution error after retries, refusal, verification-gate failure, isolation violation) and judgment agent-signaled through the structured-output envelope (ambiguity, design decision needing human judgment, security/data-integrity event, unresolvable blocker, no-progress); transient-recoverable retries with backoff, never escalates. Escalation event classes gain a severity axis mapped to org-bound notification fan-out (personal-push tier included as an org-bindable route); acknowledgment on the item + stale-unacked re-escalation (severity bump, capped) are org-bindable knobs. Mid-run interrupt (pause-for-human) deferred with trigger: evidence that kill-and-resume loses material cost/context; first-party pause/resume mechanisms verified available, so later adoption needs no contract change. Escalation telemetry rides the telemetry contract's custom namespace (no standard escalation signal exists; candidate upstream contribution).
D6 Topology: ownership seams pre-committed, shape at birth. Design-pack docs stay in the capability-distribution home; at trigger fire the runner-execution home is born owning the runner implementation + its build/release toolchain, consuming the contract docs (never duplicating them). Security-sensitive runner bindings (level→substrate, merge policy, escalation routes, admission) live in the settings-as-code home — the runner reads its governance, never writes it (the agent-writable-binding bypass-channel rationale generalizes to the runner itself); non-security operational config is deployment-owned per the hosting stance. Repo count, name, and implementation language resolve at birth via the naming pass + the re-verified spine choice. Absent settings-as-code home in an adopting org: layered resolution + fail-closed on absent security binding applies; guided-setup names the compliant path.
D7 Imports, all unchanged: T4 charter core (queue-contract split, both build triggers, self-run-primary substrate stance with hosted human-gate cap, anti-goals); WP4 D6 executor surface classes — the runner is one executor behind the invocation-adapter seam, adapters untouched on swap; WP5 matrix columns + admission decision-table + caps, promotion human-ratified / demotion automatic, L2+ fail-closed floor; WP6 routine-filed items drain through the same queue (no routine-special path); telemetry contract + trace propagation on every lifecycle transition; return-accounting capture hooks at the runner's task boundary; queue + lease reused from the work-item capability — no second claim mechanism; the 8 seams as the spine's interface set.

Constraints

  • Any fleet repo or vendor name in normative contract text is a defect; vendor names appear
    only as marked examples and in binding docs.
  • Zero build artifacts anywhere in the package: no code, no repo, no templates; no sentence
    that reads as a build commitment.
  • One queue, one lease, one escalation channel (the queue itself); no second claim, dispatch,
    or escalation mechanism.
  • Security-sensitive runner bindings never live where the runner (or the agents it runs) can
    edit them.
  • Fail-closed everywhere: absent L2 substrate, absent security binding, unbound C5 work —
    block and name the compliant path, never degrade silently.
  • No new cost by default; paid backends/surfaces advisory + explicit opt-in with cost
    surfaced.
  • Boris-alignment is the standing acceptance criterion (no step-skipping, trust before
    scale).

Acceptance criteria

  • Design pack delivers, in contract vocabulary only: spine shape + 8 seam specifications,
    lifecycle state model, two-family stop-criteria taxonomy, severity/ack/re-escalation knob
    set, launch backend derivation, topology seam map.
  • Zero build artifacts; runner-execution home unborn; T4 build triggers restated verbatim;
    no build commitment anywhere in the text.
  • WP5 D6's escalation-UX deferral — the last WP5-inherited cross-package deferral — is
    resolved by this package (mid-run interrupt stays deferred with its own evidence trigger;
    this pack resolves the inherited deferral, it does not claim nothing remains deferred).
  • Research gaps carried visibly, not laundered: CI-action-class failure-reporting UNVERIFIED;
    cross-vendor agent-needs-human signaling (agent-protocol / agent-instruction-file guidance)
    UNVERIFIED; managed-agent event names drift between stream and webhook surfaces — bind
    exact names at build from live docs; the deprecated approval-SDK is never cited as living
    precedent.
  • Boris check: step-3 trap honored (charter-not-build, trust before scale); the 2→3 "let
    Claude kick off Claude" cell stays inside the governed-queue audit trail; the step-4 cell
    is chartered, not built — closed loop via self-run substrate, programmatic-scheduling
    surface class, cost controls as caps/budget knobs, model selection as cost tiers;
    monitor-by-exception instantiated as terminal-handoff escalation; the thread-post return
    metric is fed by return-accounting capture at the runner boundary.

Captured assumptions

  • The qualifying spine library remains maintained and license-compatible at trigger time —
    re-verify at trigger; reimplement-the-pattern is the named fallback (D2).
  • First-party pause/resume mechanisms (SDK callback pause + defer/resume, managed idled
    webhook) remain available — beta/moving surfaces; re-verify at build before relying on
    them for the mid-run-interrupt growth stage.
  • The work-item capability's race-safe lease + autonomous drain mode remain the dispatch
    entrypoint (live-verified in a prior session).
  • Personal-push notification routes presuppose org-bound channel adapters (WP4) at binding
    time; absent adapters, severity fan-out degrades to tracker-item-only — never silently
    drops the escalation itself.

Out-of-scope (deferred with triggers)

  • Runner build itself — trigger: either T4 build trigger fires.
  • L3 backend — trigger: first C5-class work admitted to autonomous drain.
  • Batched gated merge serialization — trigger: observed concurrent auto-merge collisions.
  • Mid-run interrupt escalation — trigger: evidence that kill-and-resume loses material
    cost/context.
  • Fleet materializations (runner stand-up, binding instances) — /work-items backlog
    post-graduation.

Deferred questions

  • Exact seam interface tokens, envelope field names, and lifecycle state tokens —
    /architect (with the plugin naming pass).
  • Severity level names + default staleness window and re-escalation cap values —
    /architect.
  • Setup/probe mechanics per backend class (joins the WP5 D4 slice) — /architect.
  • Birth-time decisions: repo count/name/implementation language, spine re-verification
    outcome, exact managed-event name bindings — build stage, gated on the T4 trigger;
    arbiter: USER-RESERVED (trigger firing is a user-ratified event).

Plan

Recommendation-locked this round under the user's standing pre-authorization. Token sets
(D-deferred, resolved here): lifecycle state tokens leased / executing / verifying /
disposing / escalated / complete (terminal: escalated, complete); terminal-outcome
tokens success / gate-failed / needs-human / cap-exceeded; stop-criteria family
tokens runner-owned (deterministic) and agent-signaled (judgment, via the
structured-output envelope field stop_reason); severity levels notice / attention /
urgent (three levels — mapped to org-bound notification fan-out; tracker item always,
channel notification per org route, personal-push tier org-bindable at urgent); default
staleness window 72h with one re-escalation (severity bump, cap 1) — org-bindable knobs.
Design-pack docs live under reference/runner/ (hub reference/runner.md).

Prerequisites: WP4 + WP5 + WP6 implementation PRs merged (this pack imports their contracts
by citation). Design only — zero build artifacts; the runner-execution home stays unborn.

Phase 1: Charter import + spine and seam specs [DONE]

File Action What changes
plugins/autonomy/reference/runner.md Create Design-pack hub: T4 charter imported verbatim-in-substance (queue-contract split interactive-upstream / autonomous-downstream; BOTH build triggers restated verbatim; self-run-primary substrate stance with the hosted human-merge-gate cap; anti-goals) with an explicit no-build-commitment clause; the two-layer composition spine per D2 — normative spine SHAPE in seam vocabulary (minimal composable orchestration, pluggable sandbox-provider seam × pluggable agent-adapter seam, autonomous/interactive split) with the 8 seams as its interface set; adopt-first binding stance recorded (qualifying spine library re-verified at trigger time; reimplement-the-pattern the named fallback); glance rule routing depth to the leaves.
plugins/autonomy/reference/runner/seams.md Create The 8 seam specifications in contract vocabulary (invocation adapter, structured-output envelope, queue+lease, isolation policy, outcome-verification gate, merge-policy toggle, observability+cost, session/resume+caps): each seam's obligation set, its already-shipped owning contract where one exists (queue+lease → trigger-dispatch; isolation policy → guardrails; observability+cost → telemetry; capture at task boundary → return accounting) cited never restated, and the runner-side interface tokens. Envelope field names resolved: stop_reason, outcome, evidence (bundle ref), resume_handle.

Sanity Check:

  • grep -ci 'build trigger' plugins/autonomy/reference/runner.md ≥ 2 (both triggers restated)
  • grep -c 'no build' plugins/autonomy/reference/runner.md ≥ 1 (commitment clause present)
  • Seam count: grep -cE '^## ' plugins/autonomy/reference/runner/seams.md = 8
  • Vendor+fleet deny-list sweep exit 0; lychee lane passes

Phase 2: Lifecycle + stop-criteria + escalation leaves [DONE]

File Action What changes
plugins/autonomy/reference/runner/lifecycle.md Create Full state model per D4: leased → executing → verifying → disposing → (escalated | complete), every transition emitting telemetry per the telemetry contract (trace-linked); launch disposition thin (per-item PR through the platform's native flow, merge disposition governed by the WP5 matrix row — including the vendor-hosted human-gate cap whenever the executing backend is vendor-hosted, restated here rather than inherited silently); batched gated-merge serialization named as a growth stage with its evidence trigger (observed concurrent auto-merge collisions) binding to a platform-native merge-queue facility — never reimplemented.
plugins/autonomy/reference/runner/escalation.md Create D5 resolved: terminal-handoff at launch — every stop resolves to a terminal outcome (success/gate-failed/needs-human/cap-exceeded); the NON-SUCCESS outcomes file the human-gated work item with the evidence bundle (failure summary, run-transcript link, cost, trace link, resume_handle; human takeover = resume the persisted session), while success completes through the normal disposition + return-accounting path — no escalation item, no ack/re-escalation obligations, else every healthy run would generate false escalation work (PR-review finding); two-family stop-criteria taxonomy verbatim (runner-owned: turn/budget/wall-clock caps, execution error after retries, refusal, verification-gate failure, isolation violation; agent-signaled via stop_reason: ambiguity, design decision, security/data-integrity event, unresolvable blocker, no-progress); transient-recoverable retries with backoff, never escalates; severity axis (notice/attention/urgent) → org-bound fan-out with personal-push as an org-bindable route; an EXPLICIT two-step mapping so severity resolution is deterministic for every non-success stop (PR-review findings — the severity join keys on event class, which runner outcomes alone never named, and stop reasons in turn never named their outcome): STEP ONE, stop reason → terminal outcome — runner-owned: verification-gate failure → gate-failed; turn/budget/wall-clock cap → cap-exceeded; execution error after retries, refusal, and isolation violation → needs-human; agent-signaled (every stop_reason value: ambiguity, design decision, security/data-integrity event, unresolvable blocker, no-progress) → needs-human; STEP TWO, outcome → event class: gate-failed → the guardrail contract's gate-failure event class; needs-human and cap-exceeded → two runner escalation event classes with the tokens runner-needs-human and runner-cap-exceeded, registered ADDITIVELY alongside the guardrail contract's set — the Phase 3 schema edit extends the event-class registry (the enum escalation_routes and escalation_severity keys validate against) with these two tokens, and check-security-binding.mjs accepts route/severity bindings for them like any guardrail class (default severities attention and notice, org-bindable), and contract default severities for EVERY inherited guardrail event class so severity fan-out is defined with no escalation_severity binding at all (gate failure attention, verification divergence attention, admission rejection notice, demotion event attention, structural-class plan approval attention, untrusted-provenance urgent — all org-bindable overrides); an isolation violation or a security/data-integrity stop reason carries an urgent severity override regardless of its event class's default; the filed escalation item's envelope records the resolved event class AND the originating stop reason; acknowledgment-on-item + stale-unacked re-escalation (default 72h window, one severity-bump re-escalation, both org-bindable); mid-run interrupt deferred with its evidence trigger; escalation telemetry rides the telemetry contract's custom-namespace mechanism — the exact namespace token is read from the shipped telemetry contract at implementation, not pinned here (candidate upstream contribution noted). Research gaps carried verbatim (CI-action-class failure-reporting UNVERIFIED; cross-vendor needs-human signaling UNVERIFIED; managed-agent event-name drift — bind at build; deprecated approval-SDK never cited as living precedent).
plugins/autonomy/reference/runner/topology.md Create D6: ownership seam map — design pack in the capability-distribution home; at trigger fire the runner-execution home is born owning implementation + build/release toolchain, consuming contracts never duplicating; security-sensitive runner bindings in the settings-as-code home (runner reads its governance, never writes it); non-security operational config deployment-owned; launch backend set per D3 (one free self-run L2 container-class backend; L3 deferred with the first-C5 trigger, fail-closed until bound — the C5→L3 floor CITED from the WP5 work-classes matrix cell, never asserted independently here, per stress-test F5; paid/cloud advisory + opt-in, and any cloud backend IS a vendor-hosted executor: it forces the security binding's executor_class: vendor-hosted, capping every merge row at human-gated, per F6); birth-time decisions listed with arbiter USER-RESERVED (repo count/name/language, spine re-verification, exact managed-event names).

Sanity Check:

  • State tokens present: grep -c 'disposing' plugins/autonomy/reference/runner/lifecycle.md ≥ 1
  • grep -c 'cap-exceeded' plugins/autonomy/reference/runner/escalation.md ≥ 1 and grep -c 'stop_reason' …/escalation.md ≥ 1
  • grep -ci 'UNVERIFIED' plugins/autonomy/reference/runner/escalation.md ≥ 2
  • grep -c 'USER-RESERVED' plugins/autonomy/reference/runner/topology.md ≥ 1
  • Vendor+fleet deny-list sweep exit 0

Phase 3: Setup note + WP5 escalation-route join [DONE]

File Action What changes
plugins/autonomy/skills/setup/SKILL.md Modify A short runner note only: the design pack is bindable-when-born; setup records NOTHING runner-specific until the trigger fires except escalation notification routes (severity axis + personal-push tier as route options). No probe, no wiring, no binding section for the unborn home.
plugins/autonomy/skills/setup/schemas/guardrails-security-binding.schema.json Modify The severity refinement is GENUINELY additive (stress-test F2 — the schema is additionalProperties: false, so an undeclared shape would fail every severity-tiered binding): escalation_routes keeps its existing event-class→route entries unchanged; three new OPTIONAL top-level keys land beside it, modeling the event/severity join explicitly — escalation_severity (event class → severity token, the join: which severity each event class escalates at; contract defaults per event class, org-bindable), escalation_severity_routes (severity token → route, notice/attention/urgent, personal-push a legal route value at any tier; route resolution = event class → its severity → that severity's route, falling back to the event class's own escalation_routes entry when no severity route is bound), and escalation_ack (staleness_window, default 72h; reescalation_cap, default 1). Old bindings validate unchanged — no major bump; that resolution is now in-plan, not asserted.
plugins/autonomy/skills/setup/scripts/check-security-binding.mjs Modify Semantic checks for the new keys: severity tokens ∈ the three-level set; escalation_ack values positive; routability per event class matches the resolution rule — an event class keyed in escalation_severity is routable when its severity has an escalation_severity_routes entry OR the event class has its own escalation_routes entry (severity-only fan-out is legal, matching severity-route-first resolution; a legacy per-event route is the fallback, never a requirement), and only an event class with NEITHER is flagged unroutable.
plugins/autonomy/skills/setup/evals/evals.json Modify Escalation-route slice case (severity + personal-push binding recorded; unborn-home refusal restated) — stress-test F7: every other WP adds eval coverage for its SKILL.md change; no exemption here.
plugins/autonomy/README.md + plugins/autonomy/.claude-plugin/plugin.json Modify Capability list gains the runner design pack; the roadmap row stays trigger-gated (build), now pointing at the pack; minor version bump.

Sanity Check:

  • grep -ci 'unborn' plugins/autonomy/skills/setup/SKILL.md ≥ 1
  • README roadmap still carries the build trigger row (grep -c 'build trigger' plugins/autonomy/README.md ≥ 1)
  • Schema additivity: grep -c 'escalation_severity_routes' …schema.json ≥ 1 and a pre-WP7 fixture binding still passes check-security-binding.mjs unchanged (no major bump proven, not asserted)
  • /skill-quality:check + validate-evals pass; claude plugin validate --strict exit 0

Phase 4: Zero-build audit + gates [DONE]

Acceptance probe (mechanical): the package introduces no executable/runtime artifact — the
diff contains no new files outside reference/, skills/setup/, README, and plugin
manifest; no new scripts; no repo-creation instruction anywhere. Then the full gate roster
(validate-plugins.sh, run-plugin-tests.sh, validate-plugin-contracts.mjs,
markdown/typos/lychee, claude plugin validate --strict, catalog regen). Near-duplicate
audit statement: the pack cites the shipped contracts for every inherited obligation and
defines only runner-new content.

Sanity Check:

  • git diff --name-only <base> contains no path outside the four allowed surfaces; no *.sh/*.mjs additions
  • grep -rci 'git init\|create the repo' plugins/autonomy/reference/runner* = 0
  • All gate scripts exit 0; catalog in-sync; near-duplicate audit statement in the PR body

Blast radius

MEDIUM — docs-only within one plugin, but the pack pre-commits topology and escalation
contracts the eventual build must honor; WP5's last cross-package deferral resolves here.
Fully git-revertible; zero runtime surface by design.

Stress-test summary

Fresh-context plan review (WP6+WP7 batch): 10 findings, verdict FIX-THEN-SHIP, WP7's share
folded — F2 (HIGH): the escalation-route severity refinement touched the WP5 security-binding
schema (additionalProperties: false) but Phase 3 listed neither the schema nor the
validator, leaving the flagship severity/ack knob set unbindable, and "additive, no major
bump" was asserted over what read as a value-shape change → both files added to Phase 3 and
the refinement modeled as genuinely additive optional keys (escalation_severity_routes,
escalation_ack), with a pre-WP7 fixture-passes gate proving no major bump. F5 (MED): the
C5→L3 fail-closed gate now CITES the WP5 work-classes matrix cell (which imports T3's C5/L3
row) instead of asserting the value. F6 (LOW-MED): the vendor-hosted human-gate merge cap is
restated on the cloud-backend and disposition paths instead of silently inherited. F7 (LOW):
the Phase 3 SKILL.md change gains eval coverage like every other WP. F9 (LOW): the
"last cross-package deferral" claim scoped to the WP5-inherited deferral. F10 (LOW): the
escalation-telemetry namespace token is read from the shipped telemetry contract at
implementation, not pinned in the plan. Scope discipline (zero build artifacts, unborn
runner-execution home, USER-RESERVED birth decisions) audited clean.

Execution shape

Fully sequential 1 → 2 → 3 → 4 — leaves depend on the hub's imported charter; the setup note
cites Phase 2's escalation severity axis; Phase 4 audits the authored tree. Cross-package:
after WP4+WP5+WP6 implementation PRs.

Phase Surface Basis
1 main-session charter import fidelity + seam-spec judgment
2 main-session lifecycle/escalation normative authoring
3 main-session minimal setup-skill touch
4 main-session mechanical audit + gate runs

Open questions

  • Birth-time decisions (repo count/name/language, spine re-verification, managed-event
    names) — USER-RESERVED at trigger fire, restated in topology.md.

Decisions made (gate-passed)

Decision What it changes in the plan Basis (evidence)
Lifecycle tokens leased/executing/verifying/disposing/escalated/complete Phase 2 leaf D4's state model named each stage; kebab/lowercase matches shipped token sets
Terminal outcomes success/gate-failed/needs-human/cap-exceeded Phase 2 leaf D5 names exactly these four
Severity set notice/attention/urgent; 72h staleness, one re-escalation Phase 2 leaf D5 requires a severity axis + ack/re-escalation knobs with suggested defaults; three tiers is the smallest set covering tracker-only / channel / push fan-out
Envelope fields stop_reason/outcome/evidence/resume_handle Phases 1–2 D5's evidence-bundle + resume requirements; smallest field set carrying them
Hub-and-leaves under reference/runner/ Phase 1–2 paths Same layout as WP5/WP6 hubs
Escalation-route severity refinement = new OPTIONAL schema keys (escalation_severity as the explicit event→severity join, escalation_severity_routes, escalation_ack) beside an untouched escalation_routes; schema + validator edits in Phase 3 Phase 3 WP5 D6 routes live there; stress-test F2 — only genuinely additive keys avoid a major bump under additionalProperties: false, proven by the pre-WP7 fixture gate; the join key answers the PR-review finding that severity→route alone left route selection non-deterministic per event class

Handoff to implementation

User-approval gates

  • Anything that reads as a build commitment or creates a runtime artifact → STOP (D1
    user-locked; the zero-build audit is the backstop).
  • Birth-time decisions stay USER-RESERVED — never resolved by implementation.
  • Any scope expansion beyond the four phases re-enters /architect review.

Execution shape ([EXEC-SHAPE] tagged)

Sequential 1→4, all main-session (table above). PLAN.md phase tags advance in the same
commit as each phase.

Mechanical work

Commit per phase on the implementation branch (suggest docs/autonomy-runner-design-pack
docs-type: the package is normative text only); gates re-run in full at Phase 4; PR body
carries the zero-build audit output + near-duplicate audit statement + this PLAN in a
<details> block at close-out.

kyle-sexton and others added 4 commits July 20, 2026 05:52
Charter import plus spine and seam specifications, design contract only.
runner.md imports the T4 charter verbatim in substance: the queue-contract
split (interactive upstream with the plugins, autonomous drain with the
runner), both build triggers restated with executors rendered in the
shipped surface-class vocabulary, the self-run-primary substrate stance
with the vendor-hosted human-merge-gate cap, inherited constraints cited
from their owning contracts, anti-goals, and an explicit no-build clause -
the runner-execution home stays unborn until a T4 build trigger fires.
The two-layer composition spine records the normative shape (minimal
composable orchestration over the sandbox-provider and agent-adapter
seams with the autonomous/interactive split) and the adopt-first binding
stance with reimplement-the-pattern as the named fallback, no library
pinned. seams.md specifies the eight seams as the spine's complete
interface set, each citing its shipped owning contract (queue+lease,
isolation policy, observability+cost, return accounting) or marked
runner-new, with the envelope fields stop_reason, outcome, evidence, and
resume_handle resolved and all deeper token sets routed to the phase-2
leaves. PLAN phase 1 tagged DONE.

Gates: contract validator clean (vendor deny-list on reference/), typos
clean, markdownlint clean, 8 seam sections exact, both build triggers and
the no-build clause grep-verified, every cited anchor and leaf file
verified present.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…7 phase 2)

Three leaves complete the design pack's normative content. lifecycle.md
fixes the linear state model (leased, executing, verifying, disposing,
then escalated or complete), each state's owning seam cited, transition
telemetry riding the telemetry contract, the thin per-item-PR launch
disposition with the vendor-hosted human-gate cap restated explicitly on
the disposition path, and batched gated-merge serialization named as a
growth stage binding a platform-native merge-queue facility on its
evidence trigger. escalation.md resolves the terminal-handoff shape:
four terminal outcomes with success never filing escalation work, the
two-family stop-criteria taxonomy (runner-owned deterministic,
agent-signaled through stop_reason) with transient-recoverable retrying
instead of escalating, the deterministic two-step mapping from stop
reason to outcome to event class, two additively registered runner event
classes (runner-needs-human, runner-cap-exceeded) beside the guardrail
contract's six, contract-default severities for all eight classes on the
notice/attention/urgent axis, the urgent stop-reason override for
isolation violations and security/data-integrity events, evidence-bundle
contents with resume_handle takeover, 72h/one-bump acknowledgment knobs,
the deferred mid-run interrupt with its evidence trigger, escalation
telemetry on the custom-namespace mechanism, and four research gaps
carried as UNVERIFIED. topology.md maps the four ownership homes (design
pack, unborn runner-execution home, settings-as-code governance the
runner reads and never writes, deployment-owned operational config), the
launch backend set (one free self-run L2 container-class backend; L3
deferred, C5 dispatch blocked until bound, the floor cited from the
work-classes cell; cloud backends advisory and vendor-hosted-capped),
and the USER-RESERVED birth-time decisions. Hub links corrected to
reference-relative paths. PLAN phase 2 tagged DONE.

Gates: contract validator, typos, markdownlint all clean; lychee over
the five-file pack 66 links, 0 errors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…P7 phase 3)

The security binding gains the escalation-severity refinement as three
genuinely additive optional keys beside an untouched escalation_routes:
escalation_severity (event class to severity token - the explicit join),
escalation_severity_routes (severity token to route, personal-push a
legal route value at any tier; resolution is severity-first with the
event class's own escalation_routes entry as fallback), and
escalation_ack (staleness_window, reescalation_cap; contract defaults
72h and one bump live in the runner escalation contract, not the
schema). The event-class registry grows additively with
runner-needs-human and runner-cap-exceeded: escalation_routes keeps
REQUIRING only the six inherited guardrail classes - existing bindings
validate unchanged - while the two runner classes are legal OPTIONAL
route keys, accepted exactly like any guardrail class per the escalation
contract. check-security-binding.mjs mirrors the shapes and adds the one
semantic rule the schema cannot express: an event class bound in
escalation_severity with neither a bound severity route nor its own
escalation_routes entry is unroutable, fail-closed.

Setup surface: SKILL.md gains the short runner note (design pack
bindable-when-born; nothing runner-specific recorded until a build
trigger fires except the escalation notification routes; 427/500 lines),
evals.json gains case 29 covering that slice, the plugin README gains
the runner-design-pack capability with the build row still
trigger-gated, plugin.json bumps to 0.7.0, and the root catalog is
regenerated. PLAN phase 3 tagged DONE.

Verified: full fixture sweep 11 pass / 95 reject with ZERO flips among
the 102 pre-WP7 fixtures (additivity proven, not asserted); the four new
escalation fixtures behave exactly as named (valid binding with runner
classes, severities, personal-push urgent route, and ack knobs passes;
bad severity token, unroutable class, and non-positive ack values each
reject with their own finding); a runner class bound through an optional
escalation_routes entry alone is routable; validate-plugins.sh, catalog
--check, contract validator, and typos all clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Mechanical acceptance probe: the branch diff against the base contains
exactly seventeen paths, all inside the four allowed surfaces (reference/
pack files, skills/setup/ surfaces, the two READMEs, the plugin manifest)
plus the PLAN's own phase tags; no new script files of any kind; zero
repo-creation instructions under reference/runner*. Full gate roster run
locally: validate-plugins.sh, generate-catalog --check,
validate-plugin-contracts.mjs, run-plugin-tests.sh (all pass or skip),
claude plugin validate --strict, markdownlint, typos, and lychee over the
five-file pack (0 errors). PLAN phase 4 tagged DONE.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@claude

claude Bot commented Jul 20, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 3m 49s —— View job


PR Review: docs(autonomy): autonomous-runner design pack (WP7)

  • Read changed files and gather context
  • Review reference documentation (runner.md hub + 4 leaves)
  • Review schema changes (guardrails-security-binding.schema.json)
  • Review script changes (check-security-binding.mjs)
  • Review eval fixtures and evals.json
  • Review plugin.json, README, SKILL.md changes
  • Synthesize and post final review

Overview

Well-constructed design-pack PR. The progressive-disclosure architecture is sound, the no-build covenant is consistently upheld across all five doc files, and the schema/script changes are genuinely additive — the additivity proof (10→11 pass, 92→95 reject, zero flips on pre-WP7 fixtures) is credible given what's added. Two issues found: one is stale text that will be incorrect at merge, one is a contract ambiguity that could split implementors.


Issues

1. Stale forward-link note in runner.md (minor correctness issue)

Lines 121–123:

The `lifecycle`, `escalation`, and `topology` leaves land with the pack's later phase; their
forward links are expected within an in-progress design pack.

This was accurate at phase 1 commit time, but all four leaves (seams.md, lifecycle.md, escalation.md, topology.md) are added in this same PR and will be present at merge. A reader hitting the merged hub will see a "forward links are expected" note for leaves that already exist. The glance-layer routing table above it is correct; just these two trailing sentences need to be removed.

Fix this →

2. Urgent stop-reason override ambiguity in escalation.md

Lines 133–139:

"the override forces the filed item to urgent regardless of that default"

"That default" refers to the contract-default attention severity for runner-needs-human. The phrase is ambiguous about whether an org-configured escalation_severity.runner-needs-human: notice binding can downgrade an isolation-violation or security/data-integrity stop from urgent. An implementor reading this charitably would let the org binding win; one reading it strictly for safety would treat the stop-reason override as absolute.

For these two specific stop reasons (isolation violation, security/data-integrity event), the stop-reason override should almost certainly be absolute — otherwise an org misconfiguration silently suppresses urgent safety signals. A clarifying sentence would close this: e.g. "The override is absolute and is not configurable lower through escalation_severity; those stop reasons are always urgent regardless of the event class's org-configured severity."


Positive observations

Schema additivity is clean. The three new optional top-level keys (escalation_severity, escalation_severity_routes, escalation_ack) don't touch any required field, and escalation_routes correctly keeps requiring only the original six guardrail classes while accepting the two runner classes as optional properties. The EscalationEventClass $def is the single authoritative registry. This matches the checker's ESCALATION_EVENT_CLASSES = [...EVENT_CLASSES, ...RUNNER_EVENT_CLASSES] split.

The unroutable semantic check is correct. check-security-binding.mjs lines 1501–1515 implements the severity-first resolution rule exactly: !severityRouted && !eventRouted fires a finding only when neither path yields a route. The continue guard on bad-token entries (!SEVERITY_TOKENS.includes(severity)) correctly avoids double-reporting a secondary unroutable finding on top of the enum error.

Fixture coverage is correct. All four new fixtures exercise distinct failure modes independently:

  • escalation-severity-valid.json — both runner classes routable via severity_routes
  • escalation-severity-bad-token.json"critical" fails the severity enum check
  • escalation-severity-unroutable.jsonrunner-needs-human → attention with no severity route and no direct event route
  • escalation-ack-invalid.jsonstaleness_window: 0 fails the >= 1 check

The two-step severity mapping is properly deterministic. The stop reason → outcome → event class path in escalation.md has no ambiguous cells: gate-failed routes through the inherited gate-failure class (not re-minting), while needs-human and cap-exceeded introduce two new additive classes. The inherited gate-failure reuse avoids splitting the guardrail event-class registry.

Disposition vendor-hosted cap restatement is intentional and correct. Both lifecycle.md (disposition section) and topology.md (cloud backend entry) explicitly restate the vendor-hosted human-gate cap rather than letting it be inherited silently. The PR description calls these the "stress-test F6" deliberate restatements — this is right, since the cap is security-critical and easy to miss when following a cross-reference chain.

SKILL.md runner note is appropriately scoped. The 14-line addition at lines 397–410 correctly carves out the single exception (escalation route bindings on the security surface) without front-running the unborn runner-execution home, and points to the escalation leaf rather than duplicating its content.

Eval case 29 scope is tight. The case tests exactly what the runner note enables (wiring severity levels and a personal-push tier) and correctly asserts that the runner-execution home is unborn and no other runner-specific binding is written.


Verdict: Approve pending the stale text removal (issue 1) and an optional clarification of the urgent override semantics (issue 2). Issue 1 is a must-fix before merge; issue 2 is strongly recommended given the security implications.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 56507c517a

ℹ️ 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".

Comment thread plugins/autonomy/skills/setup/schemas/guardrails-security-binding.schema.json Outdated
Comment thread plugins/autonomy/reference/runner/topology.md Outdated
…ss (wave 1)

Two review findings. First, the schema accepted any reescalation_cap >= 1
while the escalation contract allows a single stale-unacked re-escalation
- one severity bump, never a loop. The schema now pins the value at
exactly 1 and check-security-binding.mjs rejects a higher cap with its
own finding (new fixture escalation-ack-loop rejects on exactly that).

Second, topology.md forced executor_class vendor-hosted for ANY cloud
backend, contradicting the executor-surface contract: self-operated
executors are CLI/SDK processes wherever they run, and hosting
configuration is deployment-owned. The merge-row cap now follows the
executor surface class, never the hosting alone - an org-operated cloud
substrate running the self-operated runner stays self-operated, while a
vendor-managed backend (the vendor operates the executor) still forces
vendor-hosted and its human-gate cap.

Verified: loop fixture rejects with the single new finding; full sweep
11 pass / 96 reject, zero flips among prior fixtures; schema parses;
contract validator, typos, and lychee clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@claude

claude Bot commented Jul 20, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 2m 27s —— View job


Wave-1 fix review — docs(autonomy): autonomous-runner design pack (WP7)

  • Gather context and identify changed files in latest commit
  • Check runner.md — stale forward-link note (prior must-fix)
  • Check schema + script — re-escalation cap pin (Codex P2)
  • Check topology.md — executor class for cloud runners (Codex P2)
  • Check escalation.md — urgent override ambiguity (prior recommended fix)
  • Synthesize findings and post final review

Wave-1 delta review

The commit e6fa783 targeted the two Codex P2 issues. Both are resolved; the two issues from the prior Claude review remain.


Fixed ✅ — Re-escalation cap pinned at one (Codex P2)

Three-layer fix is correct and complete:

  • Schema (guardrails-security-binding.schema.json): "maximum": 1 added alongside the existing "minimum": 1, so the schema now rejects any reescalation_cap ≠ 1 at validation time. The description is also updated to explain the reason explicitly.
  • Script (check-security-binding.mjs:637): Belt-and-suspenders semantic check fires a human-readable finding for reescalation_cap > 1, explaining the notification-loop hazard. Correct approach — schema handles structural rejection; the checker explains the contract violation.
  • Fixture (escalation-ack-loop.json): New reject fixture (reescalation_cap: 2) exercises the new rejection path independently from the existing staleness_window: 0 fixture.

Fixed ✅ — Executor class follows surface, not hosting (Codex P2)

topology.md lines 43–51 now makes the correct distinction:

"Whether a cloud backend caps the merge rows follows the executor surface class, never the hosting alone: an org-operated cloud substrate running the self-operated runner stays executor_class: self-operated … while a vendor-MANAGED backend … is a vendor-hosted executor and forces … executor_class: vendor-hosted"

This correctly aligns with the executor-surface-classes contract and removes the prior conflation of hosting configuration with executor class. The auto-merge promotion path is now reachable for self-operated runners on cloud substrates, as it should be.


Still open — Stale forward-link note in runner.md (prior must-fix)

Lines 122–123 still read:

The `lifecycle`, `escalation`, and `topology` leaves land with the pack's later phase; their
forward links are expected within an in-progress design pack.

All four leaves (seams.md, lifecycle.md, escalation.md, topology.md) are present on this branch. A reader hitting the merged hub sees a "forward links expected" note for leaves that already exist. These two sentences should be removed before merge.

Fix this →


Still open — Urgent stop-reason override ambiguity in escalation.md (prior recommended fix)

Lines 137–139 still read:

"the override forces the filed item to urgent regardless of that default"

"That default" refers to the contract-default attention for runner-needs-human. It remains ambiguous whether an org-configured escalation_severity.runner-needs-human: notice binding can silently downgrade an isolation-violation or security/data-integrity stop from urgent. Given that the two triggers (isolation violation, security/data-integrity event) are precisely the stops where silent suppression is most dangerous, a one-sentence clarification is strongly recommended: "The override is absolute and is not configurable lower through escalation_severity; isolation-violation and security/data-integrity stops are always urgent regardless of the event class's org-configured severity."


Status

Finding Source Wave-1 status
Re-escalation cap must be ≤ 1 Codex P2 ✅ Fixed
Self-operated cloud runner executor class Codex P2 ✅ Fixed
Stale forward-link note in runner.md Prior review (must-fix) ❌ Outstanding
Urgent override ambiguity in escalation.md Prior review (recommended) ❌ Outstanding

The wave-1 changes are clean and correct. One must-fix (stale text) remains before merge.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e6fa78347a

ℹ️ 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".

Comment thread plugins/autonomy/skills/setup/schemas/guardrails-security-binding.schema.json Outdated
…route (wave 2)

One review finding. The schema descriptions and the checker's routability
rule modeled severity-first ROUTE resolution with the per-event route as
fallback - under that reading a bound severity route would replace the
event class's queue destination, so a gate failure could notify a channel
instead of filing its required queue item, breaking the always-filed
tracker item and its acknowledgment lifecycle.

Corrected to the escalation contract's actual model: the escalation item
always files at the event class's own escalation_routes destination;
escalation_severity_routes is the NOTIFICATION fan-out layered on that
filed item (channel, personal-push), never its queue destination and
never a replacement. A severity with no bound notification route degrades
to tracker-item-only fan-out - a conforming binding, not a defect - so
the unroutable semantic rule is removed and its fixture flips to
escalation-severity-tracker-only-valid (now passing, the degrade proof).

Verified: renamed fixture passes; full sweep 12 pass / 95 reject with no
other flips; schema parses; contract validator and typos clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@claude

claude Bot commented Jul 20, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 2m 18s —— View job


Wave-2 delta review — docs(autonomy): autonomous-runner design pack (WP7)

  • Gather context on latest commit (7bbfd14)
  • Check severity fan-out fix (new Codex P2 — wave-2 commit)
  • Check runner.md — stale forward-link note (prior must-fix)
  • Check escalation.md — urgent override ambiguity (prior recommended fix)
  • Synthesize findings and post final review

Overview

Commit 7bbfd14 correctly addresses the Codex P2 wave-2 finding on severity fan-out. Three changes, all sound. The two prior open issues remain.


Fixed ✅ — Severity selects notification fan-out, never the item route

Three-part fix is correct and complete.

Schema descriptions (guardrails-security-binding.schema.json lines 84, 91):
The prior escalation_severity description encoded severity-first route resolution ("resolves to its severity, then to that severity's escalation_severity_routes entry, falling back to the event class's own escalation_routes entry"). Under that reading a bound attention → channel:autonomy-escalations severity route could replace a gate-failure → queue:escalations/gate-failure queue destination, breaking the always-filed tracker item. Both descriptions are now corrected: severity selects NOTIFICATION fan-out layered on the filed item, never its queue destination; escalation_routes is the item's destination and is untouched by severity.

Semantic check removed (check-security-binding.mjs lines 1496–1515):
The unroutable check (!severityRouted && !eventRouted → finding) is correctly removed. Under the corrected model, a severity binding with no notification route anywhere is a conforming binding — the item always files at escalation_routes, and the severity route is the notification layer; absent a notification route the fan-out degrades to tracker-item-only, which the escalation.md fan-out table explicitly names as the notice row behavior. The replacement comment states this correctly.

Fixture rename (escalation-severity-unroutable.jsonescalation-severity-tracker-only-valid.json, now passing):
The renamed fixture has escalation_severity.runner-needs-human: "attention" with no escalation_severity_routes.attention entry and no escalation_routes.runner-needs-human entry. Under the old model, this was unroutable (a finding); under the corrected model this is tracker-item-only fan-out (valid). The fixture correctly flips from reject to pass and serves as the degrade proof. The commit message's sweep count (12 pass / 95 reject, zero other flips) is consistent with exactly one fixture changing state.

The escalation.md fan-out section (lines 95–110) was already correctly describing this model — no doc change was needed there, and none was made.


Still open — Stale forward-link note in runner.md (must-fix)

Lines 122–123 still read:

The `lifecycle`, `escalation`, and `topology` leaves land with the pack's later phase; their
forward links are expected within an in-progress design pack.

All four leaves (seams.md, lifecycle.md, escalation.md, topology.md) are present on this branch and will exist at merge. The glance-layer routing table immediately above is correct; these two trailing sentences are the only stale content. A reader hitting the merged hub sees a "forward links expected" note for leaves that already exist. Must-fix before merge.

Fix this →


Still open — Urgent stop-reason override ambiguity in escalation.md (recommended)

Lines 134–139 still read:

"the override forces the filed item to urgent regardless of that default"

"That default" refers only to the contract-default attention severity for runner-needs-human. With escalation_severity now clearly documented as an org-bindable override, the phrase is ambiguous: an org could configure escalation_severity.runner-needs-human: notice, and an implementor reading "regardless of that default" charitably might let that org binding downgrade an isolation-violation or security/data-integrity stop from urgent. For precisely these two stop reasons the override should be absolute — a misconfigured org severity binding silently suppressing an urgent safety signal is the failure mode the override guards against. Suggested addition: "The override is absolute: it is not configurable lower through escalation_severity. Isolation-violation and security/data-integrity stops are always urgent regardless of the event class's org-configured severity."


Status

Finding Source Current status
Severity fan-out vs queue route Codex P2 (wave 2) ✅ Fixed
Re-escalation cap pinned at 1 Codex P2 (wave 1) ✅ Fixed (prior wave)
Executor class follows surface, not hosting Codex P2 (wave 1) ✅ Fixed (prior wave)
Stale forward-link note in runner.md Prior review (must-fix) ❌ Outstanding
Urgent override ambiguity in escalation.md Prior review (recommended) ❌ Outstanding

Wave-2 changes are clean and correct. One must-fix (stale text in runner.md) remains before merge; the urgent-override clarification is strongly recommended given the security implications.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7bbfd14c02

ℹ️ 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".

Comment thread plugins/autonomy/reference/runner/escalation.md Outdated
Comment thread plugins/autonomy/skills/setup/scripts/check-security-binding.mjs
Comment thread plugins/autonomy/skills/setup/schemas/guardrails-security-binding.schema.json Outdated
Comment thread plugins/autonomy/reference/runner/lifecycle.md Outdated
…routes (wave 3)

Four review findings. First, the success exception suppressed every
escalation, but the guardrail matrix fires untrusted-provenance on every
C5 item unconditionally: escalation.md now scopes the exception to the
runner's OWN outcome escalation and states that inherited always-firing
classes fire regardless of outcome, emitted before completion under
their own route and severity.

Second, the per-item-PR disposition wrongly covered C1, whose matrix row
is not applicable and whose class definition forbids repository
mutation: lifecycle.md's disposition now splits - a read-only class
completes by attaching its artifact to the governed queue item (the
audit trail), only mutating classes take the per-item PR path.

Third, a severity route was a single opaque string, so an urgent binding
could carry only a push route while the contract's cumulative fan-out
ladder requires the channel notification beneath it:
escalation_severity_routes entries are now explicit leg objects
({channel, push}, at least one), and a push leg without a channel leg
rejects (new fixture escalation-push-without-channel).

Fourth, a severity-bound runner event class with no escalation_routes
entry had no queue destination for its filed handoff: the checker now
requires the runner class's own route whenever that class is severity
bound (new fixture escalation-runner-route-missing rejects; legacy
bindings that never key a runner class stay untouched), and the
tracker-only degrade fixture now proves the legal form on an inherited
class whose queue route is always required.

Verified: all seven escalation fixtures behave exactly as named; full
sweep 12 pass / 97 reject with no other flips; schema parses; contract
validator, typos, markdownlint, and lychee clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@claude

claude Bot commented Jul 20, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 2m 33s —— View job


Wave-3 delta review — docs(autonomy): autonomous-runner design pack (WP7)

  • Gather context on latest commit (46689b4)
  • Check C5 always-fires fix (Codex P1 — wave-3 commit)
  • Check C1 queue-artifact fix (Codex P2 — wave-3 commit)
  • Check leg model fix (Codex P2 — wave-3 commit)
  • Check runner routes fix (Codex P2 — wave-3 commit)
  • Check runner.md — stale forward-link note (prior must-fix)
  • Check escalation.md — urgent override ambiguity (prior recommended fix)
  • Synthesize findings and post final review

Overview

Commit 46689b4 addresses all four Codex P1/P2 findings from wave 3. All four are correct and complete. The two issues from prior Claude reviews — one must-fix, one recommended — remain open.


Fixed ✅ — C5 always-fires (escalation.md Codex P1)

Lines 39–45 now carry a precise carve-out:

"Inherited always-firing classes are untouched by the success exception. An event class the guardrail escalation contract fires unconditionally — untrusted-provenance on every C5 item — fires regardless of outcome, success included: the runner emits it before the run completes, and the resulting item and fan-out follow that class's own route and severity, not the runner outcome mapping."

The carve-out correctly scopes the success exception to the runner's own outcome escalation only, preserves the guardrail matrix's unconditional untrusted-provenance obligation on C5, and specifies timing (before the run completes) and resolution path (own route and severity). No ambiguity remains about whether a successful C5 drain silently skips the required human notification.


Fixed ✅ — C1 queue-artifact disposition (lifecycle.md Codex P2)

Lines 44–52 now splits the disposition path correctly:

"A read-only class — C1, whose merge row is not applicable and whose definition forbids repository mutation — never opens a PR: its passing result completes by attaching the produced artifact or report to the governed queue item, the audit trail the matrix names as C1's disposition surface."

This aligns with the matrix's "n/a; artifacts via queue audit trail" merge row for C1 and removes the incorrect PR-path coverage. Mutating classes still take the per-item PR path; only C1 is separated. The fix is exactly scoped to the affected class.


Fixed ✅ — Notification leg model (escalation_severity_routes Codex P2)

The schema now models escalation_severity_routes entries as {channel, push} objects (at least one leg, both optional) instead of bare strings. Three layers of enforcement:

SchemaadditionalProperties changed from { "$ref": "#/$defs/Route" } to an object with channel and push as named properties and minProperties: 1, so a structurally empty or bare-string entry rejects at parse time.

Checker (check-security-binding.mjs) — validates:

  1. Each entry is a plain object (not a bare string)
  2. No unknown keys beyond channel and push
  3. At least one leg is present (empty object rejects)
  4. Each bound leg carries a non-empty string
  5. A push leg without a channel leg rejects — the cumulative fan-out ladder is correctly enforced

Fixturesescalation-push-without-channel.json (push-only urgent entry → rejects at rule 5) and the updated escalation-severity-valid.json (attention with channel only; urgent with both legs → passes). The leg model matches the fan-out table in escalation.md exactly.


Fixed ✅ — Runner event class queue destination (check-security-binding.mjs Codex P2)

The checker's new rule fires when a runner event class appears in escalation_severity without a corresponding escalation_routes entry. The implementation is correctly scoped: RUNNER_EVENT_CLASSES.includes(eventClass) limits enforcement to the two runner classes only, leaving the six inherited classes (whose escalation_routes entries are enforced by the existing required-key check) untouched.

Fixturesescalation-runner-route-missing.json has runner-needs-human in escalation_severity with no matching escalation_routes entry → correctly rejects. The escalation-severity-tracker-only-valid.json fixture (now keyed on the inherited gate-failure class, which always has a required route entry) proves the legal degrade path — an inherited class with a severity binding and no notification route is tracker-item-only fan-out, which is valid.

The commit message's sweep count (12 pass / 97 reject, no other flips) is consistent with the two new reject fixtures and the unchanged tracker-only degrade fixture.


Still open — Stale forward-link note in runner.md (must-fix)

Lines 122–123 still read:

The `lifecycle`, `escalation`, and `topology` leaves land with the pack's later phase; their
forward links are expected within an in-progress design pack.

All four leaves (seams.md, lifecycle.md, escalation.md, topology.md) are present on this branch and exist at merge. The glance-layer routing table immediately above these lines is correct; the two trailing sentences are the only stale content. A reader hitting the merged hub sees a "forward links expected" note for leaves that already exist. This has been flagged in every prior wave review. Must remove before merge.

Fix this →


Still open — Urgent stop-reason override ambiguity in escalation.md (recommended)

Lines 141–148 still read:

"the override forces the filed item to urgent regardless of that default"

"That default" refers to the contract-default attention severity for runner-needs-human. With escalation_severity now clearly documented as an org-bindable override of the contract default, an org could configure escalation_severity.runner-needs-human: notice. An implementor reading "regardless of that default" charitably infers the org binding can still win; one reading it strictly for safety infers the stop-reason override is absolute. For precisely these two stop reasons — isolation violation and security/data-integrity event — silent suppression via an org misconfiguration is the dangerous failure mode the override guards against. Suggested addition: "The override is absolute: it is not configurable lower through escalation_severity. Isolation-violation and security/data-integrity stops are always urgent regardless of the event class's org-configured severity."


Status

Finding Source Wave-3 status
C5 always-fires: success exception suppressed inherited class Codex P1 (wave 3) ✅ Fixed
C1 queue-artifact: PR path wrongly covered read-only class Codex P2 (wave 3) ✅ Fixed
Urgent fan-out leg model: push-only binding skips channel rung Codex P2 (wave 3) ✅ Fixed
Runner class queue destination: severity-bound with no route Codex P2 (wave 3) ✅ Fixed
Severity selects fan-out, never item route Codex P2 (wave 2) ✅ Fixed (prior wave)
Re-escalation cap pinned at 1 Codex P2 (wave 1) ✅ Fixed (prior wave)
Executor class follows surface, not hosting Codex P2 (wave 1) ✅ Fixed (prior wave)
Stale forward-link note in runner.md Prior review (must-fix) ❌ Outstanding — 3 waves
Urgent override ambiguity in escalation.md Prior review (recommended) ❌ Outstanding — 2 waves

Wave-3 changes are clean and correct. One must-fix (stale text in runner.md) remains before merge; the urgent-override clarification remains strongly recommended given the security implications.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 46689b41cc

ℹ️ 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".

Comment thread plugins/autonomy/reference/runner/escalation.md Outdated
One review finding. The one-level severity bump was undefined for an item
already at urgent (the untrusted-provenance default and both urgent
stop-reason overrides), leaving an implementation unable to bump within
the defined axis. escalation.md now specifies saturation: an
already-urgent item still re-escalates once, by re-notifying with a fresh
urgent fan-out at the same severity - the re-escalation is never skipped
and no level above the axis is minted.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@claude

claude Bot commented Jul 20, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 1m 30s —— View job


Wave-4 delta review — docs(autonomy): autonomous-runner design pack (WP7)

  • Gather context on latest commit (433fb97)
  • Check re-escalation saturation fix (Codex P2 — wave-4 commit)
  • Check runner.md — stale forward-link note (prior must-fix, outstanding 3 waves)
  • Check escalation.md — urgent override ambiguity (prior recommended fix, outstanding 2 waves)
  • Synthesize findings and post final review

Overview

Commit 433fb97 correctly resolves the wave-4 Codex P2 finding on undefined urgent re-escalation behavior. The fix is the only change in this commit. The two issues from prior Claude reviews — one must-fix (stale text), one recommended (override ambiguity) — remain open for the fourth consecutive wave.


Fixed ✅ — Re-escalation bump saturates at urgent (Codex P2)

escalation.md lines 158–162 now read:

"The bump saturates at urgent: an item already at urgent — an untrusted-provenance default, or either urgent stop-reason override — still re-escalates once, by re-notifying with a fresh urgent fan-out at the same severity, never by skipping the re-escalation or minting a level above the axis."

The fix correctly handles all three cases that could present an already-urgent item:

  1. untrusted-provenance (table default urgent, line 133)
  2. Isolation-violation stop-reason override (always urgent)
  3. Security/data-integrity stop-reason override (always urgent)

Three implementation-critical properties are now unambiguous: (a) re-escalation is never skipped for an urgent item — an implementation cannot use "cannot bump higher" as a skip rationale; (b) no level above the defined axis is minted — the axis closes at urgent; (c) the mechanism is specified — fresh urgent fan-out at the same severity, not a silent no-op. The fix is minimal and correct.


Still open — Stale forward-link note in runner.md (must-fix, 4 waves)

Lines 122–123 still read:

The `lifecycle`, `escalation`, and `topology` leaves land with the pack's later phase; their
forward links are expected within an in-progress design pack.

All four leaves (seams.md, lifecycle.md, escalation.md, topology.md) are present in this PR and will exist at merge. The glance-layer routing table immediately above these lines (lines 115–120) is correct; these two trailing sentences are the only stale content. This note has been flagged as a must-fix in every wave review since wave 1 and is the single remaining blocker before merge.

Fix this →


Still open — Urgent stop-reason override ambiguity in escalation.md (recommended, 3 waves)

Lines 143–148 still read:

"the override forces the filed item to urgent regardless of that default"

"That default" refers only to the contract-default attention severity for runner-needs-human. With escalation_severity now clearly documented as an org-bindable override of the contract default, an org could configure escalation_severity.runner-needs-human: notice. An implementor reading "regardless of that default" might reasonably infer the org binding can still win for the stop-reason override's event class. For isolation-violation and security/data-integrity stops specifically, silent suppression via an org severity binding is the exact failure mode the override guards against. Suggested addition: "The override is absolute: it is not configurable lower through escalation_severity. Isolation-violation and security/data-integrity stops are always urgent regardless of the event class's org-configured severity."


Status

Finding Source Wave-4 status
Re-escalation saturation at urgent Codex P2 (wave 4) ✅ Fixed
C5 always-fires: success exception scoped correctly Codex P1 (wave 3) ✅ Fixed (prior wave)
C1 queue-artifact: PR path excluded for read-only class Codex P2 (wave 3) ✅ Fixed (prior wave)
Urgent fan-out leg model: push-only binding rejects Codex P2 (wave 3) ✅ Fixed (prior wave)
Runner class queue destination: severity-bound requires route Codex P2 (wave 3) ✅ Fixed (prior wave)
Severity selects fan-out, never item route Codex P2 (wave 2) ✅ Fixed (prior wave)
Re-escalation cap pinned at 1 Codex P2 (wave 1) ✅ Fixed (prior wave)
Executor class follows surface, not hosting Codex P2 (wave 1) ✅ Fixed (prior wave)
Stale forward-link note in runner.md Prior review (must-fix) ❌ Outstanding — 4 waves
Urgent override ambiguity in escalation.md Prior review (recommended) ❌ Outstanding — 3 waves

Wave-4 change is clean and correct. One must-fix (two stale sentences at runner.md:122–123) is the single remaining blocker before merge. The urgent-override ambiguity clarification remains strongly recommended given the security implications.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 433fb9732a

ℹ️ 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".

Comment thread plugins/autonomy/reference/runner/lifecycle.md
One review finding. The state model let a C4 item pass leased to
executing on ordinary admission, but the guardrail matrix fires
structural-plan-approval for a C4 item before execution. lifecycle.md now
specifies the two-phase C4 drain through the one queue: the first leased
run plans only and disposes as the structural-plan-approval item (the
inherited event class on its own route and severity, plan attached); the
structural execution is a second run admitted only from the
human-approved item, whose leased-to-executing transition requires the
recorded approval and fail-closes to escalated without it. No second
approval channel; the terminal-handoff shape is untouched - neither
phase pauses mid-run.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@claude

claude Bot commented Jul 20, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 1m 31s —— View job


Wave-5 delta review — docs(autonomy): autonomous-runner design pack (WP7)

  • Gather context on latest commit (ea741e0)
  • Check C4 plan-approval gate fix (Codex P2 — wave-5 commit)
  • Check runner.md — stale forward-link note (prior must-fix, outstanding 4 waves)
  • Check escalation.md — urgent override ambiguity (prior recommended fix, outstanding 3 waves)
  • Synthesize findings and post final review

Overview

Commit ea741e0 correctly addresses the Codex P2 finding on the missing C4 plan-approval gate. The fix is well-scoped prose in the state model section of lifecycle.md and covers all the required implementation properties. The two issues from prior Claude reviews — one must-fix (stale text, now 5 waves), one recommended (override ambiguity, now 4 waves) — remain open.


Fixed ✅ — C4 execution gates on plan-approval item (Codex P2)

lifecycle.md lines 29–41 add a "C4 pre-execution plan approval" subsection with the following implementation-critical properties all correctly specified:

  • Two-phase drain through one queue: the first leased run plans only, emitting the inherited structural-plan-approval item (on its own route and severity, with the produced plan attached) and completing without touching the structure. The structural execution is a second run, admitted only from the human-approved item. This correctly models the existing guardrail class rather than inventing a new approval channel.
  • Gate on leased → executing: the second run's leased → executing transition requires the recorded approval; absent one, the run fail-closes to escalated. The fail-closed direction is the safe one.
  • No mid-run pause: both phases are stated to complete without pausing mid-run, keeping the terminal-handoff shape in the escalation leaf untouched. This prevents a degenerate "suspended" state the escalation contract has no path for.
  • Correct class citation: the section correctly names structural-plan-approval as an inherited class (not a new runner class), citing guardrails.md#escalation as its home. This means the class's route and severity are already bound by any conforming security binding — no runner-specific binding needed.

The prose-only treatment (no state machine diagram change) is appropriate for a design doc at this stage. The top-level state model (leased → executing → verifying → disposing → (escalated | complete)) stays unchanged, which is correct: the approval gate gates admission to the execution phase rather than introducing a new state.


Still open — Stale forward-link note in runner.md (must-fix, 5 waves)

Lines 122–123 still read:

The `lifecycle`, `escalation`, and `topology` leaves land with the pack's later phase; their
forward links are expected within an in-progress design pack.

All four leaves (seams.md, lifecycle.md, escalation.md, topology.md) are present on this branch and will exist at merge. The glance-layer routing table immediately above (lines 115–120) is correct and complete; these two trailing sentences are the only stale content. This two-sentence removal has been the single remaining must-fix blocker since wave 1 — five review waves.

Fix this →


Still open — Urgent stop-reason override ambiguity in escalation.md (recommended, 4 waves)

Lines 143–148 still read:

"the override forces the filed item to urgent regardless of that default"

"That default" refers only to the contract-default attention severity for runner-needs-human. With escalation_severity now clearly documented as an org-bindable override of the contract default, an org could configure escalation_severity.runner-needs-human: notice. An implementor reading "regardless of that default" charitably might infer the org binding can still win; one reading it strictly for safety infers the stop-reason override is absolute. For precisely these two stop reasons — isolation violation and security/data-integrity event — silent suppression via an org severity binding is the dangerous failure mode the override guards against. Suggested addition: "The override is absolute: it is not configurable lower through escalation_severity. Isolation-violation and security/data-integrity stops are always urgent regardless of the event class's org-configured severity."


Status

Finding Source Wave-5 status
C4 execution gates on plan-approval item Codex P2 (wave 5) ✅ Fixed
Re-escalation saturation at urgent Codex P2 (wave 4) ✅ Fixed (prior wave)
C5 always-fires: success exception scoped correctly Codex P1 (wave 3) ✅ Fixed (prior wave)
C1 queue-artifact: PR path excluded for read-only class Codex P2 (wave 3) ✅ Fixed (prior wave)
Urgent fan-out leg model: push-only binding rejects Codex P2 (wave 3) ✅ Fixed (prior wave)
Runner class queue destination: severity-bound requires route Codex P2 (wave 3) ✅ Fixed (prior wave)
Severity selects fan-out, never item route Codex P2 (wave 2) ✅ Fixed (prior wave)
Re-escalation cap pinned at 1 Codex P2 (wave 1) ✅ Fixed (prior wave)
Executor class follows surface, not hosting Codex P2 (wave 1) ✅ Fixed (prior wave)
Stale forward-link note in runner.md Prior review (must-fix) ❌ Outstanding — 5 waves
Urgent override ambiguity in escalation.md Prior review (recommended) ❌ Outstanding — 4 waves

Wave-5 change is clean and correct. One must-fix (two stale sentences at runner.md:122–123) is the single remaining blocker before merge. The urgent-override clarification remains strongly recommended given the security implications of silent severity downgrade on isolation-violation and security/data-integrity stops.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ea741e04b2

ℹ️ 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".

Comment thread plugins/autonomy/skills/setup/scripts/check-security-binding.mjs
…s (wave 6)

One review finding. A legacy binding omitting the optional
escalation_severity map and both optional runner routes still validates,
yet every non-success stop maps to a runner event class - a runner
launched under such a binding would have no queue destination for its
required human-gated handoff. The static checker cannot close this (no
binding key says a runner is enabled), so the escalation contract now
carries the launch precondition: at startup the runner verifies both
runner-needs-human and runner-cap-exceeded carry bound escalation_routes
entries and fail-closes - blocking dispatch - when either is absent,
exactly as for an absent security binding. The binding stays valid for
every pre-runner surface; the requirement binds the runner.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@claude

claude Bot commented Jul 20, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 1m 50s —— View job


Wave-6 delta review — docs(autonomy): autonomous-runner design pack (WP7)

  • Gather context on latest commit (958655c)
  • Check runner-launch fail-close fix (Codex P2 — wave-6 commit)
  • Check runner.md — stale forward-link note (prior must-fix, outstanding 5 waves)
  • Check escalation.md — urgent override ambiguity (prior recommended fix, outstanding 4 waves)
  • Synthesize findings and post final review

Overview

Commit 958655c correctly resolves the Codex P2 wave-6 finding on runner launch without escalation routes. The two-part fix is sound and properly scopes enforcement to runtime. The two issues from prior Claude reviews — one must-fix (stale text, now 6 waves), one recommended (override ambiguity, now 5 waves) — remain open.


Fixed ✅ — Runner launch fail-closes without its escalation routes (Codex P2)

Two-part fix is correct and complete.

escalation.md lines 104–112 — "Runner launch precondition" paragraph added immediately after the outcome-to-event-class table:

"Both runner classes' queue routes are part of the runner's required governance: at launch the runner verifies that runner-needs-human and runner-cap-exceeded each carry a bound escalation_routes entry, and fail-closes — blocking dispatch — when either is absent, exactly as it does for an absent security binding (topology leaf). Every non-success stop maps to one of these classes, so a runner without their routes would have no queue destination for its required human-gated handoff. The requirement binds the RUNNER, not the binding: a binding without the runner keys stays valid for every pre-runner surface, which is why the static checker cannot enforce this (no binding key says a runner is enabled) and the launch gate does."

All four implementation-critical properties are now unambiguous: (a) the check is both-classes (not one-or-other); (b) fail-closed on absent entry, matching the absent-security-binding precondition in the topology leaf; (c) pre-runner bindings stay valid; (d) the rationale for why schema/checker enforcement is not possible is stated inline, so an implementor knows not to hunt for static rejection.

check-security-binding.mjs lines 613–616 — The comment on the existing conditional check (runner class in escalation_severity with no escalation_routes entry) is updated to explain the division: the static check fires for partial bindings (severity bound for a runner class but no queue destination), while the full "both routes absent, no severity binding at all" case is the runner's own LAUNCH precondition. This correctly preserves the partial-binding guard (it still fires a finding) while explaining why there's no complementary "runner enabled, routes missing" static check.

The approach correctly identifies that the enforcement gap is structural — no binding schema field declares "a runner is enabled" — and closes it at the right layer.


Still open — Stale forward-link note in runner.md (must-fix, 6 waves)

Lines 122–123 still read:

The `lifecycle`, `escalation`, and `topology` leaves land with the pack's later phase; their
forward links are expected within an in-progress design pack.

All four leaves (seams.md, lifecycle.md, escalation.md, topology.md) are present on this branch and will exist at merge. The glance-layer routing table immediately above (lines 115–120) is correct and complete; these two trailing sentences are the only stale content. This is the single remaining blocker before merge and has been flagged every wave since wave 1.

Fix this →


Still open — Urgent stop-reason override ambiguity in escalation.md (recommended, 5 waves)

Lines 153–158 still read:

"the override forces the filed item to urgent regardless of that default"

"That default" refers only to the contract-default attention severity for runner-needs-human. With escalation_severity now clearly documented as an org-bindable override of the contract default, an org could configure escalation_severity.runner-needs-human: notice. An implementor reading "regardless of that default" charitably might infer the org binding can still win; one reading it strictly for safety infers the stop-reason override is absolute. For isolation-violation and security/data-integrity stops specifically, silent suppression via an org severity binding is the exact dangerous failure mode the override guards against. Suggested addition: "The override is absolute: it is not configurable lower through escalation_severity. Isolation-violation and security/data-integrity stops are always urgent regardless of the event class's org-configured severity."


Status

Finding Source Wave-6 status
Runner launch fail-closes without escalation routes Codex P2 (wave 6) ✅ Fixed
C4 execution gates on plan-approval item Codex P2 (wave 5) ✅ Fixed (prior wave)
Re-escalation saturation at urgent Codex P2 (wave 4) ✅ Fixed (prior wave)
C5 always-fires: success exception scoped correctly Codex P1 (wave 3) ✅ Fixed (prior wave)
C1 queue-artifact: PR path excluded for read-only class Codex P2 (wave 3) ✅ Fixed (prior wave)
Urgent fan-out leg model: push-only binding rejects Codex P2 (wave 3) ✅ Fixed (prior wave)
Runner class queue destination: severity-bound requires route Codex P2 (wave 3) ✅ Fixed (prior wave)
Severity selects fan-out, never item route Codex P2 (wave 2) ✅ Fixed (prior wave)
Re-escalation cap pinned at 1 Codex P2 (wave 1) ✅ Fixed (prior wave)
Executor class follows surface, not hosting Codex P2 (wave 1) ✅ Fixed (prior wave)
Stale forward-link note in runner.md Prior review (must-fix) ❌ Outstanding — 6 waves
Urgent override ambiguity in escalation.md Prior review (recommended) ❌ Outstanding — 5 waves

Wave-6 change is correct and well-scoped. One must-fix (two stale sentences at runner.md:122–123) is the single remaining blocker before merge. The urgent-override clarification remains strongly recommended given the security implications of silent severity downgrade on isolation-violation and security/data-integrity stops.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 958655c73c

ℹ️ 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".

Comment thread plugins/autonomy/reference/runner/lifecycle.md Outdated
…e (wave 7)

One review finding. The terminal invariant said only a run that lands its
CHANGE becomes complete, contradicting the same leaf's non-mutating
dispositions - a C1 queue artifact and a C4 planning run's plan-approval
item both complete without a repository change. The invariant now keys on
a successfully landed class disposition (queue artifact, plan-approval
item, or per-item PR); every other ending stays escalated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@claude

claude Bot commented Jul 20, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 1m 31s —— View job


Wave-7 delta review — docs(autonomy): autonomous-runner design pack (WP7)

  • Gather context on latest commit (0dabf52)
  • Check completion-is-disposition fix (Codex P2 — wave-7 commit)
  • Check runner.md — stale forward-link note (prior must-fix, outstanding 6 waves)
  • Check escalation.md — urgent override ambiguity (prior recommended fix, outstanding 5 waves)
  • Synthesize findings and post final review

Overview

Commit 0dabf52 correctly addresses the Codex P2 wave-6 finding on non-mutating dispositions. The state model's invariant now keys on the disposition, not the presence of a repository change, which correctly unblocks C1 and C4 planning-run completions. The two issues from prior Claude reviews remain open for the seventh and sixth waves respectively.


Fixed ✅ — Completion is a landed disposition, not a landed change (Codex P2)

lifecycle.md lines 26–28 now read:

"Only a run that reaches disposing and successfully lands its class's disposition — a queue artifact for a read-only class, the plan-approval item for a C4 planning run, a per-item PR for a mutating class — becomes complete; every other ending is escalated."

The fix is exactly correct and covers all three cases:

  • C1 (read-only class): completes via queue artifact — no PR ever opens, consistent with lifecycle.md:60–63 which carves C1 out of the PR path and routes it to the governed queue item's audit trail.
  • C4 planning run: completes when the structural-plan-approval item lands — the first phase produces an approval item as its disposition; the complete terminal is reachable for that phase without any repository mutation.
  • Mutating classes: completes via per-item PR — unchanged from prior intent, now explicitly named.

The state-table description for complete at line 22 ("The disposition landed; the run closes through the return-accounting capture at the task boundary") was already keyed on "disposition landed" — the new inline enumeration in lines 26–28 brings the terminal-state invariant into alignment with that phrasing. No other file needed changing; the Codex reviewer's analysis was correct and the fix is minimal.


Still open — Stale forward-link note in runner.md (must-fix, 7 waves)

Lines 122–123 still read:

The `lifecycle`, `escalation`, and `topology` leaves land with the pack's later phase; their
forward links are expected within an in-progress design pack.

All four leaves (seams.md, lifecycle.md, escalation.md, topology.md) are present on this branch and will exist at merge. The glance-layer routing table at lines 115–120 is correct and complete; these two trailing sentences are the only stale content in the entire file. This two-sentence removal has been the single remaining must-fix blocker since wave 1 — now seven review waves. Nothing else blocks merge.

Fix this →


Still open — Urgent stop-reason override ambiguity in escalation.md (recommended, 6 waves)

Lines 153–158 still read:

"the override forces the filed item to urgent regardless of that default"

"That default" refers only to the contract-default attention severity for runner-needs-human. With escalation_severity now clearly documented as an org-bindable override of the contract default, an implementor could configure escalation_severity.runner-needs-human: notice and read "regardless of that default" as meaning only "regardless of the contract default attention" — leaving the org-configured notice free to win. For isolation-violation and security/data-integrity stops, this silent downgrade is precisely the dangerous failure mode the override guards against. Suggested addition: "The override is absolute: it is not configurable lower through escalation_severity. Isolation-violation and security/data-integrity stops are always urgent regardless of the event class's org-configured severity."


Status

Finding Source Wave-7 status
Completion is a landed disposition, not a landed change Codex P2 (wave 6→7) ✅ Fixed
Runner launch fail-closes without escalation routes Codex P2 (wave 6) ✅ Fixed (prior wave)
C4 execution gates on plan-approval item Codex P2 (wave 5) ✅ Fixed (prior wave)
Re-escalation saturation at urgent Codex P2 (wave 4) ✅ Fixed (prior wave)
C5 always-fires: success exception scoped correctly Codex P1 (wave 3) ✅ Fixed (prior wave)
C1 queue-artifact: PR path excluded for read-only class Codex P2 (wave 3) ✅ Fixed (prior wave)
Urgent fan-out leg model: push-only binding rejects Codex P2 (wave 3) ✅ Fixed (prior wave)
Runner class queue destination: severity-bound requires route Codex P2 (wave 3) ✅ Fixed (prior wave)
Severity selects fan-out, never item route Codex P2 (wave 2) ✅ Fixed (prior wave)
Re-escalation cap pinned at 1 Codex P2 (wave 1) ✅ Fixed (prior wave)
Executor class follows surface, not hosting Codex P2 (wave 1) ✅ Fixed (prior wave)
Stale forward-link note in runner.md Prior review (must-fix) ❌ Outstanding — 7 waves
Urgent override ambiguity in escalation.md Prior review (recommended) ❌ Outstanding — 6 waves

Wave-7 change is clean and correct. One must-fix (two stale sentences at runner.md:122–123) is the single remaining blocker before merge. The urgent-override clarification remains strongly recommended given the security implications of silent severity downgrade on isolation-violation and security/data-integrity stops.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0dabf52fc9

ℹ️ 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".

Comment thread plugins/autonomy/skills/setup/scripts/check-security-binding.mjs
…ve 8)

One review finding, resolved as a contract clarification rather than a
new rejection. The fan-out legs are org-bound routes and each leg exists
only where its route is bound: an org with no push adapter legitimately
binds urgent with the channel leg alone, and an unbound leg degrades the
fan-out toward the always-filed tracker item - a reviewed security-surface
choice, not an unverifiable claim, so it does not fail closed. The one
rejected shape stays the inverse (a push leg without the channel beneath
it), because the ladder is cumulative. escalation.md now states this
explicitly where the fan-out table is defined.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@claude

claude Bot commented Jul 20, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 2m 8s —— View job


Wave-8 delta review — docs(autonomy): autonomous-runner design pack (WP7)

  • Gather context on latest commit (c1aabe2)
  • Check channel-only urgent degraded fan-out fix (Codex P2 — wave-8 commit)
  • Check runner.md — stale forward-link note (prior must-fix, outstanding 7 waves)
  • Check escalation.md — urgent override ambiguity (prior recommended fix, outstanding 6 waves)
  • Synthesize findings and post final review

Overview

Commit c1aabe2 addresses the Codex P2 wave-8 finding on urgent requiring a push leg. The fix is a doc clarification only (no schema or checker change), and it's correct: the checker and schema were already right; the contract just hadn't stated the channel-only degraded form explicitly. The two issues from prior Claude reviews remain open for the eighth and seventh waves respectively.


Fixed ✅ — Channel-only urgent is the legal degraded fan-out (Codex P2)

escalation.md lines 127–133 now read:

"The tracker item is always filed; channel notification and the personal-push tier are org-bound routes, and each leg exists only where its route is bound. An unbound leg degrades the fan-out toward the always-filed tracker item — an org with no push adapter legitimately binds urgent with the channel leg alone, and absent a bound channel adapter fan-out degrades to tracker-item-only; degradation never drops the escalation item itself. The one rejected shape is the inverse: a push leg bound without the channel leg beneath it, because the ladder is cumulative and the push tier rides on top of the channel notification."

The fix is a prose clarification only — no schema, checker, or fixture change was needed. This is correct because:

  • The schema already permitted channel-only urgent (additionalProperties of escalation_severity_routes entries carry minProperties: 1 with both channel and push optional).
  • The checker already only rejected push-without-channel (the legs.push && !legs.channel guard at line 654), not channel-without-push.
  • The escalation-severity-valid.json fixture already bound urgent with both legs, demonstrating the full-fan-out path.

The Codex finding misread the intended behavior: urgent in the fan-out table carries the personal-push tier as an org-bindable addition, not a mandatory floor. An org without a push adapter is conforming when it binds only the channel leg. The wave-8 fix makes this explicit so an implementor reading the fan-out table doesn't infer push-is-required.

No fixture change is needed: the existing escalation-severity-valid.json (full fan-out) and escalation-push-without-channel.json (rejected shape) together cover the meaningful cases. A channel-only urgent fixture would add coverage but the schema and checker behavior are already unambiguous.


Still open — Stale forward-link note in runner.md (must-fix, 8 waves)

Lines 122–123 still read:

The `lifecycle`, `escalation`, and `topology` leaves land with the pack's later phase; their
forward links are expected within an in-progress design pack.

All four leaves (seams.md, lifecycle.md, escalation.md, topology.md) are present on this branch and will exist at merge. The glance-layer routing table at lines 115–120 is correct and complete; these two trailing sentences are the only stale content in the entire file. The wave-8 commit touched only escalation.md and did not address this. This two-sentence removal has been the single remaining must-fix blocker since wave 1 — eight review waves.

Fix this →


Still open — Urgent stop-reason override ambiguity in escalation.md (recommended, 7 waves)

Lines 157–162 still read:

"the override forces the filed item to urgent regardless of that default"

"That default" refers only to the contract-default attention severity for runner-needs-human. With escalation_severity now clearly documented as an org-bindable override of the contract default, an org could configure escalation_severity.runner-needs-human: notice. An implementor reading "regardless of that default" might reasonably infer the org binding can still win — the phrase grammatically excludes only the contract default, not an org-configured severity. For isolation-violation and security/data-integrity stops specifically, silent suppression via an org severity binding is the exact dangerous failure mode the override guards against. Suggested addition: "The override is absolute: it is not configurable lower through escalation_severity. Isolation-violation and security/data-integrity stops are always urgent regardless of the event class's org-configured severity."


Status

Finding Source Wave-8 status
Channel-only urgent is the legal degraded fan-out Codex P2 (wave 8) ✅ Fixed
Completion is a landed disposition, not a landed change Codex P2 (wave 7) ✅ Fixed (prior wave)
Runner launch fail-closes without escalation routes Codex P2 (wave 6) ✅ Fixed (prior wave)
C4 execution gates on plan-approval item Codex P2 (wave 5) ✅ Fixed (prior wave)
Re-escalation saturation at urgent Codex P2 (wave 4) ✅ Fixed (prior wave)
C5 always-fires: success exception scoped correctly Codex P1 (wave 3) ✅ Fixed (prior wave)
C1 queue-artifact: PR path excluded for read-only class Codex P2 (wave 3) ✅ Fixed (prior wave)
Urgent fan-out leg model: push-only binding rejects Codex P2 (wave 3) ✅ Fixed (prior wave)
Runner class queue destination: severity-bound requires route Codex P2 (wave 3) ✅ Fixed (prior wave)
Severity selects fan-out, never item route Codex P2 (wave 2) ✅ Fixed (prior wave)
Re-escalation cap pinned at 1 Codex P2 (wave 1) ✅ Fixed (prior wave)
Executor class follows surface, not hosting Codex P2 (wave 1) ✅ Fixed (prior wave)
Stale forward-link note in runner.md Prior review (must-fix) ❌ Outstanding — 8 waves
Urgent override ambiguity in escalation.md Prior review (recommended) ❌ Outstanding — 7 waves

Wave-8 change is correct (doc clarification only; schema and checker were already right). One must-fix (two stale sentences at runner.md:122–123) is the single remaining blocker before merge. The urgent-override ambiguity clarification remains strongly recommended given the security implications of silent severity downgrade on isolation-violation and security/data-integrity stops.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c1aabe21e1

ℹ️ 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".

Comment thread plugins/autonomy/skills/setup/schemas/guardrails-security-binding.schema.json Outdated
… (wave 9)

One review finding. Two schema descriptions still carried the superseded
severity-only routing option for runner classes, so a consumer following
the schema contract would prepare a binding the checker rejects. Both now
state the enforced rule: a runner class keyed in escalation_severity must
also carry its own escalation_routes entry, because severity selects only
notification fan-out and can never supply the filed item's queue
destination.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@claude

claude Bot commented Jul 20, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 1m 37s —— View job


Wave-9 delta review — docs(autonomy): autonomous-runner design pack (WP7)

  • Gather context on latest commit (fd0b5a7)
  • Check schema description fix (wave-9 commit)
  • Check runner.md — stale forward-link note (prior must-fix, outstanding 8 waves)
  • Check escalation.md — urgent override ambiguity (prior recommended fix, outstanding 7 waves)
  • Synthesize findings and post final review

Overview

Commit fd0b5a7 is a pure schema description fix — two descriptions in guardrails-security-binding.schema.json, no other files touched. Both are correct and resolve the Codex P2 wave-8 finding. The two issues from prior Claude reviews remain open for the ninth and eighth waves respectively.


Fixed ✅ — Schema descriptions match the runner-route requirement (Codex P2)

Two description fields updated; no structural schema change.

escalation_routes description (line 62):

The prior description said "a runner class may also route solely through the escalation_severity join" — directly contradicting the checker's escalation-runner-route-missing.json rejection path. The replacement states: "a runner class bound in escalation_severity REQUIRES its entry here: severity selects only notification fan-out and can never supply the filed item's queue destination." This matches what the checker already enforces and what the escalation leaf's fan-out model specifies.

EscalationEventClass description (line 231):

The prior description named three valid binding shapes: "an optional escalation_routes key, the escalation_severity join, or both" — the middle option being the illegal severity-only shape. The replacement correctly removes that option: "a runner class keyed in escalation_severity must also carry its own escalation_routes entry (the queue destination severity can never supply)."

Both corrections are minimal and consistent with each other. No fixture changes were needed: escalation-runner-route-missing.json was already rejecting the severity-without-route shape, and escalation-severity-tracker-only-valid.json already demonstrated the legal degrade on an inherited class (which keeps its required route regardless). The schema descriptions now match the enforcement that was already in place.


Still open — Stale forward-link note in runner.md (must-fix, 9 waves)

Lines 122–123 still read:

The `lifecycle`, `escalation`, and `topology` leaves land with the pack's later phase; their
forward links are expected within an in-progress design pack.

All four leaves (seams.md, lifecycle.md, escalation.md, topology.md) are present on this branch and will exist at merge. The glance-layer routing table at lines 115–120 is correct and complete; these two trailing sentences are the only stale content in the entire file. This two-sentence removal has been flagged as the single remaining must-fix blocker since wave 1 — nine review waves.

Fix this →


Still open — Urgent stop-reason override ambiguity in escalation.md (recommended, 8 waves)

Lines 157–162 still read:

"the override forces the filed item to urgent regardless of that default"

"That default" refers only to the contract-default attention severity for runner-needs-human. With escalation_severity now clearly documented as an org-bindable override of the contract default, an org could configure escalation_severity.runner-needs-human: notice. An implementor reading "regardless of that default" might reasonably infer the org binding can still win — the phrase grammatically excludes only the contract default, not an org-configured severity. For isolation-violation and security/data-integrity stops specifically, silent suppression via an org severity binding is the exact dangerous failure mode the override guards against. Suggested addition: "The override is absolute: it is not configurable lower through escalation_severity. Isolation-violation and security/data-integrity stops are always urgent regardless of the event class's org-configured severity."


Status

Finding Source Wave-9 status
Schema descriptions match the runner-route requirement Codex P2 (wave 8→9) ✅ Fixed
Channel-only urgent is the legal degraded fan-out Codex P2 (wave 8) ✅ Fixed (prior wave)
Completion is a landed disposition, not a landed change Codex P2 (wave 7) ✅ Fixed (prior wave)
Runner launch fail-closes without escalation routes Codex P2 (wave 6) ✅ Fixed (prior wave)
C4 execution gates on plan-approval item Codex P2 (wave 5) ✅ Fixed (prior wave)
Re-escalation saturation at urgent Codex P2 (wave 4) ✅ Fixed (prior wave)
C5 always-fires: success exception scoped correctly Codex P1 (wave 3) ✅ Fixed (prior wave)
C1 queue-artifact: PR path excluded for read-only class Codex P2 (wave 3) ✅ Fixed (prior wave)
Urgent fan-out leg model: push-only binding rejects Codex P2 (wave 3) ✅ Fixed (prior wave)
Runner class queue destination: severity-bound requires route Codex P2 (wave 3) ✅ Fixed (prior wave)
Severity selects fan-out, never item route Codex P2 (wave 2) ✅ Fixed (prior wave)
Re-escalation cap pinned at 1 Codex P2 (wave 1) ✅ Fixed (prior wave)
Executor class follows surface, not hosting Codex P2 (wave 1) ✅ Fixed (prior wave)
Stale forward-link note in runner.md Prior review (must-fix) ❌ Outstanding — 9 waves
Urgent override ambiguity in escalation.md Prior review (recommended) ❌ Outstanding — 8 waves

Wave-9 change is correct (two schema description fixes; no structural change, no fixture change needed). One must-fix (two stale sentences at runner.md:122–123) is the single remaining blocker before merge. The urgent-override clarification remains strongly recommended given the security implications of silent severity downgrade on isolation-violation and security/data-integrity stops.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fd0b5a7861

ℹ️ 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".

Comment thread plugins/autonomy/reference/runner/lifecycle.md Outdated
…e 10)

One review finding. The C4 fail-close on a missing recorded approval went
straight to escalated with no enumerated stop, leaving its event class,
severity, and route unspecified. Missing plan approval is now a
runner-owned stop reason in the taxonomy and the step-one table, mapping
to needs-human (so it files through runner-needs-human at its bound route
and severity like every other non-success stop), and the lifecycle leaf's
C4 gate names that stop instead of a bare escalated transition.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@claude

claude Bot commented Jul 20, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 1m 50s —— View job


Wave-10 delta review — docs(autonomy): autonomous-runner design pack (WP7)

  • Gather context on latest commit (05e96dc)
  • Check C4 approval stop-mapping fix (Codex P2 — wave-10 commit)
  • Check runner.md — stale forward-link note (prior must-fix, outstanding 9 waves)
  • Check escalation.md — urgent override ambiguity (prior recommended fix, outstanding 8 waves)
  • Synthesize findings and post final review

Overview

Commit 05e96dc correctly resolves the Codex P2 wave-9 finding: the missing-plan-approval condition for a C4 structural run is now a properly mapped runner-owned stop reason. The fix is minimal and correct. The two issues from prior Claude reviews — one must-fix (stale text, now 10 waves), one recommended (override ambiguity, now 9 waves) — remain open.


Fixed ✅ — Missing C4 approval is a mapped runner-owned stop (Codex P2)

Two-file fix is correct and complete.

escalation.md taxonomy + step-one table — Two additions:

  1. The runner-owned stop list (lines 51–57) now includes "missing plan approval (a C4 structural run leased without its recorded approval — lifecycle leaf)" alongside isolation violation and the other runner-owned criteria. The cross-reference back to the lifecycle leaf is correct.

  2. The step-one table (line 84) gains a new row: runner-owned | missing plan approval (C4) | needs-human. This routes missing-approval through runner-needs-human at its bound route and attention default severity — identical to any other needs-human stop, no special-casing required.

lifecycle.md C4 gateLines 39–42 now name the stop explicitly:

"fail-closes through the missing-plan-approval stop — a runner-owned stop reason resolving to needs-human in the escalation leaf's mapping — rather than executing"

Previously this was a bare "fail-closes to escalated" with no enumerated stop, leaving event class, severity, and queue destination unspecified. The fix ties the lifecycle gate directly to the escalation mapping so an implementor has a complete path: leased-without-approval → missing-plan-approval (runner-owned) → needs-human → runner-needs-human → bound escalation_routes entry + attention severity → required human-gated handoff.

No schema or checker change was needed: the condition resolves through the existing runner-needs-human class and its required escalation_routes entry, inheriting all the enforcement already in place for that class.


Still open — Stale forward-link note in runner.md (must-fix, 10 waves)

Lines 122–123 still read:

The `lifecycle`, `escalation`, and `topology` leaves land with the pack's later phase; their
forward links are expected within an in-progress design pack.

All four leaves (seams.md, lifecycle.md, escalation.md, topology.md) are present on this branch and will exist at merge. The glance-layer routing table at lines 115–120 is correct and complete; these two trailing sentences are the only stale content in the entire file. This two-sentence removal has been the single remaining must-fix blocker since wave 1 — ten review waves.

Fix this →


Still open — Urgent stop-reason override ambiguity in escalation.md (recommended, 9 waves)

Lines 160–165 still read:

"the override forces the filed item to urgent regardless of that default"

"That default" refers only to the contract-default attention severity for runner-needs-human. With escalation_severity now clearly documented as an org-bindable override of the contract default, an org could configure escalation_severity.runner-needs-human: notice. An implementor reading "regardless of that default" might reasonably infer the org binding can still win — the phrase grammatically excludes only the contract default, not an org-configured severity. For isolation-violation and security/data-integrity stops specifically, silent suppression via an org severity binding is the exact dangerous failure mode the override guards against. Suggested addition: "The override is absolute: it is not configurable lower through escalation_severity. Isolation-violation and security/data-integrity stops are always urgent regardless of the event class's org-configured severity."


Status

Finding Source Wave-10 status
Missing C4 approval is a mapped runner-owned stop Codex P2 (wave 9→10) ✅ Fixed
Schema descriptions match the runner-route requirement Codex P2 (wave 8→9) ✅ Fixed (prior wave)
Channel-only urgent is the legal degraded fan-out Codex P2 (wave 8) ✅ Fixed (prior wave)
Completion is a landed disposition, not a landed change Codex P2 (wave 7) ✅ Fixed (prior wave)
Runner launch fail-closes without escalation routes Codex P2 (wave 6) ✅ Fixed (prior wave)
C4 execution gates on plan-approval item Codex P2 (wave 5) ✅ Fixed (prior wave)
Re-escalation saturation at urgent Codex P2 (wave 4) ✅ Fixed (prior wave)
C5 always-fires: success exception scoped correctly Codex P1 (wave 3) ✅ Fixed (prior wave)
C1 queue-artifact: PR path excluded for read-only class Codex P2 (wave 3) ✅ Fixed (prior wave)
Urgent fan-out leg model: push-only binding rejects Codex P2 (wave 3) ✅ Fixed (prior wave)
Runner class queue destination: severity-bound requires route Codex P2 (wave 3) ✅ Fixed (prior wave)
Severity selects fan-out, never item route Codex P2 (wave 2) ✅ Fixed (prior wave)
Re-escalation cap pinned at 1 Codex P2 (wave 1) ✅ Fixed (prior wave)
Executor class follows surface, not hosting Codex P2 (wave 1) ✅ Fixed (prior wave)
Stale forward-link note in runner.md Prior review (must-fix) ❌ Outstanding — 10 waves
Urgent override ambiguity in escalation.md Prior review (recommended) ❌ Outstanding — 9 waves

Wave-10 change is clean and correct. One must-fix (two stale sentences at runner.md:122–123) is the single remaining blocker before merge. The urgent-override clarification remains strongly recommended given the security implications of silent severity downgrade on isolation-violation and security/data-integrity stops.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 05e96dcafd

ℹ️ 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".

Comment thread plugins/autonomy/reference/runner/seams.md Outdated
One review finding. The turn, budget, and wall-clock caps (and the retry
budget behind the execution-error stop) had no owning configuration seam
- only the drain-level autonomous_concurrency and items_per_run were
cited - so cap-exceeded could not be made deterministic. The
session/resume/caps seam now pins the home: the per-item caps are
admission-policy knobs on the SECURITY binding, siblings of the
drain-level pair on the same agent-unwritable surface (a cap the governed
agents could edit is no cap). Their exact keys land as additive schema
keys with the build, token names resolving at /architect like every other
deferred seam token; the runner reads them and fail-closes at launch when
they are unbound, so no item ever runs unbounded on implicit defaults.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@claude

claude Bot commented Jul 20, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 1m 46s —— View job


Wave-11 delta review — docs(autonomy): autonomous-runner design pack (WP7)

  • Gather context on latest commit (5081b81)
  • Check per-item caps binding fix (Codex P2 — wave-11 commit)
  • Check runner.md — stale forward-link note (prior must-fix, outstanding 10 waves)
  • Check escalation.md — urgent override ambiguity (prior recommended fix, outstanding 9 waves)
  • Synthesize findings and post final review

Overview

Commit 5081b81 correctly resolves the Codex P2 wave-10 finding on per-item caps having no owning configuration seam. The fix is a targeted prose addition to seams.md — one file, eleven changed lines, correct in all four implementation-critical properties. The two issues from prior Claude reviews remain open for the eleventh and tenth waves respectively.


Fixed ✅ — Per-item caps get an owning binding home (Codex P2)

seams.md lines 114–121 add a "Per-item caps — owning home pinned" bullet to the session/resume/caps seam:

"The turn, budget, and wall-clock caps that bound a single run, and the retry budget behind the execution-error stop, are admission-policy knobs on the SECURITY binding — siblings of the drain-level pair, on the same agent-unwritable surface, for the same reason: a cap the governed agents could edit is no cap. Their exact keys land as ADDITIVE schema keys with the build (token names resolve at /architect like every other deferred seam token); the runner READS them and fail-closes at launch when they are unbound, so the cap-exceeded stop is deterministic and no item ever runs unbounded on implicit defaults."

All four implementation-critical properties are now specified and correct:

  1. Owning surface: the security binding — sibling of autonomous_concurrency and items_per_run on the same contract surface. This is the correct surface: it is agent-unwritable by design, and the drain-level pair already lives there.
  2. Rationale: stated inline ("a cap the governed agents could edit is no cap") — an implementor reading this knows not to put these in runner-owned config.
  3. Deferral path: exact keys are deferred to /architect as additive schema keys with the build, consistent with the pack's established pattern for all other deferred seam tokens. No token names are committed in the design, which is correct.
  4. Launch behavior: fail-closes when unbound — consistent with the fail-close patterns established in earlier waves (absent security binding, absent escalation routes). The cap-exceeded stop is now deterministic: the runner cannot launch and run an item with implicit defaults.

The prose-only treatment is appropriate for a design pack: the exact schema keys and their allowed ranges are genuinely build-time decisions, and claiming otherwise would violate the no-build covenant. The fix correctly closes the gap identified by the Codex finding without over-specifying.

The commit also tightens the preceding "Plugs into (shipped)" bullet from "run caps bind the admission-policy knobs" to "drain-level caps bind the admission-policy knobs" — a small but correct clarification that distinguishes the drain-level pair (already shipped) from the per-item caps (now pinned to the same surface but deferred to /architect).


Still open — Stale forward-link note in runner.md (must-fix, 11 waves)

Lines 122–123 still read:

The `lifecycle`, `escalation`, and `topology` leaves land with the pack's later phase; their
forward links are expected within an in-progress design pack.

All four leaves (seams.md, lifecycle.md, escalation.md, topology.md) are present on this branch and will exist at merge. The glance-layer routing table immediately above (lines 115–120) is correct and complete; these two trailing sentences are the only stale content in the entire file. This has been flagged as the single remaining must-fix blocker in every wave since wave 1 — eleven review waves.

Fix this →


Still open — Urgent stop-reason override ambiguity in escalation.md (recommended, 10 waves)

Lines 162–165 still read:

"the override forces the filed item to urgent regardless of that default"

"That default" refers only to the contract-default attention severity for runner-needs-human. With escalation_severity documented as an org-bindable override of the contract default, an org could configure escalation_severity.runner-needs-human: notice. An implementor reading "regardless of that default" might reasonably infer the org binding can still win — the phrase grammatically excludes only the contract default, not an org-configured severity. For isolation-violation and security/data-integrity stops, silent suppression via an org severity binding is the exact dangerous failure mode the override guards against. Suggested addition: "The override is absolute: it is not configurable lower through escalation_severity. Isolation-violation and security/data-integrity stops are always urgent regardless of the event class's org-configured severity."


Status

Finding Source Wave-11 status
Per-item caps: owning binding home pinned Codex P2 (wave 10→11) ✅ Fixed
Missing C4 approval is a mapped runner-owned stop Codex P2 (wave 10) ✅ Fixed (prior wave)
Schema descriptions match the runner-route requirement Codex P2 (wave 9) ✅ Fixed (prior wave)
Channel-only urgent is the legal degraded fan-out Codex P2 (wave 8) ✅ Fixed (prior wave)
Completion is a landed disposition, not a landed change Codex P2 (wave 7) ✅ Fixed (prior wave)
Runner launch fail-closes without escalation routes Codex P2 (wave 6) ✅ Fixed (prior wave)
C4 execution gates on plan-approval item Codex P2 (wave 5) ✅ Fixed (prior wave)
Re-escalation saturation at urgent Codex P2 (wave 4) ✅ Fixed (prior wave)
C5 always-fires: success exception scoped correctly Codex P1 (wave 3) ✅ Fixed (prior wave)
C1 queue-artifact: PR path excluded for read-only class Codex P2 (wave 3) ✅ Fixed (prior wave)
Urgent fan-out leg model: push-only binding rejects Codex P2 (wave 3) ✅ Fixed (prior wave)
Runner class queue destination: severity-bound requires route Codex P2 (wave 3) ✅ Fixed (prior wave)
Severity selects fan-out, never item route Codex P2 (wave 2) ✅ Fixed (prior wave)
Re-escalation cap pinned at 1 Codex P2 (wave 1) ✅ Fixed (prior wave)
Executor class follows surface, not hosting Codex P2 (wave 1) ✅ Fixed (prior wave)
Stale forward-link note in runner.md Prior review (must-fix) ❌ Outstanding — 11 waves
Urgent override ambiguity in escalation.md Prior review (recommended) ❌ Outstanding — 10 waves

Wave-11 change is minimal, correct, and well-reasoned. One must-fix (two stale sentences at runner.md:122–123) is the single remaining blocker before merge. The urgent-override clarification remains strongly recommended given the security implications of silent severity downgrade on isolation-violation and security/data-integrity stops.

@kyle-sexton
kyle-sexton merged commit a2f804d into main Jul 20, 2026
19 checks passed
@kyle-sexton
kyle-sexton deleted the docs/autonomy-runner-design-pack branch July 20, 2026 12:14
kyle-sexton added a commit that referenced this pull request Jul 20, 2026
## Summary

Effort-end housekeeping for the AI-adoption-ladder effort: all seven
work packages are merged,
so the per-WP topic slices come out per the close-out convention
(publish the PLAN, then prune
the slice).

- WP4–WP7 PLANs were already spliced into their PR bodies at each
close-out (#372, #377,
  #600, #676).
- WP1–WP3 PLANs are now published the same way into #333, #343, and #356
(each merged PR body
gained a `PLAN (published at effort-end close-out)` details block), so
every slice's content
  has a durable home on its merged PR before the directory is removed.
- The WP map in `docs/topics/ai-adoption-ladder/index.md` now records
delivery PRs instead of
live slugs. The effort hub itself (index, design evidence, research
docs) stays.

No content is lost: every deleted PLAN.md is byte-recoverable from git
history and readable in
its merged PR's details block.

## Related

No linked issue (effort-end housekeeping; the WP map issue #239 is
already closed).

- #239 (WP map: AI adoption ladder — the effort this closes out)
- #333 / #343 / #356 (WP1–WP3 delivery PRs, PLANs published into their
bodies in this
  close-out)
- #372 / #377 / #600 / #676 (WP4–WP7 delivery PRs, PLANs published at
their own close-outs)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
kyle-sexton added a commit that referenced this pull request Jul 20, 2026
…ger row (#698)

## Summary

D1 sweep for #353: the WP1–WP7 PLAN out-of-package notes (mined from the
merged PR bodies #333/#343/#356/#372/#377/#600/#676) contained 31
deferred notes; every note that named no tracking issue and had no
contract-recorded trigger now has a durable home:

- **README roadmap** gains four trigger-gated rows: fleet guardrail
materializations (WP5), fleet routine stand-up + existing-scheduler
reconciliation (WP6), vendor-binding capability templates (WP6), cost
enforcement / hard spend caps (WP5, 3→4 trigger).
- **Trigger register** gains the second-binding-consumer cross-repo
drift check (WP1).
- **`reference/return-accounting.md`** records the per-work-class
precision-graduation deferral beside its band-stability rule (WP3).
- **CHANGELOG.md created** for the autonomy plugin (first entry;
0.1.0–0.7.0 history stays in the WP PR bodies) + version bump to 0.7.1 —
starts the CHANGELOG-parity posture #663 gates on.

All other mined notes were already covered: tracked issues (#351, #352,
#694#697), contract-recorded triggers (telemetry immutable-ID,
return-accounting expansion/revisit), delivered sibling WPs, resolved
`/architect` questions, or the user-held dormant triggers (runner build
T4, L3 backend, merge serialization, mid-run interrupt, org-enablement,
cross-team). Full disposition table lands as a comment on #353 at close.

Documentation only — no contract semantics change.

## Related

- #685 (effort-end prune that moved the PLAN records into the merged PR
bodies)
- #663 (CHANGELOG-parity gate this PR's new CHANGELOG.md starts
satisfying)
- WP delivery PRs mined: #333, #343, #356, #372, #377, #600, #676

Closes #353

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Fable 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