Skip to content

test(tools): gate the logprob gap check on the engine preamble - #1357

Merged
JustVugg merged 2 commits into
JustVugg:devfrom
monotophic:evidence/engine-transcripts
Sep 21, 2026
Merged

JustVugg merged 2 commits into
JustVugg:devfrom
monotophic:evidence/engine-transcripts

Conversation

@monotophic

@monotophic monotophic commented Sep 5, 2026 •

Copy link
Copy Markdown
Contributor

Authored by Opus 5 in Claude Code, analysis in partnership with @monotophic

Revised 2026-09-17 in response to review. The native-MTP witness is parked and this PR is now the logprob-gap
hardening alone
β€” 11 files and +7,464 down to 4 files and +2,319. Title updated to match; the previous one
still advertised the witness.

A command-line check that reads an engine transcript and says whether it is internally consistent.

tests/check_data_logprob_gaps.py already existed and had two weaknesses. It read a transcript without first
establishing that the transcript came from an engine it understands, so an unrecognised header was treated as no
header; and it reported problems without saying where in the byte stream they were, which makes a disagreement on a long capture tedious to localise. It now parses the engine's preamble through a shared helper and fails loudly
when that preamble is unparsable
, the protocol grammar is exact, the numeric tail and the top-k cap are enforced,
and every reported problem cites the byte offset of the frame it concerns.

The numeric grammar accepts both the fixed six-decimal form the engine ships today and an earlier %.17g form
(plus nan/inf/-inf); a token can satisfy both spellings exactly, so form classification stays informational β€”
a tally in the summary line β€” rather than a pass/fail rule.

What was parked, and why. tests/check_native_mtp_witness.py and its test β€” 2,613 lines exactly β€” are out
of this PR. The review was right on every number: MTPEMIT appears in zero files on dev, so the tool could only
ever exit 3 UNSUPPORTED on any build that exists, and carrying a reader ahead of its writer is the pattern we
identified ourselves in #1353. The work is preserved at monotophic/colibri codex/parked-mtp-witness @
e0474748 and is proposed again alongside the engine change that emits the record it needs β€” not before.

What invokes this tool. A person. It is a human-invoked argparse tool, like tools/check_ablate_evidence.py,
which is why nothing in c/Makefile or any workflow references it and why an import walk cannot find a caller. Its
unit tests run in CI; the tool itself is run by hand against a captured transcript when diagnosing an engine. If you
would rather it were wired into something, say which and we will do that as a separate change.

