Skip to content

fix(OMN-16859): OCC receipts are filed under the check_type their contract item declares - #2195

Merged
jonahgabriel merged 1 commit into
devfrom
jonah/omn-16859-occ-checktype-receipt-agreement
Aug 29, 2026
Merged

jonahgabriel merged 1 commit into
devfrom
jonah/omn-16859-occ-checktype-receipt-agreement

Conversation

@jonahgabriel

@jonahgabriel jonahgabriel commented Aug 29, 2026 •

Copy link
Copy Markdown
Contributor

OMN-16859 — OCC receipts are filed under the check_type their contract item declares

Closes 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_compute declares the OMN-16434 diff-derived behavior proof as
check_type: "test_passes" but hardcoded command at three places — the receipt
head template, the receipt filename, and the supersession record. validator_occ_merge_eligibility
resolves an item's receipt at drift/dod_receipts/<ticket>/<item>/<check_type>.yaml
and keys it <ticket>:<item>:<check_type>, so the minted command.yaml was
unreachable and occ-preflight returned reason=missing_receipt.

The supersede half is worse than misnaming: resolve_supersession globs
<check_type>.supersede.*.yaml and then key-validates the record's own check_type
field against the key it is filed under, so a record hardcoded to command for a
test_passes item is never a candidate and the rebind to the 2nd consumer PR
silently 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_control contract_compliance_check._check_test_passes is an executed
alias
of command — it runs check_value and reads its exit status — and
node_dod_verify always did. So test_passes is an honest statement about a check the
OCC runner really runs, and derive_proof_tier keys that type to tier L1. Downgrading
the 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) already
made in the same file, kept deliberately consistent.

