Repository navigation
fix(OMN-19817): the dispatch protocol declares no_escalation and the kwarg-parity reader resolves the consumer's TypedDict-typed splat - #4192
Conversation
…kwarg-parity reader resolves the consumer's TypedDict-typed splat omnimarket#2841 (OMN-18931) declared no_escalation on the consumer protocol and passes it as **_no_escalation_dispatch_kwargs(request), a module-level helper annotated to return a module-level TypedDict, so a released omnibase_infra port predating the keyword keeps working. The always-run consumer-kwarg-parity hook then failed 3 cases on every omnibase_infra commit: the protocol lacked the keyword (the implementation has accepted it since #4088), and the call-site reader failed closed on any splat. - ProtocolDelegationDispatchPort.dispatch gains no_escalation: bool = False. - The call-site reader resolves exactly that splat shape to the TypedDict's keys, records them as conditional (never counted as passed for direction 3), and still fails closed on every other splat. - A new assertion holds every keyword the call site can send, explicit or splatted, to what the protocol and implementation accept. Onex-Lane: kwarg-parity-fix-83 Onex-Session: 097bff177c7b49ccbb1b5aa566dacfd7
…ibase_infra#4192 (#11540) * evidence(OMN-19817): author OCC companion for OmniNode-ai/omnibase_infra#4192 OCC companion by node_pr_lifecycle_fix_effect (OMN-13317 F1 / OMN-13990 / OMN-14285). Product PR head 946239e98f75cfdd509cb89e9bb2f015ef0b2ed0. * evidence(OMN-19817): self-bind OCC#11540 + rebind contract_sha256 --------- Co-authored-by: omnimarket-bot <bot@omninode.ai>
There was a problem hiding this comment.
Hostile Reviewer — adversarial findings (OMN-17492)
Models succeeded: qwen3-review, gpt-oss-review
Models failed: none
New finding threads: 0
Deduped (already posted on this PR): 0
Below quorum (one model only, reported not threaded): 10
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: 10 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/tests/integration/runtime/test_delegation_dispatch_port_consumer_kwarg_parity.py, _typed_dict_splat_keys(qwen3-review) — Splat resolution silently ignores helper arguments, enabling false-negative parity | The new_typed_dict_splat_keysresolver accepts any call of the form**_helper(request)as long as_helperis - [MAJOR]
src/tests/integration/runtime/test_delegation_dispatch_port_consumer_kwarg_parity.py, _consumer_call_site_keywords(qwen3-review) — Conditional keys are subtracted from passed, but the subtraction is asymmetric and undocumented | In_consumer_call_site_keywords, the return is `_CallSiteKeywords(passed=frozenset(passed), conditio - [MAJOR]
src/omnibase_infra/runtime/protocols/protocol_delegation_dispatch_port.py(gpt-oss-review) — Added positional parameter shifts existing call signatures | The newno_escalationargument is inserted beforeresponse_contractin thedispatchfunction signature. Callers that invoke `dispatch - [MAJOR]
src/omnibase_infra/runtime/protocols/protocol_delegation_dispatch_port.py(gpt-oss-review) —no_escalationflag is accepted but never used | The addedno_escalationparameter is part of the public API but the function body does not reference it. Consumers may set the flag expecting the ru - [MINOR]
src/tests/integration/runtime/test_delegation_dispatch_port_consumer_kwarg_parity.py, _consumer_call_site_keywords(qwen3-review) — AST-based static analysis of consumer source is brittle and can be bypassed by obfuscation | The entire parity check relies onast.parseof the consumer's source file. This is a static analysis that - [MINOR]
src/tests/integration/runtime/test_delegation_dispatch_port_consumer_kwarg_parity.py, _OPAQUE_SPLATS(qwen3-review) — No test for the case where the TypedDict has zero keys | The_typed_dict_splat_keysfunction raises anAssertionErrorifnot keys, but there is no test case in_OPAQUE_SPLATSfor a TypedDict w - [MINOR]
src/tests/integration/runtime/test_delegation_dispatch_port_consumer_kwarg_parity.py, _SPLAT_HELPER_SOURCE(qwen3-review) — The resolver does not handle TypedDict withtotal=True(the default) | The test source_SPLAT_HELPER_SOURCEusesclass _Kwargs(TypedDict, total=False):. The resolver checks that the base is `Typ - [MINOR]
src/omnibase_infra/runtime/protocols/protocol_delegation_dispatch_port.py(gpt-oss-review) — Missing docstring for newno_escalationargument | The new keyword is introduced without any inline documentation explaining its purpose, default behavior, or interaction with existing escalation me - [MINOR]
tests/integration/runtime/test_delegation_dispatch_port_consumer_kwarg_parity.py(gpt-oss-review) — Integration tests perform extensive AST parsing for each run | The new test suite parses consumer source files with theastmodule for every test case, which can noticeably increase CI execution tim - [MINOR]
tests/integration/runtime/test_delegation_dispatch_port_consumer_kwarg_parity.py(gpt-oss-review) — Tests rely on source‑file location and exact string replacements | The test suite constructs temporary consumer files by performing string replacements on a base source snippet. Any change to formatti
✅ Hostile Reviewer — REVIEWEDCritical findings: 0
Semantics (OMN-17492 — the model finds, thread resolution gates)
Powered by omniintelligence.review_pairing.cli_review — multi-model adversarial review: qwen3-review (Qwen3.8-27B), gpt-oss-review (gpt-oss-120b) (OMN-8468/OMN-8524/OMN-17492) |
There was a problem hiding this comment.
Hostile Reviewer — adversarial findings (OMN-17492)
Models succeeded: qwen3-review, gpt-oss-review
Models failed: none
New finding threads: 0
Deduped (already posted on this PR): 0
Below quorum (one model only, reported not threaded): 10
Nit-level findings suppressed: 0
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: 10 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/tests/integration/runtime/test_delegation_dispatch_port_consumer_kwarg_parity.py(qwen3-review) — Splat resolution ignores helper arguments, enabling false-negative parity | The new_typed_dict_splat_keysresolver treats any call to a module-level helper returning a TypedDict as resolvable, but - [MAJOR]
src/tests/integration/runtime/test_delegation_dispatch_port_consumer_kwarg_parity.py(qwen3-review) — Resolver does not handle forward references or string annotations for TypedDict | The resolver_typed_dict_splat_keyshandlesast.Nameandast.Constant(string) annotations for the helper's retu - [MAJOR]
src/omnibase_infra/runtime/protocols/protocol_delegation_dispatch_port.py(gpt-oss-review) — Added no_escalation parameter is never used | The dispatch function signature now includes a no_escalation boolean flag with a default value, but the implementation does not reference this argument. C - [MAJOR]
src/omnibase_infra/runtime/protocols/protocol_delegation_dispatch_port.py(gpt-oss-review) — Signature change not reflected in RuntimeDelegationDispatchPort | The protocol definition now accepts a no_escalation keyword, but the RuntimeDelegationDispatchPort implementation is unchanged in this - [MINOR]
src/omnibase_infra/runtime/protocols/protocol_delegation_dispatch_port.py(qwen3-review) — No security vulnerability, but fail-closed posture is correct | The change introduces a static analysis tool that resolves TypedDict splats. The fail-closed posture (raising AssertionError on unresolv - [MINOR]
src/tests/integration/runtime/test_delegation_dispatch_port_consumer_kwarg_parity.py(qwen3-review) — Test for opaque splats uses string replacement, which is fragile | The testtest_splat_reader_still_fails_closed_on_every_other_splatuses string replacement on_SPLAT_HELPER_SOURCEto create vari - [MINOR]
src/tests/integration/runtime/test_delegation_dispatch_port_consumer_kwarg_parity.py(qwen3-review) — Static analysis in tests couples test to consumer's internal implementation | The testtest_runtime_port_accepts_every_keyword_the_call_site_can_send_including_splatsreads the consumer's source cod - [MINOR]
tests/integration/runtime/test_delegation_dispatch_port_consumer_kwarg_parity.py(gpt-oss-review) — Duplicate definition of _consumer_passed_keywords | The test module defines _consumer_passed_keywords twice: an original implementation returning a set of passed keywords, and a later redefinition tha - [MINOR]
tests/integration/runtime/test_delegation_dispatch_port_consumer_kwarg_parity.py(gpt-oss-review) — AST parsing of consumer source in each test iteration | The helper _consumer_call_site_keywords parses the entire consumer source file with ast.parse for every test that invokes it. This adds unnecess - [MINOR]
tests/integration/runtime/test_delegation_dispatch_port_consumer_kwarg_parity.py(gpt-oss-review) — Signature inspection may include implicit parameters | The test test_runtime_port_accepts_every_keyword_the_call_site_can_send_including_splats obtains accepted parameters via inspect.signature(dispat
…erge Concludes the in-flight merge of origin/dev's queued omnimarket pin advance (OMN-17292, #4164) with the vendored session_content projection migration. Pulls the OMN-19817/#4192 dispatch-protocol no_escalation fix's own two files verbatim from dev's fix commit so the always_run consumer-kwarg-parity hook, unrelated to this PR's own diff, no longer blocks the commit. Onex-Lane: repo-drain-omnimarket-pr Onex-Session: 6166a1801d9e4059bc4a41476e0f1299
Summary
OMN-19817 (lineage: omnimarket#2841 and omnibase_infra#4088). Priority: this unblocks every omnibase_infra commit.
Since omnimarket#2841 merged at 2026-09-26T21:10Z, the always-run pre-commit hook
onex-delegation-dispatch-consumer-kwarg-parityhas failed 3 cases on every omnibase_infra commit, whatever the commit touches. omnimarket#2841 declaredno_escalationon the consumer'sProtocolDelegationDispatchPort.dispatchand passes it as**_no_escalation_dispatch_kwargs(request). That is a module-level helper annotated to return_NoEscalationDispatchKwargs(TypedDict, total=False), and it adds the keyword only when it is true.The splat is deliberate. The latest released omnibase_infra, v0.38.58, does not carry #4088, so an explicit
no_escalation=Falsewould raiseTypeErroron every delegation against a released port. For that reason the fix goes on this side and omnimarket is left alone.The hook failed for two reasons:
ProtocolDelegationDispatchPort.dispatchprotocol here did not declareno_escalation.RuntimeDelegationDispatchPort.dispatchhas accepted it and put it on the published payload since feat(OMN-18931): dogfood fault-pin admission and typed terminal-evidence capture (K1 infra, salvaged from #3951) #4088. The protocol was the only half that had not been updated.**splat.Changes
ProtocolDelegationDispatchPort.dispatchnow takesno_escalation: bool = False, matching the implementation. It has a default, following the rule already written in that file._consumer_call_site_keywordsreads exactly one splat shape:**helper(...), wherehelperis the only module-leveldefwith that name, its return annotation names the only module-level class with that name, that class's only base isTypedDict, and its body holds annotated names plus an optional docstring. The keys go to a set of keywords the call may send, which never counts as keywords sent on every call. So direction 3, "nothing required here that the consumer does not pass", is exactly as strict as before. Every other splat still fails closed: a bare name, an attribute, a dict literal, a method call, an undefined or duplicate helper, an unannotated helper, adict[...]annotation, a non-TypedDict class, an inherited TypedDict, or a body with other statements. There is a parametrized test for each of these.test_runtime_port_accepts_every_keyword_the_call_site_can_send_including_splats, run for both the protocol and the implementation. Every keyword the call site can send, written out or splatted, must be accepted here. A key that arrives only through the splat is held to the same bar as one written out, so the resolved splat adds a check and removes none.Test plan
Hook output before (fresh worktree of origin/dev at bc00160, reading the omnimarket clone at dev 6b7da747f):
After (head 946239e):
uv run pre-commit run onex-delegation-dispatch-consumer-kwarg-parity --all-files: Passed. The hook also passed inside this PR's own commit.origin/devhandler throughONEX_DELEGATION_CONSUMER_SOURCE: 19 passed.bogus_keyto the consumer's TypedDict fails the new assertion for both protocol and implementation (2 failed, 17 passed).test_delegation_dispatch_port_handler_compat,test_protocol_ownership,test_dispatch_port_budget_defaults_omn18924,test_omn18933_handler_wiring_route_scopeandtest_handler_wiring_resolver_integration: 68 passed.ruff format,ruff checkandmypy --strictare clean on both files. The pre-commit and pre-push hooks passed.Lab-first: this PR does not affect the runtime. The only src change adds one defaulted parameter to a structural
typing.Protocolthat nothing calls at runtime. The implementation that runs on the lab is unchanged, so there is no lab surface to exercise, and no tenant, RLS or reader-authorization path is touched.Runtime startup gate
Type safety checklist
metadata["key"]ormetadata.get("key")string literal access on Pydantic model fieldsmetadata: dict[str, Any]fields without TypedDict or# ONEX_EXCLUDE:commentexcept ExceptionStrict-gate ordering
Related issues
OMN-19817. Lineage: omnimarket#2841 and omnibase_infra#4088 (the no_escalation work this ticket is a child of), and the earlier dispatch-port parity incidents recorded in the parity module's docstring.
Evidence-Ticket: OMN-19817
Evidence-Source: OCC#11540