Skip to content

feat(immune): inert Lane A dry-run thread (precommit -> receipt -> would-write) [D-145] - #1513

Merged
DealAppSeo merged 1 commit into
mainfrom
claude/2026-11-04-lane-a-dryrun
Nov 4, 2026
Merged

DealAppSeo merged 1 commit into
mainfrom
claude/2026-11-04-lane-a-dryrun

Conversation

@DealAppSeo

Copy link
Copy Markdown
Owner

What

Stands up Lane A (one real economic E2E) as an inert dry-run thread. New file src/immune/lane-a-dryrun.ts + test. Writes nothing; moves no money / RepID / on-chain state.

The pieces already existed and are (partly) live, but nothing joined them: runTrustedSettlement + settleImmuneReceipt have zero non-test callers, and the precommit world (multi-criterion acceptance, work_statement_hash) and the receipt world (single binary verdict, experiment_id) are two unlinked subsystems. This threads them:

work-statement precommit hash → parseCriterionRatings satisfaction → versioned, default-OFF collapse to the receipt's binary verdict (LANE_A_ACCEPT_THRESHOLD, default 1.0 = all criteria met) → runTrustedSettlement (dry-run, signed + independently verified) → the would-write experimental shadow row.

Deliberately small join (Grok co-signed, D-054)

  • Receipt bound to the contract via experiment_id = contractId — a transitive bind to the immutable work_statement_hash on service_contracts. The signed public combined receipt is NOT changed.
  • Multi→binary collapse is one versioned, reversible threshold, explicit on the output — never silent.
  • Same-controller throughout; eligibility can only ever be same_controller_measured. This is not independent commerce.

Owner (MAJOR) gates — all left undone

authoritative receipt (engine origin auth) · EXPERIMENTAL_REPID_MODE + IMMUNE_SETTLE_ENABLED to move even shadow credit · real testnet USDC payment + ERC-8004 / EAS writes · promoting work_statement_hash to a first-class bound receipt field · any canonical credit.

Tests

5/5 jest. The test caught a real Number('')===0 bug that collapsed the default threshold to 0 (accept-anything); fixed. Existing 57 immune-lane tests remain green.

🤖 Generated with Claude Code

…uld-write) [D-145]

Threads the existing, unjoined Lane A pieces end to end as an inert dry-run:
work-statement precommit hash -> multi-criterion acceptance -> versioned
default-OFF collapse to the receipt's binary verdict -> combined trust receipt
(signed + independently verified) -> the would-write experimental shadow row.
Writes nothing; moves no money / RepID / on-chain state.

The receipt is bound to the contract via experiment_id = contractId (a transitive
bind to the immutable work_statement_hash on service_contracts); the signed public
combined receipt is NOT changed. Same-controller throughout — never claims
independence. 5/5 jest; the test caught a Number('')===0 threshold bug, fixed.

Grok co-signed the scope (D-054). Promoting work_statement_hash to a first-class
bound receipt field, the activation flags, and the real testnet USDC payment +
ERC-8004 / EAS writes remain Sean's MAJOR gates.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@strix-security

strix-security Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

Strix Security Review

✅ No open security findings.

PR summary: Adds `src/immune/lane-a-dryrun.ts` plus a test: an inert dry-run harness that threads a precommit work-statement hash through multi-criterion acceptance, a versioned threshold collapse, a signed (non-authoritative) settlement receipt, and a would-write experimental shadow row, writing nothing.

Review summary

