Repository navigation
test(exp-repid): adversarial proof of the t12-exp-v1 owner priorities (inert, D6) - #1519
Conversation
… (inert) Test-first hardening of the EXPERIMENTAL RepID namespace against the six owner-independence priorities. FINDING: every attack is already refused by code on main -- no new guard or scoring math was needed. This pins each guard and the honest cross-mode ledger semantics so a later weakening turns red. New: tests/experimental-repid/experimental-repid-adversarial.test.ts (17 tests) P1 eligibility verified+authoritative only (authoritative===true, not truthy) P2 independence the eligibilityFor path inherits D-148 (#1516): admin-only builder_ids are sameness, never independence P3 negative adverse delta persists, can't be flipped/erased by replay or clone P4 replay verbatim replay (already_consumed) vs transplant (subject_mismatch) P5 lineage content.claimed_by bound to subject agent; wrong-worker refused P6 two-number same_controller vs independent counts stay separate; label/flag fixed Each attack carries a positive control (LESSONS 5) so green is a measurement. Inert: in-memory fake store only, mode never active against a real store, no DB touched, no migration. 48 pass combined with the two existing exp suites. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Strix Security Review✅ No open security findings. PR summary: Adds one inert test file that pins the existing experimental RepID (t12-exp-v1) owner-independence guards with adversarial cases and positive controls. No production source, migration, or configuration is changed. Review summaryThis PR adds a single inert test file, I reviewed the full diff and triaged the repository lint inventory against the test's import graph. Every lint item that surfaced sits in code this PR neither changes nor reaches: No security vulnerability is introduced or exposed by this change. Ruled out (7)
Review 1 on this PR · Reviewed by Strix |
There was a problem hiding this comment.
This PR adds a single inert test file, tests/experimental-repid/experimental-repid-adversarial.test.ts (+271/-0), with no source, migration, config or runtime change. It exercises the existing experimental RepID guards (settleImmuneReceipt gate 1, eligibilityFor → partyIndependence → verifierIndependence, settleExperimental replay/lineage refusals, and the two-number scores route) against an in-memory Supabase fake and stubbed owner resolvers.
I reviewed the full diff and triaged the repository lint inventory against the test's import graph. Every lint item that surfaced sits in code this PR neither changes nor reaches: src/routes/arena.ts ownerSide() (fabricated proven_wallet claims), src/scoring/grounding.ts (SAME_OWNER_SETTLEMENT_MODE default off, GROUNDING_EVIDENCE_UNIQUE=agent), src/db.ts service-role client, src/immune/combined-receipt.ts verifyCombinedReceipt, src/auth/api-keys.ts, and two migrations. The test imports only types from combined-receipt, injects a fake client everywhere, and stubs the resolver, so none of those paths are executed or newly exposed. The test file itself contains no credentials or secrets — only agent UUIDs and display names.
No security vulnerability is introduced or exposed by this change.
Reviewed by Strix
Configure security review settings
What
Test-first adversarial hardening of the existing experimental RepID namespace (
t12-exp-v1) against the six owner-independence priorities. This is inert development only (D6 lane, owner-authorized 2026-11-07): one new test file, no source change, no migration, no mode flip, no canonical write, no DB touched.Finding
Every attack is already refused by code on
main. No new guard or scoring math was needed — the namespace is sound as built. So this PR is a proof of each guard plus coverage of the gaps the existing suites missed. Per LESSONS 5, every attack carries a positive control that returns the opposite verdict through the same code path, so a green run is a measurement, not a vacuous pass.New:
tests/experimental-repid/experimental-repid-adversarial.test.ts— 17 tests, 6 blocks.authoritativemust be=== true, not merely truthy ("true"/1/{}/undefinedrefused)settleImmuneReceiptgate 1eligibilityFor→partyIndependence→verifierIndependencepath inherits D-148 (#1516): two administrative builder_ids are sameness, never independence; both sides need a proven binding in a shared namespacebounty-authorization.tsalready_consumed) / a clone (subject_mismatch) can neither flip nor erase itexperimental-repid.ts+ migration unique/chainalready_consumed) vs signature transplant (re-seal onto a new subject ⇒subject_mismatch) — named distinctlysettleExperimentalcontent.claimed_bymust equal the subject'sagent_id, so "credit X's work to Y" ⇒subject_mismatcheven re-sealedsettleExperimentalsame_controller_measuredandindependent_counterpartyas two separate counts;independent_reputation:falseand the label are fixed; a negative same-controller score is reported as-is, never laundered into the independent countroutes/experimental-repid.ts+ viewDesign clarification (not a hole)
The brief asked that a duplicate be rejected "even across shadow/active". The one-time UNIQUE key is
(domain, dimension, evidence_id|evidence_hash, **mode**)by design — shadow and active are separate ledgers, and the same evidence settles once in each. This is not a replay hole: onlyactiverows can gate anything (experimentalTierfiltersmode==='active'; shadow never changes a tier). Adding a cross-mode global nullifier would break the intended shadow-vs-active A/B design and the existing "shadow and active produce identical deltas" test, so per LESSONS 9 I did not invent it — I pinned the real invariant (the gating ledger admits each receipt once) and documented the cross-mode semantics in a test.NOT covered (honest)
UPDATE/DELETE/TRUNCATErefusal is a DB trigger; the in-memory fake can't exercise it (the existing migration test asserts the trigger SQL exists; real refusal is only provable against a live DB this inert lane does not touch).activeagainst a real store.Verification [V 2026-11-07]
🤖 Generated with Claude Code