What changed

  • occ_evidence_stamp.py — render_compute_receipt takes check_type (default "command",
    so every pre-existing caller renders byte-identically); both head templates substitute it.
  • handler_occ_companion_compute.py
    • declared_check_value_for → declared_check_for, returning (check_type, check_value) from the
      same 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).
    • Mint path: behavior item declares and files under test_passes; the admissibility slot stays command.
    • Supersede path: filename, record check_type, and supersedes: target all derive from the
      superseded item's own declared type.
  • New invariant assert_receipt_keys_match_declarations, placed beside the existing
    assert_append_only_emissions as the last gate before the plan escapes the pure core. This is
    AC2 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 ≡ declared check_type) on every path, and
    completeness (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 files itself, no new I/O seam.

Scope honesty — what this does NOT do

  • AC3 (receipt honesty) is NOT closed here. The test_passes receipt still records
    status: PASS with a gh pr view probe_command. That is deliberate, not overlooked: this
    producer 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_output names
    which surface executes the check. AC3 needs a separate decision (OWED-status receipt vs. a
    product-repo runner) and should stay open on the ticket.
  • AC4 honored — the four hand-authored receipts are left in place.

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, including
test_core_resolve_supersession_finds_the_rebind, which drives core's real resolve_supersession
over 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 and
cited here as the fifth and last occurrence. See the companion-evidence comment below.

Gates

  • ruff format + ruff check clean; mypy --strict — Success, 3071 source files
  • pre-commit run --all-files — exit 0, 76 hooks
  • Governed pre-push selector suite: 8164 passed, 53 skipped, 1 xfailed (532s).
    Serialized through heavy_lock.py under genuine contention (three peer lanes cycled through
    the lock; waits >2200s observed). Selector never bypassed, PREPUSH_FULL_SUITE never set.

Evidence-Ticket: OMN-16859
Evidence-Source: OCC#7498

Summary by CodeRabbit

  • Bug Fixes

    • Corrected evidence receipt filenames and contents to match each item’s declared check type.
    • Behavior-proof receipts now use test_passes.yaml, while command-based receipts retain command.yaml.
    • Improved supersession handling so updated evidence remains correctly linked.
    • Added validation to detect mismatched or missing receipts before plans are finalized.
  • Tests

    • Added coverage for receipt consistency, completeness, and supersession scenarios.

…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.
@coderabbitai

coderabbitai Bot commented Aug 29, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9202a737-99b7-48df-b5b8-2662fa4dc370

📥 Commits

Reviewing files that changed from the base of the PR and between a131114 and 7921eff.

📒 Files selected for processing (4)
  • src/omnimarket/nodes/node_occ_companion_compute/handlers/handler_occ_companion_compute.py
  • src/omnimarket/nodes/node_pr_lifecycle_fix_effect/handlers/occ_evidence_stamp.py
  • tests/unit/nodes/node_occ_companion_compute/test_autobind_diff_derived_behavior_proof_omn_16434.py
  • tests/unit/nodes/node_occ_companion_compute/test_occ_receipt_checktype_agreement_omn_16859.py

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.


📝 Walkthrough

Walkthrough

Receipt generation now preserves declared evidence check_type values in filenames and payloads. Companion-plan production validates receipt keys and completeness. Supersession handling supports typed receipts, including test_passes.yaml, while retaining command behavior.

Changes

Receipt key agreement

Layer / File(s) Summary
Typed receipt contracts
src/omnimarket/nodes/node_pr_lifecycle_fix_effect/handlers/occ_evidence_stamp.py, src/omnimarket/nodes/node_occ_companion_compute/handlers/handler_occ_companion_compute.py
Receipt rendering accepts check_type. Contract parsing returns normalized check types and values, with command as the default.
Producer validation and supersession
src/omnimarket/nodes/node_occ_companion_compute/handlers/handler_occ_companion_compute.py
Plan generation validates receipt paths, recorded types, contract declarations, and required receipt coverage. Minting and supersession receipts use item-specific check types.
Receipt agreement coverage
tests/unit/nodes/node_occ_companion_compute/test_autobind_diff_derived_behavior_proof_omn_16434.py, tests/unit/nodes/node_occ_companion_compute/test_occ_receipt_checktype_agreement_omn_16859.py
Tests verify test_passes and command receipt behavior, completeness validation, supersession metadata, and core supersession resolution.

Estimated code review effort: 4 (Complex) | ~60 minutes

Merge Risk: ⚪ Minimal · up to 7921e

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
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 76.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 25 functions across 4 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: OCC receipts now use the contract-declared check_type for filing.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch jonah/omn-16859-occ-checktype-receipt-agreement

Comment @coderabbitai help to get the list of available commands.

@onexbot

onexbot Bot commented Aug 29, 2026

Copy link
Copy Markdown

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 node_occ_companion_effect (decline code already_bound, OMN-16665). This decision was made against the PR's LIVE state at compute time, not at publish time — a green publisher job only means the command reached the broker.

@github-actions

Copy link
Copy Markdown

✅ Hostile Reviewer — PASSED

Blocking findings (critical/error): 0
Total findings: 0
Models succeeded: qwen3-review,qwen3-review-b


Gate semantics

Verdict Meaning Blocks merge?
passed >=2 models succeeded, no critical/error findings No
blocked CRITICAL or ERROR findings found Yes
degraded Fewer than 2 models succeeded (infra unavailable/timeout) Yes (OMN-15110)

Powered by omniintelligence.review_pairing.cli_review — node-based adversarial review via HandlerLlmCliSubprocess (OMN-8524)

@jonahgabriel
jonahgabriel enabled auto-merge (squash) August 29, 2026 01:50
@github-actions

Copy link
Copy Markdown

✅ Architectural Review — PASSED

Errors: 0
Warnings: 0

What this checks

Rule Description
ARCH-TOPIC-001 No hardcoded Kafka topic strings in handler code
ARCH-DI-001 No event_bus=None bypass
ARCH-DI-002 No direct Handler instantiation outside workflow_runner/adapters
ARCH-DI-003 No reinvented DI containers
ARCH-TOPIC-002 contract.yaml topics follow `onex.{cmd

No architectural violations found.

Static architectural lint — no model inference (OMN-14176).

jonahgabriel pushed a commit to OmniNode-ai/onex_change_control that referenced this pull request Aug 29, 2026
…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>
@jonahgabriel
jonahgabriel merged commit 482648e into dev Aug 29, 2026
120 checks passed
@jonahgabriel
jonahgabriel deleted the jonah/omn-16859-occ-checktype-receipt-agreement branch August 29, 2026 02:29
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