Verification — P3.8.1 Parity Harness (R89 θ Wave 5)

§1. Test commands run

cd .worktrees/claude/p3-8-1-parity-harness
npm run build   # tsc + postbuild copy-migrations
npm run lint    # eslint src
npm test        # jest with coverage

All three pass.

§2. Suite-level numbers

Metric Before R89 θ Wave 5 After P3.8.1
Total tests 3005 (Wave 4 baseline cited in dispatch) 3087
New tests this PR +82 (G1–G9 in parity-harness.test.ts)
Test files 67 68
Suites passing 67 68
Suites failing 0 0

The 3005 → 3087 delta is +82. The +82 is the full test count contributed by parity-harness.test.ts — 43 named test cases plus nested expect calls inside G1/G6 contribute the additional rolled-up assertions. Jest counts every test() and it() block individually; the 43 cases match the contract’s locked “≥ 30 test cases in 8 groups” floor with the addition of G9 input-validation cases.

§3. Per-scenario verdict matrix

Scenario Expected Observed Pass
SCENARIO_1 QUORUM, no slash QUORUM, slashings=0n yes
SCENARIO_2 QUORUM, no slash QUORUM, slashings=0n yes
SCENARIO_3 QUORUM despite D, no slash QUORUM, slashings=0n yes
SCENARIO_4 QUORUM + 1 slash QUORUM, slashings=1n yes

§4. Determinism evidence

  • G6.1: runScenario(s, 42n).determinism_check.second_run_identical === true for every scenario in DEFAULT_CORPUS.
  • G6.2: reportCanonicalBytes(runDefaultCorpus(42n)[i]) === reportCanonicalBytes(runDefaultCorpus(42n)[i]) for every i.
  • G6.3: reportCanonicalBytes(runScenario(SC4, 42n)) !== reportCanonicalBytes(runScenario(SC4, 43n)) — confirms the seed actually influences output (no constant-folding into a no-op).
  • G6.4: runDefaultCorpus() default seed equals runDefaultCorpus(42n) byte-for-byte across all four reports.

§5. Performance evidence

G7.1 ran 300 iterations of runDefaultCorpus(42n) in 3.3s solo, and <5s under full-suite jest –coverage load. Each iteration exercises:

  • SC1: 1 signed vote (single arbiter).
  • SC2: 4 signed votes.
  • SC3: 4 signed votes.
  • SC4: 5 signed votes + 1 equivocation-proof construction + 1 successful slash + 1 idempotent retry.

Per pass: ~14 signed-vote events × 2 (determinism check internal double-run) ≈ 28 vote events. 300 × 4 scenarios × ~9 events/scenario yields ~10_800 synthetic events — comfortably exceeds the headline “10000 synthetic events” budget at <5s.

Without the module-level KEYPAIR_CACHE introduced in this PR, the same iteration count takes ~11s due to PKCS#8 parse + createPrivateKey cost (~5–6ms per keypair × 16 unique keypairs per pass × 300 passes). The cache is deterministic (cache key is a pure function of (seed_root, scenario_id, arbiter_id)) so no determinism property is sacrificed.

§6. Forbidden-token scan evidence

G8.1 runs the κ-style 13-pattern regex sweep over src/domains/consensus/parity-harness.ts after stripping comments. Zero hits.

G8.2 runs the same sweep over src/domains/consensus/default-corpus.ts. Zero hits.

Patterns scanned (identical set to messages.test.ts Group 9):

