Repository navigation
fix(OMN-18956): require receipt evidence only where the request demanded it - #3896
Conversation
…ded it _require_completed_terminal_evidence documents itself as refusing a completed receipt that lacks evidence its request required, and its only caller passed both flags as literal True. So every completed delegation had to carry budget_evidence and response_contract_evidence, which no caller asked for and the deployed producer emits for neither. Measured on the dev lane: correlation 0b21b5f0-fb56-4ab6-9219-24bbfd841f35 reached a completed terminal, passed its quality gate at 1.0 and wrote its projection row, and the CLI still exited non-zero. Every lane brief in this session cites a delegate receipt, so an exit status that disagrees with the terminal makes a caller read success as failure. The check is untouched and still refuses. What changes is who arms it: a response contract in the request arms the contract half, and nothing arms it when no contract was asked for. The budget half returns False because nothing a caller can pass expresses that demand today, the comparison happening only where a backend declares its own input budget; the parameter stays so a future demand has one place to land. Third surface of the same change as the two OMN-18924 fixed, all three from omnibase_infra#3882. Positive controls assert the refusal still fires on each half when asked, so this cannot have quietly become a no-op.
#10616) * evidence: OCC companion pass 1 for OmniNode-ai/omnibase_infra#3896 * evidence: OCC companion self-bind for #10616 --------- Co-authored-by: node-occ-companion-effect <occ-companion-effect@omninode.ai>
There was a problem hiding this comment.
Hostile Reviewer — adversarial findings (OMN-17492)
Models succeeded: glm-review
Models failed: codex
New finding threads: 0
Deduped (already posted on this PR): 0
Below quorum (one model only, reported not threaded): 5
Nit-level findings suppressed: 1
The model is the FINDER, never the gate: merge is gated only by the
deterministic Hostile Review Thread Gate, which blocks while
hostile-reviewer threads are unresolved. Resolve each thread after
addressing (or rejecting, with a reply) its finding.
Below quorum: 5 finding(s) raised by one model only (OMN-18479)
These are reported and NOT dropped, but they get no thread and do not block: a single model's finding no other model reproduced is not evidence enough to stop a merge. Read them; act on them if they are right.
- [CRITICAL]
src/omnibase_infra/cli/cli_delegate.py, _receipt_evidence_requirements(glm-review) — Contract evidence demanded but producer reportedly never emits it | The docstring states the deployed producer emits neither budget_evidence nor response_contract_evidence. Yet _receipt_evidence_requi - [MAJOR]
tests/unit/cli/test_receipt_evidence_only_when_requested_omn18956.py(glm-review) — No test exercises the new call-site wiring | The tests validate _require_completed_terminal_evidence (unchanged code) and _receipt_evidence_requirements in isolation. Nothing verifies that run_delegat - [MINOR]
src/omnibase_infra/cli/cli_delegate.py(glm-review) — Dead parameter retained on speculative future demand | require_budget_evidence is threaded through _delegate_receipt_evidence_error and the call site while the derivation always returns False. The doc - [MINOR]
src/omnibase_infra/cli/cli_delegate.py, _receipt_evidence_requirements(glm-review) — Any non-None response_contract arms the check, including empty or placeholder contracts | The predicate treats dict as a boolean proxy for 'a contract was asked for.' A caller passing an empty dict {} - [MINOR]
docker/runners/runner-image.lock.json(glm-review) — Lock digests rotated in same PR with no stated provenance | identity_digest and shared_env_digest change with no accompanying change to the inputs (shared_env_install_args is unchanged) and no comment
|
| Surface | Meaning | Blocks merge? |
|---|---|---|
| Review threads | Per-finding, posted by the reviewer | No (informational) |
Hostile Review Thread Gate |
Deterministic: unresolved hostile-reviewer threads exist | Fails until resolved (not yet a required context) |
degraded verdict |
Fewer than 2 models succeeded (infra) | No |
Powered by omniintelligence.review_pairing.cli_review — multi-model adversarial review: qwen3-review, qwen3-review-b, glm-review (OMN-8468/OMN-8524/OMN-17492)
…frozen receipt The unit module proves the predicate. The failure was one layer out, at the entry the CLI actually wires as receipt_validator, which walks a receipt to its terminal through two receipt shapes and two carrier shapes before asking the question. A fix proven at the leaf can still be wrong there. Adds the verbatim envelope from correlation 0b21b5f0-fb56-4ab6-9219-24bbfd841f35 as a frozen capture and drives the entry point over it: the lane's own terminal is accepted, the same terminal is still refused when a contract was requested and its evidence is absent, and a requested contract that was answered passes. The capture is deliberate. The first draft hand-built what I believed the envelope looked like and the validator answered that it carried no delegation terminal; my shape was wrong, and the contract-evidence object I invented was refused by the model for three separate reasons before it was right. A test written against a believed shape proves nothing about the artifact, which is the same class of error as the outage this sits under. Carries a positive control asserting the capture really is a completed terminal with neither kind of evidence, so the other three cannot pass against a capture that quietly became something else.
…t-evidence-only-when-requested # Conflicts: # docker/runners/runner-image.lock.json # pyproject.toml # uv.lock
There was a problem hiding this comment.
Hostile Reviewer — adversarial findings (OMN-17492)
Models succeeded: glm-review
Models failed: codex
New finding threads: 0
Deduped (already posted on this PR): 0
Below quorum (one model only, reported not threaded): 5
Nit-level findings suppressed: 2
The model is the FINDER, never the gate: merge is gated only by the
deterministic Hostile Review Thread Gate, which blocks while
hostile-reviewer threads are unresolved. Resolve each thread after
addressing (or rejecting, with a reply) its finding.
Below quorum: 5 finding(s) raised by one model only (OMN-18479)
These are reported and NOT dropped, but they get no thread and do not block: a single model's finding no other model reproduced is not evidence enough to stop a merge. Read them; act on them if they are right.
- [MAJOR]
src/omnibase_infra/cli/cli_delegate.py, _receipt_evidence_requirements(glm-review) — Budget evidence enforcement is now globally unreachable | The previous behavior enforced budget_evidence on every completed terminal. The new derivation returns require_budget_evidence=False unconditi - [MAJOR]
tests/fixtures/delegation/omn18956/completed_terminal_no_evidence.json(glm-review) — Frozen capture fixture embeds infrastructure details and credential material | The verbatim log capture committed as a test fixture contains the tailnet hostname and Kafka broker endpoint (omninode-pc - [MAJOR]
src/omnibase_infra/cli/cli_delegate.py(glm-review) — The production wiring path is never tested | The integration tests were written precisely because the failure occurred 'one layer out', at the receipt-validator wiring. Yet no test exercises run_deleg - [MINOR]
src/omnibase_infra/cli/cli_delegate.py, run_delegate(glm-review) — Tuple index access for a two-value semantic pair | receipt_evidence_demanded[0] and [1] at the call site rely on positional knowledge of an undocumented tuple. A future reorder or third element breaks - [MINOR]
src/omnibase_infra/cli/cli_delegate.py, _receipt_evidence_requirements(glm-review) — Empty dict response_contract arms the contract-evidence requirement | The predicate is response_contract is not None, so response_contract={} arms the requirement. If an empty dict is a legitimate 'no
A delegation that fully succeeds exits non-zero. This makes the exit status agree with the terminal.
What happens today
_require_completed_terminal_evidencedocuments itself as refusing "a completed receipt that lacks evidence its request required", and its only caller passed both flags as literalTrue. So every completed delegation was required to carry budget evidence and response-contract evidence, which no caller asked for and the deployed producer emits for neither.Measured on the dev lane, correlation
0b21b5f0-fb56-4ab6-9219-24bbfd841f35: the terminal wascompleted, the quality gate passed at 1.0, the projection row was written, and the CLI still exited non-zero. Nothing about the delegation failed; the receipt assertion did.That is not cosmetic here. Every lane brief in this session cites a delegate receipt, so a caller branching on exit status reads success as failure, while a caller reading the terminal reads it correctly. Two readers of the same run disagreeing is the defect.
What changes, and what deliberately does not
The check itself is untouched and still refuses. What changes is who arms it. A response contract in the request arms the contract half; nothing arms it when no contract was asked for, because a run that asked for no contract has no contract to evidence and refusing it asserts a requirement nobody stated.
The budget half returns false, and the reason is worth stating rather than leaving as a default. Nothing a caller can pass expresses "I require budget evidence": the comparison happens only where the backend declares its own input-token budget, which is not knowable when the request is built. There is no honest request-side predicate to return. It is returned as a value rather than dropped, so the day a demand exists it has exactly one place to land, and the refusal stays armed either way.
Why this cannot have quietly become a no-op
That is the obvious risk in relaxing a gate, so it is the thing under the most test. Three positive controls assert the refusal still fires: on the contract half alone, on the budget half alone, and on both together with each named in one message. A fourth pins that a non-completed terminal is still never refused here, so the guard cannot widen onto it.
The derivation is also read directly rather than only through behaviour, so an edit back to a literal
Trueis a red test rather than another silent outage.Context
Third surface of the same change as the two fixed under the parent, all three from
#3882: a consumer-side requirement landing ahead of the producer that satisfies it. The first refused the CLI before dispatch, the second terminalized every lane delegation, and this one only disagrees about the exit code. Severity descends across the three and they should not be read as equivalent.Local: 746 tests green in
tests/unit/cli/,mypy --strictclean,ruffclean, whole-tree hooks green, runner image identity regenerated because the version bump restales it.Owed
The lane readback: a fresh delegate whose exit status is zero on a completed terminal. It needs this merged and the dispatch venv reconciled, and it is cited on the ticket when taken.
Evidence-Ticket: OMN-18956
Evidence-Source: OCC#10616