Repository navigation
fix(OMN-16964): the rebuild trigger learns ledger_readback, unblocking every dev-lane lab pass - #3387
Conversation
…g every dev-lane lab pass
omnimarket#2437 (9d14eecf, merged 2026-09-10T04:17:04Z) added a
`ledger_readback` block to the dev lane of omnimarket config/ci_bus_lanes.yaml.
scripts/trigger_rebuild_on_merge.py sparse-checks that same file and validates
it with extra="forbid". It had not learned the key, so it rejected the whole
overlay:
lanes.dev.ledger_readback
Extra inputs are not permitted
That is not a cosmetic red. This publisher is what emits the rebuild-requested
event, so while it is broken the deploy agent does not rebuild the .201 dev
lane on merge -- which is the automatic lab pass of CLAUDE.md rule 24(a).
Every runtime-affecting merge in the window landed on dev with no lab pass
behind it, including other lanes' work. Confirmed live on two unrelated
branches within two minutes of that merge (omnibase_infra#3379 at 04:18:09Z,
the OMN-18108 lane at 04:19:24Z), with the last green trigger run predating it
at 02:08:49Z. Reported by the omnigate-projection-degraded-fix lane, which
handed over the evidence rather than opening a competing PR.
This is my regression: I authored #2437.
THE FIX IS TO MODEL THE KEY, NOT TO LOOSEN THE MODEL. The model's own
docstring already recorded this class happening twice -- the transport keys
under OMN-18012 (run 34160709151) and projection_readback under OMN-18060 --
and states the rule: an unknown key here is indistinguishable from a typo that
would route a publisher to a default it never declared. extra="forbid" stays.
A test asserts a genuinely unknown lane key is still refused, so the fix
cannot later be mistaken for a licence to relax it.
The shape class is generalised from ModelCiBusLaneProjectionReadback to
ModelCiBusLaneDsnReference and used by both blocks, because this publisher is
not a consumer of either and needs nothing from them but their shape. The two
remain SEPARATE FIELDS: two legs, two relations, two OMN-16025 links, and the
component that does act on them keeps them apart for that reason.
Proof, with a negative control:
- The live merged overlay from omnimarket@dev now validates:
CI_BUS_OVERLAY_LIVE_PATH=<omnimarket@dev:config/ci_bus_lanes.yaml>
pytest tests/unit/scripts/test_ci_bus_overlay_live_binding.py -> 6 passed.
- The same live overlay against origin/dev's unfixed publisher still refuses
on lanes.dev.ledger_readback, so the pass above is the fix and not a
fixture that never exercised the path.
- 55 passed across the new suite plus the two existing trigger suites.
RED first: 2 of 6 new cases failed before the change.
Structural residual, stated rather than left implied: nothing in omnimarket
fails when a new overlay key is added there. The publisher only discovers it
after that PR has merged, on someone else's unrelated omnibase_infra PR. Three
occurrences of one shape is a structural gap, not three mistakes. A cross-repo
parity gate would move the failure to the PR that causes it; it is filed
separately rather than bolted on here.
|
| 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)
There was a problem hiding this comment.
Hostile Reviewer — adversarial findings (OMN-17492)
Models succeeded: glm-review
Models failed: codex
New finding threads: 4
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
-
[MINOR] hostile-reviewer (glm-review)
Verbatim duplication of the lane-scope policy comment invites drift | The comment block added above ledger_readback repeats the projection_readback comment nearly word for word, including the argument that the lane-scope rule is 'deliberately not duplicated here: two copies of a policy drift'. The comment then creates exactly such a duplication, of documentation rather than policy. The next edit to one copy will not propagate to the other, and the text will begin to contradict itself. | Evidence: # The lane
Resolve this thread when addressed — the
Hostile Review Thread Gateblocks while hostile-reviewer threads are unresolved (OMN-17492). -
[MINOR] hostile-reviewer (glm-review)
Docstring claims evidence 'see ModelCiBusLane below' for occurrences not recorded there | ModelCiBusLaneDsnReference states the failure happened 'three separate times (see ModelCiBusLane below)', but the diff removes the OMN-18012 reference from this class's docstring and the new text in ModelCiBusLane documents only the third occurrence (OMN-16964) with incident detail. The pointer promises a record the cited location does not obviously contain, degrading the docstring's stated role as 'the standing warnin
Resolve this thread when addressed — the
Hostile Review Thread Gateblocks while hostile-reviewer threads are unresolved (OMN-17492).
Findings demoted from threads (anchor rejected)
-
[MAJOR] hostile-reviewer (glm-review)
Broad pytest.raises(Exception) without match can pass on unrelated failures | test_an_unknown_key_inside_the_block_is_still_refused and test_a_genuinely_unknown_lane_key_is_still_refused use pytest.raises(Exception) with no match constraint in the latter case, and no match at all in the former. Any exception during load_ci_bus_overlay, including a YAML parse error or a KeyError from test fixture construction, satisfies the assertion. These tests claim to guard the strictness of extra="forbid", but they woul
Resolve this thread when addressed — the
Hostile Review Thread Gateblocks while hostile-reviewer threads are unresolved (OMN-17492). -
[MINOR] hostile-reviewer (glm-review)
Fixture reuses one DSN env var name for both readback blocks | The _LIVE_DEV_LANE fixture sets projection_readback.dsn_env and ledger_readback.dsn_env to the same value, CHAIN_CANARY_PROJECTION_DSN. The docstring asserts the two blocks are 'two legs reading two relations', which implies distinct DSNs and therefore distinct variable names. A fixture with identical values cannot distinguish a copy-paste error in omnimarket#2437 (ledger pointing at the projection DSN) from the real contract, and it weakens the
Resolve this thread when addressed — the
Hostile Review Thread Gateblocks while hostile-reviewer threads are unresolved (OMN-17492). -
[MINOR] hostile-reviewer (glm-review)
No equivalent shape-refusal coverage for the projection_readback block | The new tests verify that ledger_readback refuses a DSN value, an empty name, and extra keys. No test verifies the same refusals for projection_readback now that both fields share ModelCiBusLaneDsnReference. If the class rename or a future edit accidentally attaches a looser model to projection_readback, nothing in this diff's test suite would catch it. | Evidence: def test_a_dsn_value_where_a_name_belongs_is_refused(tmp_path: Path) ->
Resolve this thread when addressed — the
Hostile Review Thread Gateblocks while hostile-reviewer threads are unresolved (OMN-17492). -
[MINOR] hostile-reviewer (glm-review)
Fragile import-by-path of the script executes arbitrary module top level | exec_module runs the entire script at import time. If trigger_rebuild_on_merge.py gains top-level side effects (argument parsing, env reads, network setup guarded only by main assumptions), these unit tests fail for reasons unrelated to the models, and the failure mode is opaque because the module is loaded under a non-canonical name. There is also no guard against the script being imported twice under different module names acro
Resolve this thread when addressed — the
Hostile Review Thread Gateblocks while hostile-reviewer threads are unresolved (OMN-17492).
…ibase_infra#3387 (#8885) * evidence(OMN-16964): author OCC companion for OmniNode-ai/omnibase_infra#3387 OCC companion by node_pr_lifecycle_fix_effect (OMN-13317 F1 / OMN-13990 / OMN-14285). Product PR head 2f5f3d22d132e8da72bd33ef46262e8107be6852. * evidence(OMN-16964): self-bind OCC#8885 + rebind contract_sha256 --------- Co-authored-by: omnimarket-bot <bot@omninode.ai>
|
Independent verification from the What I ran against your head
11 of 11, plus your own suite and the two existing trigger suites: 62 passed. The live-binding case is 6 passed with The positive control is the one I care about most, and it holds: Two things I checked specifically because the rename could have broken them silently, both clean:
On scope split, agreed: the structural half is OMN-18127 and I have taken it — the reverse-direction gate on omnimarket PRs, so the fourth key fails the PR that adds it. I also own the post-merge proof for this one and will report the first Runtime Rebuild Trigger run after merge, its published event, and whether the deploy agent job converges on the dev lane. |
This unblocks every dev-lane lab pass. It is my regression.
omnimarket#2437 (
9d14eecf, merged 2026-09-10T04:17:04Z) added aledger_readbackblock to the dev lane of omnimarketconfig/ci_bus_lanes.yaml.scripts/trigger_rebuild_on_merge.pysparse-checks that same file and validates it withextra="forbid". It had not learned the key, so it rejected the whole overlay:That is not a cosmetic red. This publisher emits the rebuild-requested event, so while it is broken the deploy agent does not rebuild the
.201dev lane on merge — which is the automatic lab pass of CLAUDE.md rule 24(a). Every runtime-affecting merge from 04:17Z onward landed ondevwith no lab pass behind it, other lanes' work included.Confirmed live on two unrelated branches within two minutes of that merge — omnibase_infra#3379 at 04:18:09Z and the OMN-18108 lane at 04:19:24Z — with the last green trigger run predating it at 02:08:49Z. Found and reported by the
omnigate-projection-degraded-fixlane, which handed over the evidence rather than opening a competing PR, and which correctly established that my other open PR (#3381) does not touch this script and so does not fix it.The fix is to model the key, not to loosen the model
This model's own docstring already recorded this class happening twice — the transport keys under OMN-18012 (run 34160709151), and
projection_readbackunder OMN-18060 — and states the rule:So
extra="forbid"stays, and a test asserts that a genuinely unknown lane key (ledger_raedback) is still refused. That test is what keeps this fix from later reading as a licence to relax the strictness.The shape class is generalised from
ModelCiBusLaneProjectionReadbacktoModelCiBusLaneDsnReferenceand used by both blocks, because this publisher consumes neither declaration and needs nothing from them but their shape. The two remain separate fields: two legs, two relations, two OMN-16025 links, and the component that does act on them keeps them apart for that reason.Proof, with a negative control
A passing fixture that never exercised the path would prove nothing, so both directions are shown:
omnimarket@devnow validates.CI_BUS_OVERLAY_LIVE_PATH=<omnimarket@dev:config/ci_bus_lanes.yaml> pytest tests/unit/scripts/test_ci_bus_overlay_live_binding.py→ 6 passed.origin/dev's unfixed publisher still refuses onlanes.dev.ledger_readback.55 passed across the new suite plus the two existing trigger suites.
ruffandmypy --strictclean. RED first: 2 of 6 new cases failed before the change.Structural residual, stated rather than implied
Nothing in omnimarket fails when a new overlay key is added there. The publisher only discovers it after that PR has merged, on someone else's unrelated omnibase_infra PR. Three occurrences of one shape is a structural gap, not three mistakes. A cross-repo parity gate would move the failure to the PR that causes it; it is filed separately rather than bolted onto this fix, which needs to land quickly.
Ticket: OMN-16964
Evidence-Ticket: OMN-16964
Evidence-Source: OCC#8885