CR-DD-012B: shared preview/execution consumption (accepted at bbe5336; merge withheld) - #179
Merged
coreytshaffer merged 7 commits intoAug 29, 2026
Conversation
…execution Build one immutable GovernedRunInputSnapshot and one canonical GovernedDecision at a single seam in tc_run, placed after argument assembly and privacy mapping and before the `if planning:` branch. Context sources are read exactly once there, as bytes, which closes the preview/execution TOCTOU gap. Preview's early return is preserved: it acquires no packet construction, ledger wiring, task-ID generation, or backend construction. build_run_plan now projects a completed decision rather than computing one, and TriageClient.run_task accepts an optional (snapshot, decision) pair and consumes its policy instead of re-deriving classification or logical route. Callers who pass nothing keep current behavior unchanged; a caller who passes a decision gets different behavior, because policy then comes from the decision. Runtime binding is a filter over the decision's closed, ordered envelope, in the new triage_core/runtime_observation.py. Capability constrains binding only and no longer reaches route policy: the three reachable outcomes are primary binding, an already-authorized fallback, or a closed failure. A route outside the envelope is unreachable by construction. CapabilityResolution stays the sole source of local capability evidence and is carried as provenance, never re-derived, with observed/configured/unknown preserved verbatim. Bounded decision_id linkage rides the existing open route_decision and worker_result payload extension point. The closed route-worker-ledger.v1 contract is neither modified nor used by this path, so no durable schema is added and no schema version changes. Retire tests/test_governed_decision_integration_absence.py, which failed by design once the foundation was integrated. Its coverage is replaced, not removed: the new parity suite asserts the integrated shape it asserted the absence of, and carries over its two governed_decision purity tests verbatim. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…nted gates Record CR-DD-012B as implemented on this branch with implementation authority spent, and implementation acceptance, merge, and closeout NOT granted. The instruction named no replacement file allowlist, so the CR's own provisional list bound the work. Two paths beyond it were taken, both regression-test updates that the slice's intended behavior necessarily invalidates, and both are named rather than absorbed. Every deliberately excluded module is untouched. The record also states, in the terms an accepting reviewer would need: the behavioral changes they would be approving, including the deliberate correction to CR-DD-013 route selection and the changed plan-artifact assembled-input digest; the three places the built code is narrower than the recommendation, so the no-rebuild claim is not read more strongly than the code supports; the two mechanical accommodations forced by the excluded modules; and gate-by-gate evidence for all five approval gates. Sweep the companion documents for passages the implementation makes self-contradictory, and state in each that `main` behavior is unchanged until the slice is accepted and merged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ndoff exit 3 Repairs 2 and 3 from the acceptance review that withheld acceptance at 909838f. ProjectSteward no longer runs on the governed path; the ethical firewall is consumed from the decision field that already carries it. The previous claim that removing it would drop the credit-allowance and energy gates was wrong: ProjectSteward.__init__ does `budgets or {}`, so token_credit_allowance is always 0 here, and the energy and validation gates require a non-empty completed_orders that run_task never supplies. The only live output was the firewall verdict, which the decision already holds. There was no gate to lose. SpecialistRouter.route_task is not invoked on the governed path at all. Its offload verdict is a second policy decision, and two of its three branches turn on a live is_internet_available() probe -- a volatile observation, which may decide whether an authorized plan can execute now but never what route the task receives. Its high-risk branch the decision already expresses as a preferred human_handoff. Only its two execution parameters were still needed; both are pure functions of the classification the decision carries, and a drift guard pins them against route_task's own tables for every classifier category. The executed timeout is now exactly the forecast the preview published. A firewall handoff is a governed terminal outcome, not an unavailable route. It returns handoff_required with a worker_result record at exit 3 instead of being caught by the local-only guard at exit 2. The distinguishing fact is the binding outcome, not the route name: human_handoff bound as primary with a triggered firewall is a governed handoff; human_handoff reached as an envelope fallback means the authorized route could not bind and stays fail-closed. Adds traps for both removed recomputations, installed after the seam so they isolate downstream re-decision rather than catching the seam's single legitimate evaluation, plus the parameter drift guard and exit-code regression tests. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…epairs Repair 1 from the acceptance review. No implementation allowlist was ever granted: the instruction opened the implementation phase and named no bounded file list, and I inferred the CR's provisional list as the bound scope. That inference is recorded as an inference, not converted into a grant. The CR now quotes the instruction verbatim, states the defect plainly, sets out the three available dispositions, and names the exact wording that would close the gap under the amendment reading. This change issues no amendment. Also records repairs 2 and 3, and corrects a wrong claim from the previous revision: removing ProjectSteward would not have dropped the credit-allowance and energy gates, because neither is reachable from run_task. That claim was the stated reason for keeping the recomputation, so the correction is recorded rather than quietly dropped. Flags one residual asymmetry left unchanged because it was outside the requested repairs: a high-risk local-only run also reaches a primary human_handoff and still exits 2, pinned by a CR-DD-009 exit-code contract this slice did not regress. By the review's own evidence argument it arguably belongs at exit 3. Records the plan-artifact digest discontinuity explicitly so a pre/post mismatch is read as the intended single-assembly change, and preserves the Smart App Control explanation alongside the verification record. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…e5336 Documentation only. Changes no code and no test: `git diff bbe5336 -- triage_core/ tests/` is empty, so the accepted candidate state is untouched and the acceptance attaches to that state rather than to the branch tip. Records, verbatim, the operator's one-time corrective bounded implementation ratification pinned to exact `bbe5336`, and implementation acceptance at the same head. Merge, release, and closeout authority are withheld. The original authority defect is preserved, not erased: the implementation instruction granted intent but named no bounded file allowlist, the CR's provisional list was inferred as the bound scope, and two regression-test paths beyond even that inferred list were taken. The operator chose corrective ratification over reconstruction on the ground that replaying the work would improve the appearance of the process without changing the evidence. That reasoning is recorded alongside the defect. Adds an Open Discovery record for the high-risk terminal exit class -- whether the CLI outcome should follow why human_handoff was selected or simply that the authoritative decision selected it -- deliberately unresolved here and carrying no authority, with the accepting reviewer's architectural lean marked as a lean. Sweeps the companion documents and this document for passages the grants make self-contradictory. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
✅ Deploy Preview for poetic-quokka-0fd859 ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
…suite Bounded supplemental repair for PR #179, authorized for exactly two paths. The mandatory windows_executor group names tests/test_governed_decision_integration_absence.py by path. That guard was retired under approval gate 3 and its coverage replaced, but the retirement was never swept for references outside the test tree, so CI could no longer collect the group and could not evaluate the accepted candidate at all. Three Ubuntu pytest jobs passed; the Windows job failed on collection. The substitution points the group at tests/test_governed_consumption_parity.py, which carries the retired guard's replacement coverage including its two governed_decision purity tests, carried over verbatim. Acceptance does not migrate to this tip. The accepted implementation and test state remains bbe5336: `git diff bbe5336 HEAD -- triage_core/ tests/` is empty, and this commit's only non-documentation change is the single workflow path. Found by the publication gate rather than by any local run -- a stale executable reference outside the implementation allowlist is integration residue that a local suite structurally cannot surface. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… review Documentation only, under a bounded governance-record grant. Changes no runtime, test, or workflow path: `git diff bbe5336 HEAD -- triage_core/ tests/` stays empty, and implementation acceptance stays pinned to bbe5336. Independent merge review found four record defects, none of which reopened an accepted implementation property: - The parent CR and the backlog both named a branch that does not exist. The real branch is claude/cr-dd-012b-shared-preview-execution-35b467. The erroneous selector originated in this agent's own prose and propagated into the documents and then into the publication grant. - The parent CR said implementation proceeded "bounded by" the provisional allowlist. That is too strong and contradicted the defect preserved further down the same document: the list was inferred, not granted. It now says so. - The backlog still asserted acceptance remains ungranted while later sections correctly recorded acceptance at bbe5336. Merging that would have landed an internally contradictory lifecycle record. - The CR carried an unresolved <new tip> placeholder where the pinning block should name e5f3218. Records the operator's corrective publication clarification, which ratifies the publication grant for exact commit 8180bca as applying to the actual branch and preserves the erroneous name as a documentary selector error rather than treating it as authority for a different code state. The exact commit was always right; only the selector was wrong. Also pins the CI evidence: Actions run #482 succeeded at e5f3218 across all four jobs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
coreytshaffer
added a commit
that referenced
this pull request
Aug 29, 2026
main advanced twice more after the reconciliation was written against c798e0e. Re-pin it to the current tip and record what each merge did. - Reconciliation retitled to 96eb3d3, with a table of the three merges that landed while this record was drafted: #179 (CR-DD-012B, the only one to touch triage_core/), #180 (CR-DD-016 closeout, docs only), and #166 (CR-132, docs only -- one new CR document). - Verified directly that `git diff c798e0e 96eb3d3 -- triage_core/ tests/ schemas/` is empty, so no source fact changed across those two merges and every finding that held at c798e0e holds at 96eb3d3. - All reconciliation citations re-verified against 96eb3d3. - Citation drift re-checked using the two stale anchors as negative controls: run_plan.py:59 and route_events.py:217 still point at the wrong content at 96eb3d3, confirming the drift is a real property of the record rather than an artifact of how it was measured. No finding changed. Documentation only. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
7 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pinning — read this before reviewing
Implementation acceptance is granted for exact commit
bbe5336, not for the PR tip.Branch:
claude/cr-dd-012b-shared-preview-execution-35b467.Nothing after
bbe5336touches runtime or tests. Verify it directly rather than taking this on trust:git diff bbe5336 5cb9505 -- triage_core/ tests/ # returns emptyThe only non-documentation change after the accepted state is a single authorized line in
.github/workflows/tests.yml, which repointed the mandatory Windows group at the replacement suite after this PR retired the integration-absence guard:git diff 8180bca e5f3218 -- .github/workflows/tests.yml # exactly one path substitution, line 88Acceptance does not attach to any later implementation state, examined or otherwise. A one-time corrective ratification pinned to
bbe5336states that a single substantive commit voids it; the CI repair was authorized as a bounded exception that explicitly did not migrate the pin.Merge, release, and closeout authority are withheld. This PR exists to expose the candidate for independent review and CI.
What the slice does
tc run --planand ordinarytc runnow consume one immutableGovernedRunInputSnapshotand one canonicalGovernedDecision, so the preview a reviewer reads and the decision execution honors are the same object rather than two independently computed answers that happened to agree.tc_runbuilds the snapshot and decision after argument assembly and privacy mapping and before theif planning:branch. Context sources are read exactly once, there, as bytes — which is what closes the preview/execution TOCTOU gap. Preview's earlyreturnis preserved: it acquires no packet construction, ledger wiring, task-ID generation, or backend construction.build_run_planprojects a completed decision.TriageClient.run_tasktakes an optional(snapshot, decision)pair and consumes its policy. Callers who pass nothing are unaffected.triage_core/runtime_observation.pyfilters over the decision's closed, ordered envelope: primary binding, an already-authorized fallback, or a closed failure. A route outside the envelope is unreachable by construction. Capability constrains binding only and never reaches route policy.decision_idlinkage onroute_decisionandworker_result, through the existing open payload extension point. The closedroute-worker-ledger.v1contract is neither modified nor used by this path; no durable schema is added and no schema version changes.Behavioral changes this PR carries
tc runno longer emitsspecialist_offload_decision, and no longer offloads medium-risk or large-context work on the basis of live connectivity. Both were volatile-observation-driven policy overrides.assembled_input_bindingdigest changes value — it now digests the snapshot's authoritative assembled bytes instead of a second independentf"{prompt}\n{data}"assembly. A pre/post mismatch is the intended single-assembly change, not corruption. No schema version changes.--modelis validated on the execution path; an unknown profile exits 1.tc run --plangains apermitted_fallback_envelopeline, androute_required_checkslists the governed verification codes.governed_run_plan.v1is otherwise unchanged and carries nodecision_id.Governance defect, preserved rather than erased
The original implementation instruction granted intent but named no bounded file allowlist, which this CR requires. The CR's provisional list was inferred as the bound scope, and two regression-test paths were taken beyond even that inferred list (
tests/test_tc_run_cli.py,tests/test_tc_run_plan_cli.py— a now-no-op mock and a task-ID contract the governed snapshot tightened).That defect is recorded in the CR and is not relabelled. It was handled by a one-time corrective ratification rather than by reconstructing the work, on the recorded ground that replaying it would improve the appearance of the process without changing the evidence.
Review history
909838f— acceptance withheld, three repairs required.9231a82— repairs 2 and 3:ProjectStewardandSpecialistRouter.route_taskremoved from the governed path; ethical-firewall handoff restored to exit 3 withworker_resultevidence.bbe5336— repair 1: authority record corrected. Accepted head.8180bca— ratification and acceptance recorded. Docs only.e5f3218— bounded CI repair: the mandatory Windows group still named the retired guard by path, so CI could not collect it. Found by this publication gate, not by any local run.5cb9505— record-integrity repairs found in merge review: a branch name that did not exist, an overstated "bounded by the provisional allowlist" claim, a stale "acceptance ungranted" line, and an unresolved tip placeholder. Docs only.One correction worth surfacing: an earlier revision justified keeping
ProjectStewardon the grounds that removing it would drop the credit-allowance and energy gates. That was wrong —ProjectSteward.__init__doesbudgets or {}, sotoken_credit_allowanceis always0on this path, and the energy and validation gates need a non-emptycompleted_ordersthatrun_tasknever supplies. There was no gate to lose. The correction is recorded in the CR rather than quietly dropped.Verification
python -m pytest tests/ -q→ 1802 passed, 6 skipped.GitHub Actions run #482 succeeded at
e5f3218across all four jobs —pyteston 3.10/3.11/3.12 plus the mandatorywindows_executor.Focused: 106 tests across the no-rebuild traps, approval gates 3–5, the fail-closed matrix, and terminal routing.
tests/test_governed_decision_integration_absence.pyis retired, not deleted: it failed by design once the foundation was integrated, andtests/test_governed_consumption_parity.pyasserts the integrated shape it asserted the absence of, carrying over its twogoverned_decisionpurity tests verbatim.Suggested review gate
Verify the base/head relationship, the changed-file inventory, CI at the tip, that
git diff bbe5336 <tip> -- triage_core/ tests/is empty, that the only non-documentation change afterbbe5336is the one authorized workflow line, and that no finding reopens an accepted implementation property. Merge authority remains withheld until that independent review is complete.Deliberately out of scope
An open discovery is recorded in the CR and left unresolved: whether the
tc runexit class should follow whyhuman_handoffwas selected, or simply that the authoritative decision selected it. Today a firewall handoff exits 3 and a high-risk local-only handoff exits 2. Folding that in here would have turned a convergence slice into a semantic rewrite; it needs its own read-only investigation against CR-DD-009, CR-125, the high-risk tests, and downstream consumers.🤖 Generated with Claude Code