Repository navigation
fix(OMN-18978): union caller criteria with the task class definition of done, and never lose a terminal to a validation failure - #2742
Merged
jonahgabriel merged 2 commits intoSep 21, 2026
Conversation
…ver lose a terminal to a ValidationError A caller naming a criterion its task class already declares produced two evaluations of one rule. The terminal DTO refuses that, so the terminal could not be constructed, nothing was published, and the caller waited out its whole 240-second handler budget for a synthesized timeout carrying an empty attempt list. Both halves land together because either one alone leaves a silent hang: the merge now unions by rule name, and terminal construction now degrades to a typed failure terminal instead of propagating.
|
| 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 |
ARCH-DI-002: Direct Handler instantiation (warning)\n\n```\nsrc/omnimarket/nodes/node_delegation_orchestrator/handlers/handler_delegation_workflow.py:980: loop = HandlerComplianceLoop()
src/omnimarket/nodes/node_delegation_orchestrator/handlers/handler_delegation_workflow.py:1753: HandlerEscalationDecision()\n```\n\nHandler classes should be wired only in workflow_runner.py or adapter modules. Direct instantiation elsewhere bypasses the contract system.\n\n
Static architectural lint — no model inference (OMN-14176).
jonahgabriel
enabled auto-merge (squash)
September 21, 2026 08:29
onexbot-occ-writer Bot
added a commit
to OmniNode-ai/onex_change_control
that referenced
this pull request
Sep 21, 2026
…nimarket#2742 The declared checks were executed for real in the OmniNode-ai/omnimarket checkout at the PR head by the product-repo OCC receipt runner, and the results written append-only into this companion. Producer-minted PENDING receipts are superseded by a net-new record; no existing receipt was edited. Ticket: OMN-16859 (AC3b) Onex-Workflow: OCC Receipt Runner Onex-Run: https://github.com/OmniNode-ai/omnimarket/actions/runs/35578123280
✅ Hostile Reviewer — PASSEDBlocking findings (critical/error): 0 Gate semantics
Powered by omniintelligence.review_pairing.cli_review — node-based adversarial review via HandlerLlmCliSubprocess (OMN-8524) |
jonahgabriel
pushed a commit
to OmniNode-ai/onex_change_control
that referenced
this pull request
Sep 21, 2026
…imarket#2742 (#10651) * evidence(OMN-18978): author OCC companion for OmniNode-ai/omnimarket#2742 OCC companion by node_pr_lifecycle_fix_effect (OMN-13317 F1 / OMN-13990 / OMN-14285). Product PR head 29d6319a68e0929a9655cdf2dfe1eacc491e7b65. * evidence(OMN-18978): self-bind OCC#10651 + rebind contract_sha256 * evidence(OMN-16859): executed test_passes receipts for OmniNode-ai/omnimarket#2742 The declared checks were executed for real in the OmniNode-ai/omnimarket checkout at the PR head by the product-repo OCC receipt runner, and the results written append-only into this companion. Producer-minted PENDING receipts are superseded by a net-new record; no existing receipt was edited. Ticket: OMN-16859 (AC3b) Onex-Workflow: OCC Receipt Runner Onex-Run: https://github.com/OmniNode-ai/omnimarket/actions/runs/35578123280 --------- Co-authored-by: omnimarket-bot <bot@omninode.ai> Co-authored-by: onexbot-occ-writer[bot] <307849072+onexbot-occ-writer[bot]@users.noreply.github.com>
…criteria-and-terminal-failsafe # Conflicts: # src/omnimarket/nodes/node_delegation_quality_gate_reducer/handlers/handler_quality_gate.py
jonahgabriel
deleted the
jonah/omn-18978-union-criteria-and-terminal-failsafe
branch
September 21, 2026 09:12
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
OMN-18978
A caller naming an acceptance criterion that its task class already declares as part of
its definition of done got that rule evaluated twice. The terminal event model refuses a
rule recorded more than once, so the terminal could not be constructed at all, nothing
was published, and the caller waited out its whole 240-second handler budget before a
synthesized timeout arrived reporting zero attempts for a run that had dispatched five
times and been decided.
Measured end to end on the dev lane, correlation
e379a4b9-8fbc-4408-b277-07ec32ac1876:five rungs ran, five models answered inside 37 seconds, the quality gate refused every
one at 0.373 against a bar of 0.800, and at the exact second of the final decision the
runtime logged a validation error saying rule evaluations must record each rule at most
once. Then 196 seconds of silence.
Both halves land together, because either one alone still leaves a silent hang.
1. The merge unions by rule name
handler_quality_gate.deltaconcatenated three sequences: the class's deterministicrules, its heuristic rules, and the caller's criteria. A name appearing in two of them
produced two evaluations. It now unions them, under two deliberate policies:
criterion does not promote it to blocking, because the caller named a rule, not an
enforcement tier, and letting a caller escalate one would silently make the bar
stricter than the contract the response is graded against.
asking for a veto gets the veto.
A criterion naming no declared rule still joins the deterministic set, unchanged, which
is what makes the flag mean anything. There is a positive control for that, because a
fix that silently discarded the caller's criteria would pass every dedup assertion and
defeat the feature.
2. Terminal construction degrades instead of propagating
The duplicate is fixed above, but the silence is the other half and it generalises: any
future rejected field reproduces the same 240-second wait. So the guard is written
against terminal CONSTRUCTION, not against this one field. A validation failure there
now publishes a typed failure terminal carrying the run's identity, its answer, and a
reason naming both the validation error and the workflow it happened to, and logs at
error under a countable metric name.
The degraded terminal is deliberately narrow. It is emitted as failed even where the run
had been decided completed, because a terminal whose evidence fields could not be
constructed cannot honestly claim it was graded and passed. It states no cost and no
token count, so it cannot become a second, divergent writer of a row the single-builder
invariant protects, and that property is asserted structurally rather than trusted. It
never borrows one of the provider-side failure causes, none of which is true here.
Both directions proven against the pre-image at
origin/dev, path-scoped, no sharedstate touched.
Part 1, the merge, before the fix:
Part 2, the guard, same inputs on the pre-image and then with the fix:
Local: 375 passed, 1 skipped across the 44 test modules touching acceptance criteria,
the contract mode, the terminal builder or rule evaluations. Full lint, format and strict
type check clean. All hooks green.
The single-builder structure test was amended rather than relaxed: it now admits exactly
one additional construction site and pins that it passes no measured cost or token field,
which is the property that invariant actually protects.
Not done here
The lane readback with a fresh overlapping-criteria delegate is owed and is blocked on
an unrelated broken state in the shared canonical clone, which has taken the CLI down on
the launching host. Reported to the coordinator; it needs its owner, not a workaround
from this lane.
Evidence-Ticket: OMN-18978
Evidence-Source: OCC#10651