Context. This PR is one of five independent contributions derived from a single locally-verified working tree
(the fp8 container line in #1102, the OpenAI-compatible server hardening in #1353, the evaluation harness in #1355,
the engine's ablation scoring mode in #1356, and this transcript check). This one carries the logprob-gap check and
its suite. It imports tools/engine_evidence.py for the preamble grammar and carries that file itself, so it builds and tests standalone; once #1355 lands, that file drops out of this diff on the next dev merge. #1356 does not carry
it β€” that PR ended up importing nothing from the module, so it was dropped there. The others
are proposed separately, each with its own evidence. The set-level explanation and a traceability matrix covering every request across the three PRs are in the #1355 comment: #1355 (comment).

Behavioral contract

  • A transcript whose preamble cannot be parsed is a named failure quoting the offending line, never a silent pass.
  • Every reported problem names the byte offset of the frame it concerns.
  • Both numeric spellings the engine has used are accepted; neither is treated as evidence of anything by itself.
  • Every record the check declares required is individually required β€” dropping any one of them fails the check.
  • No model is run by anything here, and no fixture is downloaded: every case is built from literals inside the suite.

Capstone matrix β€” one decisive artifact per claim.

claim decisive evidence
an unparsable preamble cannot pass test_unparsed_banner_is_a_named_failure_quoting_the_line, test_unparsed_loaded_is_a_named_failure_quoting_the_line, and test_full_capture_with_unparsed_preamble_fails_the_whole_check β€” the last drives a complete, otherwise-valid capture and requires the whole check to fail
the preamble gate cannot fail open test_preamble_returning_none_is_defensively_named_not_silently_passed β€” the case where the parser returns nothing at all is asserted to be a named failure, which is the shape a "no news is good news" gate would pass
the frame-order gate is not decorative the seven test_dropping_<record>_breaks_its_own_ordinal_check cases (BANNER, LOADED, READY, STAT, HWINFO, TIERS, EMAP) plus test_required_order_matches_the_frozen_anchor. Before this revision every one of the seven could be dropped individually with the suite green β€” the list was declared, not enforced. Each now fails on its own
the numeric grammar is source-true, both forms test_fixed6_form_is_accepted_and_reported, test_c17g_form_is_accepted_and_reported, and test_a_token_matching_both_grammars_is_ambiguous_and_still_accepted; the fixtures use the engine's own printf formats
the grammar checks bite independently test_done_domains_and_fixed_grammar_bite_independently β€” each rule fails on its own input rather than being masked by a neighbour
the tool and the shared grammar cannot drift apart test_checker_dispatch_prefixes_stay_recognized_by_the_module β€” the check's own dispatch prefixes are asserted to still be recognised by engine_evidence, in both directions. An earlier one-directional version of this test passed while the module's dispatch was deleted outright
Fuller matrix, what changed since the reviewed head, and origin accounting

What changed since e0474748, the head reviewed on 2026-09-17

change origin
check_native_mtp_witness.py + its test parked (2,613 lines) maintainer-requested
five further files returned to the PR that owns each β€” eval_glm.py, test_eval_glm.py, check_ablate_evidence.py, test_check_ablate_evidence.py, test_pack_python.py maintainer-requested (the de-duplication raised on #1355)
the seven per-ordinal frame-order cases, and the frozen order anchor re-review-found β€” the gate declared seven required records and enforced none
the dispatch-prefix coupling test made bidirectional re-review-found
the docstring now explains WHY a non-finite logprob is a real defect rather than a tolerable value re-review-found β€” grammar-constrained decoding never zeroes or -infs a vocabulary logit, so the only path to one is the total-vocabulary numerical collapse that sample.h's own comments call a blow-up upstream. Behaviour is unchanged, and this is added explanation β€” not the correction of a false claim: measured across the two heads, the mentions of grammar/masking went up, not down
requirement instrument result
preamble gate four named cases, including a full-capture case loud failure in every shape
byte offsets offsets asserted in the problem strings present on every reported problem
exact protocol grammar malformed and misordered global records, malformed framing refused by name
frame-order lifecycle per-record ablation, one record dropped at a time all seven fail individually
numeric tail and top-k cap literal fixtures in both spellings, non-dyadic values accepted; classification informational
suite runs on dev plus this PR's files python3 -m pytest tests/test_check_data_logprob_gaps.py 61 passed, 110 subtests, 0.11 s

Suite cost. Parking the witness takes the two transcript-tool suites from 107 tests / 0.64 s to 61 tests /
0.11 s
, measured at e0474748 and at this head. No test here exceeds 0.02 s (slowest three measured at 0.02 s); there is no
fixture that waits on a timeout.

A limitation we would rather state than have you find. The gap this check hunts is not producible by the
engine's current multiplexing loop, so on today's builds it is regression coverage for an invariant rather than a
live detector, and the preamble check binds no binary or container digest by itself. Both facts are in the tool's
own docstring. Separately: the wire-format literals here are hand transcriptions of formats printed by
c/colibri.c and c/telemetry.h. Drift in the Python module is pinned by the tests above; drift in the C source
is not
β€” no test in this branch reads a C file. That predates this revision, and fixing it would reopen the
shared file across all three PRs, so it is noted as a follow-up rather than folded in here.

Scope note: no file outside the four listed is touched, and no surrounding code was reformatted.

Durable vs current state: the grammar, the preamble gate and the frame-order contract are durable. The case
count (61) is current state, measured 2026-09-17 against base cc756a63 on macOS (Apple silicon).

@monotophic

Copy link
Copy Markdown
Contributor Author

Authored by Claude Fable 5.1 in Claude Code, analysis in partnership with @monotophic

Merged current dev (87c54a93) into this branch β€” no functional change. Dev's commits since this PR's base never touch any of the 11 files this PR adds or changes; clean auto-merge. This PR's six test modules run to completion with zero skips on the merged head (282 tests), including the release-packer test that exercises c/tools/pack_python.py, which dev has changed since this PR opened.

@JustVugg similar steering request to #1102, #1353, #1355, and #1356, this PR is part of the set to make the full checkpoint-quality GLM 5.2/5.3 containers work and to establish the OpenAI API instrumentation needed for container quality studies. Let me know if this PR is off target or otherwise not likely to merge. Thanks again!

@JustVugg

Copy link
Copy Markdown
Owner

Reviewed, and I am asking for a split rather than a change.

The check_data_logprob_gaps.py hardening stands on its own. Failing loudly on an unparsable preamble instead of treating it as no preamble, and citing byte offsets, is a straightforward improvement to an existing tool.

check_native_mtp_witness.py is the problem, and it is not a code problem. It matches a per-emission stderr record that nothing in this repository emits. I checked the dev tree directly: MTPEMIT appears in zero files, against a positive control that finds coli_omp_tune in eleven. The engine's MTP_DEBUG prints something else. So those 2,613 lines, tool plus test, can only ever exit 3 UNSUPPORTED on any build that exists, and they are waiting on an engine change that is not proposed anywhere.

That is 62% of this PR. It is the same pattern you identified yourself in #1353 and offered to drop there, and I would like to be consistent about it: send the witness alongside the engine change that emits the record it needs, and the logprob-gap hardening as its own small PR now.

One question about the half that stays: neither transcript tool is referenced by c/Makefile or by any workflow. Only their unit tests run. What is meant to invoke them?

monotophic and others added 2 commits September 17, 2026 20:08
Add tools/engine_evidence.py, a shared parser for the two fixed-format
lines the C engine prints at startup: the banner line (backend, cache
size, compute/idot precision) and the loaded line (load time, resident
memory, layer/expert counts, MTP state). parse_engine_preamble splits a
captured stream into the two and hands each to its own exact-text
parser, raising PreambleError on anything that does not match the
documented grammar rather than guessing at a partial parse.

Every numeric field is range-checked on both sides of its bound, and
the two parsers only ever accept the exact banner/loaded text the
engine actually emits -- no fuzzy matching, no optional fields treated
as present. Downstream tools that need to bind evidence to a specific
engine run share this module instead of re-deriving the grammar.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…mble and widen the numeric-tail check

check_data_logprob_gaps.py's original speculative-decoding gap was
already closed on today's engine (an accepted draft token is emitted
through the same mux_data() call as any other generated token), so
retarget the module as regression coverage for that invariant and
harden the rest of the check well past the original narrow gap hunt.

capture_mode() now names and enforces the transcript's shape explicitly
(full-process / ready-suffix / request-only): a transcript whose
leading line is not a recognized global preamble record or a
legitimate request-frame kind is rejected as invalid before any other
check runs, so nothing reaches later checks unclassified. Where a
BANNER/LOADED preamble is present, it is parsed with the shared
engine_evidence grammar (tools/engine_evidence.py) rather than a
local, looser re-implementation.

The numeric-tail check now recognizes either spelling the engine has
shipped -- the fixed six-decimal form ("fixed6") and the older %.17g
form ("c17g") -- classifying each token independently against both
grammars rather than trying one first and hiding the other; a token
matching both is reported "ambiguous" (informational only, never
affects the verdict), and a nan/inf/-inf spelling is accepted as a
value but always fails the finite/non-positive check with a named
reason. Every reported problem now cites the byte offset of the
offending frame's own header line.

Coverage: test_check_data_logprob_gaps.py exercises capture_mode's
classification, both numeric grammars (including the ambiguous and
special-token cases), the preamble gate's coupling to engine_evidence,
and the byte-offset reporting, against literal transcript fixtures
built by hand rather than a real engine capture.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
monotophic added a commit to monotophic/colibri that referenced this pull request Sep 18, 2026
engine_evidence.py is shared verbatim across branches, not immutable --
a root fix here costs nothing while the sibling branches are unbuilt.

F3 (root fix): parse_engine_banner/parse_engine_loaded now catch
ValueError from their own int()/float() conversions and re-raise as
PreambleError, so a numeric field beyond Python's 4300-digit
int-string conversion limit refuses with this module's own named
error instead of escaping as a bare ValueError from all three entry
points. eval_glm.py's downstream catches of (PreambleError, ValueError)
stay as defense in depth.

F2: corrected premise -- check_data_logprob_gaps.py in this tree has
no engine_evidence coupling, but JustVugg#1357's own (much larger) copy does,
and its _global_header treats any problem entry, including a spurious
malformed-preamble complaint, as a whole-transcript hard failure.
Confirmed at primary source (grep across every "loaded"-prefixed
printf in the C sources) that no engine anywhere emits "loaded index"
or anything else that collides with the "loaded in" prefix test today,
so per that finding, the fix is prose: parse_engine_preamble's
docstring now states plainly that "starts like one of them" is a
literal prefix test, not a semantic one, and names the collision.

test_engine_evidence.py (also shared, also not frozen) gains:
- IdotKernelRosterTest: every IDOT_KERNELS entry parsed from the real
  banner format, sourced from c/quant.h:582-594 with file:line
  citations ("neon" confirmed RAN via this host's own default-build
  compiler flags), plus a roster-size backstop -- closes the roster
  gap the previous round wrongly reported as already closed (that
  claim rested on eval_glm.py's own test, not on this module's own
  45-test suite, which a scratch reduction to ("avx2",) alone left
  fully green).
- test_trailing_newline_rejected on both parse_engine_banner and
  parse_engine_loaded: fullmatch requires consuming a trailing "\n";
  $ alone does not, so match()/search() would accept a newline-
  terminated banner/load record that fullmatch correctly refuses --
  the shape a real `for line in f:` caller actually hands over.
- test_oversized_field_raises_preamble_error_not_bare_value_error on
  both functions, pinning the F3 root fix directly.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@monotophic
monotophic force-pushed the evidence/engine-transcripts branch from e047474 to da0c938 Compare September 18, 2026 04:39
@monotophic monotophic changed the title test(tools): gate the logprob gap check on the engine preamble; add the native-MTP witness test(tools): gate the logprob gap check on the engine preamble Sep 18, 2026
@monotophic

Copy link
Copy Markdown
Contributor Author

Set-level explanation and the full traceability matrix: #1355 (comment)

You were right about the redundancy, and the PR is now the small one you asked for: 11 files and +7,464 β†’ 4 files and +2,319.

The witness is parked

check_native_mtp_witness.py and its test β€” 2,613 lines exactly β€” are out. We confirmed your numbers: MTPEMIT
appears in zero files on dev, so those lines could only ever exit 3 UNSUPPORTED on any build that exists, and it is
the same pattern we identified ourselves in #1353. Being consistent about it is the right call.

They are preserved at monotophic/colibri codex/parked-mtp-witness @ e0474748, and they come back alongside the engine change that emits the record they need β€” not before.

What is left is the check_data_logprob_gaps.py hardening you said stands on its own.

"What is meant to invoke them?"

A person (or agent). These are manually-invoked argparse tools, like check_ablate_evidence.py β€” which is why nothing in c/Makefile or any workflow references them and why static analysis cannot see a caller. Their unit tests run in CI; the tools themselves are run by hand against a captured transcript when you are diagnosing an engine.

We think that is reasonable simplicity rather than a gap, but if you would rather they were wired into something, say
which and we will do it as a separate change.

Your asks

you asked disposition where it lives now
"send the witness alongside the engine change that emits the record it needs" parked β€” un-parks when an engine emits MTPEMIT monotophic/colibri codex/parked-mtp-witness @ e0474748
"the logprob-gap hardening as its own small PR now" done β€” that is now the whole PR, 4 files this PR
"neither transcript tool is referenced by c/Makefile or by any workflow … What is meant to invoke them?" answered β€” human-invoked; offer above above

Five further files left this PR β€” eval_glm.py, test_eval_glm.py, check_ablate_evidence.py,
test_check_ablate_evidence.py, test_pack_python.py β€” back to the PR that owns each. That is most of the
de-duplication you asked for on #1355, landing here.

Details β€” origin accounting

maintainer-requested: the witness park; the split.
re-review-found: the frame-order lifecycle check in check() could have every one of its seven required
ordinals dropped individually with the suite green β€” it now fails on each. A docstring claiming non-finite logprobs
the docstring now explains WHY a non-finite logprob is a real defect rather than a tolerable value: grammar-constrained decoding never zeroes or -infs a vocabulary logit, so the only path to one is a total-vocabulary numerical collapse that sample.h's own comments call a blow-up upstream. This is added explanation, not the correction of a false claim β€” measured across the two heads, the mentions of grammar/masking went up, not down.
The two transcript-tool suites go 107 tests / 0.64 s β†’ 61 tests / 0.11 s on this branch (test_check_data_logprob_gaps.py plus the parked witness's tests, measured at e0474748 and da0c938a).

The wire-format literals in this tool are hand transcriptions of the C source. Module drift is pinned by tests;
C-source drift is not. Noted as a limitation that predates this revision, with a follow-up in mind.

Authored by Opus 5 in Claude Code, analysis in partnership with @Monotophic

@JustVugg
JustVugg merged commit 201af1c into JustVugg:dev Sep 21, 2026
28 checks passed
@monotophic
monotophic deleted the evidence/engine-transcripts branch September 21, 2026 04:41
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.

3 participants