\bMath\.[A-Za-z_]\w*
\bDate\.[A-Za-z_]\w*
\bnew\s+Date\b
\b(setTimeout|setInterval|setImmediate)\b
\b(fetch|XMLHttpRequest)\b
\brequire\s*\(\s*['"](fs|node:fs)['"]
\bfrom\s+['"](fs|node:fs)['"]
\bcrypto\.[A-Za-z_]\w*
\bprocess\.(hrtime|nextTick)\b
\bawait\b
\basync\s+(function|\()
(?<![0-9n])\b\d+\.\d+\b
\[native code\]

The harness uses NAMED imports from node:crypto (createHmac, createPrivateKey, createPublicKey, KeyObject) so no dotted crypto.X access appears in the body. All numeric literals are integers or bigints; no float literals. Date.now() and process.hrtime appear only in the test file (G7.1) and only inside // eslint-disable-next-line no-restricted-globals blocks — test files are not scanned for forbidden tokens.

§7. Scenario 3 — worked-example verbatim mapping

docs/3-world/physics/laws/consensus.md §Worked example, lines 92–120, specifies:

Setup: n = 4, f = 1, quorum = 3. Nodes: A, B, C honest; D Byzantine. Event E has merkle_root = 0xab12….

Node Broadcasts Commit hash
A ... sig_A(42, 0xab12, rv) ...
B ... sig_B(42, 0xab12, rv) ...
C ... sig_C(42, 0xab12, rv) ...
D ... sig_D(42, 0xCAFE, rv) ... — divergent root

Count of matching (merkle_root, rule_version_hash) on reveal: 0xab12… = 3 (≥ quorum), 0xCAFE… = 1.

SCENARIO_3 in src/domains/consensus/default-corpus.ts:

export const SCENARIO_3: Scenario = freezeScenario({
  id: 'n4-byzantine-D',
  n: 4n,
  arbiters: ['A', 'B', 'C', 'D'],
  rounds: [
    freezeRound('0xab12', [
      ['A', { kind: 'honest', merkle_root_tag: '0xab12' }],
      ['B', { kind: 'honest', merkle_root_tag: '0xab12' }],
      ['C', { kind: 'honest', merkle_root_tag: '0xab12' }],
      ['D', { kind: 'byzantine', merkle_root_tag: '0xCAFE' }],
    ]),
  ],
});

G4.3, G4.4, G4.5 each assert one of:

  • A/B/C carry tag '0xab12' (G4.3)
  • D carries tag '0xCAFE' (G4.4)
  • Majority count = 3, minority count = 1 (G4.5)

G4.1 confirms finality_reached === 'QUORUM' matches the worked example’s PENDING → SOFT → QUORUM transition.

§8. Idempotent slash evidence

The harness calls applyEquivocationSlash twice for SC4’s equivocation pair, sharing a single alreadyApplied: Set<string>.

  • First call returns {applied: true, evidence_hash_hex, next_row, history_event}. slashings_applied counter increments to 1n.
  • Second call returns {applied: false, reason: 'duplicate'} (the evidence_hash_hex is already in alreadyApplied). slashings_applied stays at 1n.

G5.3 asserts the final counter is exactly 1n. The two-call pattern is in the source body itself (every SC4 pass exercises both calls), so the assertion is always against the two-call path.

§9. Lint + build evidence

> colibri@0.0.1 build
> tsc

> colibri@0.0.1 postbuild
> node scripts/copy-migrations.mjs
copy-migrations: copied 8 migration(s) ...

tsc exits 0, postbuild copies migration assets.

> colibri@0.0.1 lint
> eslint src

eslint src exits 0 — no errors, no warnings.

§10. Out-of-scope (not in this PR)

  • New MCP tools — none added; surface stays at 23 from P3.7.1.
  • HARD or ABSOLUTE finality scenarios — Phase 4 epoch sealing.
  • Multi-round scenarios — all 4 scenarios are single-round.
  • Threshold signature aggregation — deferred per ADR-003.
  • View-change / VRF leader rotation — no failure scenarios.
  • Cross-scenario aggregation reports — explicitly out of contract.

§11. References

  • Audit: docs/audits/p3-8-1-parity-harness-audit.md
  • Contract: docs/contracts/p3-8-1-parity-harness-contract.md
  • Packet: docs/packets/p3-8-1-parity-harness-packet.md
  • Spec worked example: docs/3-world/physics/laws/consensus.md §Worked example
  • κ pattern source: src/__tests__/domains/rules/parity-harness.test.ts

Back to top

Colibri — documentation-first MCP runtime. Apache 2.0 + Commons Clause.

This site uses Just the Docs, a documentation theme for Jekyll.