KB-50F0

C1 Staging Codex R3 Fixes — Codex-Style Hostile Self-Review

4 min read Revision 1
c1stagingcodex-r3-fixesready-for-r42026-06-23

08 — CODEX-STYLE HOSTILE SELF-REVIEW (A1–A12)

Each attack is refuted with code evidence and, where applicable, read-only empirical proof.

# Attack Verdict Evidence
A1 P3 writes P3_DONE then fatal gate fails REFUTED p3 gate(70) < DONE(85) < COMMIT(86), one BEGIN(10); gate RAISE → txn rollback → no c1_vocab_build row.
A2 P4 writes P4_DONE then fatal gate fails REFUTED p4 gate(27) < DONE(45) < COMMIT(46), one BEGIN(9).
A3 P5 writes P5_DONE then fatal gate fails REFUTED p5 gate(54) < DONE(68) < COMMIT(69), one BEGIN(15).
A4 P6 sees DONE rows but canonical set is wrong REFUTED P6 step 2: count=3 AND extra IS NULL AND missing IS NULL. Live proof: count=3 wrong-set flags extra=C1.WRONG + missing=C1.VERIFY_DIGEST.
A5 P6 sees P5_DONE but harness rows missing REFUTED P6 step 5: total=9 + joined_n=9. Live F3 (case7 missing) → total=8 → RAISE.
A6 P6 sees P5_DONE but bad case accepted REFUTED P6 step 5: accepted=0 + verdict requires outcome='rejected'. Live F1 → indep_pass=8, disagree=1.
A7 P6 sees P4_DONE but P4 invariant rows missing REFUTED P6 steps 3+4 recompute nvalid=3, field+mode invariants from canonical_operation directly (CASE-guarded).
A8 Digest excludes harness rows REFUTED c1_digest serializes c1_test_resultsharness_md5 + harness segment of combined_md5.
A9 Digest excludes P4 verification facts REFUTED vops now includes per-op evidence (P4 verify result) + status.
A10 P6_DONE commits after partial upstream success REFUTED Fix A: partial success ⇒ a Pn DONE stamp is absent ⇒ P6 step 1 RAISE; gate+digest+ledger one txn — no commit on RAISE.
A11 Ledger/stamp says DONE but no matching verified facts REFUTED Core Fix B: P6 re-derives all facts; stored pass not trusted. Live F2 (pass=true, wrong code) → P6_FATAL_PASS_TAMPER.
A12 Failure after DONE leaves committed false success REFUTED DONE is last write before COMMIT (atomic); P6 verdict only post-gated-commit; bin prints P6_DONE only on psql exit 0; plan emits DRY_RUN_OK only after P2 RETIRED_OK + count=0.

No attack left unrefuted. No HOLD.

Additional defects Claude found during self-review (beyond the literal Codex R3 blocker)

  1. OR / jsonb_array_length non-short-circuit reliance. The existing validation uses jsonb_typeof(x)<>'array' OR jsonb_array_length(x)<1; PostgreSQL does not guarantee OR short-circuit. Empirically PG16.13 short-circuits at runtime (so the existing trigger works — column ref, not const-folded), so the byte-identical trigger was left unchanged; but the NEW P6 field checks use documented-safe CASE guards so jsonb_array_length is never evaluated on a non-array.
  2. Duplicate-key JSON forgery. A raw --owner can inject a duplicate "op" key producing valid-but-forged JSON that jq accepts (last-wins). So a jq-verify alone would not stop forgery — the escaping is essential. Both are applied (#4).
  3. psql interpolation gotcha. Confirmed read-only that :var is inert inside single-quoted and dollar-quoted strings, so the existing p5 JSON literals and the new DO $g$ body are safe; the intended :'sbx'/:'operator' substitutions are all outside quotes.

Codex R3 required-fixes #3/#4 (not the headline blocker, but listed by Codex)

Both addressed (see 07) to ensure a clean R4 rather than a re-reject.

Back to Knowledge Hub knowledge/dev/laws-new/reports/c1-staging-codex-r3-fixes-ready-for-r4/08-codex-style-self-review.md