Skip to content

fix: make the C0.4 corpus prove what its cases claim - #22

Merged
Freshair129 merged 1 commit into
mainfrom
fix/c0-corpus-review
Sep 27, 2026
Merged

Freshair129 merged 1 commit into
mainfrom
fix/c0-corpus-review

Conversation

@Freshair129

Copy link
Copy Markdown
Owner

Summary

This PR follows up the RKOI architecture review of the C0.4 golden corpus v2 (Freshair129/Genesis-Knowledge-System#20), which was merged before the review finished. The first review returned REVISION_NEEDED, with 3 claim-honesty findings and 10 warnings. After this change, the re-review returned APPROVED, and its three residual suggestions are fixed here too.

No product code changes. Everything here is corpus fixtures, the runner, tests and docs, plus one root devDependency.

Claim honesty in GENESISRAG17-RECEIPTS (must-fix 1–3)

  1. Denials came from the wrong check. The wrong-hash and forged-stage graph receipts used to run after the first receipt was accepted. So they were refused as "a different receipt", whichever check actually existed. They now run before any receipt exists, together with:

    • a principal whose scope differs from the request;
    • a tenant-b worker addressing tenant-a's decision;
    • the wrong role.

    Each denial now names its message through a new toolMessage annotation, because several different checks all answer gks_conflict. The "different receipt after acceptance" conflict is now its own step.

  2. "A failed stage blocks publication" was not shown. The gate verdict looked the same with or without the Stage 15 failure. The case now shows the failure itself blocking the chain:

    • the worker receipt is refused with "pipeline execution is already terminal…";
    • the gate answers FAIL;
    • publication is refused;
    • the evidence rows (9–14 SUCCEEDED, 15 FAILED, 17 FAILED) are pinned through the public gks_pipeline_evidence export and directly in the store.
  3. Ordering was never exercised. Publishing before the gate is now tried, and it is refused.

Normalization cannot hide a regression

Before Now
Any instant not present in the request became <server-time> Only instants inside the run's own wall-clock window are replaced (1 s slack). The epoch or an instant a day off stays literal.
Every duration_ms was replaced A duration the request reported stays literal. Worker metrics use distinctive values (4301–4304), and the runner rejects any request duration under 1000 ms.
Clock-derived hashes were only replaced by labels The runner also recomputes decisionHash, graphReceiptHash, receiptHash and publicationHash with the contract functions GKS uses. A value the request carried is never labelled. --write refuses a labelled value that is identical in both of its runs.

Other warnings

  • The legacy default portfolio is now c0-legacy-default, which differs from every explicit scope, so a server that ignored an explicit portfolio would fail. AUTH-DENIAL checks both the scope-less API-010 payload and an explicit-scope envelope.
  • The manifest records productSha (apps, packages, migrations, package files) and corpusSha (fixtures and tooling, excluding the manifest itself).
  • A graceful stop must exit with code 0 within 5 s. The store directory must not appear in stdout or stderr. --case requires an id.
  • BACKEND-FAILURE no longer cites the redaction test. Its reason now records that the SQLite message naming the dropped table reaches the caller, which is accepted C0 behaviour.
  • better-sqlite3 is declared as a root devDependency. The runner and 12 test files import it from the root and previously resolved it only through workspace hoisting.
    • npm dropped hasInstallScript: true from its lock entry; I restored it by hand.
    • RKOI reproduced the lock exactly with npm install --package-lock-only.
    • The lock diff is that one devDependency line, and the baseline is re-locked.

Golden diff

Three golden transcripts change. Each change follows from a change to the fixtures, not from a change in the server:

  • TOOL-017: the worker-reported duration_ms values are now literal (4301–4303) instead of <duration-ms>.
  • AUTH-DENIAL: the scope-less payload now resolves under c0-legacy-default, so its knowledge and entity refs are different. The explicit-scope steps and the final count of 2 promotions are new.
  • GENESISRAG17-RECEIPTS: the new denial, ordering and failed-batch steps are added.

The other 21 transcripts are unchanged.

Test plan

  • Mutation checks. Each mutation was applied to product code, the corpus was run, then the mutation was reverted:

    Mutation Cases that fail
    core decision-hash check removed RECEIPTS
    stage-identity check removed RECEIPTS
    terminal-state check on the worker receipt removed RECEIPTS
    gate-required check removed RECEIPTS
    failed-state publication check removed RECEIPTS
    decision clock a day off 8 cases
    echoed worker duration zeroed 2 cases
    explicit portfolio replaced by the default 13 cases
    receiptHash computed over a wrong object 5 cases, caught only by the runner's recomputation
    publicationHash computed over a wrong object 3 cases, caught only by the runner's recomputation
  • New contract tests pin the three normalization rules: the time window, echoed durations and request-carried hashes.

  • npm test: vitest 292 passed, 2 skipped (the MSP suites need MSP_REPO_ROOT); security 12/12; unit 9/9.

  • check:c0: PASS 24 / NOT_RUN 1. check:baseline holds. check:corpus passes on every run, and --write agrees across its runs.

  • RKOI re-review: APPROVED.

  • CI on this PR

🤖 Generated with Claude Code

This addresses the RKOI review of the golden corpus v2 (#20).

GENESISRAG17-RECEIPTS now demonstrates each of its assertions:

- Wrong-hash, forged-stage, other-tenant, mismatched-scope and wrong-role
  graph receipts run before any receipt exists, so each is refused by its
  own check, and the refusal message is annotated.
- After acceptance, an identical graph receipt is idempotent and a
  different one is a conflict.
- Publishing before the quality gate is refused.
- After a Stage 15 failure, the worker receipt is refused because the
  execution is terminal, the gate fails and publication is refused. The
  public evidence export and the store both show stages 9-14 SUCCEEDED,
  15 FAILED and 17 FAILED.

Normalization is narrowed so it cannot hide a regression:

- Instants are normalized only inside the run's wall-clock window.
- Durations and hashes the request itself carried stay literal. Worker
  durations are distinctive values, and the runner rejects any request
  duration under 1000 ms.
- The runner recomputes decision, graph, worker and publication hashes with
  the contract functions GKS uses.
- --write refuses a labelled value that is identical in both of its runs.

Other runner changes:

- A graceful stop must exit cleanly, the store path must not leak, and
  --case requires an id.
- The legacy default portfolio differs from every explicit scope.
  AUTH-DENIAL covers both a scope-less and an explicit-scope envelope.
- The manifest records productSha and corpusSha separately.

better-sqlite3 is declared as a root devDependency: the runner and 12 test
files import it from the root. The baseline lock is re-locked.

No product code changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Freshair129
Freshair129 merged commit 0344f33 into main Sep 27, 2026
14 checks passed
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