Repository navigation
fix(OMN-18114): carry the tenant-projection profile on the lab lanes, and gate lane profile carriage - #3385
Conversation
… and gate lane profile carriage
Eight omnimarket contracts declare `runtime_profiles: [tenant-projection]`.
`filter_manifest_for_runtime_profile` admits a contract to a profile only when
that profile is named in the contract's own list, so `main` and `effects` skip
all eight -- and NO service on any .201 compose lane bound
RUNTIME_PROFILE=tenant-projection. All eight were therefore discovered and
consumed by nothing, permanently, with no error on any process, because the
manifest each process sees simply never contained them.
Measured read-only on the .201 dev lane 2026-09-10, inside the running
omninode-runtime container:
total_discovered 499
main owned 301
effects owned 177
tenant-projection owned 8
main skipped_target True effects skipped_target True
and off the broker:
local.omnimarket.node_projection_delegation_inference_response.consume.1.0.0
.__i.runtime-main.__t.onex.evt.omnibase-infra.inference-response.v1
STATE Empty MEMBERS 0 CURRENT-OFFSET 644 LOG-END-OFFSET 840 LAG 196
last commit 2026-09-04T09:46Z, lag 126 on 09-06 and 143 on 09-08. All eight
contracts read Empty on that lane; the delegation-orchestrator group on the SAME
topic reads Stable, which is the positive control that the probe works.
The profile pin was made for onex-dev (OMN-17641, ratified permanent by
OMN-17556), where no pod binds ONEX_TENANT_DB_URL and strict-mode wiring was
crash-looping the runtime plane. It is a GLOBAL contract declaration, and it
collaterally orphaned the same eight on the compose lanes -- which do bind that
DSN and whose local topology resolves `tenant_projection` by `dsn_env`.
RED then GREEN, same working tree:
* before: 3 failed, 2 passed, 1 skipped -- the two lab lanes named, and the
base compose reported as declaring no carrier at all.
* after: 5 passed, 1 skipped.
WHY NO GATE SAW IT. tests/ci/test_lane_projection_writer_coverage_omn17562.py
measures the adjacent class -- contracts the kernel SUBSCRIBES and never
dispatches. A contract removed from the manifest by the profile filter is never
subscribed, so it cannot appear in that gate's 16-name registry, and it does not.
OMN-17641 scoped compose out in as many words; OMN-17562 scoped profile-filtered
contracts out implicitly. The class fell between the two.
THE GATE (tests/ci/test_lane_runtime_profile_carriage_omn18114.py) asserts, per
governed lane: every profile a contract pins itself to resolves through the real
load_runtime_profile and is consumer-attached in core (negative-controlled
against a name the registry must refuse); dev and stability-test each START a
service binding it; the per-lane uncarried count is pinned shrink-only; no
started service names a profile the runtime cannot resolve (OMN-17985's k8s
finding, applied at the compose layer where it never was); and the carrier stays
inert on prod, judge and lakshman. A sixth test re-derives each profile's
contract set through discover_contracts + filter_manifest_for_runtime_profile
when omnimarket is importable, so the registry cannot drift from the ownership
filter it describes.
THE CARRIER is the ONEX runtime kernel under a different RUNTIME_PROFILE -- same
image, same entrypoint, same wire_from_manifest path, no `command:` override --
mirroring the onex-dev Deployment exactly. It is NOT a BaseProjectionRunner like
the six standalone writers: that class builds a topology-blind adapter, which
handler_hook_event_capture's own docstring records as the reason it stopped
extending it.
It is declared in docker/docker-compose.infra.yml, because the runtime env
anchors live there and YAML anchors do not cross compose files -- declaring it in
an overlay would mean re-declaring ~340 lines of environment. It carries a
compose profile no lane's bring-up requests, so prod, judge and lakshman RENDER
it and never START it; the two lab overlays opt in by overriding `profiles:`.
That inertness is asserted, not assumed.
Its role identity is its own, not main's: a second kernel reusing main's
capabilities would put a second claimant on main-owned topics and start duplicate
heartbeat loops for the same deterministic node IDs. The runtime policy contract
gains a fourth, OPTIONAL process name; the three shared kernels stay mandatory on
every lane, so no lane is forced to declare a carrier it does not deploy.
Changes:
* contracts/services/runtime_policy.contract.yaml + docker/runtime-policy.env:
a `tenant-projection` process on the dev and stability-test lanes only.
Rendered, not hand-edited; --check-env-file passes.
* model_runtime_process_policy.py / model_runtime_profile_policy.py: the
fourth name, and REQUIRED_RUNTIME_PROCESSES so "a name a lane MAY use" and
"a name every lane MUST supply" stay two different statements.
* docker-compose.infra.yml: the carrier, its volumes, and the inert profile.
* docker-compose.dev-lane.yml / docker-compose.stability-test.yml: the opt-in.
The proof lane gets it too -- `stability-proven` is resolved from that lane,
so a proof lane carrying fewer contracts than the mutable one proves less
than the lane it certifies.
* docker/catalog/services/tenant-projection-writer.yaml + bundles.yaml: the
catalog render is validated on every deploy, and an overlay stanza with no
base definition there makes that render invalid.
* scripts/deploy-runtime.sh: the two lane-only restart arrays. Deliberately
NOT RUNTIME_SERVICES -- that array is lane-agnostic, and since the service
IS declared in the base, a prod `up -d --no-deps` naming it would succeed
and start the carrier on a lane that never opted in.
* deploy/lane-census/lane-manifest.yaml, the two required-env manifests, and
the four counting assertions that now count four runtime kernels instead of
three, each with the reason recorded rather than the number bumped.
Out of scope, stated: what the eight can WRITE once carried.
projection_delegation_inference_response_text has FORCE RLS with no writer
policy (OMN-17298) and the no-authority GUC defect is OMN-17422. This makes them
carried; whether their INSERTs are accepted is those tickets'. onex-dev already
has the carrier and is unchanged. No lane was mutated by this change.
OMN-18114
…enant_projection binding
Both found by the governed pre-push full suite on the lab host, not locally.
* tests/unit/infra/test_stability_test_runtime_lane.py
::test_stability_lane_volumes_do_not_reuse_production_names -- the proof
lane's carrier was sharing the base's concrete log volume name with the dev
lane's carrier. Both volumes are now lane-scoped, which the lane's own
invariant requires and which also keeps two processes' output attributable.
* tests/unit/topology/test_application_database_topology.py -- the catalog
manifest declares ONEX_TENANT_DB_URL, so the carrier is a discovered
application-DSN consumer and must be declared in
docker/catalog/database-consumers.yaml. It binds tenant_projection for the
same reason every other entry there does; the inventory is exact by design,
so an undeclared consumer is drift rather than an omission.
OMN-18114
There was a problem hiding this comment.
Hostile Reviewer — adversarial findings (OMN-17492)
Models succeeded: glm-review
Models failed: codex
New finding threads: 1
Deduped (already posted on this PR): 0
Nit-level findings suppressed: 0
The model is the FINDER, never the gate: merge is gated only by the
deterministic Hostile Review Thread Gate, which blocks while
hostile-reviewer threads are unresolved. Resolve each thread after
addressing (or rejecting, with a reply) its finding.
Findings not anchored to a changed file
-
[MAJOR] hostile-reviewer (glm-review)
Dev lane inherits shallow curl healthcheck; only stability-test gets the strict probe | The base declaration in docker-compose.infra.yml ships
curl -sf http://localhost:8085/health, which the diff's own commentary (OMN-17883, OMN-15217) identifies as incapable of failing on a DEGRADED runtime. The stability-test overlay replaces it with the semantic probe, but the dev lane overlay adds only profiles, environment, and labels. The dev lane therefore runs the carrier with exactly the healthcheck the diff calResolve this thread when addressed — the
Hostile Review Thread Gateblocks while hostile-reviewer threads are unresolved (OMN-17492). -
[MAJOR] hostile-reviewer (glm-review)
STABILITY_TEST tenant-projection env vars absent from required-env manifests | The stability-test overlay requires six STABILITY_TEST_RUNTIME_TENANT_PROJECTION_* variables with
:?/?interpolation, but the diff adds only the three DEV_ spellings to docker/required-env-vars.manifest.txt and generated-compose-required-env.manifest.txt. If the manifest gates completeness (its name and sorted structure indicate it does), the proof lane's requirements are undeclared, and a deployment that validates againstResolve this thread when addressed — the
Hostile Review Thread Gateblocks while hostile-reviewer threads are unresolved (OMN-17492). -
[MAJOR] hostile-reviewer (glm-review)
Backlog on stranded consumer groups is abandoned, not drained or reset | The carrier deliberately uses new group ids so the eight contracts do not resume the stranded
__i.runtime-maingroups. That decision is stated but its consequence is not handled: the existing lag (documented at 196 and climbing for node_projection_delegation_inference_response, plus whatever backlog the other seven groups hold) is orphaned on the old groups with no offset-reset, migration, or monitoring plan. The defect that motivateResolve this thread when addressed — the
Hostile Review Thread Gateblocks while hostile-reviewer threads are unresolved (OMN-17492). -
[MINOR] hostile-reviewer (glm-review)
Proof lane mounts the dev delegation bifrost config | The stability-test overlay's volume list mounts
./lane-overlays/dev.bifrost.yamlinto the proof-lane carrier. The lane sets BIFROST_VERIFY_ENDPOINTS=0 (verify disabled) per its contract profile, yet receives the dev lane's delegation configuration. Cross-lane config bleed on a lane whose purpose is to certify prod behavior undermines the proof premise the diff itself argues for ('a proof lane that carries fewer contracts than the mutable dev lane proveResolve this thread when addressed — the
Hostile Review Thread Gateblocks while hostile-reviewer threads are unresolved (OMN-17492). -
[MINOR] hostile-reviewer (glm-review)
Merged-services test helper diverges from real compose merge semantics |
_merged_servicesin the new CI gate implements a hand-rolled merge:{**base_body, **overlay_body}plus special cases for environment and profiles. Real compose merge has per-key rules for many other keys (ports, volumes append sequences, labels append sequences, depends_on merges per-service). The gate's carriage and inertness decisions read only profiles and environment, so the special cases cover what it uses today, but the helpeResolve this thread when addressed — the
Hostile Review Thread Gateblocks while hostile-reviewer threads are unresolved (OMN-17492).
Findings demoted from threads (anchor rejected)
-
[MINOR] hostile-reviewer (glm-review)
Strict-probe and labels-override tests assert global regex counts | The updated assertions count regex matches across the entire stability-test compose file:
len(strict_blocks) == 4andoverride_count == 4. These counts include every service in the file, so the test fails spuriously when any unrelated service adds a strict probe or an override label block, and it does not verify WHICH services carry the probe, only that the file-wide total is 4. The same brittleness the comment criticizes in>= 3applResolve this thread when addressed — the
Hostile Review Thread Gateblocks while hostile-reviewer threads are unresolved (OMN-17492).
|
| Surface | Meaning | Blocks merge? |
|---|---|---|
| Review threads | Per-finding, posted by the reviewer | No (informational) |
Hostile Review Thread Gate |
Deterministic: unresolved hostile-reviewer threads exist | Fails until resolved (not yet a required context) |
degraded verdict |
Fewer than 2 models succeeded (infra) | No |
Powered by omniintelligence.review_pairing.cli_review — multi-model adversarial review: qwen3-review, qwen3-review-b, glm-review (OMN-8468/OMN-8524/OMN-17492)
Four counting/coverage assertions that describe the lab lanes by exact count and
now describe four runtime kernels instead of three. Each is updated with the
reason recorded, never the number bumped:
* tests/ci/test_bifrost_lane_overlay.py — the carrier overrides `volumes:`
wholesale (it needs a lane-scoped state root), so it would LOSE the pinned
bifrost overlay mount silently if the override omitted it. The exact count
is the point: an inequality would not see a service dropping out of the pin.
* tests/ci/test_runtime_policy_contract.py — the carrier is the same kernel
under a different RUNTIME_PROFILE, so its auto-wired consume boundary makes
the same DLQ-routing decision and must read the same lane-scoped stance.
Leaving it unbound would give one process on the lane an implicit position
on a flag every other process declares explicitly.
* tests/scripts/test_deploy_runtime_rt6_scoped_readback.py, both lane cases —
RT-6 refuses to certify a deploy whose in-scope service has no running
container, so a new member of either lane-only recreate array must appear in
the readback fixture or the fixture stops describing the real lane. The
proof-lane case needs no ps_map special case, which is itself the check that
the overlay's lane-scoped container_name follows the convention.
WHY THE GOVERNED PRE-PUSH DID NOT CATCH THESE, stated because it matters more
than the four fixes. The heavy fail-closed escalation runs
`pytest ${FULL_SUITE_TARGET}` with FULL_SUITE_TARGET="tests/unit/"
(scripts/hooks/prepush_smart_tests.sh:1337) — a positional path. pytest then
ignores `testpaths`, so that run collects tests/unit/ ONLY and never
tests/ci/, tests/scripts/, tests/integration/, scripts/ci/tests or
scripts/tests. That is why h105 reported 27468 tests green on this exact tree
while CI failed four tests in tests/ci/ and tests/scripts/. It is the OMN-15410
defect class — a hardcoded positional path making the invocation, not
pyproject's testpaths, the real definition of "the full suite" — which
OMN-15410 closed in ci.yml and not in this hook. Reported separately; not fixed
here, because widening the pre-push target is a cost decision about every lane's
push, not a change to smuggle into a projection-carriage PR.
OMN-18114
…cope test and OMN-18110's attach retry)
…cope OMN-18108 landed on dev while this branch was open and bound the shell array to its Python twin: scripts/deploy-runtime.sh's DEV_LANE_ONLY_RUNTIME_SERVICES and deploy_agent.events.DEV_LANE_ONLY_RUNTIME_SERVICES are now asserted equal in both directions by test_dev_lane_only_scope_omn18108.py, so editing one alone is a red test. That is the property the binding was added for, and it fired here exactly as intended. The carrier belongs in that scope for the OPPOSITE reason the six writers do, stated separately so the two do not merge. Those services exist only in the dev-lane overlay, so a prod deploy naming one fails outright. This service IS declared in docker-compose.infra.yml, so every lane resolves the name — which is precisely why it cannot be lane-agnostic: a prod or judge `up -d --no-deps tenant-projection-writer` would SUCCEED and start the carrier on a lane that never opted in, defeating the compose profile that keeps it inert. It also matters more than most members. It is the only process that owns the eight contracts pinned to `runtime_profiles: [tenant-projection]`, so an agent scope that could not reach it would leave those eight running an image the rest of the lane had moved past — the exact defect OMN-18108 measured, on the one service where nothing else would ever notice. Also merges origin/dev, which brings in OMN-18110's failed-attach retry. That is the peer lane's fix for node_omnigate_projection and is a DIFFERENT mechanism from this one: that contract is in main's manifest and its attach raised after readiness passed, so a retry reaches it. The eight here are never in the manifest at all, so no retry can. OMN-18114
#8881) * evidence: OCC companion pass 1 for OmniNode-ai/omnibase_infra#3385 * evidence: OCC companion self-bind for #8881 * evidence(OMN-18114): bind AC1-AC4 to the RED-first carriage gate and the two lab-lane carriers Additive only. No generated item is edited and the autobind-authored checks are byte-identical. AC1 — the gate is RED against the tree as it stood at parent 170474981: 3 failed, 2 passed, 1 skipped, naming dev and stability-test and all eight contracts, and reporting that no service in the base compose bound a carrier profile at all. GREEN after the change: 5 passed, 1 skipped. The two that passed at the parent are the registration and unregistered-profile controls, so the three reds are the defect and not a broken harness. AC2 — the obligation is re-derived through the kernel's own discover_contracts then filter_manifest_for_runtime_profile path and through the real load_runtime_profile, and carriage is computed from the base plus overlay merge rather than from a hand-maintained list. AC3 — the gate lives under tests/ci/, collected by the full-suite step through pyproject testpaths (that step passes no positional path by design), and the per-lane count is pinned in BOTH directions so a landed carrier that did not lower the pin fails too. AC4 — both lab lanes carry it and prod does not. THE THREE ABSENCE CONTROLS ARE COMPOUND, not bare. Each first requires a needle that must be present at that ref, then requires the absent one to be absent, so a failed fetch reads as a failure instead of as a green control. Proven both ways: all 17 bound checks exit 0, and the two absence controls were re-run against inputs where the needle IS present (the dev overlay, and tests/ci at the merged head) and correctly exited non-zero. AC5 is deliberately left unbound. It is the live consumer-group readback after the deploy agent rebuilds the dev lane from the merged head, which has not happened yet. It will be bound once real, or its absence named, rather than asserted early. OMN-18114 * evidence(OMN-18114): count with awk in the three absence controls, not grep Two separate defects in the same three lines, both caught by this repo's own gates rather than by review. 1. SIGPIPE. The re-run after the installation's API quota recovered went from 0/22 to 19/22 PASS with a single BLOCK, and that one exited 141. `grep -q` stops at its first match and closes the pipe, killing the `printf` feeding it; under `pipefail` the command is then 141, not 0. A false red this gate has produced before. 2. Fail-open. Rewriting it as `grep -c ... || true` is the exact shape the OMN-9350 check_value linter rejects, and it is right to: the `|| true` swallows a failed fetch. `awk` closes both. It reads all of its input, so nothing SIGPIPEs it; it always exits 0, so no `|| true` is needed; and it prints an integer, so the comparison is explicit. The result is fail-CLOSED, which is the property that matters: proven by running the check with an empty body, where PRESENT counts 0 and the check exits 1 rather than reporting a clean absence. Verified under `set -o pipefail`: the live control exits 0 with present=1 absent=0, and the empty-body control exits 1. OMN-18114 * fix(OMN-18114): bind AC receipts for OCC companion --------- Co-authored-by: node-occ-companion-effect <occ-companion-effect@omninode.ai> Co-authored-by: jonahgabriel <jonah@omninode.ai>
The committed census snapshot (deploy/lane-census/census-snapshot.json) was emitted 2026-09-02T12:28:09Z and crossed the Lane Census Staleness gate's 7-day MAX_AGE_DAYS boundary at ~2026-09-09T12:28Z, so `Lane Census Staleness + E-5 Env Drift (OMN-13034)` has been red on every open omnibase_infra PR since. This is the fourth occurrence of the same treadmill; prior refreshes were #2691, #2846 and #2998. Regenerated READ-ONLY against 192.168.86.201's live Docker Engine API inventory (GET /containers/json, GET /networks — 166 containers, 23 networks, inventory_source=engine_api, no stderr, no compose mutation, no lane touched), following the process the prior refresh PRs used: capture the inventory with lane_census_inventory.py, then run the pure planner (lane_census_plan.py) and the event builder (lane_census_event.py) against this branch's lane-manifest.yaml. The inventory script was shipped to a scratch path on .201 and checksum- matched to this branch's copy (md5 5c85a052ce1bbee97fff2893316284f4) rather than run from a checkout there, because .201 carries no canonical omnibase_infra clone and the desired-state definition must match this PR exactly. New snapshot: emitted_at=2026-09-10T10:06:57.003308+00:00, drift_count=6 (up from 2). Nothing here is hand-edited; the four added findings are what live state actually is. Two of the four are the direct, expected consequence of #3385 (OMN-18114), which merged as the current dev tip and added `omnimarket-stability-test-tenant-projection-writer` and `omnimarket-tenant-projection-writer` to the manifest's desired state. Neither lane has been rebuilt since that merge, so both read container_absent. The census is correct: desired moved, actual has not caught up yet. This snapshot documents that gap; it does not remediate it, and remediation is out of scope for a doc-freshness refresh. The other two are dev-lane unexpected_container warnings for `onex-api` and `omninode-infra-routing-decisions-consumer` — both running and healthy on the dev lane, both carrying com.omninode.lane='dev', neither declared in the manifest. Also documented, not remediated. The two findings already in the prior snapshot are unchanged: the prod `omninode-prod-runtime-worker` container_absent and the dev `omnibase-infra-forward-migration` unexpected_container warning. Verified locally before commit, all three of the gate's own steps: - check_lane_census_age.py --max-age-days 7 -> OK, 0h old - check_lane_env_drift.py (E-5) -> OK, no drift across all five lanes - generate_claude_lane_block.py -> renders clean - 73/73 lane_census unit tests pass Ticket: OMN-13034
OMN-18114
Eight omnimarket contracts declare
runtime_profiles: [tenant-projection].filter_manifest_for_runtime_profileadmits a contract to a profile only when that profile is named in the contract's own list, somainandeffectsskip all eight — and no service on any.201compose lane boundRUNTIME_PROFILE=tenant-projection. All eight were therefore discovered and consumed by nothing, permanently, with no error on any process, because the manifest each process sees simply never contained them.Root cause, proven live and read-only before any edit
Inside the running
omninode-runtimecontainer on the.201dev lane, 2026-09-10:Off the broker, same lane:
Last commit on that group was 2026-09-04T09:46Z; lag was 126 on 09-06 and 143 on 09-08, so it grows monotonically. All eight contracts read
Emptyon the lane — uniform, so systemic. Positive control:local.runtime_config.delegation-orchestrator...on the same topic and partition readsStable, so the probe works and the zero is a real absence.The mechanism is
src/omnibase_infra/runtime/auto_wiring/profile_ownership.py:88. The pin was made for onex-dev (OMN-17641, ratified permanent by OMN-17556), where no pod bindsONEX_TENANT_DB_URLand strict-mode wiring was crash-looping the runtime plane. It is a global contract declaration, and it collaterally orphaned the same eight on the compose lanes — which do bind that DSN (RUNTIME_PROFILE=main,ONEX_WIRING_STRICT_MODE=1,ONEX_TENANT_DB_URL=postgresql://tenant_projection_writer:***@postgres:5432/omnidash_analytics) and whose local topology resolvestenant_projectionbydsn_env, notsecret_ref.The only carrier that exists anywhere is the onex-dev Deployment
omnimarket-tenant-projection-writer.Why no gate saw it
tests/ci/test_lane_projection_writer_coverage_omn17562.pymeasures the adjacent class: contracts the kernel subscribes and never dispatches. A contract removed from the manifest by the profile filter is never subscribed at all, so it cannot appear in that gate's 16-name registry, and it does not. OMN-17641 scoped compose out in as many words ("no compose-lane change, the .201 lab lanes are OMN-17562's"); OMN-17562 scoped profile-filtered contracts out implicitly. The class fell between the two.RED then GREEN, same working tree
tests/ci/test_lane_runtime_profile_carriage_omn18114.pyat the parent commit:With the change:
5 passed, 1 skipped. The two that passed at the parent are the registration and unregistered-profile controls, both negative-controlled, so the three reds are the defect and not a broken harness.The gate
Per governed lane it asserts: every profile a contract pins itself to resolves through the real
load_runtime_profileand is consumer-attached in core, negative-controlled against a name the registry must refuse;devandstability-testeach start a service binding it; the per-lane uncarried count is pinned shrink-only; no started service names a profile the runtime cannot resolve (OMN-17985's k8s finding, applied at the compose layer where it never was); and the carrier stays inert onprod,judgeandlakshman. A sixth test re-derives each profile's contract set throughdiscover_contracts+filter_manifest_for_runtime_profilewhen omnimarket is importable, so the registry cannot drift from the ownership filter it describes; it skips loudly in the CI job where omnimarket is deliberately absent, the same limit the sibling gate records.The carrier
The ONEX runtime kernel under a different
RUNTIME_PROFILE— same image, same entrypoint, samewire_from_manifestpath, nocommand:override — mirroring the onex-dev Deployment exactly. It is not aBaseProjectionRunnerlike the six standalone writers: that class builds a topology-blind adapter, whichhandler_hook_event_capture's own docstring records as the reason it stopped extending it.It is declared in the base compose because the runtime env anchors live there and YAML anchors do not cross compose files; declaring it in an overlay would mean re-declaring ~340 lines of environment. It carries a compose profile no lane's bring-up requests, so
prod,judgeandlakshmanrender it and never start it, and the two lab overlays opt in by overridingprofiles:. That inertness is asserted, not assumed. Its role identity is its own, not main's: a second kernel reusing main's capabilities would put a second claimant on main-owned topics and start duplicate heartbeat loops for the same deterministic node IDs.The proof lane gets it too.
stability-provenis resolved from that lane, so a proof lane carrying fewer contracts than the mutable one proves less than the lane it certifies.Verification
h201.2. Its first run was RED on three tests I had not hit locally, all real: the proof lane's carrier was sharing a concrete log-volume name with the dev lane's, and the catalog manifest'sONEX_TENANT_DB_URLmade the carrier a discovered application-DSN consumer thatdocker/catalog/database-consumers.yamldid not declare. Both fixed in the second commit; that is what the selector is for.uv run mypy src/ --strict—Success: no issues found in 3002 source files.uv run ruff format/ruff checkclean;pre-commit run --all-filesclean..201probe was read-only:rpk group describe/group listthrough the credential-on-stdin helper with no SASL value printed,docker ps, anddocker exec pythonrunning discovery plus the ownership filter. No compose action, no restart, no group or topic touched, no credential work.Deliberately out of scope, stated rather than left absent
What the eight can write once carried.
projection_delegation_inference_response_texthas FORCE RLS with no writer policy (OMN-17298, In Progress) and the no-authoritySET LOCAL app.tenant_iddefect is OMN-17422. This change makes the contracts carried; whether their INSERTs are then accepted belongs to those tickets. onex-dev already has the carrier and is unchanged.lakshmanis measured and not deployed here. The cross-repo leg — proving carriage against onex-dev's manifest set from this repo's CI — remains OMN-17456's honest limit.A related but distinct defect, so the two are not conflated
A peer lane is fixing
node_omnigate_projection, which looks similar and is not: that contract is in main's manifest and its attach raisedInfraTimeoutErrorafter readiness passed, which the boot reconciliation never retries. Transient, and it self-heals on the next boot. This one is never in the manifest at all and does not self-heal. None of its four blocker contracts is one of these eight.Evidence-Ticket: OMN-18114
Evidence-Source: OCC#8881