Repository navigation
feat(OMN-19215): place a lane-added delegation backend in the tier ladder as an unavailability-only sibling - #2803
Conversation
…dder as an unavailability-only sibling
A bifrost backend may declare placement {tier, fallback_for, max_context_tokens}.
The routing authority mirrors it into that tier after the rungs it backs when it
loads the ladder, so the reducer, the same-tier sibling probe and the local
dispatch path read one placed ladder. Invalid placements raise
ProtocolConfigurationError naming the backend. The replay-provenance hash covers
the placement. A quality rejection on the local dispatch path no longer hops to a
sibling serving the same model id; a transport failure still does.
Onex-Lane: pc2-delegation-load
Onex-Session: 85986327e3c342f1afa982a2ad965fc8
|
| 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_delegate_skill_orchestrator/ports/port_local_delegation_dispatch.py:881: self._effect_handler = effect_handler or HandlerLlmDelegationCall()
src/omnimarket/nodes/node_delegate_skill_orchestrator/ports/port_local_delegation_dispatch.py:882: self._projection_handler = projection_handler or HandlerProjectionDelegation(
src/omnimarket/nodes/node_delegate_skill_orchestrator/ports/port_local_delegation_dispatch.py:904: self._judge = judge if judge is not None else HandlerJudgeAdequacy()
src/omnimarket/nodes/node_delegation_orchestrator/handlers/handler_delegation_workflow.py:1159: loop = HandlerComplianceLoop()
src/omnimarket/nodes/node_delegation_orchestrator/handlers/handler_delegation_workflow.py:1958: 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).
✅ Hostile Reviewer — PASSEDBlocking findings (critical/error): 0 Gate semantics
Powered by omniintelligence.review_pairing.cli_review — node-based adversarial review via HandlerLlmCliSubprocess (OMN-8524) |
…ead of widening the wire model The released consumer's ModelDelegationBackendConfig refuses unknown keys, so the Wire Compatibility Gate refused a placement field on it. A placement is routing configuration read once at load, not a payload, so it now lives in non-wire models (ModelDelegationBackendPlacement, ModelPlacedDelegationBackend), the loader lifts it off each backend entry before the wire model validates, and load_bifrost_backend_placements reads it from the same resolved contract pair. Onex-Lane: pc2-delegation-load Onex-Session: 85986327e3c342f1afa982a2ad965fc8
…nimarket#2803 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/35991067861
…imarket#2803 (#11059) * evidence(OMN-19215): author OCC companion for OmniNode-ai/omnimarket#2803 OCC companion by node_pr_lifecycle_fix_effect (OMN-13317 F1 / OMN-13990 / OMN-14285). Product PR head 5294af7d08ec477f2ce54511abdf2328e43ecc47. * evidence(OMN-19215): self-bind OCC#11059 + rebind contract_sha256 * evidence(OMN-16859): executed test_passes receipts for OmniNode-ai/omnimarket#2803 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/35991067861 --------- Co-authored-by: omnimarket-bot <bot@omninode.ai> Co-authored-by: onexbot-occ-writer[bot] <307849072+onexbot-occ-writer[bot]@users.noreply.github.com>
Summary
OMN-19215, design (B), omnimarket half. A lane overlay can add a delegation backend, but routing only offers a backend the packaged
routing_tiers.yamlnames, so the second lab host serving the same Qwen3.8-27B as .201 (local-omnipc2-chatat .202) takes traffic only on a per-run pin.placement: {tier, fallback_for, max_context_tokens}. It is routing configuration read once at load, so it lives in non-wire models (omnimarket.models.delegation.model_delegation_backend_placement). The loader lifts it off each entry beforeModelDelegationBackendConfigvalidates, so the wire model keeps the shape the released consumer accepts (the Wire Compatibility Gate refused the first revision, which put the field on the wire model), andload_bifrost_backend_placementsreads it from the same resolved contract/overlay pair. No placement means unchanged behaviour.omnimarket.routing.backend_placement.apply_backend_placementsappends one mirrored tier entry per named rung AFTER the tier's existing models (id = the placed backend's own served model name,use_forcopied from the rung, context = the smaller of the two). The routing reducer's_get_config()applies it, so the reducer, the same-tier sibling probe and the local dispatch path read one placed ladder. Declaration-order selection means the placed backend is reached only when its rung is unroutable or already tried, never ahead of it.ProtocolConfigurationErrornaming the backend. The context-window check lives in the infra renderer, the only place that knows the window._routing_tiers_hash()folds in a digest of the placements; with none it is the tiers file's sha256 exactly as before.Load-spreading across same-model rungs is not in this PR (AC4).
Sequencing
Lands before the omnibase_infra companion that passes
placementthrough the renderer and placeslocal-omnipc2-chatin the dev overlay: a rendered contract carrying the key is refused by any omnimarket without this change. Lab proof on the .201 dev lane (AC2) follows after the M4 streak window closes; nothing here is deployed until then.Tests
tests/unit/routing/test_backend_placement_omn19215.py(13): mirror order and fields, no-placement identity, five invalid placements naming the backend, digest, the wire loader accepting a placed contract while the placement loader reads it, a malformed placement refused naming the backend, the real routing authority loading a placed fixture, the sibling probe offering the placed backend only after its rung is tried, and the replay hash with a positive control.scripts/ci/check_wire_compatibility.py --base origin/devlocally: PASS against released v0.4.207.tests/unit/nodes/node_delegate_skill_orchestrator/test_local_dispatch_same_model_sibling_omn19215.py(2): RED before the port change (['cloud-primary', 'cloud-mirror']called after a quality rejection), green after; the transport-failure control passes both before and after.routing_tiersor the bifrost config loader: 2071 passed, 4 skipped.mypy --strictclean on the six changed modules.Landing after M4
Held per the orchestrator's M4 fence: this PR stays draft and disarmed (
autoMergeRequestread backnull) until the board reports green. This section records what landing requires once that holds lifts.Merge order (OMN-19215): 1) this PR (omnimarket#2803) merges to
devfirst. 2)release-on-merge.yml(OMN-18010) auto-cuts an omnimarket release publishing the version carryingapply_backend_placements/ModelDelegationBackendPlacement— no manual release-train step;config/release_train_policy.yamlhas omnimarket inmode: report_onlyprecisely because this automation already cuts it on every source-touching merge. 3)omnibase_infra#3999merges, consuming that published omnimarket version in the dev-lane runtime image. 4) the AC2 lab pair (below) runs on the.201dev lane.Release cut required between this PR and omnibase_infra#3999: the omnimarket auto-release from step 2 above.
omnibase_infra#3999renders aplacementkey that this omnimarket version is the first to accept; an omnibase_infra dev-lane image still running the pre-#2803 omnimarket would refuse to load the lane's delegation config.Lab proof needed on the
.201dev lane after M4 (not run today —.201is fenced): AC2 from the Sequencing section above — a test-scoped run whose rendered contract bindslocal-coderto a closed port answered by.202, plus an unmodified control answered by.201, both exercised through the deployed dev-laneonex-apicontainer (never a raw client or shortcut).M4 probes to re-run after landing: C13, C14, C29 — this PR changes local-dispatch same-model-sibling behavior on the customer-local delegation path that those probes exercise.
Evidence-Ticket: OMN-19215
Evidence-Source: OCC#11059