Reviewed both changed files in full and traced every leg of the new Lane A thread into the modules it joins (work-statement-spec, trusted-settler, experimental-settlement), including a runtime check of the side effects. No security vulnerability is introduced by this PR: the new module is inert and uncalled. runLaneAJDryRun has no non-test callers, settleImmuneReceipt rejects its receipt at the non-attestation gate before the mode, enabled and store gates, no store is injected, buildImmuneExperimentalRow is a pure constructor, and nothing touches canonical RepID, USDC, ERC-8004/EAS or the DB — confirmed with all env flags opened and a hostile injected store. The acceptance parser is sound (out-of-set criteria, non-boolean met and missing criteria are all refused; denominator is the spec's criteria count), and the threshold default genuinely fails closed to 1.0. Four suspicions raised during the deeper analysis — a signed receipt asserting execution/containment that never occurred against a constant-expectation fixture oracle, a LANE_A_ACCEPT_THRESHOLD=0 accept-anything knob, an unvalidated caller-supplied contractId with an unenforced work_statement_hash bind, and a 4-decimal score rounding that can reach 1.0 with one criterion unmet — were each independently validated and rejected as inert, operator-controlled, caller-self-harming, or pre-existing in unchanged code. They remain worthwhile design notes before Lane A is wired to any producer or credit path.

Ruled out (4)
  • Does the signed receipt falsely attest sandbox execution and containment that never happened?
    The harness does fabricate `airlock_decision:'promote'` and self-hashed artifact evidence, but the receipt is `authoritative:false`, `runLaneADryRun` has zero non-test callers, and every consumer (`settleImmuneReceipt`, `anchorReceipt`) refuses a non-authoritative receipt, so no trust boundary is c…
  • Can `LANE_A_ACCEPT_THRESHOLD=0` make every deliverable count as correct?
    An explicit `0` does invert the collapse to accept-anything, but the value comes only from process env (never a request), and with no caller, no injected store and a non-authoritative receipt the setting produces no credit or persisted state.
  • Can an attacker bind a receipt to someone else's contract via an unvalidated `contractId`?
    `contractId` is only used to build local hashes and signing context and is echoed back on the caller's own return value; nothing is read from `service_contracts`, so there is no victim object and no access-control check to bypass.
  • Can an unmet criterion still yield 'correct' at the default 1.0 threshold?
    The 4-decimal rounding in unchanged `work-statement-spec.ts` does allow 19999/20000 to round to 1.0, but the caller supplies both the spec and the ratings it would be subverting, the code is pre-existing, and the function is unreachable and non-persisting.

Review 1 on this PR · a67a85f · requested Nov 4 22:43 UTC when the PR was opened


Reviewed by Strix
Re-run review · Configure security review settings

@DealAppSeo
DealAppSeo enabled auto-merge (squash) November 4, 2026 22:45
@DealAppSeo
DealAppSeo merged commit 9bfdbad into main Nov 4, 2026
18 checks passed
@DealAppSeo
DealAppSeo deleted the claude/2026-11-04-lane-a-dryrun branch November 4, 2026 22:49

@strix-security strix-security 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.

Reviewed both changed files in full and traced every leg of the new Lane A thread into the modules it joins (work-statement-spec, trusted-settler, experimental-settlement), including a runtime check of the side effects. No security vulnerability is introduced by this PR: the new module is inert and uncalled. runLaneAJDryRun has no non-test callers, settleImmuneReceipt rejects its receipt at the non-attestation gate before the mode, enabled and store gates, no store is injected, buildImmuneExperimentalRow is a pure constructor, and nothing touches canonical RepID, USDC, ERC-8004/EAS or the DB — confirmed with all env flags opened and a hostile injected store. The acceptance parser is sound (out-of-set criteria, non-boolean met and missing criteria are all refused; denominator is the spec's criteria count), and the threshold default genuinely fails closed to 1.0. Four suspicions raised during the deeper analysis — a signed receipt asserting execution/containment that never occurred against a constant-expectation fixture oracle, a LANE_A_ACCEPT_THRESHOLD=0 accept-anything knob, an unvalidated caller-supplied contractId with an unenforced work_statement_hash bind, and a 4-decimal score rounding that can reach 1.0 with one criterion unmet — were each independently validated and rejected as inert, operator-controlled, caller-self-harming, or pre-existing in unchanged code. They remain worthwhile design notes before Lane A is wired to any producer or credit path.


Reviewed by Strix
Configure security review settings

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