Skip to content

CR-DD-012B: shared preview/execution consumption (accepted at bbe5336; merge withheld) - #179

Merged
coreytshaffer merged 7 commits into
mainfrom
claude/cr-dd-012b-shared-preview-execution-35b467
Aug 29, 2026
Merged

CR-DD-012B: shared preview/execution consumption (accepted at bbe5336; merge withheld)#179
coreytshaffer merged 7 commits into
mainfrom
claude/cr-dd-012b-shared-preview-execution-35b467

Conversation

@coreytshaffer

@coreytshaffer coreytshaffer commented Aug 22, 2026

Copy link
Copy Markdown
Owner

Pinning — read this before reviewing

Implementation acceptance is granted for exact commit bbe5336, not for the PR tip.

bbe5336    = accepted implementation/test state
8180bca    = governance record
e5f3218    = governance record + authorized CI repair
5cb9505    = documentation-record corrections only  (PR tip)

Branch: claude/cr-dd-012b-shared-preview-execution-35b467.

Nothing after bbe5336 touches runtime or tests. Verify it directly rather than taking this on trust:

git diff bbe5336 5cb9505 -- triage_core/ tests/    # returns empty

The 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 88

Acceptance does not attach to any later implementation state, examined or otherwise. A one-time corrective ratification pinned to bbe5336 states 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 --plan and ordinary tc run now consume one immutable GovernedRunInputSnapshot and one canonical GovernedDecision, 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.

  • One seam. tc_run builds the snapshot and decision after argument assembly and privacy mapping and before the if planning: branch. Context sources are read exactly once, there, as bytes — which is what 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.
  • Projection, not computation. build_run_plan projects a completed decision. TriageClient.run_task takes an optional (snapshot, decision) pair and consumes its policy. Callers who pass nothing are unaffected.
  • Binding is a pure envelope filter. triage_core/runtime_observation.py filters 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.
  • Bounded decision_id linkage on route_decision and worker_result, through the existing open payload extension point. The closed route-worker-ledger.v1 contract is neither modified nor used by this path; no durable schema is added and no schema version changes.

Behavioral changes this PR carries

  • Capability no longer reaches route policy. A run whose local capability is unknown produces a decision naming local routes and then fails at binding.
  • tc run no longer emits specialist_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.
  • The plan artifact's assembled_input_binding digest changes value — it now digests the snapshot's authoritative assembled bytes instead of a second independent f"{prompt}\n{data}" assembly. A pre/post mismatch is the intended single-assembly change, not corruption. No schema version changes.
  • --model is validated on the execution path; an unknown profile exits 1.
  • Execution-path privacy failures report bounded finding codes instead of scanner free text. Exit code unchanged at 2.
  • tc run --plan gains a permitted_fallback_envelope line, and route_required_checks lists the governed verification codes. governed_run_plan.v1 is otherwise unchanged and carries no decision_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: ProjectSteward and SpecialistRouter.route_task removed from the governed path; ethical-firewall handoff restored to exit 3 with worker_result evidence.
  • 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 ProjectSteward on the grounds that removing it would drop the credit-allowance and energy gates. That was wrong — ProjectSteward.__init__ does budgets or {}, so token_credit_allowance is always 0 on this path, and the energy and validation gates need a non-empty completed_orders that run_task never supplies. There was no gate to lose. The correction is recorded in the CR rather than quietly dropped.

Verification

python -m pytest tests/ -q1802 passed, 6 skipped.

GitHub Actions run #482 succeeded at e5f3218 across all four jobs — pytest on 3.10/3.11/3.12 plus the mandatory windows_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.py is retired, not deleted: it failed by design once the foundation was integrated, and tests/test_governed_consumption_parity.py asserts the integrated shape it asserted the absence of, carrying over its two governed_decision purity 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 after bbe5336 is 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 run exit class should follow why human_handoff was 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

coreytshaffer and others added 5 commits August 21, 2026 20:39
…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>
@netlify

netlify Bot commented Aug 22, 2026

Copy link
Copy Markdown

Deploy Preview for poetic-quokka-0fd859 ready!

Name Link
🔨 Latest commit 5cb9505
🔍 Latest deploy log https://app.netlify.com/projects/poetic-quokka-0fd859/deploys/6a89cccc79db3c000796e047
😎 Deploy Preview https://deploy-preview-179--poetic-quokka-0fd859.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

coreytshaffer and others added 2 commits August 22, 2026 09:15
…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
coreytshaffer merged commit c798e0e into main Aug 29, 2026
8 checks passed
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>
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