Repository navigation
fix(OMN-16859): OCC receipts are filed under the check_type their contract item declares - #2195
Conversation
…tract item declares `node_occ_companion_compute` declares the OMN-16434 diff-derived behavior item as `check_type: "test_passes"` and then writes its receipt at `<item>/command.yaml`. `validator_occ_merge_eligibility` reads an item's receipt at `drift/dod_receipts/<ticket>/<item>/<check_type>.yaml` and keys it `<ticket>:<item>:<check_type>`, so it looks for `:test_passes`, finds only the `:command` sibling, and returns `reason=missing_receipt`. The companion goes BLOCKED and, because OCC companions merge FIRST, the product PR goes with it. Four independent lanes hit this on 2026-08-28 alone -- OMN-16838 (omninode_infra#1040), OMN-16842 (omnibase_infra#2964 / OCC#7407), OMN-16844 (omnibase_infra#2965 / OCC#7409), OMN-16901 (omniclaude#2063 / OCC#7468, run 33213072645 job 98990549438) -- each re-diagnosing it from scratch because the failure text says "missing receipt" rather than naming the generator, and each hand-authoring the file the producer should have written. THE SECOND HALF, and the worse one. The SUPERSEDE renderer hardcoded `check_type="command"`, `supersedes=".../command.yaml"`, and the filename `command.supersede.<NNNN>.yaml`. `resolve_supersession` GLOBS `<check_type>.supersede.*.yaml` and then key-validates the record's own `check_type` against the key it is filed under, so a record filed under `command.` for a `test_passes` item is not merely misnamed -- it is never a candidate. The 2nd consumer's rebind silently does not apply and nothing reports it. Live: OCC#7465 `drift/dod_receipts/OMN-16442/dod-occ-diff-derived-behavior-proof/command.supersede.2192.yaml` against a contract entry declaring `test_passes`, minted 2026-08-28T21:25:23Z -- i.e. AFTER OMN-16892 fixed the born-path mint, which never touched this half. EMIT-MATCHING, NOT DECLARE-`command` -- decided at the consumer, not by convenience. Since OMN-16824 `contract_compliance_check._check_test_passes` (onex_change_control) is an EXECUTED alias of `command`: it runs `check_value` and reads its exit status, exactly like `command`, and `node_dod_verify` has always executed it and honoured `cwd`. So declaring `test_passes` is an honest statement about a check the OCC runner really does execute -- there is nothing false in the declaration, only in the path. `check_contract_substance_floor .derive_proof_tier` additionally keys `check_type == "test_passes"` to tier L1. Downgrading the declaration to `command` would discard the author's stated intent at both consumers to paper over a path bug, would diverge from the born-path producer OMN-16892 just fixed the other way, and would orphan the four hand-authored `test_passes.yaml` receipts already in the corpus (AC4 keeps them). The receipt follows the declaration; the declaration does not follow the receipt. WHAT CHANGED * `render_compute_receipt` takes `check_type` (default `"command"`, so every pre-existing caller renders byte-identically) and both compute-receipt head templates substitute it. The compute-producer twin of the parameter OMN-16892 added to the born path's `render_downstream_receipt`. * The mint slot derives `slot_check_type` alongside `slot_evidence_id` / `slot_check_value` from the same branch the contract renderer took, and the receipt path is `<slot_evidence_id>/<slot_check_type>.yaml`. * `declared_check_value_for` is now the value half of `declared_check_for`, which returns `(check_type, check_value)` from the SAME selected check. Returning only the value is what left the supersede caller with no type to supply but the constant `"command"`. * `_supersede_file` takes the superseded item's OWN declared type and uses it for the record's `check_type`, the `supersedes` pointer, the nested replacement receipt, and the emitted filename. THE MECHANISM, not a point fix. `assert_receipt_keys_match_declarations` sits beside `assert_append_only_emissions` as the last gate before the plan escapes the pure core, for the same reason that one does: this producer grew a new emission site in each of OMN-14742, OMN-15247, OMN-16434 and OMN-16892, and fixing today's two is a point fix. It enforces two invariants read off the consumers, not invented here: * AGREEMENT (every path): a receipt's path basename, its own recorded `check_type`, and the contract entry's declared `check_type` are one value at three sites. Any disagreement is either unreachable (wrong filename) or self-contradictory (right filename, wrong field); both read downstream as `missing_receipt`. * COMPLETENESS (fresh/all-adds contracts only): every declared item has an emission at its declared key, excusing an honestly-superseded item exactly as eligibility excuses it. Scoped to fresh contracts because on the merged path the plan is deliberately NOT the whole truth -- the 1st consumer's receipts are already merged and immutable and this plan re-binds them with net-new supersessions; demanding an emission there would refuse every legitimate 2nd-consumer companion. KNOWN RESIDUAL, exempted narrowly and named rather than silently allowed: the self-bind item is DECLARED whenever `occ_pr_number` is known but its receipt is minted only when `occ_probe` is also supplied, so a caller passing one without the other declares an item with no receipt. Same defect FAMILY, pre-existing, and a caller-shape gap rather than a producer key mismatch -- failing the whole mint closed on it would refuse a plan this producer has always emitted. PROOF New gate `tests/unit/nodes/node_occ_companion_compute/ test_occ_receipt_checktype_agreement_omn_16859.py`, 10 cases. RED-proven against exists-but-wrong: with `src/` stashed back to dev tip, 8 fail (7 new + the OMN-16434 assertion below) and 19 pass; with the fix, all pass. The consumer leg writes the producer's REAL output to disk and calls omnibase_core's `resolve_supersession` -- against dev tip it returns `None`, i.e. core cannot see the rebind at all. Controls hold in both directions: the OWED branch keeps `command.yaml` byte-for-byte and a `command` item keeps `command.supersede.<NNNN>.yaml`, so no existing merged receipt shape moves. `test_autobind_diff_derived_behavior_proof_omn_16434.py:: test_the_behavior_item_has_a_backing_receipt` asserted the literal `command.yaml` -- that is how the defect shipped green: it asked whether a receipt existed, never whether the consumer could resolve it. It now derives the key from the declaration so the pair cannot drift apart again. 600 passed / 18 skipped across `node_occ_companion_compute` + `node_pr_lifecycle_fix_effect` with `OCC_REPO_DIR` set, so the consumer-parity gates that need the sibling checkout actually executed (yamlfmt idempotency F-03, the substance floor, `lint-contract-check-values`, evidence admissibility). 6123 passed / 26 skipped / 1 xfailed on the full unit suite. `mypy --strict` clean, `pre-commit run --all-files` clean.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
Included review availability: 0 reviews are currently available. Your included PR review attempts over the past 7 days set your current allowance at 1 review per hour. 📝 WalkthroughWalkthroughReceipt generation now preserves declared evidence ChangesReceipt key agreement
Estimated code review effort: 4 (Complex) | ~60 minutes Merge Risk: ⚪ Minimal · up to This change aligns OCC receipt filenames and metadata with each contract item's declared check type and adds validation for that agreement. No actionable merge-blocking risk remains based on the supplied evidence; the PR is merge-ready after normal checks and review. Sequence Diagram(s)sequenceDiagram
participant Contract
participant compute_companion_plan
participant ReceiptRenderer
participant ReceiptStore
participant omnibase_core
Contract->>compute_companion_plan: declare evidence check_type
compute_companion_plan->>ReceiptRenderer: render typed receipt
ReceiptRenderer->>ReceiptStore: write matching receipt path and metadata
compute_companion_plan->>compute_companion_plan: validate receipt keys
omnibase_core->>ReceiptStore: resolve typed supersession receipt
ReceiptStore-->>omnibase_core: return supersession rebind
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
|
No OCC evidence companion was minted for this PR. this PR is already bound to OCC#7498; its evidence companion exists and nothing needs authoring To clear this: Nothing to do — the companion already exists. Reported by |
✅ Hostile Reviewer — PASSEDBlocking findings (critical/error): 0 Gate semantics
Powered by omniintelligence.review_pairing.cli_review — node-based adversarial review via HandlerLlmCliSubprocess (OMN-8524) |
✅ Architectural Review — PASSEDErrors: 0 What this checks
No architectural violations found. Static architectural lint — no model inference (OMN-14176). |
…imarket#2195 (#7498) * evidence(OMN-16859): author OCC companion for OmniNode-ai/omnimarket#2195 OCC companion by node_pr_lifecycle_fix_effect (OMN-13317 F1 / OMN-13990 / OMN-14285). Product PR head 7921efffa69b909997f100380eb3651081be408c. * evidence(OMN-16859): self-bind OCC#7498 + rebind contract_sha256 --------- Co-authored-by: omnimarket-bot <bot@omninode.ai>
OMN-16859 — OCC receipts are filed under the
check_typetheir contract item declaresCloses the generator half of OMN-16859. Four independent lanes hand-authored the same
missing receipt on 2026-08-28 (OMN-16838 / OMN-16842 / OMN-16844 / OMN-16901), each
paying a full CI round-trip with the product PR blocked behind its companion.
Root cause
node_occ_companion_computedeclares the OMN-16434 diff-derived behavior proof ascheck_type: "test_passes"but hardcodedcommandat three places — the receipthead template, the receipt filename, and the supersession record.
validator_occ_merge_eligibilityresolves an item's receipt at
drift/dod_receipts/<ticket>/<item>/<check_type>.yamland keys it
<ticket>:<item>:<check_type>, so the mintedcommand.yamlwasunreachable and occ-preflight returned
reason=missing_receipt.The supersede half is worse than misnaming:
resolve_supersessionglobs<check_type>.supersede.*.yamland then key-validates the record's owncheck_typefield against the key it is filed under, so a record hardcoded to
commandfor atest_passesitem is never a candidate and the rebind to the 2nd consumer PRsilently never applies. Live example: OCC#7465
.../OMN-16442/dod-occ-diff-derived-behavior-proof/command.supersede.2192.yaml,minted 21:25:23Z after OMN-16892 fixed the born-path mint.
Design: emit-matching, decided at the consumer
The receipt follows the declaration; the declaration was not downgraded to
command.Justification is downstream, not convenience: since OMN-16824,
onex_change_controlcontract_compliance_check._check_test_passesis an executedalias of
command— it runscheck_valueand reads its exit status — andnode_dod_verifyalways did. Sotest_passesis an honest statement about a check theOCC runner really runs, and
derive_proof_tierkeys that type to tier L1. Downgradingthe declaration would have lost real tier signal to work around a filename.
This is the compute-producer twin of the born-path decision OMN-16892 (
b4ffdff6) alreadymade in the same file, kept deliberately consistent.
What changed
occ_evidence_stamp.py—render_compute_receipttakescheck_type(default"command",so every pre-existing caller renders byte-identically); both head templates substitute it.
handler_occ_companion_compute.pydeclared_check_value_for→declared_check_for, returning(check_type, check_value)from thesame selected check. Returning only the value is precisely what left callers to supply the
constant
"command". The old name is kept as a thin wrapper (OMN-15459 API).test_passes; the admissibility slot stayscommand.check_type, andsupersedes:target all derive from thesuperseded item's own declared type.
assert_receipt_keys_match_declarations, placed beside the existingassert_append_only_emissionsas the last gate before the plan escapes the pure core. This isAC2 and is the load-bearing half: fixing today's three sites is a point fix — this producer grew a
new emission site in each of OMN-14742, OMN-15247, OMN-16434, OMN-16892. It enforces
agreement (basename ≡ recorded
check_type≡ declaredcheck_type) on every path, andcompleteness (every declared item has a receipt at its declared key) only on the fresh-contract
path — on the merged path the 1st consumer's receipts are already merged and immutable, so
demanding an emission there would refuse every legitimate 2nd-consumer companion. Purity preserved:
contract and receipts are read out of
filesitself, no new I/O seam.Scope honesty — what this does NOT do
test_passesreceipt still recordsstatus: PASSwith agh pr viewprobe_command. That is deliberate, not overlooked: thisproducer runs inside the OCC companion's CI against the GitHub API and has no product-repo
checkout, so it cannot execute the declared check. Writing a fabricated "N passed" would be
exactly the false-evidence class the Receipt Honesty Gate exists to catch.
actual_outputnameswhich surface executes the check. AC3 needs a separate decision (OWED-status receipt vs. a
product-repo runner) and should stay open on the ticket.
TDD red-first
tests/unit/nodes/node_occ_companion_compute/test_occ_receipt_checktype_agreement_omn_16859.py— 10 tests. Red proven by reverting only the two source files at
HEAD~1: 7 fail, includingtest_core_resolve_supersession_finds_the_rebind, which drives core's realresolve_supersessionover the OCC#7465 shape and fails with "core found no supersession record for the test_passes key —
the producer filed the rebind under a key nothing resolves". All 10 green with the fix.
The irony, stated on the record
This PR's own OCC companion is minted by the very generator being fixed — the deployed copy on
dev, not this branch. If it exhibits the defect, the receipt is hand-authored one final time andcited here as the fifth and last occurrence. See the companion-evidence comment below.
Gates
ruff format+ruff checkclean;mypy --strict— Success, 3071 source filespre-commit run --all-files— exit 0, 76 hooksSerialized through
heavy_lock.pyunder genuine contention (three peer lanes cycled throughthe lock; waits >2200s observed). Selector never bypassed,
PREPUSH_FULL_SUITEnever set.Evidence-Ticket: OMN-16859
Evidence-Source: OCC#7498
Summary by CodeRabbit
Bug Fixes
test_passes.yaml, while command-based receipts retaincommand.yaml.Tests