Repository navigation
feat(OMN-18135): the closer joins readbacks to state-shaped criteria, and names the bar - #3409
Conversation
… and names the bar Implements AC3 and the closer half of AC4 from the ruling recorded at docs/tracking/ROLLING_WORK_LEDGER.md:6148 (orchestrator, under the deterministic-truth doctrine; not an operator ruling). omnimarket#2460 carries the proof class. This carries the JOIN, because deciding whether a criterion is state-shaped needs the ticket's acceptance text and node_dod_verify never sees it. It moves in BOTH directions, deliberately. LOOSER: a ticket whose every parsed criterion asserts live state, each discharged by a verified readback, no longer dies on behavior_proving_count <= 0. That is the case the ruling exists to admit. Bounded to ALL criteria: one behaviour-shaped criterion, or a body whose criteria cannot be read, and the behaviour proof is still required. A ticket is judged by its strictest criterion, never on average. STRICTER: a behaviour-shaped criterion whose only verified checks are readbacks now HOLDS. Binding used to key on status alone and never on proof class, so a readback silently discharged a criterion asserting what the code does. That hole is invisible to every test that has no behaviour proof at all, so it has its own test with a real proof beside it. Deliberately untouched: merge-state, surrogate and indeterminate checks bind exactly as before. Narrowing those is a different argument nobody has made, and making it here would retroactively un-close tickets that flipped on that basis. AC3: the gap_no_behavior_proof comment now names the bar -- which command shapes prove behaviour, which prefixes are transparent, that a live probe through ssh/aws/kubectl/curl/a shell loop is not behaviour-proving, and that an asserted readback is the admissible route for live state. A hold that states a verdict without a remedy teaches nobody anything, which is what three lanes spent a night rediscovering by measurement. HONEST LIMIT, in the code and not only in the PR: criterion shape is read from prose and is a heuristic. State-shaped requires a positive state marker AND no behaviour marker; everything else falls to behaviour and holds. The asymmetry is chosen -- reading a criterion as behaviour-shaped costs a comment, reading one as state-shaped RELEASES a flip on a readback -- so the vocabulary earns its way in one phrase at a time and the veto wins ties. node_version 1.11.0 -> 1.12.0, so the gap-comment fingerprint moves with the rule it describes.
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: 1
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)
Overly broad state markers ('returns', 'responds', 'serves', 'contains') can release behaviour criteria | _STATE_MARKER_RE admits \breturns?\b, \bresponds?\b, \bserves?\b, and \bcontains?\b as positive evidence of live-state shape. These verbs are equally at home in behaviour assertions, e.g. 'the API returns 404 when the token is expired', 'the parser serves the malformed case', 'the CLI contains a retry loop'. None of these examples carry a veto word from _BEHAVIOUR_MARKER_RE (no 'test', 'handler', 'suite
Resolve this thread when addressed — the
Hostile Review Thread Gateblocks while hostile-reviewer threads are unresolved (OMN-17492). -
[MAJOR] hostile-reviewer (glm-review)
State-shaped gate trusts parsed criteria only; criteria outside the parser are unchecked | _every_criterion_is_state_shaped gates the behavior_proving_count conjunct on _acceptance_criteria_items(description). If the parser extracts a subset of the ticket's real acceptance criteria (e.g. criteria listed without a recognised heading, nested lists, or a body over a truncation limit), the join is computed over a partial view. A ticket with one state-shaped parseable criterion and one unparseable behaviour crit
Resolve this thread when addressed — the
Hostile Review Thread Gateblocks while hostile-reviewer threads are unresolved (OMN-17492). -
[MINOR] hostile-reviewer (glm-review)
Readback-blocked note truncates without an overflow indicator | readback_note joins readback_blocked[:_MAX_UNCOVERED_LISTED] with no 'and N more' suffix. The unbound list elsewhere in the same function tracks unlabelled counts and appends summary text; the new note can silently under-report when more criteria than _MAX_UNCOVERED_LISTED are readback-blocked, which understates the scope of the hold the author is being asked to fix. | Evidence: " OMN-18135: "
+ ", ".join(readback_blocked[:_MAX_UNCOResolve this thread when addressed — the
Hostile Review Thread Gateblocks while hostile-reviewer threads are unresolved (OMN-17492). -
[MINOR] hostile-reviewer (glm-review)
Admissible-command list duplicated as prose in the hold comment will drift | The gap_no_behavior_proof reason enumerates test runners, transparent prefixes, and readback-capable tools as a hardcoded English sentence. The classifier that actually decides proof class lives elsewhere (omnimarket / the verifier). When the verifier adds a runner or prefix, the comment becomes false, and nothing in this repo pins the two together. The diff bumps _GAP_FINGERPRINT_CONTRACT_VERSION for the gap fingerprint but no tes
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)
No test for readback release with a description lacking any criteria | The comment on the new conjunct claims a body with no parseable criteria is held by the OMN-18056 binding gate 'a conjunct later'. This dependency is asserted in prose but untested in the diff. If _ac_binding_gap permits a description with no AC heading through some other leg (for example when bindings exist for labels a human added to the companion contract rather than the ticket body), a readback_proving_count > 0 combined with an empt
Resolve 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)
#8985) * evidence: OCC companion pass 1 for OmniNode-ai/omnibase_infra#3409 * evidence: OCC companion self-bind for #8985 --------- Co-authored-by: node-occ-companion-effect <occ-companion-effect@omninode.ai> Co-authored-by: jonahgabriel <jonah@omninode.ai>
… and names the bar (#3409) Implements AC3 and the closer half of AC4 from the ruling recorded at docs/tracking/ROLLING_WORK_LEDGER.md:6148 (orchestrator, under the deterministic-truth doctrine; not an operator ruling). omnimarket#2460 carries the proof class. This carries the JOIN, because deciding whether a criterion is state-shaped needs the ticket's acceptance text and node_dod_verify never sees it. It moves in BOTH directions, deliberately. LOOSER: a ticket whose every parsed criterion asserts live state, each discharged by a verified readback, no longer dies on behavior_proving_count <= 0. That is the case the ruling exists to admit. Bounded to ALL criteria: one behaviour-shaped criterion, or a body whose criteria cannot be read, and the behaviour proof is still required. A ticket is judged by its strictest criterion, never on average. STRICTER: a behaviour-shaped criterion whose only verified checks are readbacks now HOLDS. Binding used to key on status alone and never on proof class, so a readback silently discharged a criterion asserting what the code does. That hole is invisible to every test that has no behaviour proof at all, so it has its own test with a real proof beside it. Deliberately untouched: merge-state, surrogate and indeterminate checks bind exactly as before. Narrowing those is a different argument nobody has made, and making it here would retroactively un-close tickets that flipped on that basis. AC3: the gap_no_behavior_proof comment now names the bar -- which command shapes prove behaviour, which prefixes are transparent, that a live probe through ssh/aws/kubectl/curl/a shell loop is not behaviour-proving, and that an asserted readback is the admissible route for live state. A hold that states a verdict without a remedy teaches nobody anything, which is what three lanes spent a night rediscovering by measurement. HONEST LIMIT, in the code and not only in the PR: criterion shape is read from prose and is a heuristic. State-shaped requires a positive state marker AND no behaviour marker; everything else falls to behaviour and holds. The asymmetry is chosen -- reading a criterion as behaviour-shaped costs a comment, reading one as state-shaped RELEASES a flip on a readback -- so the vocabulary earns its way in one phrase at a time and the veto wins ties. node_version 1.11.0 -> 1.12.0, so the gap-comment fingerprint moves with the rule it describes.
Evidence-Source: OCC#8985
Evidence-Ticket: OMN-18135
OMN-18135 AC3 + AC4 — the closer's half
Implements the ruling at
docs/tracking/ROLLING_WORK_LEDGER.md:6148, 2026-09-10T17:50:03Z. Provenance stated as it is: an orchestrator ruling under the deterministic-truth doctrine, not an operator ruling.omnimarket#2460carries the proof class. This carries the join, because deciding whether a criterion is state-shaped needs the ticket's acceptance text, andnode_dod_verifyhas no Linear access and never sees it. That is why AC4 could not be a single omnimarket change.It moves in both directions
Looser. A ticket whose every parsed criterion asserts live state, each discharged by a verified readback, no longer dies on
behavior_proving_count <= 0. This is the case the ruling exists to admit. It is bounded to all criteria: one behaviour-shaped criterion, or a body whose criteria cannot be read at all, and the behaviour proof is still required. A ticket is judged by its strictest criterion, never on average.Stricter. A behaviour-shaped criterion whose only verified checks are readbacks now holds. Binding used to key on check status alone and never looked at proof class, so a readback silently discharged a criterion asserting what the code does. That hole is invisible to every test that has no behaviour proof at all, because the behaviour conjunct catches those first — so it has its own test with a real behaviour proof sitting beside it, and a positive control where the same shape with a state-shaped criterion does release.
Untouched, deliberately. A criterion proved by a merge-state, surrogate or indeterminate check binds exactly as before. Narrowing those is a different argument nobody has made, and making it here would retroactively un-close tickets that have already flipped on that basis.
AC3: the hold names the bar
The
gap_no_behavior_proofcomment now says what would clear it:env -uorcd;ssh,aws,kubectl,curl,psqlor a shell loop is not behaviour-proving, however real the thing it exercised;Three lanes spent a night rediscovering this rule by measurement because the comment stated a verdict and no remedy.
The honest limit, in the code and not only here
Criterion shape is read from prose. It is a heuristic and it is tight on purpose: state-shaped requires a positive state marker and no behaviour marker, and everything else falls to behaviour and holds. The asymmetry is chosen rather than incidental — reading a criterion as behaviour-shaped costs a comment, while reading one as state-shaped releases a flip on a readback. So the vocabulary earns its way in one phrase at a time, every entry is drawn from a criterion that exists in the corpus, and the veto wins ties.
test_anything_else_falls_to_behaviour_and_holdspins the ambiguous cases, including a state marker vetoed by behaviour language.RED first
At parent
0a704957c, verbatim: 13 failed, 4 passed. After: 19 passed in the new module and 416 passed across the closer suite.Verification
9fddfcc8b8e82b0ba524dfeb7d3125d72d895041. The selector escalated and placed the run off-box:REMOTE LAB RUN PASS accepted ... h201.3 ran 27597 tests green ... (suite log sha256 6009ab599f801d9e003e31d15728e586fe718b2cbd590d0409772d33f68c6151, 285s). No override variable set, no escalation bypassed.uv run mypy --stricton the node: clean.ruff format --check,ruff check: clean.node_version1.11.0 to 1.12.0, so the gap-comment fingerprint moves with the rule it describes.evidence-autoclose-sweepworkflow, not on the.201compose dev lane or theonex-laboverlay. No lab pass exercises it and none is claimed. Its proof surface is the next scheduled closer tick after merge.Landing order
omnimarket#2460should land first. It is inert on its own — binding already keyed on status and never on proof class, andbehavior_proving_countdoes not change — so nothing moves until this PR teaches the closer the join. Landing this one first would be the harmless order too, sincereadback_proving_countreads 0 from a verifier that does not emit it and 0 releases nothing.