Skip to content

chore(OMN-15181): promote omnibase_infra dev->main — prod deploy-agent bootstrap unblock - #2475

Closed
jonahgabriel wants to merge 482 commits into
mainfrom
dev
Closed

jonahgabriel wants to merge 482 commits into
mainfrom
dev

Conversation

@jonahgabriel

Copy link
Copy Markdown
Collaborator

OMN-15181 — promote omnibase_infra dev → main (prod-bootstrap unblock)

Promotes dev (@cc013670) to main (@e3c43206, ~480 commits behind). Content
is dev's tree verbatim — infra main is strict=false, so no main
back-merge is required.

Driver (Finding 15, ledger 2026-07-26T17:40Z)

The prod deploy-agent self-updates from origin/main on every job
(git pull against main, not dev, before rebuilding/redeploying). All of
today's OMN-15181 prod-bootstrap fixes are dev-only today — the
operator-worded prod bootstrap (grant landed at onex_change_control#4926,
1be82bc9) cannot proceed to a real redeploy attempt until main carries
them. This promotion is the critical path item blocking that retry.

Fix-family riding along (OMN-15181, all merged to dev today)

  • omnibase_infra#2463 — materialize typed envelope for operation_match
    handlers (Finding 4: AttributeError: 'dict' object has no attribute 'event_type' crash in the deployed HandlerRedeployOrchestrator)
  • omnibase_infra#2467 — deploy-agent digest verify by image ID +
    local-presence-first pull (round 2)
  • omnibase_infra#2470 — parameterize prod compose image slot for
    pinned-digest deploys (round 3)
  • omnibase_infra#2473 — per-service stability-digest resolution in
    deploy-agent executor (round 4, Finding 11): resolve_stability_ready_digest
    / verify_running_image_digest / resolve_prod_target_service now key off
    a shared SERVICE_HEALTH_TARGET_INDEX instead of a single lane-wide digest

F14 contract correction riding along (no new commit — already on dev)

