Repository navigation
feat(OMN-20678): add node_delegate_fanout_effect over the delegation chain - #3614
Merged
Merged
Conversation
Added node node_delegate_fanout_effect to omnimarket: contract.yaml, metadata.yaml, handler HandlerDelegateFanout (definition-B handle(request) -> result), request and result models, registered under onex.nodes in pyproject.toml. The node was ported from omnibase_internal node_delegate_fanout_effect (landed there earlier in the ticket); behavior is unchanged: admission precheck, one publish per admitted item through the delegation client, receipt-derived rows, no retries, chunk barrier. Topics declared in contract.yaml: onex.cmd.omnimarket.delegation-fanout-requested.v1 (command), onex.evt.omnimarket.delegation-fanout-completed.v1 (terminal event) and onex.evt.omnimarket.delegation-fanout-failed.v1 (failure terminal); handler holds no topic literals. Tests added under tests/nodes/node_delegate_fanout_effect: 54 tests pass, including golden and error chain tests, including the captured old-workflow parity fixture; collection fails when the handler file is removed. Not in this commit: repointing the morning driver caller in omnibase_internal and deleting the omnibase_internal copy (pending a lab proof on the deployed runtime).
✅ Architectural Review — PASSEDErrors: 0 What this checks
No architectural violations found. 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) |
jonahgabriel
enabled auto-merge (squash)
October 9, 2026 06:38
The pull request omnimarket#3614 cited OMN-20678 but its head carried no contracts/OMN-20678.yaml, so the repo-evidence dod-verify job refused it. This commit adds contracts/OMN-20678.yaml binding AC1 of OMN-20678 to one dod_evidence item that runs uv run pytest tests/nodes/node_delegate_fanout_effect. AC2 of OMN-20678 is about omnibase_internal and is not bound here. No product or test file changes.
Two dod_evidence items, one in contracts/OMN-20678.yaml and one in contracts/OMN-20429.yaml, named test directories instead of test files, causing test_every_repo_contract_binds_every_criterion to fail. The item dod-omn20678-ac1-canonical-node now names the three test files under tests/nodes/node_delegate_fanout_effect: test_golden_chain_delegate_fanout.py, test_delegate_fanout_handler.py, and test_delegate_fanout_parity.py. Additionally, contracts/OMN-20429.yaml item dod-omn-20429-ac4 now names tests/golden_chains/delegation_acceptance_judge/test_golden_chain_delegation_acceptance_judge.py. The CI test now passes with 5 passed, and the 54 fanout tests and 7 judge golden chain tests pass.
This was referenced Oct 9, 2026
jonahgabriel
added a commit
that referenced
this pull request
Oct 9, 2026
) * feat(OMN-20279): mirror delegation terminals through ledger serve * OMN-20279: add contracts/OMN-20279.yaml Repo Evidence Gate (repo-evidence / dod-verify) reported the ticket contract was missing: 'pull request cites OMN-20279 but carries no contracts/OMN-20279.yaml'. Evidence command: uv run pytest tests/unit/work_ledger_bus/test_delegation_terminal.py Result: 6 passed on h201 * fix(OMN-20279): remove handler_routing from node_work_ledger_bus_mirror The dogfood audit incorrectly bucketed node_work_ledger_bus_mirror as non_command_or_missing_command_topic because it declares handler_routing but lacks an event_bus command topic. Removed handler_routing from its contract.yaml to match other in-process experimental nodes like node_lab_job_submit_effect. This allows the audit to skip it as experimental_handler_pending, increasing the dogfood test's skipped count from 17 to 18. * chore(OMN-20279): bump version to 0.4.307 * feat(OMN-20668): Add node_lab_fill_effect and the lab-fill outcome operations (#3604) * feat(OMN-20668): Add node_lab_fill_effect and the lab-fill outcome operations New effect node node_lab_fill_effect in omnimarket. Its contract declares the command topic onex.cmd.omnimarket.lab-fill-effect-requested.v1 and the terminal events onex.evt.omnimarket.lab-fill-effect-completed.v1 and onex.evt.omnimarket.lab-fill-effect-failed.v1. It declares no event_bus block, because it is hosted by a serve process on the host that holds the ledger, the remote-lane runner and the PR watcher state. Six operations, each a handle(request) -> result handler: probe_lab_fill_hosts, read_lab_fill_owner_facts, launch_lab_fill_lane, read_lab_fill_receipts, pick_lab_fill_fallback_host, write_lab_fill_status. Every handler takes its ports in its constructor; local adapters reach the remote-lane runner's pool read and launcher, the ledger file, the approved-work list, Linear, the PR watcher state and the claim store. The status operation appends the STATUS row (and the idle alarm's FRICTION row first) through the ledger host's bus append under a request id derived from the run key, so a resend answers duplicate. node_lab_fill_plan_compute gains five pure operations: decide_lab_fill_ownership, render_lab_fill_lane, verify_lab_fill_placement, plan_lab_fill_fallbacks, compose_lab_fill_status. 179 parity cases; the expected answers were produced by running the old lab-fill workflow's own code. The launch spec of a lane moved to a shared model package, omnimarket.models.lab_fill, used by both nodes. Tests: golden chain, cycle chain (JSON handed between the effect node and the plan node), error chain and adapter tests; 462 tests pass across the two node test directories. Not included: enumerating candidates, a node that sequences the cycle, repointing the launchd job, deleting lab-fill.js. * fix(OMN-20668): Pin OMNI_HOME in the lane launcher adapter tests Two tests of the lab-fill effect node's lane launcher adapter (test_lane_runner_passes_args_env_and_reports_the_exit and test_lane_runner_times_out_as_124) failed on lab host h200 at commit 144a47a30a82, with 508 other tests passing: the adapter runs the remote-lane runner from the OMNI_HOME directory, and the tests did not set it, so on h200 it named a directory that does not exist. The two tests now set OMNI_HOME to their scratch directory. A new test pins the adapter's behaviour when OMNI_HOME names a missing directory: it raises LabFillPortError with "runner not started". The 76 tests in tests/nodes/node_lab_fill_effect pass with OMNI_HOME set to /nonexistent and with the host's own OMNI_HOME. * fix(OMN-20668): bump to 0.4.307, bind AC4/AC5 to test files, tag the Linear urlopen boundary * chore(release): open dev for v0.4.307 (#3603) Disarms the OMN-16344 release-identity gate that publishing v0.4.306 armed against dev. Triggered-by: https://github.com/OmniNode-ai/omnimarket/actions/runs/37869634875 Co-authored-by: onexbot-occ-writer[bot] <onexbot-occ-writer[bot]@users.noreply.github.com> * feat(OMN-20680): add linear-comments and hourly-tick decision compute nodes (#3597) * feat(OMN-20680): add linear-comments and hourly-tick decision compute nodes Adds node_linear_comments_decision_compute and node_hourly_tick_decision_compute to omnimarket. Each node includes a contract.yaml with declared command and terminal topics, a metadata.yaml, a definition-B handler handle(request) -> result, typed models, and an onex.nodes entry point in pyproject.toml. node_linear_comments_decision_compute is a Python port of the pure block of the linear-comments-hourly workflow script (owned today by omnibase_internal). It implements author classification, the draft-or-not decision with its own reason, the drafting prompt, the draft citation check, truncation detection, the closed held-reason classifier, the held tally with the degraded flag, and the delegate metrics row. node_hourly_tick_decision_compute holds the tick's deterministic decisions. The probe turns checkpoint, sweep pointer and ledger contents (read by the caller) into the window state, the checkpoint line and the sweep request. The record turns the state and sweep result into the completion line, phase, degraded class and fire-result payload. It has no clock and reads no files. Parity fixtures: tests/fixtures/linear_comments_hourly_parity.json holds inputs and outputs captured by running the old JS pure block under node (source commit 38c45975d93d870cb3f4f1a5eee2860357bd211f of omnibase_internal); tests/fixtures/hourly_tick_parity.json holds 60 cases captured from the pre-conversion tick (source commit fb45651168a1bb5390f5120ceee0fe61b36111d3). Tests: golden chain through RuntimeLocal on the in-memory bus, error chain (typed validation refusals; bus run ends FAILED with no result), and parity. 214 tests pass on the two node test directories; ruff, ruff format and mypy --strict are clean on the new files. Not in this change: the model stages of the sweep (Linear MCP collection and the opus verifier), the host file effects, repointing the callers, and deleting the old script. Those stay in omnibase_internal until the nodes are released. * fix(OMN-20680): add contracts/OMN-20680.yaml to satisfy dod_evidence The repo-evidence / dod-verify check on PR omnimarket#3597 failed because the pull request cited OMN-20680 without providing the required contracts/OMN-20680.yaml, causing CI Summary, Coverage Sweep Gate, and deploy-gate to fail. This commit adds the missing contract file, which defines three acceptance criteria: AC1 verifies linear-comments decisions match the old JS pure block's captured outputs, AC2 ensures the linear-comments node runs over the RuntimeLocal in-memory bus and refuses invalid requests, and AC3 confirms the hourly-tick probe then record matches the pre-conversion tick. Two dod_evidence test_passes checks run the two node test directories, and the node_dod_verify verifier pinned by CI (omnimarket 0.4.294) returned status verified with 2 of 2 checks passing on this contract. The contract does not claim repointing callers or deleting the old script. * fix(OMN-20680): correct dod_evidence test file selectors Updated contracts/OMN-20680.yaml to specify explicit .py test file paths for the dod_evidence checks, replacing directory references that failed the CI validation. The test passes check now points to the specific parity and golden-chain files for node_linear_comments_decision_compute and the golden-chain file for node_hourly_tick_decision_compute, ensuring the evidence test passes. --------- Co-authored-by: onexbot-occ-writer[bot] <307849072+onexbot-occ-writer[bot]@users.noreply.github.com> * fix(OMN-17427): withhold ci_red_triage start command when act is false (#3591) * fix(OMN-17427): withhold ci_red_triage start command when act is false The contract sets ci_red_triage.act: false. Before this change the triage still published a pr-lifecycle start command (dry_run=True, fix_only=True) for every new owner; each such run inventories its PRs with gh on the operator's GitHub login and changes nothing. On 2026-10-08 from 21:00Z to 22:05Z the bus carried 114 ci-run-failed events and 51 start commands for 25 owners (72 PR inventories). Measured on h201: about 30 operator REST calls per PR inventory. The landing controller read 262 remaining at 21:59Z and 242 at 22:00Z, below its QUOTA_FLOOR of 500. After this change, with act false the triage still records its decision (action, run id, owner joins) with action_applied false and evidence "start=withheld:act=false", and publishes no start command. With act true nothing changes. Tests: two new tests (shadow mode starts nothing; contract default is shadow mode) fail on the old handler; tests of the acting path now pass act=True. 138 tests in tests/unit/nodes/node_pr_lifecycle_orchestrator pass. * test(OMN-17427): add shadow-mode CI red triage evidence The CI check "repo-evidence / dod-verify" failed on omnimarket PR #3591 head f4867d5b07a00389cce9ad63011b7df84b4b49d3 because every bound check was carried unchanged from the merge base's contract and the pull request bound no evidence of its own. Consequently, Repo Evidence Dependency, Coverage Sweep Gate, and CI Summary failed. This commit adds to contracts/OMN-17427.yaml the requirement req-ci-red-triage-shadow with acceptance AC21, an evidence_requirements tests entry, and a dod_evidence item dod-omn17427-ac21-ci-red-triage-shadow binding AC21 to: uv run pytest tests/unit/nodes/node_pr_lifecycle_orchestrator/test_ci_red_triage.py -q -k shadow_mode. AC21 specifies that with act false, HandlerCiRedTriage records each decision with action_applied false and evidence start=withheld:act=false, publishing no start command; the contract default is act false. Verified locally: the bound command passes at the head (2 passed); at merge base 14df4e08c7fcc7dcad9cc4e469606a59f631b13b with the head's test file overlaid it fails (2 failed). The contract passes onex_change_control validate_yaml. * OMN-17427: ci_red_triage shadow mode no longer records owner in in-memory owners cache Change: ci_red_triage handler in shadow mode (act=false) no longer records an owner in the in-memory owners cache, since it starts no run; each shadow decision stays action_applied=false with start=withheld:act=false evidence. Test test_shadow_mode_records_decision_and_starts_nothing updated: three START_CAUSE_OWNER decisions, handler._owners empty. 22 tests in test_ci_red_triage.py pass. Also merged origin/dev (release identity check OK: 0.4.306 > 0.4.300). Addresses the Hostile Reviewer blocking finding 'Shadow mode still claims owner and mutates state'. * OMN-17427: bump version to 0.4.307 above published v0.4.306 --------- Co-authored-by: codex <codex@omninode.ai> * OMN-20282: Authenticate bus ledger appends and operator consent (#3602) * OMN-20282: Authenticate bus ledger appends and operator consent * OMN-20282: add contract for work ledger append effect Add contracts/OMN-20282.yaml to satisfy repo-evidence / dod-verify for PR #3602. The contract defines two requirements: - AC1: signed append handler tests - AC2: CLI signing and bus round-trip tests dod_evidence commands: - tests/unit/nodes/node_work_ledger_append_effect/test_handler_work_ledger_append_effect.py - tests/unit/work_ledger_bus/test_work_ledger_append_cli.py Both test files pass locally on lab host h202 (76 passed). No source change. * OMN-20282: Bump version to 0.4.307 to pass release identity gate Release Identity Gate failed on head 6af6ce4ba because pyproject version 0.4.306 equals the latest published tag v0.4.306. This commit bumps project.version to 0.4.307 in pyproject.toml and the omnimarket entry in uv.lock. scripts/check_release_identity.py --base origin/dev now exits 0. * feat(OMN-20673): host the morning ground-state orchestrator node with a deployment overlay (#3598) * feat(OMN-20673): add morning ground state orchestrator node Adds node_morning_ground_state_orchestrator to src/omnimarket/nodes/. Includes contract.yaml with declared bus topics (start command onex.cmd.omnimarket.morning-ground-state-start.v1; terminal events onex.evt.omnimarket.morning-ground-state-completed.v1 and onex.evt.omnimarket.morning-ground-state-failed.v1; phase work over the existing delegation request and reply topics), a declarative orchestrator node, an async Definition-B handler handle(request) -> result, a bus phase gateway, typed request, phase and terminal models, protocols, and metadata.yaml. The node is hosted unregistered: lifecycle experimental, no onex.nodes entry point in pyproject.toml, listed in tests/test_market_node_runtime_dogfood.py. The registration hand-over, caller switch and retirement of the source copy in the operator tooling repository are separate steps. Deployment briefs, phase specs, report locations, default documents and repositories, ticket defaults, kb-clone texts and the ledger-reconcile command are read from a strict overlay: OMNIMARKET_MORNING_GROUND_STATE_OVERLAY pointer, otherwise the first node_morning_ground_state_orchestrator/overlay.yaml under ONEX_SKILL_OVERLAY_ROOTS. An absent or invalid overlay refuses to start. Request fields planDocs, mustDoDoc, offRailsDoc, integrationRepos and closureProbeTicket now default to None and fall back to the overlay. The node package names no private repository or path (a test enforces it). The error message prefix 'delegation cell refused (OMN-17009)' lost its ticket id and reads 'delegation cell refused'. The request topic used for the envelope event_type is now read from the contract instead of a string literal in the handler. Tests under tests/nodes/node_morning_ground_state_orchestrator cover: golden chain, error chain, nine recorded decision scenarios of the original workflow, overlay resolution and validation, phase gateway, and one full cycle over the in-memory bus auto-wired from the contract path. 77 tests pass. Side-by-side check outside the repo: the original handler and this handler with the real deployment overlay agreed on 12 request cases, 80 phase prompts compared byte for byte, results identical; changing one overlay value made all 12 cases differ. contracts/OMN-20673.yaml is the change contract. * fix(OMN-20673): narrow AC3 evidence command to single test On head 71f4f1531, the repo-evidence / dod-verify check failed with EVIDENCE_UNVERIFIABLE because the AC3 evidence check dod-omn20673-ac3-overlay exceeded the verifier's 30.0s per-check budget. The check ran the whole tests/test_market_node_runtime_dogfood.py file, which takes about 30s on its own. The fix narrows the AC3 command in contracts/OMN-20673.yaml (both evidence_requirements and dod_evidence) to tests/test_market_node_runtime_dogfood.py::test_market_node_runtime_dogfood_inventory_classifies_all_entry_points, the same selection contracts/OMN-20712.yaml uses. The narrowed AC3 command runs 15 tests in about 6.6s on lab host h202. No code change. * fix(OMN-20673): update runtime profile for impure orchestrator Changed node_morning_ground_state_orchestrator runtime_profiles from [main] to [effects] in contract.yaml. This aligns the descriptor with other impure command-consuming orchestrators in the repository. The change resolves the failing test test_effectful_command_consumers_declare_effects_runtime_profile. --------- Co-authored-by: onexbot-occ-writer[bot] <307849072+onexbot-occ-writer[bot]@users.noreply.github.com> * test(OMN-19978): _connect_or_skip returns once, explicitly (CodeQL alert 1324) (#3564) * test(OMN-19978): _connect_or_skip returns once, explicitly (CodeQL py/mixed-returns, alert 1324) The helper returned inside try and fell through after pytest.skip, which CodeQL reads as mixed explicit and implicit returns. It now binds the connection and returns it once; pytest.skip still ends both skip paths. No behaviour change: 24 passed, 2 skipped (no Postgres password) before and after. * evidence(OMN-19978): repo contract for the explicit-return helper change The Repo Evidence Gate requires a cited ticket to carry contracts/<ticket>.yaml (OMN-20070). This one is scoped to #3564's test-side change, like OMN-19984.yaml for #3548: AC1 binds the two real-Postgres usage tests, which the hosted job runs against its Postgres. Local hosted-audience node_dod_verify: status verified. * test(OMN-19978): initialise conn so CodeQL sees it bound on every path CodeQL (py/uninitialized-local-variable) read conn as possibly unset after the except branch, since it does not know pytest.skip never returns. conn now starts as None and is asserted before the single return, so neither the mixed- returns nor the uninitialised-local rule fires. No behaviour change: 24 passed, 2 skipped (no Postgres password). * ci(OMN-20422): the Hostile Reviewer's second voter is Qwen3.6-35B-A3B on the Studio's :8131 (#3605) * ci(OMN-20422): the Hostile Reviewer's second voter is Qwen3.6-35B-A3B on the Studio's :8131 * fix(OMN-20422): add missing contract and CI tests Adds contracts/OMN-20422.yaml (AC1, one test_passes check) and tests/ci/test_hostile_reviewer_voter_omn20422.py (3 tests: LLM_GPT_OSS_REVIEW_URL ends :8131 in hostile-review job env, CIDR allowlist at job level, both --model qwen3-review and gpt-oss-review still requested). Resolves repo-evidence / dod-verify failure ("pull request cites OMN-20422 but carries no contracts/OMN-20422.yaml") and downstream failures in Repo Evidence Dependency, CI Summary, and Coverage Sweep Gate. Ran new tests and test_hostile_review_lab_roster_omn17492.py: 10 passed on h201. * feat(OMN-20758): onex dashboard pins the omnidash v1.1.9 bundle (#3607) v1.1.8 retitles the Overview's Spend, Measured runs and Tokens in and out cards as Actual spend, Agent calls and Tokens processed; v1.1.9 carries that plus OMN-20759's table fit, so this pins v1.1.9 and asserts a floor of v1.1.8. The sha256 was computed from the downloaded bytes. Co-authored-by: Jake Brower <jake@bodegalogic.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * feat(OMN-20759): onex dashboard pins the omnidash v1.1.9 bundle (#3606) v1.1.9 (omnidash#379, tag at 3c808c79) is the first bundle whose Runs and Recent runs tables fit their panels at 1440x900 with every column; it also carries the mockup's card titles (omnidash#378, OMN-20758). The sha256 was computed from the downloaded bytes and matches the published .sha256; a fresh cache downloads, verifies and unpacks it. A floor test keeps an older bundle from being pinned. Co-authored-by: Jake Brower <jake@bodegalogic.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(OMN-17427): assign node_branch_claim_check_effect to main profile (#3559) * fix(OMN-17427): assign node_branch_claim_check_effect to main profile The contract runtime_profiles changed from [effects] to [main] because no compose lane's runtime-effects declares ONEX_RUNTIME_LANE (OMN-19144 keeps it on omninode-runtime). Under OMN-19408 the effects runtime fails closed with a discovery error, its health reads DEGRADED and Docker marks omninode-runtime-effects unhealthy. On the .201 dev lane that held every C28 consumer-flow probe since 2026-10-08T10:21Z, so the M4 board's c28-consumer-flow went red; the .202 dev lane's runtime-effects is unhealthy for the same reason. No runtime attached the node, so the branch claim check never ran on the lab. The main runtime carries OMNINODE_INTERNAL_DB_URL, ONEXBOT_OCC_APP_ID and ONEXBOT_OCC_PRIVATE_KEY. node_pr_landing_orchestrator already uses main for the same reason. tests/test_omn17427_lane_scoped_contracts_main_profile.py asserts every contract declaring runtime_lanes is owned by main only. * fix(OMN-17427): bind evidence for the lane-scoped contracts main-profile fix Add the requirement req-lane-scoped-contracts-main-profile with acceptance criterion AC19 to contracts/OMN-17427.yaml. Bind the dod_evidence item dod-omn17427-ac19-lane-scoped-contracts-main-profile to AC19 via a tests evidence_requirement. The bound check runs uv run pytest tests/test_omn17427_lane_scoped_contracts_main_profile.py -q, which fails at the merge base and passes on this branch. This resolves the repo-evidence failure on omnimarket#3559 and follows the same binding pattern as AC18 in omnimarket#3551. * fix(OMN-17427): bump omnimarket to 0.4.305 past the published 0.4.304 The Release Identity Gate (OMN-16344) failed because the pyproject version 0.4.304 was not ahead of the latest published version 0.4.304. This change updates pyproject.toml and uv.lock to version 0.4.305 to satisfy the gate. The bump matches the value in the open automated post-release bump omnimarket#3558, ensuring it merges cleanly if that PR lands first. * fix(OMN-17427): shorten the AC19 dod_evidence id to fit the 50 character limit The contract-validation check on omnimarket#3559 failed because the id exceeded the 50 character limit. The id has been shortened to 45 characters and the contract is now valid according to onex_change_control. * chore(release): open dev for v0.4.308 (#3608) Disarms the OMN-16344 release-identity gate that publishing v0.4.307 armed against dev. Triggered-by: https://github.com/OmniNode-ai/omnimarket/actions/runs/37889146849 Co-authored-by: onexbot-occ-writer[bot] <onexbot-occ-writer[bot]@users.noreply.github.com> * test(OMN-20429): golden and error chains for the delegation acceptance judge (#3609) * test(OMN-20429): add delegation acceptance judge golden chains Adds golden and error chains under tests/golden_chains/delegation_acceptance_judge/ Three JSON chain fixtures and one test file added Chains replayed through handler_routing command topic onex.cmd.omnimarket.delegation-acceptance-judge-requested.v1 Positive chain: 72 primary and 8 second-judge verdicts from 2026-10-08 rubric v1 give published matrix and agreement Negative chain 1: inverted second-judge verdicts fail kappa_below_minimum Negative chain 2: invalid ids, accept below quality 2, reject with none, outside vocabulary refused 7 tests pass; flipping one recorded verdict makes the positive chain fail * Add tests and binding for OMN-20429 PR 3609 adds only tests for OMN-20429. repo-evidence / dod-verify failed at head e814398 with 'every bound check is carried unchanged from the merge base's contract; this pull request binds no evidence of its own'. Change: contracts/OMN-20429.yaml gains AC4 and dod-omn-20429-ac4 binding 'uv run pytest tests/golden_chains/delegation_acceptance_judge -q'. dod_verify node run locally: all 4 checks verified; 7 tests pass. * feat(OMN-20671): add node_handshake_policy_gate_compute for the handshake policy gate decisions (#3615) Adds a new COMPUTE node node_handshake_policy_gate_compute in omnimarket. It includes contract.yaml with command topic onex.cmd.omnimarket.handshake-policy-gate-decide-requested.v1 and terminal topic onex.evt.omnimarket.handshake-policy-gate-decided.v1, metadata.yaml, an onex.nodes entry point in pyproject.toml, typed models, and a definition-B handler handle(request) -> result. The node ports the pure decisions of omnibase_core architecture-handshakes/check-policy-gate.sh. It handles four kinds: parse_repos (repos.conf text to repo list), resolve_branch (default-branch output to branch plus the two GitHub API endpoints), classify_read (one read of a repo's latest completed check-handshake run to pass, fail, no_workflow, no_runs, error or retry with next attempt and backoff delay), and report (per-repo statuses to report text, verdict, exit code). The node performs no reads, has no clock and never sleeps; the caller reads, sleeps and prints. Parity tests use tests/fixtures/handshake_policy_gate_parity.json, which holds 24 scenarios captured by running the old script (omnibase_core commit 6cb6dc8342e6be91b773959909bc3f26d1ce4962) against a scripted fake gh. The test replays each through the node and compares stdout, stderr, exit code, endpoints read and sleeps. capture_policy_gate_parity.py regenerates the fixture. One deliberate difference: a zero-padded base delay such as 08 is read as decimal; the old script read it as octal and exited under set -e. 44 tests pass in tests/nodes/node_handshake_policy_gate_compute, covering a golden chain over RuntimeLocal in-memory bus, an error chain, and parity. Changing the backoff base from 2 to 3 makes 12 of them fail. ruff, ruff format and mypy --strict are clean on the new files. contracts/OMN-20671.yaml was added. Not in this change: the GitHub reads (an effect), repointing the omnibase_core workflow, and deleting the old script. * fix(OMN-19392): remove the retired local delegation rung (#3584) * fix(OMN-19392): remove retired local delegation rung * fix(OMN-19392): add contracts/OMN-19392.yaml Added contracts/OMN-19392.yaml (two requirements ACs, tests evidence, dod_evidence) because the repo-evidence / dod-verify check failed on head f6dca7400709132fc64a162fafbe23febeea9b5c with 'pull request cites OMN-19392 but carries no contracts/OMN-19392.yaml'; the contract's pytest command passes 127 tests on lab host h202. * fix(OMN-19392): bind the routing-contract DoD check to the seam test that fails at the merge base The dod-verify control found dod-omn19392-routing-contract passing at the merge base. The check now also runs test_packaged_contract_renders_and_routes_after_retirement, which fails on all five task classes at origin/dev and passes at this head (129 passed). * test: update swarm fleet discovery bus coverage for 2 local endpoints Retired local 8101 endpoint was removed from the registry in f6dca7400 (OMN-19392), so fleet discovery reports 2 local endpoints, not 4. CI failures: - test_all_local_healthy_over_bus - test_combined_local_and_openrouter_over_bus Both tests asserted local_count >= 4 (got 2). Changes: - Dropped the 8101 health URL - min_healthy_endpoints 4->2 - local/healthy count asserts to == 2 7 tests in the file pass. * test(OMN-18967): Add regression test for prose task thinking suppression (#3611) * test(OMN-18967): Add regression test for prose task thinking suppression * test(OMN-18967): bind AC1 evidence to the changed test file The hosted check repo-evidence / dod-verify failed on head 051623fc7 because the base contract only bound tests/unit/inference/test_adapter_inference_bridge.py. This commit adds the dod_evidence item dod-omn18967-ac1-prose-no-think-through-bus-intent to contracts/OMN-18967.yaml. It binds AC1 to uv run pytest tests/unit/delegation/test_prose_task_class_no_think_omn18967.py -q -p no:cacheprovider. node_dod_verify with --execution-audience hosted returned status verified with both checks verified (39 passed, 28 passed). * fix(OMN-18925): fail empty remote-agent artifacts (#3610) * fix(OMN-18925): fail empty remote-agent artifacts * test(OMN-18925): add dod_evidence for empty remote artifact tests The dod-verify job refused omnimarket#3610 because every bound check of OMN-18925 was carried unchanged from the merge base's contract and the pull request bound no evidence of its own. This commit appends one dod_evidence item, dod-omn18925-empty-remote-artifact-tests, to contracts/OMN-18925.yaml, bound to AC1. It runs the two empty-artifact tests the pull request changed in tests/unit/delegation/test_operational_outcome_content_verdict_omn18925.py. With the dev handler checked out those tests gave 5 failed, 5 passed; at the head they gave 10 passed. * fix(OMN-18925): point OMN-20429 check at existing test file dev commit d2d3562141 (omnimarket#3609) added dod-omn-20429-ac4 to contracts/OMN-20429.yaml with a directory selector. test_repo_evidence_caller_workflow.py::test_every_repo_contract_binds_every_criterion requires a .py or /tests selector naming an existing file. The check now points at tests/golden_chains/delegation_acceptance_judge/test_golden_chain_delegation_acceptance_judge.py, the only test file in that directory. Locally the 5 repo evidence caller tests and the 7 golden chain tests pass (12 passed). * feat(OMN-20678): add node_delegate_fanout_effect over the delegation chain (#3614) * feat(OMN-20678): add node_delegate_fanout_effect to omnimarket Added node node_delegate_fanout_effect to omnimarket: contract.yaml, metadata.yaml, handler HandlerDelegateFanout (definition-B handle(request) -> result), request and result models, registered under onex.nodes in pyproject.toml. The node was ported from omnibase_internal node_delegate_fanout_effect (landed there earlier in the ticket); behavior is unchanged: admission precheck, one publish per admitted item through the delegation client, receipt-derived rows, no retries, chunk barrier. Topics declared in contract.yaml: onex.cmd.omnimarket.delegation-fanout-requested.v1 (command), onex.evt.omnimarket.delegation-fanout-completed.v1 (terminal event) and onex.evt.omnimarket.delegation-fanout-failed.v1 (failure terminal); handler holds no topic literals. Tests added under tests/nodes/node_delegate_fanout_effect: 54 tests pass, including golden and error chain tests, including the captured old-workflow parity fixture; collection fails when the handler file is removed. Not in this commit: repointing the morning driver caller in omnibase_internal and deleting the omnibase_internal copy (pending a lab proof on the deployed runtime). * test(OMN-20678): add contracts/OMN-20678.yaml The pull request omnimarket#3614 cited OMN-20678 but its head carried no contracts/OMN-20678.yaml, so the repo-evidence dod-verify job refused it. This commit adds contracts/OMN-20678.yaml binding AC1 of OMN-20678 to one dod_evidence item that runs uv run pytest tests/nodes/node_delegate_fanout_effect. AC2 of OMN-20678 is about omnibase_internal and is not bound here. No product or test file changes. * fix(OMN-20678): Correct contract evidence to reference test files Two dod_evidence items, one in contracts/OMN-20678.yaml and one in contracts/OMN-20429.yaml, named test directories instead of test files, causing test_every_repo_contract_binds_every_criterion to fail. The item dod-omn20678-ac1-canonical-node now names the three test files under tests/nodes/node_delegate_fanout_effect: test_golden_chain_delegate_fanout.py, test_delegate_fanout_handler.py, and test_delegate_fanout_parity.py. Additionally, contracts/OMN-20429.yaml item dod-omn-20429-ac4 now names tests/golden_chains/delegation_acceptance_judge/test_golden_chain_delegation_acceptance_judge.py. The CI test now passes with 5 passed, and the 54 fanout tests and 7 judge golden chain tests pass. * feat(OMN-20672): landing tick decision with fair share and its observe mode become contract-declared compute nodes (#3621) * feat(OMN-20672): landing tick decision with fair share and its observe mode become contract-declared compute nodes Added node_pr_landing_tick_compute: contract.yaml, handler HandlerPrLandingTick.handle(ModelLandingFacts) -> ModelLandingDecision. It runs the decision of node_pr_landing_decision_compute and shares free worker slots across repositories, the fair share the live landing controller applies in landing_decide_bridge.py. Its command and terminal topics are declared in the contract. Added node_pr_landing_tick_observe_compute: contract.yaml, handler HandlerPrLandingTickObserve.handle(ModelLandingTickObservation) -> ModelLandingTickComparison. It replays a copied tick's facts through the node path and lists every JSON path where the node's decision differs from the live controller's decision. Both registered under onex.nodes in pyproject.toml. Added contracts/OMN-20672.yaml. 70 focused tests pass. Run against the live bridge script, the node path's decision equalled the bridge's on 152 ticks (92 from the reviewed scenarios, 60 generated multi-repository worlds); fair share changed the plain decision on 14 of them. The live controller and its scripts are not changed, nothing calls the new nodes yet, and the old entry points are not deleted. * OMN-20672: Fix CI failures by re-exporting landing decision models and correcting contract evidence CI failed on Tests (Split 6/20) in tests/test_no_cross_node_reach_in.py because node_pr_landing_tick_compute and node_pr_landing_tick_observe_compute imported node_pr_landing_decision_compute models directly. CI also failed on Tests (Split 2/20) in tests/ci/test_repo_evidence_caller_workflow.py because contracts/OMN-20672.yaml dod_evidence pytest commands named directories instead of test files. Added src/omnimarket/models/landing_decision.py re-exporting EnumLandingActionKind, EnumLandingSuspension, ModelLandingDecision, and ModelLandingFacts. Both tick nodes now import from this module. Contract evidence now names test_landing_tick_compute.py and test_landing_tick_observe.py. Locally 78 tests pass, mypy strict is clean on touched packages, runtime sweep import-check is clean, and metadata dependency check is PASS. * feat(OMN-20474): pure fold of judged acceptance verdicts into model, task type and kind cells (#3612) * feat(OMN-20474): pure fold of judged acceptance verdicts into per model, task type and kind cells New node node_projection_delegation_judged_acceptance under src/omnimarket/nodes: contract.yaml, metadata.yaml, a pure handler HandlerProjectionDelegationJudgedAcceptance with handle(request) -> result, three models (fold request, cell, fold result), and an entry point in pyproject.toml. Input is a tuple of ModelDelegationAcceptanceJudgedEvent. Output is one cell per tenant, delegated model, delegated tier, task type, kind and rubric version, with n, accepts, accept_rate, Wilson 95 percent low and high, mean_quality, first_call_time, last_call_time and judge_run_count. The verdict standing for a call is the one with the latest judged_at from a calibrated judge run, ties going to the greater judge_run_id, so arrival order and redelivery do not change the output. A verdict from a judge run with calibration_agreement under 0.75 or calibration_kappa under 0.60 is refused and counted. A cell with fewer than 15 verdicts has no row; it is counted as underpowered. edit_loop_turn verdicts form their own kind cells. A kind other than task or edit_loop_turn is excluded and counted. The window is the 30 days before the cell's newest call_time; the fold reads no clock. terminal_ok is not a field of the event or the request and does not enter a cell. Tests under tests/nodes/node_projection_delegation_judged_acceptance: 26 tests pass locally in that directory. They include every permutation of a seven-event set (5040) with redelivery, and a mutant that picks the winner by arrival order, which the order-independence check fails. Not in this change: the writer, tables, bus subscription and snapshot topic. The contract sets lifecycle: experimental, because node-drift-gate refuses a node with no subscribe and publish topics; the subscribe topic belongs to the writer change. scripts/ci/check_projection_write_path_db_gate.py: the gate flagged every .py under node_projection_*/handlers/, including this fold, which has no database path. A handler under a node whose contract.yaml declares descriptor.purity: pure and has no db_io key is no longer a write path. A missing, unreadable or impure contract, or one that declares db_io, is still a write path. Selftest cases (g) to (k) and class TestPureFoldCarveOut in tests/ci/test_check_projection_write_path_db_gate.py cover it; 20 tests pass in that file. Test count change: 26 tests in the node's test directory pass; 46 pass across the node's tests and the gate's tests. * test(OMN-20474): add contracts/OMN-20474.yaml The pull request omnimarket#3612 cited OMN-20474 but its head carried no contracts/OMN-20474.yaml. The repo-evidence dod-verify job refused it. This commit adds contracts/OMN-20474.yaml. The contract carries the four acceptance criteria AC1 to AC4 of OMN-20474, each bound to one dod_evidence item. Each item runs the pytest selector the ticket's own falsifier names, over tests/nodes/node_projection_delegation_judged_acceptance. No product or test file changes. * fix(OMN-20474): bind ACs to test files and skip the in-process fold CI run 37895530690 failed two test splits. Tests (Split 2/20): test_every_repo_contract_binds_every_criterion needs each binds_ac pytest check to name a .py file. contracts/OMN-20474.yaml and contracts/OMN-20429.yaml (from dev, #3609) named test directories. They now name test_judged_acceptance_fold.py and test_golden_chain_delegation_acceptance_judge.py. Tests (Split 5/20): node_projection_delegation_judged_acceptance had handler_routing but no command topic, so the runtime dogfood inventory counted it as failed (non_command_or_missing_command_topic). The writer calls the fold in process, so handler_routing is removed, as for the other experimental in-process nodes. The node's contract test now asserts there is no handler_routing, and the dogfood skipped count goes from 17 to 18. * fix(OMN-17427): bound pytest evidence names a test file, not a directory (#3625) contracts/OMN-20429.yaml dod_evidence item dod-omn-20429-ac4 named the bare directory tests/golden_chains/delegation_acceptance_judge as its pytest selector; it now names tests/golden_chains/delegation_acceptance_judge/test_golden_chain_delegation_acceptance_judge.py. tests/ci/test_repo_evidence_caller_workflow.py::test_every_repo_contract_binds_every_criterion refuses a selector that does not end in .py or /tests; it failed on dev head fe553dc85 and made Tests (Split 2/20) red on open PRs. New test tests/ci/test_contract_evidence_selector_names_file_omn17427.py checks every binds_ac pytest check in contracts/OMN-*.yaml (not only one per item) names an existing .py file or /tests directory, and pins the dod-omn-20429-ac4 selector. contracts/OMN-17427.yaml gains requirement req-bound-selector-names-file, AC23, an evidence_requirements entry and dod_evidence item dod-omn17427-ac23-bound-selector-names-file bound to AC23. The new test fails with dev's contracts/OMN-20429.yaml (2 failed) and passes on this branch. Co-authored-by: codex <codex@omninode.ai> * feat(OMN-20679): move architecture discovery node to omnimarket (#3618) * feat(OMN-20679): move architecture discovery node to omnimarket Move node_architecture_discovery_orchestrator from omnibase_internal to omnimarket. The node previously merged into omnibase_internal as a contract, declarative node and definition-B handler. Retain the six phases (four scans, adjudication, report). Each phase runs through the existing coding-agent invocation effect and workspace validation compute node over the bus. Rename topics to the omnimarket namespace in the contract: command onex.cmd.omnimarket.architecture-discovery-requested.v1 and terminal onex.evt.omnimarket.architecture-discovery-completed.v1. The two omnibase-infra command topics are listed as externally consumed. Ship prompt templates as .txt because the strict kb-doc-gate refuses markdown. Remove two operator-private values, the substrate probe URL and the registry directory name, from the tree. They arrive on the request as a required overlay (ModelDiscoveryOverlay). The CLI reads them from a YAML file named by --overlay or ONEX_ARCHITECTURE_DISCOVERY_OVERLAY. Parity: with sentinel overlay values, all 12 captured prompts (default and configured traces, 6 phases each) hash-equal to the old tool's prompts with its two private literals replaced by the same sentinels. The renderer keeps the old tool's trailing line breaks byte for byte. Update pyproject: add onex.nodes entry point and onex-architecture-discovery console script. Raise omnibase-core floor 0.47.31 -> 0.47.35 in both places (first release whose publish_and_poll takes client_security). Update uv.lock. Tests: 8 focused tests pass under tests/nodes/node_architecture_discovery_orchestrator (golden chain with in-process bus dispatch of all six phases, error chains for missing broker and rejected workspace, overlay refusal, template scan). Not in this commit: the internal copy of the node and its callers (morning tick) are untouched; they are repointed and deleted in a later change. * fix(OMN-20679): remove entry_points block from contract.yaml The Architectural Compliance Lint check failed on the PR's first head with ARCH-TOPIC-002 at src/omnimarket/nodes/node_architecture_discovery_orchestrator/contract.yaml line 82, the line " onex.nodes:" inside a contract entry_points block. The lint greps every line containing "onex." in a changed contract.yaml and treats it as a topic. The entry points already live in metadata.yaml and pyproject.toml, and no code reads the contract block. This commit removes the entry_points block from contract.yaml. No other file changes. After the change, the same grep over the contract finds no line that is not a standard topic name or a comment. The 9 focused tests, the entry-point format check and the runtime sweep import check pass. * feat(OMN-20679): Add contracts/OMN-20679.yaml and deploy surface test Adds contracts/OMN-20679.yaml carrying AC1 word for word, two evidence requirements, and two dod_evidence items. Adds test_discovery_node_deploy_surface_is_registered to the node's golden chain test file, asserting the onex.nodes entry point, onex-architecture-discovery console script, main runtime profile, and shipped schema and prompt template files. The second dod_evidence item runs the test with -k deploy_surface. AC2 is not claimed; it is closed by the later change in omnibase_internal that repoints callers and deletes the internal copy. This does not prove a deployed-runtime cycle; that remains for after merge. The 9 tests in tests/nodes/node_architecture_discovery_orchestrator pass. * fix(OMN-20679): lock omnibase-core at 0.47.34 and bind AC1 in the contract - pyproject.toml: the omnibase-core floor goes from >=0.47.35 to >=0.47.34 in both places (dependencies and override-dependencies); the comment names 0.47.34. - uv.lock: omnibase-core is locked at 0.47.34 (was 0.47.35); uv.lock revision stays 5 as on dev. - Reason for 0.47.34: it is the first release whose publish_and_poll takes client_security (verified in the omnibase_core tags: v0.47.32 has no client_security parameter, v0.47.34 has it). The 0.47.35 release removed scripts/validation/check_ai_slop.py, which the Aislop Sweep (strict, PR diff) job in ci.yml runs from the omnibase_core tag named in uv.lock, so that job failed on this branch. - Running the v0.47.34 scanner with --strict over the 14 changed .py/.md files exits 0; a control file with a sycophantic docstring exits 1. - contracts/OMN-20679.yaml: both dod_evidence items now use check_type test_passes with cwd ${OMNI_HOME}/omnimarket and binds_ac ["AC1"], and the file has the SPDX header, matching sibling contracts. Before, node_dod_verify run locally on the contract returned NO_ACCEPTANCE_CHECKS (AC1 unbound); after, acceptance_unbound_criteria is empty. * fix(OMN-20679): bind contract evidence to the test file, not the directory * feat(OMN-20686): Add node_throughput_tick_decision_compute to omnimarket (#3617) Adds node_throughput_tick_decision_compute to omnimarket. This includes contract.yaml with command topic onex.cmd.omnimarket.throughput-tick-decision-requested.v1 and terminal topic onex.evt.omnimarket.throughput-tick-decision-completed.v1, metadata.yaml, typed request and result models, a definition-B handler handle(request) -> result, an onex.nodes entry in pyproject.toml, and contracts/OMN-20686.yaml. Ports the controller, merges, floors and escalation findings of the merge-throughput tick (throughput_tick.py and the loops_check.py checks it calls, in the omni plugin of the private plugin repository). The handler reads no files, runs no process and has no clock: the caller supplies launchctl state, the PID's ps etime, the controller's last tick lines, heartbeat and state.json, the PR watcher state, the per-repo floors and the landing policy's land-like-operator logins. Parity: tests/fixtures/throughput_tick_parity.json holds 60 cases captured by running the old tick's functions against on-disk fixtures (fake launchctl and ps, state dir, watcher state, floors file, policy file). 3000 generated cases ran old and new with 0 mismatches; a deliberate one-character format change in the handler produced 40 mismatches in 200 cases (negative control). The 60 kept cases cover all 43 distinct finding shapes. Tests: 77 pass in tests/nodes/node_throughput_tick_decision_compute (parity, golden chain over the RuntimeLocal in-memory bus, error chain). ruff, ruff format and mypy --strict are clean on the new files. Not in this change: the lab-headroom finding, the effect node that reads the files and runs launchctl and ps, repointing callers, deleting the old script. * feat(OMN-16652): Add node_reject_skip_token_compute and pre-commit hooks (#3629) Added node_reject_skip_token_compute: contract.yaml, metadata.yaml, models, and handler HandlerRejectSkipToken.handle(ModelSkipTokenScanRequest) -> ModelSkipTokenScanResult. It is a pure scan: a text carrying [skip-<letter> (any case) is a violation unless the same text has "# skip-token-allowed: <receipt-id>" on one line. A staged file is in scope by type (.md .yaml .yml .txt, and .onex_state/evidence files ending .err .json .jsonl .log .out); a commit message and a PR body are always in scope. Command and terminal topics are declared in the contract. Registered under onex.nodes in pyproject.toml. Added .pre-commit-hooks.yaml exporting two hook ids: reject-skip-token (pre-commit stage) and reject-skip-token-commit-msg (commit-msg stage). Both run .pre-commit-hooks/reject-deploy-gate-skip-token.sh with language script. The script is now the omniclaude copy (it carries the OMN-12696 .onex_state/evidence scan and avoids bash here-strings) plus a new --commit-msg <file> mode that exits 2 when the file is missing. Added contracts/OMN-16652.yaml and tests/unit/nodes/node_reject_skip_token_compute/test_reject_skip_token.py. The tests hold the node and the script to the same verdict on a 30-case table, and run pre-commit try-repo for both ids. 82 focused tests pass. Against the previous script 9 of them fail (the evidence cases, the commit-msg cases, the here-string check and try-repo). No consumer repository is repointed and no vendored copy is deleted in this commit. No release tag is cut. * feat(OMN-20287): backend config drops forthcoming harness keys (#3631) Consumer first for the harness backend keys. ModelDelegationBackendConfig accepts and drops kind, harness, surface and tenant_scope, the keys a later release declares as fields; every other unknown key is still refused. The Wire Compatibility Gate refused declaring them directly: released v0.4.307 refuses all four. contracts/OMN-20287.yaml gains AC2 bound to test_omn20287_harness_backend_key_tolerance.py (6 passed). * ci(OMN-20422): pin omniintelligence to 33a29cdf and rename voter key (#3632) The Hostile Reviewer workflow clones omniintelligence at a pinned sha. The pin moves from 51e1cb356453ad325d76aea57ab371cf975df3a4 to 33a29cdfba6f14be6f94c3c77a05e29f345c692b, the dev tip that carries omniintelligence#1016 (an unparseable reviewer reply fails the vote instead of counting as a clean review; json_schema constraint on the second voter). The same bump renames the second voter key from gpt-oss-review to local-studio-planner (registry rename in omniintelligence#1014) at all roster sites: REVIEW_MODEL_KEYS and the two --model flags. The job-level env var LLM_GPT_OSS_REVIEW_URL is renamed LLM_LOCAL_STUDIO_PLANNER_URL; its value stays http://192.168.86.200:8131. New test tests/ci/test_hostile_reviewer_pin_omn20422.py (4 tests) failed before the workflow edit and passes after; the existing voter, roster and quorum-verdict tests are updated to the new key and env var. Contract OMN-20422 gains AC2 bound to the new test; AC1 is untouched. 28 tests passed across the six affected test files in tests/ci. * feat(OMN-20674): add node_morning_friction_sweep_orchestrator (#3613) Added node_morning_friction_sweep_orchestrator under src/omnimarket/nodes/ with contract.yaml, a declarative orchestrator node, a definition-B async handler handle(request) -> result, typed request, phase-result, overlay and result models, phase schemas packaged as JSON, a bus phase gateway, and metadata.yaml. The node ports the guarded morning friction sweep: same-date idempotency precheck (already-delivered and peer-owned verdicts spawn zero expensive agents; force bypasses; an unavailable or off-schema precheck falls through to a full run), five concurrent sources (scan plus linear, checkpoints, ci, guards), then synthesize, adjudicate and report, with the delegation-cell rule and the premise-audit rule refusing the run. Bus topics are declared in contract.yaml: start command onex.cmd.omnimarket.morning-friction-sweep-start.v1, terminals onex.evt.omnimarket.morning-friction-sweep-completed.v1 and onex.evt.omnimarket.morning-friction-sweep-failed.v1; phase work uses the existing delegation request and reply topics through infra request-response wiring. Briefs, report and state paths, ledger path, watermark tool, lane stems, CI repository list, premise-control lane names and freshness bounds are read from a strict overlay (pointer env OMNIMARKET_MORNING_FRICTION_SWEEP_OVERLAY, otherwise node_morning_friction_sweep_orchestrator/overlay.yaml under ONEX_SKILL_OVERLAY_ROOTS). An absent or invalid overlay refuses to start. The node package names no private repository or path; a test enforces it. The node is hosted unregistered (lifecycle experimental, no onex.nodes entry point in pyproject.toml), listed in tests/test_market_node_runtime_dogfood.py. The caller switch and the deletion of the original script and dry-read entry points are separate steps in the operator tooling repository and are not part of this commit. Tests under tests/nodes/node_morning_friction_sweep_orchestrator: 77 pass. They cover a golden chain, an error chain, overlay resolution and validation, the phase gateway, one full cycle over the in-memory bus auto-wired from the contract, and decision parity with six transcripts recorded from the original script (sha256 fc513b4c6249529f38f8b3d33625d6afe0a2e27b26c7772c2ba9aaecc816ff3b). Side-by-side check outside the repo: the handler with the real deployment overlay and the original script, run on the same six cases, produced 37 phase calls with identical prompt text, model, effort, phase and schema, and 6 identical results; changing one overlay value made 5 prompts differ. contracts/OMN-20674.yaml is the change contract for AC1 only. * feat(OMN-19448): delegation_events stores requested_model, queue_wait_ms and execution_ms (migration 0058) (#3522) * feat(OMN-19448): add requested_model and timing columns to delegation_events Adds migration 0058_delegation_events_requested_model_and_timing.sql with three nullable columns: requested_model TEXT, queue_wait_ms INTEGER, execution_ms INTEGER, plus a rollback file. requested_model is the model_id of the first entry of the delegate-skill terminal's attempts; the canonical terminal supplies it only when its payload names requested_model; it is never inferred from model_used. routed_model is unchanged and still the answering model. queue_wait_ms comes from the terminal's queue_wait_ms and execution_ms from its execution_duration_ms; NULL means not measured, a measured 0 is stored as 0. A later sparse terminal does not erase recorded values. The three columns are added to the node contract's projection_api columns, the terminal-owned columns, the local sqlite store DDL and the sqlite declared-columns list. Tests: tests/unit/delegation/test_terminal_timing_and_requested_model_omn19448.py (new), tests/test_omn19448_terminal_timing_and_requested_model_real_postgres.py (new, skipped without Postgres), and test_terminal_columns_omn19448.py updated. contracts/OMN-19448.yaml gains AC3 and AC4 bound to those tests. The omnibase_infra vendored copy of 0058 and the omnibase-infra pin bump are separate, later steps. * test(OMN-19448): give the skill-path real-Postgres case a registered tenant Set payload["tenant_id"] to _TENANT, imported from tests.test_omn18928_terminal_outcome_projection_real_postgres, for the skill path. Fixes TenantRegistryResolutionError (OMN-16804) for tenant slug delegation-projection-test in the queue_wait_ms 1234 and 0 cases. 20 tests pass across the four real-Postgres test files on a throwaway postgres:16. * Bump omnibase-infra floor to >=0.38.69 and relock uv.lock Sibling Release Compatibility Gate failed because migration 0058_delegation_events_requested_model_and_timing.sql is not in omnibase_infra v0.38.67; v0.38.68 also lacks it; v0.38.69 is the first release vendoring it byte-identical (blob 09009ba02f41c5c0066967baa776b568761a5315). Verified: uv sync gives omnibase-infra 0.38.69, 223 delegation tests passed. * bump the omnibase_infra checkout ref pins in 6 workflow files and one test from v0.38.68 to v0.38.69 to match uv.lock (0.38.69) Fixes tests/ci/test_sibling_pins_omn20001.py::test_infra_checkout_pins_match_lock failing in Tests (Split 2/20). Verified: 31 passed in tests/ci sibling pin and bus overlay parity tests. --------- Co-authored-by: codex <codex@omninode.ai> * feat(OMN-20669): Add node_remote_lane_compute and node_remote_lane_effect to omnimarket (#3616) * feat(OMN-20669): Add node_remote_lane_compute and node_remote_lane_effect to omnimarket This commit adds two new nodes to the omnimarket system. The first is node_remote_lane_compute, a pure compute node with no I/O. It subscribes to the topic onex.cmd.omnimarket.remote-lane-decision-requested.v1 and publishes the terminal event onex.evt.omnimarket.remote-lane-decided.v1. It contains two operations: decide_remote_lane_placement, handled by HandlerRemoteLanePlacement, which ports the remote-lane runner's eligible, choose_codex, and the shared choose_lane over host readings the placement reader already evaluated, returning the chosen host (or none) and a verdict for every reading; and decide_remote_lane_result, handled by HandlerRemoteLaneResult, which ports the runner's closing_outcome, final_lane_outcome, parse_delegation_line, delegation_problem, and waiting_on_background. The second node is node_remote_lane_effect. Its contract declares runtime_dispatch only, with no event_bus block, as node_lab_fill_effect does. It uses the command onex.cmd.omnimarket.remote-lane-effect-requested.v1 and the terminal events onex.evt.omnimarket.remote-lane-effect-completed.v1 and onex.evt.omnimarket.remote-lane-effect-failed.v1. It includes the operation resolve_remote_lane_ref, handled by HandlerRemoteLaneRef behind a git port (ProtocolRemoteLaneGit, local adapter LocalRemoteLaneGit), which ports resolve_sha and resolve_landing_branch, reading refs through the canonical clone or the public URL. A fix is included: every git option now goes before the remote. Previously, git ls-remote <remote> --symref HEAD read --symref as a ref pattern and printed no ref: line, so the runner resolved no landing branch. Both entry points are registered in pyproject.toml. Tests include golden and error chains for both nodes. 500 placement and 84 closing parity cases were recorded by running the runner's own functions. The effect golden chain uses real git in a temporary directory, with a positive control showing the old argument order reads no landing branch. 625 tests pass. Not in this commit: the placement lock and marker, the host transport, the lane run, the ledger relay, repointing callers, and deleting onex_remote_lane.py. * chore(OMN-20669): remove origin_tickets from contract.yaml * feat(OMN-20669): add the DoD contract for the remote-lane nodes - Add contracts/OMN-20669.yaml, the DoD contract required by repo-evidence / dod-verify at the PR head. - The PR log indicated it cites OMN-20669 but carried no contracts/OMN-20669.yaml. - Three ACs are bound to tests/nodes/node_remote_lane_compute, tests/nodes/node_remote_lane_effect, and the entry-point and metadata tests. - node_dod_verify returned status verified locally. * test(OMN-20669): bind AC3 to remote lane registration test - CI check repo-evidence / dod-verify failed on head fa51e80d with "OMN-20669 [dod-omn20669-ac3-registration]: bound test also passes at the merge base: the control did not fail (always-pass)" - AC3 was bound to tests/test_all_node_entry_points_are_package_form.py and tests/test_metadata_schema.py, which pass on dev without this change - Added tests/test_remote_lane_registration.py, which asserts node_remote_lane_compute and node_remote_lane_effect are package-form onex.nodes entry points and their metadata.yaml validates with matching names - Rebound AC3 and dod-omn20669-ac3-registration in contracts/OMN-20669.yaml to that test; it passes at the head and fails 4 tests at merge base 0ed3e089 * fix(OMN-20669): update dod_evidence to name specific test files - Changed AC1 check in contracts/OMN-20669.yaml to name the three test files in tests/nodes/node_remote_lane_compute - Changed AC2 check in contracts/OMN-20669.yaml to name the two test files in tests/nodes/node_remote_lane_effect - Resolved "binds_ac requires uv run pytest evidence naming an existing repo test file" error in tests/ci/test_repo_evidence_caller_workflow.py::test_every_repo_contract_binds_every_criterion - Verified locally: caller-workflow test passes and check commands pass (608, 18, 4 tests) * feat(OMN-20685): decide the hook refusal ledger row in a compute node (#3619) * feat(OMN-20685): port hook refusal row compute to omnimarket Adds node_hook_refusal_row_compute to omnimarket: contract.yaml, metadata.yaml, a definition-B handler HandlerHookRefusalRowCompute.handle(request) -> result, two frozen pydantic models, and an onex.nodes entry point in pyproject.toml. The node decides one plugin hook refusal's redacted, deduplicated FRICTION ledger row: redaction of credential-shaped text and pipe/newline characters, reason normalisation, 12-character dedupe key, per-session key for the secret-leak guard. It is a port without behaviour change of the omniclaude hook refusal recorder's pure functions (redact, normalise_reason, dedupe_key, build_row). Topics declared in the contract: subscribe onex.cmd.omnimarket.hook-refusal-row-build.v1, publish onex.evt.omnimarket.hook-refusal-row-built.v1. Runtime profile main. Tests: 144 golden cases captured from the recorder at omniclaude commit ad0aa0ddc, a golden chain and an error chain, a contract topics test. 157 tests pass. With the handler file removed both test files fail at collection. Also adds contracts/OMN-20685.yaml. Not in this change: the recorder's rate-limit state, ledger append and lane resolution, the repoint of hook_refusal.sh, and deletion of hook_refusal_recorder.py. The recorder is unchanged and remains the live path; those are later shards of the same ticket. * fix(OMN-20685): add missing requirement and binds_ac to dod-verify repo-evidence / dod-verify failed at head b5451a346 in step 'Must-fail control at the merge base' with 'OMN-20685: zero bound checks'. Cause: contracts/OMN-20685.yaml had no requirements/acceptance and its dod_evidence check had no binds_ac. Change: added requirement req-row-parity with acceptance AC1 and binds_ac [AC1] on dod-hook-refusal-row-parity. The 157 tests still pass. * feat(OMN-20475): publish judged acceptance verdicts through the emit daemon and replay a committed run (#3620) * feat(OMN-20475): add judged acceptance publish and replay nodes Added node_delegation_acceptance_judged_publish_effect: sends each ModelDelegationAcceptanceJudgedEvent to the local emit daemon through omnimarket events/emit_client.py (EmitClient), event type delegation.acceptance_judged. If the emit socket path does not exist, or the socket refuses an event, it returns status failed naming the socket path and the number published; the runtime reads status failed as a non-zero exit. Added node_delegation_acceptance_judged_replay_compute: pure; turns the lines of a committed judgments.jsonl and its summary.json into one event per item that has a primary judge, with the primary judge's calibration from summary.json and the call's own timestamp as call_time. It refuses the whole run (no events) for: a model with no tier, an item with no call time, a primary judge with no verdict, a delegated call judged twice, no calibration for the primary judge, or a judged-item count that differs from the sum of the summary matrix n. Registered delegation.acceptance_judged in the emit daemon topics.yaml (duty_critical, partition key correlation_id) and declared it emit-only in event_registry_drift_baseline.txt. Added 8 shared models under models/delegation_acceptance_judge, tests (18 passing), and contracts/OMN-20475.yaml binding AC1 to the publish tests. Not in this change: the delegation-judge skill shim (another repository), the J.2 events operation of the judge node, and the dev-lane replay readback. * test(OMN-20475): Use /tmp for Unix socket paths in publish tests On lab host h200 (macOS), tests of node_delegation_acceptance_judged_publish_effect built Unix socket paths under pytest's temp directory and one failed with "OSError: AF_UNIX path too long". Added a conftest fixture short_dir that makes a directory under /tmp and removes it afterwards; the publish tests and the golden-chain test now bind their sockets there. Result on this host after the change: 9 passed in the publish effect test directory. * Fix pytest selector token in OMN-20475 contract In contracts/OMN-20475.yaml, the AC1 uv run pytest command named the test directory tests/nodes/node_delegation_acceptance_judged_publish_effect. The CI test tests/ci/test_repo_evidence_caller_workflow.py::test_every_repo_contract_binds_every_criterion (Tests Split 2/20) failed because binds_ac requires a pytest selector token ending in .py. Changed the three occurrences (evidence command, dod check_value) to name test_publish.py in that directory. On h201, the CI test plus test_publish.py pass: 12 passed. * feat(OMN-20469): run task type reasoning on Qwen3.8-27B with thinking on (#3628) * feat(OMN-20469): Move reasoning to new thinking-on profile Moves task type reasoning on Qwen3.8-27B from local-qwen-prose-no-think to new profile local-qwen38-reasoning-thinking-on in inference_protocols.v1.yaml. Sends chat_template_kwargs enable_thinking true and no /no_think prefix. Temperature 0.3 default and max_tokens unchanged. complex_reasoning and every other class stay thinking off. Qwen3.6-35B-A3B on the Studio planner rung is not matched. ModelInferenceProtocolProfile.directive becomes optional. Validator rejects a profile with no directive, no request option and no default temperature. Evidence: 60-item pre-registered replay, knowledge-base-internal#1166. Thinking on accepted 48 of 60; thinking off accepted 28 of 60 (Codex judge) and 35 of 60 (Opus judge). Gains 33.3 and 21.7 points, exact paired p 0.00001 and 0.00098. Tests: new tests/unit/delegation/test_reasoning_thinking_on_omn20469.py. test_prose_task_class_no_think_omn18967.py records reasoning as a declared exclusion. Failed before the profile change, pass after. * test(OMN-20469): update reasoning test for thinking on Add trace_separated setting to the server stand-in. complex_reasoning keeps the unparsed-server stand-in and thinking off. A new test sends reasoning with thinking on to a stand-in that separates the trace, and asserts a non-empty, unrefused deliverable. The unparsed-server thinking-on shape is still asserted as refused. Probe on 2026-10-09 of the .201 vLLM server with enable_thinking true: message.content was "### ANSWER" then the answer; the trace was in a separate reasoning field. Result: 47 passed in the three focused files; 525 passed and 3 skipped across the other named neighbouring files. * chore(OMN-20469): add contracts/OMN-20469.yaml The repo-evidence dod-verify check on the pull request failed with "pull request cites OMN-20469 but carries no contracts/OMN-20469.yaml", and its notice says the contract has to be at the pull request head. The contract binds AC3 to the new test file tests/unit/delegation/test_reasoning_thinking_on_omn20469.py and AC4 to the pull request body figures. The Repo Evidence Dependency, Coverage Sweep Gate and CI Summary failures on that head followed from the dod-verify failure: the test shards were skipped. * fix(OMN-20469): Remove AC4 evidence from contracts/OMN-20469.yaml Removed AC4 criterion and its evidence from contracts/OMN-20469.yaml. AC3 remains bound to tests/unit/delegation/test_reasoning_thinking_on_omn20469.py. node_dod_verify in hosted mode against a clone of the branch returned status verified for the AC3 evidence, 17 passed. The AC4 evidence was a gh pr view command on the pull request body. The verifier derives a live pull-request-state check from such a command, and that check requires the pull request to be merged with required checks green. The repo-evidence dod-verify check is itself a required check on the pull request, so the derived check could never pass. * Wire lab work receipts into ledger serve (OMN-20278) (#3600) * Wire lab work receipts into ledger serve (OMN-20278) * Fix OMN-20278 red checks by adding missing contract file PR 3600 (OMN-20278) failed because the repo-evidence dod-verify job rejected the PR for lacking contracts/OMN-20278.yaml, causing cascading failures in CI Summary, Coverage Sweep Gate, deploy-gat…
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.
Lab: host=h202 (omnipc2), lane=omn20678-8436, head=3624098e58f1030407ca3884f2ac8cf3d10db5e2, command=RuntimeLocal run of the node's contract.yaml with a two-item request (one prompt "The task", one control prompt "Reply with exactly the word READY" with task_type summarization) against the dev delegation lane; observed runtime=completed, items=2, admitted=1, refused=1, receipts=1, failed=1 (the refused row counts as failed, as in the old tool); the admitted item completed on the deployed dev Kafka delegation chain with correlation_id=98bcc207-3aa5-4f39-a845-4ae0cd4a2494, run_id=4eaca4ae-0fe4-44af-9161-8d9e39378e43, model=Qwen3.8-27B, quality=1.0, response excerpt READY.
Summary
Evidence
Not in this PR
Evidence-Source: OCC#13395
Evidence-Ticket: OMN-20678