contracts/llm_endpoints.yaml on dev already declares embeddings-201 at
:8002 (landed 2026-07-01, PR#2170/OMN-13807). origin/main — the ancestry
anchor check_prod_promotion_lineage.py uses for prod release builds — still
declares it at the stale :8100. Live dual-probe evidence (ledger
2026-07-26T16:30Z): :8002 returns HTTP 200 (vllm text-embedding-qwen3
serving), :8100 unreachable. This promotion closes that drift as a side
effect of bringing main current with dev; no separate contract edit is
needed or included here.

Scope / non-goals

  • No prod mutation, no deploy commands, no lane container changes.
  • Does not touch the deploy-agent, its checkout, or any lane on
    omninode-pc.
  • Squash merge (repo policy) — Codex owns the merge; this PR is opened for
    review/gate-clearing only.

Refs: OMN-15181, OMN-13418 (parent epic)

promotion-receipt: OCC-PENDING

jonahgabriel and others added 30 commits July 5, 2026 05:31
…ion core, read-only) (#2206)

* feat(OMN-13942): runner-fleet-maintain workflow — Increment 1 (detection core, read-only)

Adds a canonical ONEX node workflow for runner-fleet health detection,
closing the OMN-13932 buildx/codeload blind spot. Strictly read-only:
no path in this PR restarts a runner, cancels a run, force-recreates a
container, or dequeues/re-enqueues a merge-queue entry.

New nodes (mirroring the same-repo node_merge_sweep_* trio and the
omnimarket node_redeploy_orchestrator gate-then-effect-then-terminal-event
topology):
- node_runner_fleet_maintain_orchestrator (ORCHESTRATOR_GENERIC, new):
  coordinates the tick — start -> snapshot-gather -> health-evaluate ->
  terminal completed event. No I/O.
- node_runner_fleet_health_compute (COMPUTE_GENERIC, new): pure/deterministic
  classifier. Ports collector_runner_health.py's crash-loop/offline logic,
  OMN-13915's _diag heartbeat-freshness rule, and OMN-13109's SILENT-WEDGE
  heuristic. Adds two NEW checks (BUILDX_UNAVAILABLE, CODELOAD_THROTTLED)
  that close the OMN-13932 gap. Emits recommended_actions that are recorded/
  surfaced only — nothing here executes them.
- node_runner_health_snapshot_effect (EFFECT_GENERIC): completed the OMN-6091
  stub in place (same contract/topics declared since OMN-6082) with real
  gh-api + SSH/Docker gather logic, incl. the two new probes.

Trigger: reuses OMN-13915's runner-fleet-canary 15-min GitHub-hosted
schedule per design — no new parallel schedule.

Also:
- Register both new nodes in [project.entry-points."onex.nodes"] and
  regenerate the dispatch-selection-parity oracle and topic enums.
- Add runtime_profiles: [effects] to all three new/completed contracts
  (ValidatorRuntimeProfiles gate).
- Allowlist the 8 new infra-owned handler paths in infra-node-allowlist.txt
  (runner fleet is infra's domain object, not a market business workflow).
- Baseline the orchestrator's inherent 3-hop payload_type_match ARCH-004
  finding (same accepted shape as 6 sibling orchestrators already baselined).
- Exempt two pattern-validator false positives (workflow_name, target_id —
  neither is an internal entity/UUID) with documented reasons.
- Allowlist the external-trigger start topic in the subscribe-wiring-health
  script (triggered by the canary schedule, not a Kafka publisher).

Increment 2 (recovery effects, FSM reducer, grant/cooldown gate) is
design-only per the task — not built here; a follow-up ticket will be filed
once this increment is reviewed.

Evidence-Ticket: OMN-13942

* fix(OMN-13942): fix Split test failures — baseline frozen-list + runner-image lock

- Update ARCH-004 imperative-orchestrator baseline frozen-list tests to accept
  the new node_runner_fleet_maintain_orchestrator entry (OMN-13942): add it to
  EXPECTED_OWNER_TICKETS and bump risk-2 count 6->7.
- Regenerate docker/runners/runner-image.lock.json: the two new node entry-points
  in pyproject.toml changed the manifest_digest (and shared_env_digest), so the
  bound runner-image identity was stale. Fixes Split 1/15 identity tests and
  runner-image-build-smoke.

Evidence-Source: OCC#3607
Evidence-Ticket: OMN-13942

* fix(OMN-13942): update frozen runner-identity digest in backmerge test

test_release_backmerge_preserves_runner_identity_lock froze the pre-regen
identity/shared_env digests. The two new node entry-points in pyproject.toml
rebind the runner-image identity (binding-not-label by design), so update the
frozen values to the regenerated, build-proven (runner-image-build-smoke pass)
digests bc29a1.../d11587...

Evidence-Source: OCC#3607
Evidence-Ticket: OMN-13942

* test: tolerate docker daemon latency
…t/orphan defects (#2208)

The 2026-07-04 runner-fleet non-convergence incident traced to three
compounding defects in auto_bounce(): (1) no lock, so the */10 cron could
dispatch a second force-recreate while a prior one was still running,
producing daemon-level "removal ... already in progress" races; (2) a fixed
120s timeout that SIGTERM'd docker compose mid-batch under host load, leaving
containers Status=created but never started (36% of recreate attempts never
completed during the incident); (3) no re-targeting for stragglers left at
Status=created, since they matched neither crashloop nor wedge detection and
were therefore invisible to future remediation cycles.

Adds a flock mutex around the bounce dispatch, scales the timeout with batch
size (floor/per-container-budget/ceiling instead of one fixed cap), and adds
a verify-start + bounded-retry pass plus new stuck_created detection so a
straggler is retried by the next cycle instead of orphaned forever. New
behavioral tests drive the real script end-to-end via mock docker/gh/curl
binaries and assert on the fix directly (stuck-created flagging, actual
compose+retry dispatch, and lock-contention skip).
…superseded/zombie runs (SAT1) (#2209)

* ci(OMN-13949): concurrency cancel-in-progress + job timeouts to kill superseded/zombie runs (SAT1)

Fleet-load reduction (Track 1, OMN-13932 §5.2). Superseded CI runs were
holding saturated self-hosted runners.

- Add top-level concurrency { group: workflow-<pr#|ref>, cancel-in-progress: true }
  to PR-triggered check/test/gate workflows (24 workflows). merge_group entries
  carry a unique github.ref so distinct queue entries never cross-cancel; the
  required contexts still report on merge_group.
- Normalize 5 workflows that kept superseded PR runs alive (ci.yml,
  compose-config-lint, env-parity, lane-census-staleness, runner-disk-preflight)
  from cancel:false / merge_group-only to cancel-in-progress: true.
- Deploy/release/prod-mutation/tag workflows deliberately NOT given
  cancel-in-progress: release.yml, release-python-reusable.yml,
  build-and-push-*, auto-tag-on-merge, runtime-rebuild-trigger,
  prod-promotion-lineage stay serialized (cancel:false) or untouched — never
  cancel an in-flight prod build/tag/deploy.
- Add safety-net timeout-minutes to every job lacking one (37 jobs across
  21 workflows; reusable 'uses:' jobs skipped) so a hung job cannot hold a
  runner indefinitely.

Verified: tests/ci/test_ci_workflow_resilience.py + test_runner_disk_preflight.py
(51 passed); actionlint clean (only pre-existing shellcheck/secret findings);
pre-commit clean on changed files.

* ci: skip docker integration tests on PRs

* ci: retrigger merge sweep checks
…ofile-aware teardown gate) (#2211)

* feat(OMN-13886): guard against bare compose down of runtime lanes

The ONEX runtime services are gated behind compose profiles ["runtime","full"],
so a bare `docker compose ... down` (no --profile runtime/full and no
--remove-orphans) tears down the un-profiled core deps while orphaning the
profile-gated runtime containers — the '2 hits in 24h' teardown defect (WS-2).

Enforcement, not detection (CLAUDE.md Operating Rule #5):
- tests/test_compose_profile_teardown_policy.py — self-contained scanner+test
  (mirrors omni_home's no-raw-prod-bypass gate). Flags a `down` at a runtime
  lane (docker-compose.infra.yml / lane overlay / -p lane project) that carries
  neither --profile runtime|full nor --remove-orphans. Doubles as a standalone
  pre-commit entrypoint via __main__.
- .github/workflows/no-bare-compose-teardown.yml — CI gate (pull_request +
  merge_group + push dev/main).
- .pre-commit-config.yaml — local no-bare-compose-teardown hook.

Scoped to `down` only: a bare `up` of docker-compose.infra.yml is a documented,
non-destructive core-only bring-up (dozens of legit recipes) — flagging it would
be pure false-positive noise. Escape hatch: `# compose-profile-ok: <reason>`.

Corpus made green by adding --remove-orphans to the full-teardown docs it flags
(docker/README.md, docker/docker-compose.infra.yml header, quickstart.md) so the
documented teardown actually removes the profile-gated runtime containers; the
historical 2026-05-04 keycloak plan checklist is path-allowlisted (the
no-planning-docs gate forbids editing it inline).

* ci(OMN-13886): run standalone scanner (not pytest) to avoid conftest deps

The gate ran `python -m pytest`, which auto-loads tests/conftest.py (pulls
python-dotenv etc., absent in the minimal CI env → ModuleNotFoundError, not a
real violation). Run the module's standalone __main__ scanner instead — same
path the pre-commit hook uses, zero conftest, stdlib-only corpus scan. The
self-tests still run in the full `uv run pytest tests/` suite + pre-commit.

* ci(OMN-13886): route teardown gate on trusted runners
…istries (omnibase_infra) (#2212)

Clears all 80 hardcoded-topics aislop-sweep findings in omnibase_infra to 0
without changing any wire topic string value.

Changes:
- event_bus/topic_constants.py: doctest continuation lines showing topic
  literals converted to RST double-backticks (docstring example only,
  testpaths is tests/ only so src/ doctests are never executed).
- runtime/models/model_projector_notification_config.py,
  runtime/models/model_transition_notification_publisher_metrics.py,
  runtime/publisher_topic_scoped.py,
  runtime/transition_notification_publisher.py: same backtick treatment for
  docstring/doctest examples showing "onex.fsm.state.transitions.v1".
- topics/contract_topic_extractor.py: YAML-shaped docstring examples
  converted to backticks.
- services/cost_api/snapshot_cache.py: added `# onex-topic-sot` file-level
  marker — this module IS the canonical registry for the three cost-snapshot
  projection topic constants it defines.
- services/observability/agent_actions/tests/{test_consumer.py,
  test_hardening.py, test_routing_decision_schema_handshake.py}: true
  relocation — imported the existing SUFFIX_OMNICLAUDE_* constants from
  omnibase_infra.topics.platform_topic_suffixes and replaced 57 duplicate
  inline topic literals with references to them (no more test-fixture
  markers needed since canonical constants already existed for every
  literal used).

dod_evidence (OMN-13944):
- hardcoded-topics scanner: 80 findings -> 0 findings (self-verify replica
  of node_aislop_sweep._check_hardcoded_topics)
- ruff format + ruff check --fix: clean on all 10 changed files
- mypy --strict on 7 changed non-test src files: Success, no issues
- pytest targeted: 94/94 passed (test_consumer.py +
  test_routing_decision_schema_handshake.py), 120/124 passed in
  test_hardening.py (4 pre-existing failures reproduced identically on
  unmodified dev HEAD — missing OMNIBASE_INFRA_AGENT_ACTIONS_KAFKA_BOOTSTRAP_SERVERS
  env var in this shell, unrelated to this change)
- pytest tests/unit (full unit suite, 21109 tests): 21071 passed, 9 failed
  (pre-existing perf-benchmark timing flakiness + unrelated
  test_provision_infisical.py failures, none touching changed files), 29
  skipped
- pre-commit run --files <changed>: all hooks passed, including "Check for
  AI-slop patterns" and "No hardcoded ONEX topic strings"
* fix(OMN-13947): recreate missing runner containers

* ci(OMN-13947): make receipt honesty checkout idempotent

* ci(OMN-13947): route sibling lock refresh on trusted runners
…ad of Unknown node (#2215)

`onex skill dep_cascade_dedup` hard-failed from the canonical infra venv with
"Unknown skill" even though the backing node node_dep_cascade_dedup_orchestrator
is registered in the omnimarket onex.nodes catalog and both request + result
models exist. The only gap was a missing skill_mapping.yaml row, so the
post-release dep-bump dedup sweep was unrunnable headless. Same regression
class as OMN-13511 / OMN-13712 (node exists, skill unmapped).

Additive mapping row only (mirrors merge_sweep shape); args mirror
ModelDepCascadeDedupRequest (repos/dependency-type/label/close-comment/dry-run).

Tests:
- dep_cascade_dedup registered + wired to node + typed result model
- payload validates against ModelDepCascadeDedupRequest (repos = the sweep's
  roots/repos it scans); dry-run boolean default wiring
- registered in the node-backed dogfood catalog-resolution gate
- CLAUDE.md rule #8 fail-fast guard: the sweep-repo-fallback _resolve_root in
  BOTH node_integration_sweep_orchestrator and node_dod_sweep_orchestrator
  raises RuntimeError when the repo-registry env is unset and no explicit root
  is supplied — never a silent default.

Closes OMN-13995
…edger-append ingress (#2232)

* feat(OMN-14134): add handle() adapter to HandlerLedgerAppend — wire ledger-append ingress

node_ledger_write_effect's contract declares operation_match routing with no
event_model, so handler_wiring._make_dispatch_callback dispatches via
handle(envelope) directly rather than execute(). HandlerLedgerAppend exposed
append()/execute() but no handle(), so auto-wiring bound the _missing_handle
sentinel and every dispatched ledger-append command raised at runtime
(WI-14 keystone gap).

Mirrors the shipped HandlerBuildLoopProjection.handle() precedent: extracts
the payload via getattr(envelope, "payload", envelope), coerces to
ModelPayloadLedgerAppend, delegates to append(), and wraps the result with
ModelHandlerOutput.for_compute() the same way execute() already does.

* chore(OMN-14134): bump node_ledger_write_effect contract version for handle() adapter

Wave C contract-sync gate requires contract.yaml to move alongside any
handler change in the same node directory.
…o auto-wiring resolver (#2234)

* fix(OMN-14139)(OMN-14140): wire node_ledger_write_effect handlers into auto-wiring resolver

Two defects blocked the ledger-append pipeline from ever running:

- OMN-14139: contract.yaml's handler_routing.handlers[] used the flat
  handler_class:/handler_module: fields, which ModelHandlerRoutingEntry
  does not parse (nested handler: {name, module} required) -- both
  entries silently dropped, wiring ZERO handlers. Fixed to the nested
  schema, plus an explicit topic: per entry so the two operation_match
  handlers don't hit the multi-handler topic-assignment ambiguity guard.

- OMN-14140: HandlerLedgerAppend/HandlerLedgerQuery required a
  db_handler constructor argument the auto-wiring resolver cannot
  supply (its known-injectable set is container/event_bus/
  ownership_query only), so even with routing fixed the handlers were
  unconstructable (quarantined). Both now compose HandlerDb internally
  from `container` alone, connecting lazily on first real use via
  `_ensure_db_ready()` since the resolver never calls initialize() on
  auto-wired handlers.

Also fixed, discovered during live verification: HandlerLedgerAppend's
OMN-14134 handle() adapter (and the mirrored one added here for
HandlerLedgerQuery) extracted payload/correlation_id via
getattr(envelope, "payload", ...), which silently no-ops on the DICT
envelope MessageDispatchEngine._materialize_envelope_with_bindings
actually delivers on the live dispatch path -- only object-shaped test
doubles worked. Both now use a dict-or-attribute extraction helper
mirroring HandlerBuildLoopProjection._coerce_event_message.

Verified live on .201 dev lane: wire_from_manifest resolves both
handlers with zero quarantine and registers both topic routes; a
synthetic ledger-append event produced to
onex.cmd.platform.ledger-append.v1 landed a durable row in
event_ledger (count 0 -> 1) with the lazily-connected HandlerDb and a
published onex.evt.platform.ledger-appended.v1 confirmation.

* fix(OMN-14139): remove ledger handler env reads

* test(OMN-14139): regenerate ledger dispatch parity oracle
… dev candidate runtime image can build (#2214)

* fix(OMN-13985): install pydantic before sibling-lock-pin preflight so dev candidate runtime image can build

The 'Stage workspace sibling trees into the build context' step runs
scripts/runtime_build/stage_workspace.sh, which invokes
scripts/runtime_build/check_sibling_lock_pins.py. That script imports
pydantic (BaseModel, ConfigDict, Field) at module top level, but the
workflow only sets up Python via actions/setup-python and installs no
project deps before this step. The preflight died with
ModuleNotFoundError: No module named 'pydantic' -> stage_workspace.sh
exit 3, so the docker build / ECR push / digest steps never ran.

Only pydantic is third-party; everything else the script imports is
stdlib. Insert a minimal 'pip install pydantic>=2' step against the
setup-python interpreter immediately before the failing staging step.
The script is invoked via bare 'python3', matching this install target.

Evidence: run 28748861432 failed at the staging step with the above
ModuleNotFoundError. Locally reproduced (clean venv): import fails
before install, and after installing pydantic the script reaches
argparse (exit 2), proving the import is resolved.

* ci(OMN-13985): route sibling refresh on trusted runners

* ci(OMN-13985): clean receipt honesty sibling checkout

* ci(OMN-13985): extend contract compliance timeout

* chore(OMN-13985): retrigger lint CI
…ns the OMN-13888 grandfather validator (#2231)

* fix(OMN-14130): bump omnibase-core 0.46.3->0.46.5 (OMN-13888 OCC grandfather validator)

omnibase_infra pinned omnibase-core==0.46.3, which predates OMN-13888
(per-entry OCC receipt hashing + append-only + supersession + dual-accept /
grandfather, shipped in 0.46.5). occ-preflight installs the caller repo's
pinned core version, so infra PRs were evaluating OCC eligibility with the
pre-grandfather 0.46.3 validator. That validator re-applies the old
'all receipts must equal the current whole-file contract hash' rule and
rejects any PR whose ticket contract received an append after merge
(e.g. OMN-14127 shared between omniclaude #1870 and infra #2230 →
contract_hash_mismatch on the legacy dod-omniclaude-pr-1870 receipt).

Bump to ==0.46.5 (both dependency groups) + regenerate uv.lock +
resync _FALLBACK_MATRIX in version_compatibility.py. Verified clean on
0.46.5: 25,453 tests collect with zero import/API breaks; full unit suite
21,076 passed (0 real failures); test_version_compatibility 25 passed.

Unblocks OMN-14127 (#2230) once merged + rebased. See also OMN-14131
(harden occ-preflight so the built main wheel wins over a CWD pin).

* fix(OMN-14130): refresh runner identity for core pin bump
…osted fail-closed poller so it never wedges under self-hosted saturation (#2230)

* ci(OMN-14127): convert CI Summary to no-needs GitHub-hosted fail-closed poller

Port the proven omniclaude #1870 wedge fix to omnibase_infra. The required
branch-protection context "CI Summary" was a needs-gated aggregator over ~20
self-hosted jobs; under fleet saturation those jobs never terminalized, so the
required check-run was ABSENT (not failing/pending) and PRs wedged BLOCKED with
no auto-recovery.

- ci-summary is now a NO-needs, runs-on: ubuntu-latest, if: always(),
  fail-closed bounded-deadline poller. Its check-run instantiates immediately
  (the required context can never be absent) and it polls the current run's job
  conclusions via the GitHub jobs API. Zero self-hosted/LAN dependency. Name
  'CI Summary' preserved byte-for-byte (rename would re-wedge every PR).
- scripts/ci/ci_summary_gate.py: default-deny, fail-closed verdict (exit
  0/1/2). Reproduces infra's exact original semantics (13 strict == success
  gates + 4 success||skipped gates as the completeness anchor) and adds a
  strictly-stronger default-deny sweep that catches detect-changes /
  plugin-env-service-completeness / compose-required-env-coverage /
  contract-path-preflight failures the old tests-gate greened on 'skipped'.
  Small soft-allowlist of genuinely-non-gating jobs (advisory / not-required),
  prefix-aware for reusable-workflow callers.
- tests/ci/test_ci_summary_gate.py: 18 unit tests pinning the fail-closed
  verdict (strict-skip=fail, sweep catches leaves, allowlist ignored, empty
  run != vacuous green, docs-only success).
- Removes the (unset, no-op) OMNI_REQUIRED_CI_RUNS_ON_JSON merge_group override
  from the ci-summary runs-on selector; the poller is runner-independent.

* fix(OMN-14127): allow hosted ci summary aggregator

* fix(OMN-14127): route ci process changes to ci tests

* fix(OMN-14127): fail closed on duplicate summary jobs
* ci(OMN-14104): gate all PR workflows on OCC preflight

* ci(OMN-14104): re-arm OCC preflight after evidence merge

* ci(OMN-14104): target core dev for OCC preflight callers

* ci(OMN-14104): pin infra OCC preflight reusable workflow

* ci(OMN-14104): pin infra OCC preflight to workflow-sha fix

* ci(OMN-14104): correct OCC preflight workflow pin

* ci(OMN-14104): use working OCC preflight core pin

* ci(OMN-14104): pin OCC preflight to dev-validator workflow

* ci(OMN-14104): pin OCC preflight to isolated wheel build

* ci(OMN-14104): pass explicit OCC preflight core ref

* ci(OMN-14104): pin infra OCC preflight to compat-dev core fix

* ci(OMN-14104): fail CI Summary explicitly when OCC preflight is red

CodeRabbit flagged that gating the required CI Summary aggregate with
`if: needs.occ-preflight.result == 'success' && (always())` turns a RED
occ-preflight into a SKIPPED CI Summary. A skipped required branch-protection
check reports as success, so a failed OCC preflight could be merged.

Keep `if: always()` and enforce OCC eligibility as the first step, failing
explicitly when preflight did not succeed so the required check stays RED.
CI Summary is the single umbrella required gate (OMN-4497,
.github/required-checks.yaml), so a red CI Summary blocks the merge even
though the runner-heavy fanout is (intentionally) skipped on preflight failure.

* ci(OMN-14104): re-trigger CI after transient startup_failure batch

The 06:58Z run batch on the prior push hit a transient GitHub Actions
startup_failure across all workflows (zero jobs, name==path, no diff cause —
untouched workflows failed too). Infra recovered by 07:01Z (sibling branch
runs queuing/running normally). startup_failure runs are non-retriable, so
this empty commit re-triggers a fresh CI cycle. No code change.

* ci(OMN-14104): re-pin occ-preflight reusable to merged omnibase_core dev SHA

The 43 workflow callers pinned the occ-preflight reusable (and its core-ref
input) to 7975803283 — a commit on the omnibase_core OMN-14104 PR branch
(#1396, 'ci: use dev for OCC preflight compat checkout'). That PR squash-merged
to omnibase_core dev (8a47e092), deleting the branch and ORPHANING 7975803283.
GitHub Actions can no longer resolve the reusable at an unreachable SHA, so
every caller on this branch hit startup_failure ('workflow file issue', zero
jobs) — all 43 workflows red.

Re-pin all 86 references (43 uses:@ + 43 core-ref) to 8a47e092002dd1338599fa0733feda469436acbf,
the merged commit that last defined occ-preflight.yml on omnibase_core dev
(ancestor of dev HEAD, reachable). Input interface is identical
(contracts-dir/receipts-dir/core-ref, all optional) — verified against both
SHAs. Also rebased onto origin/dev to pick up the 4 missing commits (incl.
OMN-14130 core 0.46.5 bump for the grandfather validator).

* ci(OMN-14104): refresh dispatch parity fixture

* ci(OMN-14104): restore routed dispatch parity fixture

* ci(OMN-14104): refresh parity fixture metadata

* ci(OMN-14104): allow reusable occ preflight in webhook tests

* ci(OMN-14104): run plugin lifecycle guard in uv env
…s (WS-F) (#2219)

* fix(OMN-14017): set UV_HTTP_TIMEOUT=600 on merge_group validator gates

Three merge_group required-status validators (Runtime Profiles, URL Authority
Gate, Validate Validator Requirements) run a raw `uv sync` via astral-sh/setup-uv
directly, bypassing the hardened ./.github/actions/setup-python-uv composite.
That path inherits uv's 30s default timeout with zero retries, so it fails HARD
on the first PyPI download timeout under fleet egress saturation (WS-F) — while
the 16 composite-using workflows retry through the same contention.

Observed: the Runtime Profiles / validate merge_group check at the omnibase_infra
queue HEAD (run 28775491973) failed on `virtualenv==20.36.1` with
'network timeout ... current value: 30s'.

Set UV_HTTP_TIMEOUT=600 at the workflow env level of all three (matches the
composite's ${UV_HTTP_TIMEOUT:-600} and ci.yml/omni-standards precedent). It
propagates to every uv sync and uv run --with git+https call in the job. Minimal,
uniform, no step restructuring.

Related: OMN-13932 (WS-F fleet epic; systemic mirror decision is separate).

* ci(OMN-14017): retrigger stale canceled checks

* fix(OMN-14017): route sibling lock refresh runner

* ci(OMN-14017): widen saturated validator gate budgets
* feat(OMN-14029): scale runner fleet to 56

* ci(OMN-14029): refresh cancelled status rollup

* fix(OMN-14029): preserve runner script executable bits

* fix(OMN-14029): trust local runner listener health during api flaps

* fix(OMN-14029): reconcile runner fleet target to 64

* ci(OMN-14029): narrow stale todo checkout fetch

* ci(OMN-14029): route sibling lock refresh on trusted runners
…lows (Lever 1 fan-out) (#2224)

* ci(OMN-14078): remove merge_group triggers from 15 non-required workflows (Lever 1 fan-out)

Lever 1 fan-out from docs/plans/2026-07-06-ci-streamlining-logjam-reduction-plan.md
(sibling of OMN-14076 core canary). The merge queue only waits on required
status contexts; these 15 workflows carry none, so their merge_group runs burn
shared self-hosted runner slots and gate nothing.

Removes only the merge_group: trigger from each on: block. pull_request and
push triggers untouched -- nothing un-enforced. No logic changes. Verified
against the LIVE required_status_checks: every required-context carrier keeps
its merge_group trigger; no cut workflow produces a required context.

* ci(OMN-14078): refresh gates after OCC evidence binding

* ci(OMN-14078): route sibling lock refresh on trusted runners

* ci(OMN-14078): raise uv timeout on required install gates

* ci(OMN-14078): align runner disk preflight trigger test

* ci(OMN-14078): retrigger checks after runner reset

* ci(OMN-14078): fix url authority workflow env block
…ice 2, the §1 fix) (#2217)

* feat(OMN-13997): verification-receipts raw ledger projection (WS-L slice 2, the §1 fix)

Second migration slice of the event-sourced ledger substrate (epic OMN-13989,
plan §2.5 / §6 Phase 1). Replicates the proven slice-1 receiving-end pattern.

verification-receipts (.onex_state/verification-receipts/*.yaml) is THE ledger the
initiative exists to fix: plan §1.1 names it the direct doctrine §1 contradiction
(completion-evidence ledger on local disk); the hostile review re-ordered it to
Phase 1 "delivered early". Higher current-gap value than dispatch-log.

Pure DB projection over the existing ProjectorShell + ModelProjectorContract
engine: ZERO new node, ZERO bespoke class (rule 7a). Reference: overseer_tick_ledger
(088), decision_store (046).

Artifacts (omnibase_infra):
- docker/migrations/forward/089_create_verification_receipt_ledger.sql (089 —
  088 reserved by in-flight #2216) — append-only verification_receipt_ledger;
  envelope_id PK idempotency; single_partition ordering; queryable NULLABLE core
  columns + phases JSONB + receipt_body JSONB (lossless full-fidelity capture).
- rollback + restamped schema_fingerprint.sha256.
- src/omnibase_infra/projectors/contracts/verification_receipt_projector.yaml —
  consumes onex.evt.omniclaude.verification_receipt.v1, append mode.
- tests/unit/runtime/test_verification_receipt_projector.py.

Doc-discrepancy reconcile (verified on-disk):
- On-disk receipts are the payload shape, not full ModelEventEnvelopes (as slice-1).
- HETEROGENEOUS shapes: ticket receipts + overseer-verify-tick share a core; one
  legacy baseline snapshot omits ticket_id/phases. Handled by nullable core
  columns + lossless receipt_body JSONB.
- ticket_id nullable (1/9 files lack it); overseer_verdict on only 2/9.
- Plan §6 topic onex.evt.omniclaude.verification-receipt.v1 differs from the
  existing node_verification_receipt_generator topic
  (onex.evt.omnimarket.verification-receipt-completed.v1) — that node is not this
  skill-written flat-file ledger. Event-type uses underscore per contract pattern.

Net-negative: adds only the target projection surface (no new flat-file writer).

Deferred (follow-up children of OMN-13989): emit-side dual-write (WS-6 MSK-IAM
cutover, not this lane); golden-chain replay-equivalence (T15); cutover of the
receipt-gate reader onto the projection.

dod_evidence: 4/4 new tests pass; 457 projector suites unaffected; ruff + SPDX +
migration-sequence + writer-coupling + schema-fingerprint green.

Closes OMN-13997

* ci(OMN-13997): refresh stuck checks

* ci(OMN-13997): refresh stale PR checks

* ci(OMN-13997): refresh duplicate cancelled guard contexts

* fix(OMN-13997): require raw receipt body projection

* ci(OMN-13997): isolate receipt honesty validator checkout

* ci(OMN-13997): route sibling lock refresh via runner selector

* ci(OMN-13997): retrigger stale canceled checks

* ci(OMN-13997): refresh wedged docker build gate

* ci(OMN-13997): retry receipt honesty core clone
…schema silent-zero-parse (#2235)

* fix(OMN-14141): fail-closed guard + CI gate for handler_routing flat-schema silent-zero-parse

The flat handler_class:/handler_module: schema silently parsed to zero
handlers, then auto-wiring reported WIRED with zero dispatchers while still
subscribing to and committing Kafka offsets on the topic — silent
phantom-wiring (the WI-14 root cause, OMN-14139/OMN-14135).

Enforcement (CLAUDE.md Rule #5 — gate ships WITH the fixes):
- Guard A (parse-time): discovery._parse_handler_routing raises on a flat/
  malformed handlers[] entry instead of silently skipping it. Legacy top-level
  handler: fallback preserved (empty handlers list never raises).
- Guard B (wire-time): _commit_contract_wiring reports FAILED (not WIRED) and
  does NOT subscribe when a contract declares subscribe topics but registers
  zero dispatchers. Never fires on legacy fallbacks (>=1 dispatcher) or
  resolver-ownership/quarantine skips.
- CI gate + pre-commit hook: handler_routing_schema validator rejects flat
  entries across all node contracts (SYNC'd ci.yml step + pre-commit hook).

Contract fixes (7 infra contracts the gate would reject; ledger done in #2234):
node_savings_estimation_compute, node_build_loop_write_effect,
node_session_state_effect, node_pattern_lifecycle_effect, node_validation_executor,
node_decision_store_query_compute, node_baseline_comparison_compute.

Verified: 111/111 contracts discover with zero errors; Guard B fires on zero
real contracts; 354 auto-wiring/kernel tests + 11 new guard tests green.

Follow-up (separate PR): 3 omnimarket flat-schema contracts + omnimarket-side gate.

* test(OMN-14141): refresh dispatch parity oracle
* ci(OMN-14078): remove duplicate validator workflow env

* ci(OMN-14078): retrigger after OCC evidence merge
…t + repair tick (#2223)

* fix(OMN-14060): omnimarket venv drift guard — dynamic ref + pre-flight + repair tick

Closes the OMN-13829 recurrence: install-node-skill-package.sh baked in a
hand-edited omnimarket SHA that went stale within days, and nothing
re-asserted the venv's install state afterward, so it silently reverted to
a stale PyPI install (missing the operation: field fix, OMN-13530).

- install-node-skill-package.sh now resolves OMNIMARKET_REF dynamically from
  omnimarket's live dev HEAD (git ls-remote), falling back to the local
  canonical clone at $OMNI_HOME/omnimarket when offline. An explicit
  OMNIMARKET_REF override still wins outright (pinned/offline use). Kills the
  stale-pin-layer-two problem the OMN-14060 investigation surfaced.
- New src/omnibase_infra/cli/omnimarket_drift_guard.py: a cheap, LOCAL-ONLY
  (no network) pre-flight check wired into `onex skill <name>` that compares
  the current interpreter's installed omnimarket commit against the
  already-checked-out $OMNI_HOME/omnimarket clone. Fails open whenever either
  side can't be determined locally (CI, fresh machines); raises a clear,
  actionable error pointing at the repair command on a real mismatch. Never
  re-installs anything itself (detect only).
- New scripts/check-omnimarket-venv-drift.sh: the repair half, meant for a
  session/cron tick. Refreshes the canonical clone from origin/dev, compares
  against the target venv, and with --repair re-runs
  install-node-skill-package.sh pinned to the fresh SHA.

Verified locally end-to-end: installed a deliberately stale SHA, confirmed
`onex skill aislop_sweep` hard-fails with the STALE message, ran
check-omnimarket-venv-drift.sh --repair, confirmed it fixed the venv and the
skill dispatches again. 21 new tests (drift guard unit tests + hermetic
script tests using a local bare-repo remote and a fake python shim, no
network); all pre-existing cli/scripts tests still pass (582 total in
tests/unit/cli/ + tests/scripts/); ruff format/check, mypy, and pre-commit
all clean on the touched files.

Companion to OMN-14064 (separate lane: the release-side gate for the
PyPI-uninstallable omnimarket 0.4.6 pin) — this PR is the venv-side guard
only.

* ci(OMN-14060): refresh cancelled gate rollup
)

* fix(OMN-13992): inject _topic into projection dispatch input_data

HandlerProjectionLiveEvents.handle() requires a non-empty
input_data['_topic'] (docstring: "Expects input_data to contain ... _topic:
source Kafka topic string"), but _make_projection_dispatch_callback
computed topic locally (for logging only) and never injected it into
input_data alongside _db/_event_type. Every real dispatch on the .201 dev
lane raised ValueError and the event was dropped, non-fatally but silently,
because the contract also had no DLQ topic declared. The 6 subscribed
topics all hit this; node-heartbeat is the only one with steady traffic on
the idle dev lane, producing the ~30s drop cadence observed in OMN-13992.

Fix: inject input_data["_topic"] = topic next to the existing _db/
_event_type injection. Other projection handlers tolerate a missing
_topic via a topics[0] fallback, so they are unaffected; this closes a
real correctness gap for any handler (now or future) that requires the
actual dispatched topic rather than a same-node guess.

Companion fix in omnimarket adds event_bus.dlq_topics to
node_projection_live_events/contract.yaml so any future malformed event
is dead-lettered instead of dropped.

* ci(OMN-13992): retry runtime npm CLI install

* ci(OMN-13992): refresh cancelled node migration check

* ci(OMN-13992): retrigger stuck node migration workflow

* ci(OMN-13992): refresh cancelled required gate contexts

* fix(OMN-13992): preserve npm retry failure status

* ci(OMN-13992): refresh kafka boundary gate after runner install casualty
* fix(OMN-14028): raise hot runtime service memory caps

* ci(OMN-14028): refresh cancelled status rollup

* ci(OMN-14028): refresh cancelled required gates

* ci(OMN-14028): refresh cancelled runner contexts

* ci(OMN-14028): refresh cancelled lightweight gates

* ci(OMN-14028): refresh kafka boundary gate after runner install casualty
* chore(OMN-14030): consolidate host cleanup installer

* ci(OMN-14030): refresh cancelled status rollup

* fix(OMN-14030): consolidate host cleanup and redpanda volume gc

* ci(OMN-14030): refresh cancelled runner checks

* ci(OMN-14030): refresh cancelled node migration sync

* chore(OMN-14030): retrigger cancelled CI
…-only bypass leak) (#2225)

Shift defect detection left by closing the dominant bypass leak found in the
OMN-14099 audit: the local pre-commit git hook was never installed in 6 of 7
canonical clones under $OMNI_HOME, so every repo's .pre-commit-config.yaml was
pure decoration. No --no-verify needed -- the hook simply never ran, so every
commit silently skipped ALL local enforcement (hardcoded IPs/topics, banned
constructs, URL/model-literal authority, skip tokens, PEP-604 unions, ...) and
CI became the first (most expensive) catch point.

Fix: wire an idempotent `pre-commit install` (+ best-effort `install-hooks`)
into scripts/pull-all.sh -- the sync entrypoint every session already runs
before ticket work. It activates the already-written, correctly-scoped hooks
across every repo that ships a config, at commit time.

Guarantees:
- Idempotent: skips repos whose hook is already pre-commit-managed (fast no-op).
- Scoped: only touches repos that ship a .pre-commit-config.yaml.
- Fail-soft: a hook-install problem never fails the pull; left out of FAILED.
- Offline-safe: writing the hook script is the load-bearing step (no network);
  env pre-build is best-effort and envs otherwise install lazily at first commit.

This is NOT a new pattern check -- it closes a leak so already-existing gates
(URL-authority, canonical-inference, topic/IP/path guards, skip-token rejection)
fire pre-commit instead of first failing in CI/CodeRabbit/merge-sweep.

Net-negative surface: adds no new CI gate; instead it makes CI the BACKSTOP for
~400 already-written hooks that were previously CI-only on this machine.

Tests: TestPreCommitHookInstall (install-when-config-present, idempotent-noop,
no-config-no-hook) drive the real script via subprocess against real git repos;
all 28 tests in the module pass. E2E-verified that the installed hook blocks a
deliberately-bad commit.

Relates OMN-13979 (CI audit), OMN-13981 (validator telemetry).
* build(deps): bump omnibase-core from 0.46.3 to 0.46.5

Bumps [omnibase-core](https://github.com/OmniNode-ai/omnibase_core) from 0.46.3 to 0.46.5.
- [Release notes](https://github.com/OmniNode-ai/omnibase_core/releases)
- [Changelog](https://github.com/OmniNode-ai/omnibase_core/blob/dev/CHANGELOG.md)
- [Commits](OmniNode-ai/omnibase_core@v0.46.3...v0.46.5)

---
updated-dependencies:
- dependency-name: omnibase-core
  dependency-version: 0.46.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* build(deps): refresh runner image identity for core 0.46.5

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jonah Gray <jonah@omninode.ai>
…rd-drift in workspace builds (OMN-14138) (#2233)

* fix(OMN-13902): stop sibling-pin guard false-blocking registry forward-drift in workspace builds (OMN-14138)

The workspace-build sibling-pin preflight (check_sibling_lock_pins.py) treated
ANY version mismatch as fatal. But OMN-13929's post-publish release-identity
disarm bumps a sibling's DEV pyproject version to N+1 the instant version N is
published, so every registry-sourced sibling's dev clone is PERMANENTLY one
version ahead of the last-published pin a consumer's uv.lock can carry. A
workspace build vendors the clone (newer by design), so the guard reported
[DRIFT/forward] and aborted EVERY workspace runtime build from dev.

Fix: in workspace mode, a registry-sourced pin (git_rev is None) whose clone
version is strictly FORWARD of the lock is recorded as a non-fatal
forward_drift_allowed note -- the registry-sourced analogue of the OMN-13403
git-rev clone_ahead exemption. Backward drift (stale clone -- the 2026-06-11
crash shape), non-comparable versions, and git-sourced drift all stay FATAL, and
release-mode (the strict default) stays fully strict. The workspace callers
(stage_workspace.sh, deploy-runtime.sh) pass --build-source workspace; any other
caller fails closed to strict.

Proven behavior (unit + CLI): core lock=0.46.5 clone=0.46.6 (registry forward)
PASSES in workspace / FAILS in release; spi lock=0.23.1 clone=0.23.0 (registry
backward) FAILS in both; git-sourced forward stays fatal. The in-build re-checks
(compute_workspace_provenance _load_pin_comparison drift_count +
resolve_workspace_pins.compare_pin, which already classified forward as
allowed "ahead") are consistent with the fix.

OMN-13902 OMN-14138

* chore(OMN-13902): retrigger OCC preflight after core workflow fix
…32.0,<0.51.0 (#2227)

* build(deps): update uvicorn requirement

Updates the requirements on [uvicorn](https://github.com/Kludex/uvicorn) to permit the latest version.
- [Release notes](https://github.com/Kludex/uvicorn/releases)
- [Changelog](https://github.com/Kludex/uvicorn/blob/main/docs/release-notes.md)
- [Commits](Kludex/uvicorn@0.32.0...0.50.2)

---
updated-dependencies:
- dependency-name: uvicorn
  dependency-version: 0.50.2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* build(deps): refresh runner image identity for uvicorn bump

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jonah Gray <jonah@omninode.ai>
…ings (#2240)

Vendors omnimarket's new node-owned migrations (source of truth:
omnimarket#1649) into this repo's forward-migration tree via
scripts/sync-node-migrations.sh, so a clean redeploy picks them up:

  - docker/migrations/forward/nodes/node_projection_delegation/
    0022_delegation_events_tenant_id.sql
  - docker/migrations/forward/nodes/node_projection_savings/
    080_savings_estimates_tenant_id.sql

Both are ALTER TABLE ... ADD COLUMN IF NOT EXISTS tenant_id TEXT NOT NULL
DEFAULT 'omninode', closing a HIGH-severity defect found by independent
adversarial verification of the OMN-14058 interim tenant_id stamp
(omnibase_core#1404 / omnimarket#1648): neither delegation_events nor
savings_estimates had a tenant_id column, so PostgresSyncProjectionAdapter.
upsert() raised `column "tenant_id" does not exist` against real Postgres
the moment ONEX_TENANT_ID was set.

Verified in sync with the omnimarket dev tip's node migration source via
`scripts/sync-node-migrations.sh --check` (0 drift beyond these 2 files);
node-scoped migrations under nodes/ are excluded from the flat
schema_fingerprint.sha256 (non-recursive glob), so no fingerprint restamp
is required.

Sequencing: this repo's node-migration-sync CI check (and local
onex-check-node-migration-sync pre-commit hook) resolves against
omnimarket's dev tip, so it will read as OUT OF SYNC until omnimarket#1649
merges to dev -- expected, same pattern as the existing omnibase_core#1404
-> omnimarket#1648 dependency. Do not merge this PR before omnimarket#1649.

Closes OMN-14058 (infra vendoring half; see omnimarket#1649 for the
source-of-truth migration + real-Postgres regression test).
…0.120.1,<0.140.0 (#2228)

* build(deps): update fastapi requirement

Updates the requirements on [fastapi](https://github.com/fastapi/fastapi) to permit the latest version.
- [Release notes](https://github.com/fastapi/fastapi/releases)
- [Commits](fastapi/fastapi@0.120.1...0.139.0)

---
updated-dependencies:
- dependency-name: fastapi
  dependency-version: 0.139.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* build(deps): refresh runner image identity for fastapi bump

* fix: refresh runner identity after fastapi merge

* fix: align build loop append wiring

* fix: sync vendored node migrations

* fix: refresh fastapi gate evidence

* fix: refresh dispatch parity fixture

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jonah Gray <jonah@omninode.ai>
jonahgabriel and others added 19 commits July 25, 2026 19:41
…mount cache builds no longer fail (#2452)

* fix(OMN-15141): runner image ships docker buildx plugin — BuildKit --mount cache builds no longer fail

The omninode-deploy-runner image installed docker-ce-cli + docker-compose-plugin
(OMN-14966) but not docker-buildx-plugin. docker/Dockerfile.runtime uses
BuildKit-only RUN --mount=type=cache syntax; without buildx, docker compose
build has no BuildKit backend and falls back to the legacy builder, which
dies with "the --mount option requires BuildKit" (deploy run 30178195370,
stability release-train deploy hop iteration N+4).

Add docker-buildx-plugin to the same apt-get install line as docker-ce-cli /
docker-compose-plugin (same Docker apt repo, package add only,
identity-neutral per runner-image.lock.json).

* chore(OMN-15141): retrigger occ-preflight after Evidence-Source amendment

---------

Co-authored-by: Jonah Gray <jonah.g.gray@gmail.com>
Verifies OMN-15094 (#663)\047s workflow_receipt.json terminal_event_hash by
replaying the recorded delegation-terminal Kafka event via the real
node_kafka_replay_compute kafka.replay operation and diffing the
reconstructed hash against the receipt.

Re-verified the ticket\047s seam assumptions against #663\047s actual landed
implementation before building (per the ticket\047s own instruction) and found
two real deviations, documented inline in verifier.py:

1. node_kafka_replay_compute lives in omnibase_infra, not co-located with
   OMN-15094\047s renderer (omninode_infra docker/onex-api). Adding
   omnibase-infra as a pip dependency of onex-api is not viable --
   omnibase-infra 0.36.1 requires fastapi<0.137/redis<8.0/uvicorn<0.50, all
   three violated by onex-api\047s live pins. This verifier therefore lives
   here and consumes the rendered workflow_receipt.json as a durable
   artifact rather than importing the renderer.
2. HandlerKafkaReplay.handle() (ModelKafkaReplayOutput) exposes only
   correlation_id_chain/offsets/counts, not decoded payload content. Its
   envelope_deserializer extension point is used to capture the decoded
   terminal fields into a side-channel this verifier owns.

Acceptance tests (all RED-then-GREEN driven against the real
HandlerKafkaReplay through its documented consumer_factory test seam):
  1. No replay/verify wrapper existed before this change.
  2. Replay reproduces byte-identical terminal_event_hash -> PASS.
  3. A mutated replay input -> FAIL with a named field diagnostic.

Seams:
  - kafka.replay: node_kafka_replay_compute contract.yaml handler_routing,
    operation kafka.replay, HandlerKafkaReplay -- driven directly, not
    reimplemented.
  - Wire shape: wire_shape.parse_delegation_terminal_envelope mirrors
    omninode_infra workflow_terminal_consumer.parse_terminal_envelope
    field-for-field (cross-repo, no shared package available -- see
    wire_shape.py docstring). Pinned by
    test_wire_shape_matches_terminal_consumer.py.
  - Hash: receipt_hash.sha256_of/canonical_json mirrors
    workflow_receipt_renderer._sha256/_canonical_json byte-for-byte. Pinned
    by test_receipt_hash_matches_renderer.py.
  - Topic constants: DELEGATION_COMPLETED_TOPIC/DELEGATION_FAILED_TOPIC
    resolve from the canonical omnibase_infra.topics.platform_topic_suffixes
    registry (SUFFIX_DELEGATION_COMPLETED/SUFFIX_DELEGATION_FAILED), never
    hardcoded.

Follow-up (not done here, out of scope): the wire-shape/hash mirrors above
are exactly the class of thing omnibase_compat exists to solve -- moving
both into that shared package is real follow-up work.

Evidence-Source: OMN-15095, blocked-by OMN-15094 (omninode_infra#663, merged
2026-07-25T22:25:23Z as f262cfe8)

Co-authored-by: jonahgabriel <jonahgabriel@users.noreply.github.com>
…olidate DEPLOY_RUNNER_* var docs (#2453)

merge sweep: landing OMN-15142 after deploy-gate/OCC evidence repair and fresh clean CI.
…t catalog, T0/T1 readback, dev gotchas, prod pointer (#2454)

Extends docs/runbooks/release-train-lab.md (existing mechanism doc, not a
new file) with the operator-facing procedure proven live on run
30180376657 (2026-07-26, tag lab/stability/20260725T235956Z-87ec5b3165ce,
overall: PASS) — the terminal success of the six-iteration OMN-14900
hardening chain.

- Copy-paste tag-cut + watch procedure with expected output and a
  tag-content WARNING (never reuse a parked tag name).
- Preflight catalog: what each of the 6 landed fixes (#2450/#2446/#2444/
  #2452/#2434/#2448) catches, with pre-fix failure signatures.
- T0/T1 readback discipline: health 18085/18086, contract-count floor vs.
  regression, discovery_errors baseline, consumer groups, vcs_ref
  ancestry; FAILED_ROLLED_BACK equality-proof discipline.
- Dev-lane gotchas: stale workspace-build config YAML, OMN-14968 false
  FAILED on runtime-worker; pointer (not duplicate) to
  cold-lane-full-bringup.md for cold bring-up.
- Prod: pointer-only section citing CLAUDE.md rules 2a/12 and the
  onex_change_control#4892 prep-only grant-PR pattern; explicit
  raw-docker-mutation prohibition citing the no-raw-prod-bypass gate.
- Verification checklist + rollback section.

Co-authored-by: jonahgabriel <jonahgabriel@users.noreply.github.com>
Merged by Codex merge sweep after OCC#4991 companion landed and branch protection reported CLEAN.
@coderabbitai

coderabbitai Bot commented Jul 26, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: bbc30d90-deb7-495c-8ca5-1b3a4181062c

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev

Comment @coderabbitai help to get the list of available commands.

@jonahgabriel

Copy link
Copy Markdown
Collaborator Author

Live gate readback (2026-07-26T17:20Z)

  1. Merge conflict, resolved via backmerge PR: dev/main have diverged (merge-base 2026-06-11, ~6wks stale) — mergeStateStatus=CONFLICTING on open. Verified file-by-file that main carries no content dev lacks (Dockerfile.runtime crypto/Trivy floors, OMN-15115 LLM retry schema — all already on dev, several via dedicated prior backmerges). Opened chore(OMN-15181): backmerge main into dev for infra promotion #2476 (backmerge/OMN-15181-main-into-dev -> dev, -s ours, zero content diff, parents = dev-tip + main-tip) to resolve the ancestry-level conflict without touching content. This PR will re-sync once chore(OMN-15181): backmerge main into dev for infra promotion #2476 merges to dev.

  2. Check-suite dedup gap (GitHub-side, not this PR's content): main-target-guard, occ-autobind, CI Summary, deploy-gate, and the rest of the pull_request-triggered fanout have NOT fired on this PR at all as of open+edit — confirmed via GET /repos/.../commits/{sha}/check-suites: the head SHA (cc013670, dev's tip) already had 5 completed github-actions check-suites from the push event when infra#2473 merged (16:57:45Z), and GitHub did not create a fresh check-suite for this PR's opened (17:09:44Z) or edited event. Zero workflow runs exist for this PR beyond a stray issue_comment-triggered gate. This is the known GitHub one-check-suite-per-SHA-per-app limitation, not a defect in this PR's diff. Expected to self-resolve once chore(OMN-15181): backmerge main into dev for infra promotion #2476 merges and this PR gets a synchronize event against a genuinely new SHA (fresh check-suite guaranteed). Not working around it with a direct push to dev — staying inside normal PR/CI process.

  3. promotion-receipt line: currently a placeholder (OCC-PENDING) pending OCC autobind mint once the guard actually runs against a fresh check-suite; will update to the real OCC-<n> once autobind fires (adopt/rerun, not hand-authored).

No prod mutation, no deploy-agent/lane touch. proof_class=receipt-bound (live gh api evidence above).

Merged by Codex merge sweep after OCC#4992 companion landed and rerun CI Summary passed.
Merged by Codex merge sweep after OCC#4993 landed and required CI Summary passed; backmerge unblocks omnibase_infra dev-to-main promotion.
@jonahgabriel

Copy link
Copy Markdown
Collaborator Author

Correction to my prior comment (2026-07-26T17:20Z): the backmerge did NOT resolve the conflict.

infra#2476 merged (17:35Z) but as a squash (repo is squash-only: allow_merge_commit=false) — its resulting commit has exactly ONE parent, silently discarding the intended dev-tip + main-tip ancestry my -s ours merge was built to establish. Verified: git merge-base origin/dev origin/main is identical (b7c93a8e, 2026-06-11) before and after #2476 merged. This PR is still mergeable: CONFLICTING.

Real scope, verified via git merge-tree: 160+ conflicting files, not a small set — CLAUDE.md, pyproject.toml, uv.lock, dozens of .github/workflows/*.yml, and substantial src/omnibase_infra/ runtime/node source (e.g. service_kernel.py differs 652 lines between dev/main tips). This is a structural consequence of squash-only merge policy never letting git merge-base(dev, main) advance, compounding for ~6 weeks since the last real promotion (#2164/#2166, July 1) — not something a quick manifest-sync or ancestry trick can fix. Root cause + evidence + acceptance criteria filed as OMN-15195 (distinct from OMN-12478, which covers the opposite direction/mechanism).

This PR stays open, correctly shaped (head=dev, title/body cite OMN-15181, F14 contract fix and fix-family riding along with zero extra diff) but is blocked on OMN-15195's resolution — real per-hunk content reconciliation across the full conflict set, which is out of scope for this session (risk of silent regression across core runtime source if rushed). Not merging, not force-resolving. Handing off with full evidence.

proof_class=receipt-bound (live gh api + git merge-tree/merge-base evidence above, all reproducible).

@jonahgabriel

Copy link
Copy Markdown
Collaborator Author

Superseded by #2477 — direct dev→main is CONFLICTING (squash-severed merge-base). #2477 uses a git commit-tree bridge commit (parents = main + dev, tree = dev) under the operator-ruled one-time merge-commit exception (OMN-15195). Closing this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants