Skip to content

feat(sample): port logprob_token_ids generative scoring (#264) - #267

Merged
localai-bot merged 3 commits into
mainfrom
row/SAMPLE-LOGPROB-TOKEN-IDS
Aug 11, 2026
Merged

feat(sample): port logprob_token_ids generative scoring (#264)#267
localai-bot merged 3 commits into
mainfrom
row/SAMPLE-LOGPROB-TOKEN-IDS

Conversation

@localai-bot

Copy link
Copy Markdown
Collaborator

Closes #264. Row SAMPLE-LOGPROB-TOKEN-IDS (.agents/engine-matrix.md:133),
INVENTORIED -> PARTIAL. Spec: .agents/specs/logprob-token-ids.md,
committed in its own commit BEFORE any implementation code.

A request may now name an explicit set of vocab ids and get back exactly
those plus the sampled token — vLLM's generative-scoring path
(entrypoints/generate/generative_scoring/serving.py:247-255 sends
max_tokens=1 + logprob_token_ids=label_token_ids), and the efficient answer
to "score these five labels" without logprobs=-1 and a full-vocab sort.

What was ported, and from where

Read at the pin 555967922 in /home/mudler/_git/vllm, not from memory.

Upstream Local
sampling_params.py:31,278-283 field + MAX_LOGPROB_TOKEN_IDS include/vllm/sampling_params.h:168, kMaxLogprobTokenIds
sampling_params.py:724-729 the num_logprobs property SamplingParams::num_logprobs(), src/vllm/sampling_params.cpp:38
sampling_params.py:773-782,795-801 length + logprobs == n SamplingParams::Verify()
gpu_input_batch.py:273,443-444,574,934-951 src/vllm/v1/worker/gpu/input_batch.cpp:306
sampler.py:151-225 gather_specific_token_logprobs GatherSpecificTokenLogprobs, src/vllm/v1/sample/sampler.cpp:160
sampler.py:86 snapshot condition, :133-136 precedence Sampler::forward
scheduler.py:1815-1821 property gate src/vllm/v1/core/sched/scheduler.cpp

Three things worth calling out.

The num_logprobs property was the hidden half of this. Three of our
consumers spelled it as the raw logprobs field — the scheduler's slice gate,
LogprobsProcessor::FromNewRequest (whose comment already claimed it was the
property), and RequestState::FromNewRequest. Identical for every request that
exists today; without fixing them a scoring request produced sampler output that
nothing downstream ever read, so the feature would have been unreachable through
the engine. include/vllm.h is untouched — the C ABI does not expose logprobs
at all, so it exposes no less of this than of the SAMPLE-LOGPROBS row.

Our device-resident greedy fast path is ours, not upstream's, and it skips
the gather entirely. It is gated on the same combined predicate as the snapshot;
missing that second edit would have made the feature vanish silently on the async
greedy path.

Issue #249's defect class is kept out, its instance untouched. torch.gather
raises on an out-of-range index; the C++ equivalent reads past the row, so every
requested id is checked into [0, vocab) and every map key into [0, n) before
it indexes anything. GatherLogprobs' unbounded k (the #249 instance) is a
separate row and is deliberately not touched here.

RED, verbatim

Captured on a build carrying only the inert field declarations, with
num_logprobs() written as return logprobs; — literally what the engine did.

/tests/vllm/v1/sample/test_sampler.cpp:405:
TEST CASE:  Sampler: logprob_token_ids gathers exactly the requested ids
:420: FATAL ERROR: REQUIRE( out.logprobs_tensors.has_value() ) is NOT correct!
  values: REQUIRE( false )

TEST CASE:  Sampler: logprob_token_ids pads short and absent rows with -inf
:460: FATAL ERROR: REQUIRE( out.logprobs_tensors.has_value() ) is NOT correct!
  values: REQUIRE( false )

TEST CASE:  Sampler: logprob_token_ids wins over max_num_logprobs
:510: ERROR: CHECK( lt.num_tokens_per_position == 2 ) is NOT correct!
  values: CHECK( 3 == 2 )
:511: FATAL ERROR: REQUIRE( lt.logprob_token_ids.size() == 2 ) is NOT correct!
  values: REQUIRE( 3 == 2 )

TEST CASE:  Sampler: an out-of-vocab logprob_token_id throws
:531: ERROR: CHECK_THROWS( sampler.forward(q, tl, sm) ) did NOT throw at all!
[doctest] test cases: 16 | 12 passed | 4 failed | 0 skipped
[doctest] assertions: 56 | 51 passed | 5 failed |

/tests/vllm/v1/worker/test_input_batch.cpp:752:
TEST CASE:  logprob_token_ids: ids reach SamplingMetadata keyed by req index
:763: FATAL ERROR: REQUIRE( batch.logprob_token_ids.count("b") == 1 ) is NOT correct!
  values: REQUIRE( 0 == 1 )

TEST CASE:  logprob_token_ids: removal pops the entry, condense leaves it alone
:796: FATAL ERROR: REQUIRE( batch.logprob_token_ids.count("b") == 1 ) is NOT correct!
  values: REQUIRE( 0 == 1 )
[doctest] test cases:  29 |  27 passed | 2 failed | 0 skipped
[doctest] assertions: 195 | 193 passed | 2 failed |

/tests/vllm/test_sampling_params.cpp:363:
TEST CASE:  SamplingParams::num_logprobs mirrors the upstream property
  only logprob_token_ids -> its length
:377: FATAL ERROR: REQUIRE( p.num_logprobs().has_value() ) is NOT correct!
  values: REQUIRE( false )

TEST CASE:  SamplingParams::Verify rejects invalid logprob_token_ids
  length above MAX_LOGPROB_TOKEN_IDS (sampling_params.py:775-781)
:399: ERROR: CHECK_THROWS_AS( p.Verify(), std::runtime_error ) did NOT throw at all!
  logprobs != len(logprob_token_ids) (sampling_params.py:795-801)
:410: ERROR: CHECK_THROWS_AS( p.Verify(), std::runtime_error ) did NOT throw at all!
[doctest] test cases: 11 |  9 passed | 2 failed | 0 skipped
[doctest] assertions: 98 | 95 passed | 3 failed |

/tests/vllm/v1/test_llm_engine.cpp:1128:
TEST CASE:  llm_engine: logprob_token_ids returns exactly the requested ids
:1142: FATAL ERROR: REQUIRE( r.outputs[0].logprobs.has_value() ) is NOT correct!
  values: REQUIRE( false )
[doctest] test cases:  14 |  13 passed | 1 failed | 0 skipped
[doctest] assertions: 231 | 230 passed | 1 failed |

A second RED landed mid-implementation and is worth recording: with the sampler
and InputBatch fully wired, test_llm_engine was still red at the same
line, because RequestState::FromNewRequest gated the whole LogprobsProcessor
on sp.logprobs.has_value(). Upstream constructs it unconditionally
(output_processor.py:223-229); it is now gated on the property.

GREEN

Clean rm -rf build-cpu Release rebuild, zero warnings under -Werror:

test_sampler          16/16 test cases,  86 assertions
test_input_batch      29/29 test cases, 205 assertions
test_sampling_params  11/11 test cases, 102 assertions
test_llm_engine       14/14 test cases, 271 assertions

Full gate: ctest -j 6 364/366, 1029.87 s. The two failures were
test_engine_core_proc and test_async_llm, both re-run serially:

Test under -j 6 (load avg 87-103 on 20 cores) serial
test_engine_core_proc Failed, 0.16 s 10/10, 94 assertions, wall 0.00 s
test_async_llm Failed 0.45 s, CHECK( Drain(engine, reused) == 3 ) got 175 8/8, 320 assertions, wall 0.04 s

Both pass serially in well under a second, so both were starvation, not
regressions. Neither touches any file in this change.

Checker change

scripts/check-public-doc-tables.py: the docs/STATUS.md char ratchet is
re-pinned DOWN, 243571 -> 243479. The Sampling row owed the page a line and
paid for it inside the same cell — the beam-search paragraph was three clauses of
how-it-is-wired narrative, collapsed to its binding result plus its named
residuals, with the wiring story kept in .agents/engine-matrix.md where it
already lives. Net -92, re-pinned byte-tight.

No checker semantics changed, and the mutation evidence in
tests/scripts/test_check_public_doc_tables.py is real, not a rubber stamp:

  • STATUS_RATCHET_CEILING is lowered 243578 -> 243479 in the same change, so
    the cheap way out stays blocked at the new level. MUT A — putting the
    ratchet back to 243571 — now reds four assertions including
    test_the_status_ratchet_only_ever_moves_down, which at the old ceiling would
    have stayed green.
  • NEW test_one_char_of_growth_on_the_LIVE_page_is_rejected. The existing growth
    test grows a synthetic page by a whole ratchet, which proves the comparison
    exists but not that the cap sits on the boundary of the real page. MUT B
    moving the cap to 243480 so it trails the page by one byte — reds only this
    new test and the byte-tight one. It also asserts the error names both numbers,
    since "too big" cannot tell an author what to collapse.
  • Before/after: 53 passed -> 54 passed, and the live checker is OK.

A trap worth passing on: the old and new ratchet values are the same byte
length, so after a mutate-and-restore the stale scripts/__pycache__/*.pyc
survived mtime/size invalidation and the suite kept reading the mutated
number — three red tests against a restored tree. find . -name __pycache__ -exec rm -rf {} + before trusting any checker-mutation result.

Records

.agents/engine-matrix.md (row -> PARTIAL, code/test/spec anchors, section and
total counters), .agents/roadmap_v1.md (#264 intake row + the C7 REMAINING
note), .agents/coordination.md (CLAIM-SAMPLE-LOGPROB-TOKEN-IDS; prose, since
the claims table keys SPIKE/ACTIVE rows), .agents/porting-inventory.md (the
M1.7 "marked stub" line was stale), docs/STATUS.md, docs/BENCHMARKS.md (no
number owed, and why), docs/USAGE.md (the new field, with an example),
.agents/NOW.md (5,993 of 6,000 chars).

Residuals, which is why the row is PARTIAL and not DONE

  1. logprobs_mode variants — the row's other half. Open PR feat(sample): implement the three refused logprobs_mode variants (#238) #258 owns it and
    edits the same snapshot block in sampler.cpp; whichever lands second
    rebases. The overlap is about five lines of one condition.
  2. The OpenAI logprob_token_ids request field on /v1/completions and
    /v1/chat/completions, its four cross-field validations, and
    /v1/generative_scoring.
  3. Vocab-range validation of the ids, which upstream does in
    verify(model_config). Our Verify() has no model config, exactly as for
    allowed_token_ids. The sampler bounds them anyway, so this is a message-
    quality gap, not a safety one.

Two corrections to the record

🤖 Generated with Claude Code

mudler added 2 commits August 10, 2026 13:04
Commit the spec BEFORE any implementation, as the protocol requires.

Row `SAMPLE-LOGPROB-TOKEN-IDS` is `INVENTORIED` on main, not `PARTIAL` as
issue #264 states: the `logprobs_mode` half it credits to "#238/#258" has
NOT landed — #238 is an issue and PR #258 is still open. Recorded in the
spec so the next reader does not re-derive it.

Scope, upstream anchors (read at pin `555967922`, not from memory), the
port map, the req_id-vs-req_index keying decision, the bounds decision
that keeps issue #249's defect class out of the new gather, the written-
not-ported test inventory, and the named residuals (OpenAI request field,
`logprobs_mode`, engine-time vocab-range validation).

Also registers #264 in the roadmap intake table and adds the
`CLAIM-SAMPLE-LOGPROB-TOKEN-IDS` prose claim (the claims TABLE keys
`SPIKE`/`ACTIVE` rows; this row lands `PARTIAL`).

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: ClaudeCode:claude-opus-5 [ClaudeCode]
A request may now name an EXPLICIT set of vocab ids and get back exactly
those plus the sampled token — vLLM's generative-scoring path, and the
efficient answer to scoring a handful of labels without `logprobs=-1`
and a full-vocab sort.

Ported 1:1 from the pin `555967922`:
  - `sampling_params.py:31,278-283` — the field + MAX_LOGPROB_TOKEN_IDS.
  - `sampling_params.py:724-729` — the `num_logprobs` property.
  - `sampling_params.py:773-782,795-801` — the two validations that need
    no model config. The vocab-range check (:783-793) stays engine-time,
    exactly like `allowed_token_ids`' already does.
  - `gpu_input_batch.py:273,443-444,574,934-951` — req_ID-keyed in the
    InputBatch (so condense/swap need do nothing), re-keyed to req_INDEX
    in make_sampling_metadata over the live batch only.
  - `sampler.py:151-225` — gather_specific_token_logprobs: the padded
    `[n, max+1]` row, sampled token in column 0 and valid for every row
    including rows absent from the map, `-inf` padding, and the sampled
    token's rank over the FULL vocab rather than the requested subset.
  - `sampler.py:86` — the raw snapshot now fires when ONLY
    logprob_token_ids is set. The stale comment saying otherwise is gone,
    and so is the same omission in our device-resident greedy fast path,
    which is ours and not upstream's and would have skipped the gather.
  - `sampler.py:133-136` — explicit ids WIN over a logprobs count.

Three consumers spelled upstream's `num_logprobs` PROPERTY as the raw
`logprobs` field and are corrected: the scheduler's slice gate
(scheduler.py:1818), `LogprobsProcessor::FromNewRequest`, and
`RequestState::FromNewRequest`. Identical for every request that does not
set the new field; without them a scoring request produced sampler output
that nothing downstream ever read.

Every requested id is bounds-checked into `[0, vocab)` and every map key
into `[0, n)` before it indexes anything — which is what torch.gather
raises on, so it is a mirror, not an addition. Issue #249's instance
(GatherLogprobs' unbounded `k`) is deliberately NOT touched.

RED first, all four binaries:
  test_sampler        4 cases, `out.logprobs_tensors` had no value
  test_input_batch    2 cases, `batch.logprob_token_ids.count("b") == 0`
  test_sampling_params 2 cases, num_logprobs() returned the raw field
  test_llm_engine     1 case,  `outputs[0].logprobs` had no value
GREEN: 16/16 (86), 29/29 (205), 11/11 (102), 14/14 (271) on a CLEAN
Release CPU build, zero warnings under -Werror.

Row `SAMPLE-LOGPROB-TOKEN-IDS` `INVENTORIED` -> `PARTIAL`: its
`logprobs_mode` half is unported (open PR #258) and the OpenAI request
field is a named residual. STATUS/BENCHMARKS/NOW updated for the move;
the STATUS ratchet is re-pinned DOWN 243571 -> 243479, paid for inside
the same Sampling cell.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: ClaudeCode:claude-opus-5 [ClaudeCode]
localai-bot pushed a commit that referenced this pull request Aug 11, 2026
docs/BENCHMARKS.md has a HARD 45,000-char cap and sits at 44,689 on
`origin/main`, so its remaining headroom is 311 bytes for ALL concurrent work.
The merge that re-applied this row spent 258 of them on narrative the row does
not need: the two CPU test counts are the engine-matrix row's job and the
per-feature list is docs/FEATURES.md's, while the page's own schema asks only
for the key, the verdict, and what would make a number owed.

Collapsed to 118 bytes. Every binding claim is kept -- no number is owed, the
result is correctness-only, and a grid becomes owed at the W7 model gate. This
also leaves PR #267 room for its own no-number-owed row (145 bytes), so both
open PRs fit at 44,952 whichever lands first; without this one of them would
have arrived over the cap.

Re-gated after the edit: test_lora_layers 16/16 (4,498 assertions),
test_punica_cpu 8/8 (149 assertions), check-public-doc-tables OK,
scripts/agent-preflight.sh --staged all gates green.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: ClaudeCode:claude-opus-5 [ClaudeCode]
MERGED, never rebased: both heads are published, and `main` is never
force-pushed, so a rebase is not available. This keeps 657a63a an ancestor and
the push a plain fast-forward. The branch was 98 commits behind; `pr-size` and
`agent-record` were failing only on "base must be an ancestor of head".

PRODUCT CONFLICTS, resolved by keeping BOTH features. `logprobs_mode` (#238) and
`prompt_logprobs` (#223) landed on main after this branch was written, and both
touched the same code:

- src/vllm/v1/sample/sampler.cpp, step 1. #238 added `processed_mode` and moved
  the processed snapshot inside `sample()`; this branch made the snapshot fire
  when ONLY `logprob_token_ids` is set (sampler.py:86 is an `or`). Both kept:
  `want_logprobs = num_logprobs.has_value() || want_token_ids` AND
  `processed_mode`. They are ORTHOGONAL -- the mode selects WHICH tensor the
  snapshot holds, the ids select WHICH entries step 8 reads out of it. Step 8
  auto-merged correctly: this branch's precedence structure (explicit ids WIN,
  sampler.py:133-136) wrapping main's `-1` block verbatim, issue-#231 note and
  all.
- include/vllm/v1/worker/gpu/input_batch.h and .cpp. #223's
  `num_prompt_logprobs` and this branch's `logprob_token_ids` are independent
  req_id-keyed maps that landed at the same three sites (add_request,
  remove_request, the condense() comment). Both kept at all three.
- tests/vllm/v1/sample/test_sampler.cpp. Both PRs appended a suite after the
  same last case. Rebuilt as main's file + this branch's block appended, so
  main's 4 `logprobs_mode` cases and this branch's 5 `logprob_token_ids` cases
  both survive.

ONE TEST ADDED at the merge, because the interaction it covers did not exist on
either PR's base and neither could have written it: "logprob_token_ids reads the
PROCESSED snapshot under a processed mode". RED-first proven by mutation --
weakening the processed-snapshot request to
`(num_logprobs.has_value() && processed_mode)` leaves 20 of 21 cases green and
fails ONLY this one (SIGSEGV: the gather reads an empty buffer). Tree restored
byte-for-byte afterwards, md5 26dec0a8c79555864fcbe463512feff9.

Keyed records -- main's version taken WHOLESALE, then this branch's ONE scoped
edit reapplied with a count==1 anchor assertion. No automatic three-way merge of
a keyed record was accepted:

- `.agents/engine-matrix.md`: the `SAMPLE-LOGPROB-TOKEN-IDS` row was HAND-MERGED.
  Main's cell records `logprobs_mode` LANDED with `logprob_token_ids` as its
  residual; this branch's records the inverse. Both landed, so both bodies are
  kept, each strikes the other's residual, and the surviving residuals are the
  OpenAI request field, the vocab-range validation, and the outside-the-library
  mode selection. Spec and Owner columns carry BOTH claims. **The lifecycle
  rollup is deliberately NOT touched:** main already carries this row at
  `PARTIAL` (#238 moved it INVENTORIED -> PARTIAL), so the branch's counter edit
  is already paid for and re-applying it would double-count. RECOMPUTED against
  main's actual rows, not carried; check-agent-record green at ENGINE=147.
- `.agents/coordination.md`: main's file, plus the one prose claim inserted
  immediately before the claims TABLE, where its sibling `logprobs_mode` claim
  sits. It is NOT a table row -- the table keys SPIKE/ACTIVE and this row is
  PARTIAL. The table itself is byte-for-byte main's.
- `.agents/roadmap_v1.md`: main's issue table plus the one #264 row, and the C7
  portfolio row's stale gap list corrected (it still listed both halves as gaps).
- `.agents/NOW.md`: main already carried a `logprobs_mode` (#238) row whose next
  step WAS this work, so the scoped edit is that row updated in place rather
  than a second row added. 5,960 -> 5,979 chars, 91 lines, inside the 6,000
  budget.
- `.agents/porting-inventory.md`: `logprob_token_ids` leaves the deferred-stub
  list. The same sentence still listed the `logprobs_mode` variants as stubs
  after #238 landed; since this edit rewrites the sentence, that staleness is
  corrected here rather than left knowingly false, and the correction is called
  out in the text.
- `docs/BENCHMARKS.md`: one no-number-owed row. Written TERSE (145 bytes, not
  the branch's 506) because the page sits at 44,689 of its hard 45,000-char cap
  and PR #282 is also adding a row; see the note below.
- `.agents/benchmark-record.md`: untouched by this branch; main's append-only
  log taken as-is.

STATUS ratchet RE-MEASURED against the MERGED page, never carried: 243278.
`test_the_rebased_character_ratchet_is_byte_tight` requires cap == len(page)
exactly, and the ceiling test requires strictly-down, so the added line had to
be paid for in full. The branch's original payment was NOT available any more:
it collapsed the beam-search wiring narrative, and #223 had already spent
exactly that collapse -- its guard now PINS the collapsed form. So four
different restatements were collapsed instead, each a definition of what an
OpenAI field DOES rather than a statement of what we support: what a custom
logits processor is, what `n>1` does, what `best_of` does, and how the async
beam driver is built. All three substrings #223 and #238 pin are intact, and
both their guards still pass. Net -9 against main's 243287. The ratchet CEILING
moves down in the same change, 243578 -> 243479, and the branch's extra
live-page guard (`test_one_char_of_growth_on_the_LIVE_page_is_rejected`) is
carried over. `scripts/__pycache__` was cleared before every checker run.

NOTE FOR WHOEVER LANDS SECOND: docs/BENCHMARKS.md has a HARD 45,000-char cap and
is at 44,689 on main. This PR's row is 145 bytes and PR #282's is 118, so both
fit (44,952) -- but only because both were deliberately written terse. Any third
BENCHMARKS row lands over the cap and owes a real collapse. The STATUS ratchet
will also need one re-measure at the second merge: this PR pins 243278 and #282
pins 243227, and neither number survives the other landing.

Gate re-run on the merged tree (CPU, foreground, unbounded):
- cmake --build build-cpu -j 18: clean, 843/843, no -Werror diagnostic
- test_sampler:          21 cases | 21 passed | 0 failed | 0 skipped;  114 assertions
- test_input_batch:      29 cases | 29 passed | 0 failed | 0 skipped;  205 assertions
- test_llm_engine:       24 cases | 24 passed | 0 failed | 0 skipped;  493 assertions
- test_sampling_params:  11 cases | 11 passed | 0 failed | 0 skipped;  102 assertions
- tests/scripts/test_check_public_doc_tables: 57/57 OK
- check-agent-record, check-public-doc-tables, check-now-current,
  check-fusion-consistency: all OK
- scripts/agent-preflight.sh --staged: All gates green (rc=0)

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: ClaudeCode:claude-opus-5 [ClaudeCode]
@localai-bot
localai-bot merged commit 7f306d2 into main Aug 11, 2026
13 of 15 checks passed
localai-bot pushed a commit that referenced this pull request Aug 11, 2026
…cing (#282)

Merges `row/LORA-RUNTIME-W2` `8ff82999` for issue #278. Spec
`.agents/specs/lora-adapter.md`. `LORA-RUNTIME` moves `ANCHOR-BACKFILL` ->
`ACTIVE`.

WHAT IT DOES. W1 landed the punica CPU brick; W2 adds `PackedLoRALayerWeights`
(`Pack` optimize-then-scaling-1, per-slice `Optimize`), the multi-slice punica
`AddShrink`/`AddExpand` (`output_slices` + `offset_start` window walk),
multi-slice `AddLoraLinear`, `AddLoraEmbedding` (expand only -- the embedding
shrink is a table gather) and `AddLoraLogits` (sampler-indexed, clamped to the
narrower of the adapter vocab and the logits width), plus the wrapped layer
family in NEW `include/vllm/lora/layers.h` + `src/vllm/lora/layers.cpp`:
replicated, column, row, merged-column/gate_up, qkv, merged-qkv, variable-slice,
`VocabParallelEmbeddingWithLoRA` and `LogitsProcessorWithLoRA`, with the TP
`SliceLoraA`/`SliceLoraB` rules including the fully-sharded (S-LoRA) rank-dim
overrides. Ported against pin `555967922`: `lora_weights.py:126-270`,
`punica_cpu.py:166-236,265-312`, `lora_ops.py:42`, `base_linear.py:100-238`,
`column_parallel_linear.py:85-746`, `row_parallel_linear.py:22-177`.
`tests/vllm/lora/test_lora_layers.cpp` ports `tests/lora/test_layers.py`.

DEFERRED WITH A REFUSAL, NOT AN APPROXIMATION: the fully-sharded APPLY
(`_mcp_apply`) needs the rank-dim all-gather/all-reduce our TP seam does not
expose, so a sharded class at `tp_size > 1` throws `std::logic_error` from
`ApplyLoraToOutput` instead of returning a partial delta. `pack_moe` (W7),
`LoRAConfig` (W5) and `convert_mapping` (W3) stay out of scope. Nothing is wired
to an engine path yet and `docs/USAGE.md` says so: no CLI flag, server flag,
config key or C-ABI field for LoRA exists, so no model can be served with an
adapter today.

WHAT THE REVIEW FOUND, AND THE REPAIR. A fresh scoped review of the first head
returned FAIL -- 2 blocking + 3 major findings, and 6 of its 9 mutations
SURVIVED the suite. Both blocking findings were ASan-visible memory-safety bugs:
the fully-sharded apply returned a PARTIAL delta at `tp_size > 1` (the shrink
fills `max_rank/tp_size` of a `max_rank` buffer), and `BgmvExpandSlice` ran off
the end of every row whenever the caller's buffer was narrower than the
adapter's output -- an lm_head whose gathered logits are narrower than the
adapter vocab. A fresh implementer repaired both in-branch, each with a
RED-first mutation, and RE-RAN all six surviving mutations against the repaired
head: M1 (`AddShrink` `slot < 0` early-exit), M2 (`SetLora` A/B slicer swap),
M3 (`AddExpand` per-slice offset), M7 (`CopyIntoSlot` stride), M8 (`AddShrink`
A-stride) and M9 (embedding base-token clamp) are now ALL caught. M1 and M7
first tripped only `-Werror=unused-parameter`, so both were re-run with the
newly-unused parameter voided; the recorded results are behavioural, not compile
artifacts. The tree was restored byte-for-byte after each.

KEYED RECORDS -- main's version taken WHOLESALE, the branch's scoped edit
reapplied by hand, every deleted anchor asserted unique in main's copy, and
every non-reconciled path proven byte-identical to the branch's own edit set.

  docs/STATUS.md          auto-merge accepted only after proving the edit set
                          matches the branch's exactly. Merged page RE-MEASURED:
                          243,128 = main's 243,188 less the LoRA row's net -60.
  STATUS ratchet          `scripts/check-public-doc-tables.py` CONFLICT. Kept
                          BOTH rationale histories (main's and the branch's,
                          append-only) and pinned the RE-MEASURED 243128. The
                          branch's 243227 and main's 243188 were both DISCARDED:
                          neither was measured against this page -- the branch
                          measured against `5812b8b6`, before main re-pinned.
                          Byte-tight, strictly DOWN.
  ratchet CEILING         `tests/scripts/test_check_public_doc_tables.py`
                          CONFLICT. Lowered to 243128 in the SAME change as the
                          ratchet, never after it; the branch's stale 243482 was
                          discarded for the same reason. ALL mutation guards
                          from both sides kept -- main's
                          `test_the_ratchet_is_exactly_one_byte_wide` and
                          `test_a_repin_can_only_tighten_the_char_ratchet`
                          alongside the byte-tight, no-hidden-headroom, and the
                          two paid-for-by-a-real-collapse guards. 58/58.
  docs/BENCHMARKS.md      the branch's LoRA W2 row took the page to 45,116, over
                          the hard 45,000 cap. PAID BY MOVING, not by raising
                          the cap and not by deleting evidence: the key
                          `Vulkan vs llama.cpp Vulkan (BENCH-VK-LLAMA)` carried
                          TWO rows in a table whose contract is one row per
                          subject updated in place. `468a3876` (2026-08-08)
                          wrote the 0.6B row; `93852c28` (2026-08-09) added a
                          SECOND row for the same key rather than updating it.
                          The superseded 0.6B row (406 chars) moved VERBATIM
                          into `.agents/benchmark-record.md` under its own
                          compaction heading, with the surviving 27B row quoted
                          beside it; byte-for-byte identity asserted in the
                          archive BEFORE removal from the page. The key keeps
                          its handle on the scoreboard. 45,116 -> 44,709.
                          This headroom also pays for PR #267's row next.
  .agents/engine-matrix.md CONFLICT. Main's `Serving, API, CLI, library` row
                          (10|2|0|1|7|2|1|4) kept wholesale, the branch's
                          `LoRA and adapters` row (0|0|0|0|1|0|0|1) reapplied,
                          and the **Total** RECOMPUTED from the ten actual area
                          rows rather than carried from either side:
                          147|35|16|4|8|27|8|9|39. Confirmed by
                          `check-agent-record.py` (ENGINE=147).
  .agents/NOW.md          CONFLICT twice. Main dropped `Invocation-parity` for
                          `Muse Glimmer (#333)` and added `Containers #170`;
                          both kept, with the branch's compaction of the
                          MiniMax-H3 and Release cells reapplied on top. The
                          branch's net +16 took the page to 6,011 over the hard
                          6,000 budget, because main had spent the headroom the
                          branch measured against. Paid inside the page: the
                          `SERVE-METRICS` cell said `/metrics` was dead twice
                          ("was DEAD on the shipped server" and "AsyncLLM folded
                          nothing"); the restatement collapsed. 5,986 / 94 lines.
  .agents/coordination.md CONFLICT. Claims TABLE -- the table
                          `check-agent-record` cross-references. Main's
                          `CLAIM-MUSE-GLIMMER-SPEC` row and the branch's
                          `CLAIM-LORA-RUNTIME-W2` row are distinct keys, unioned
                          with main's first. Not an automatic three-way merge.
  .agents/roadmap_v1.md, .agents/specs/lora-adapter.md, docs/USAGE.md,
  scripts/check-gate-commands.py (+LORA-RUNTIME in `RUNNABLE_BASELINE`, beside
  main's +ENG-RELEASE-CONTAINERS), CMakeLists.txt, tests/CMakeLists.txt --
  each redone by hand and proven equal to the branch's own scoped edit set.

GATE, re-run by the operator on the merged tree, CPU Release, foreground:
  cmake --build build-cpu -j 18                    396 targets, 0 errors
  ./build-cpu/tests/test_lora_layers              16/16 cases, 4498 assertions
  ./build-cpu/tests/test_punica_cpu                8/8  cases,  149 assertions
  scripts/check-public-doc-tables.py               OK
  tests/scripts/test_check_public_doc_tables.py    58/58
  scripts/check-agent-record.py                    OK, ENGINE=147 MODEL=362
                                                   QUANT=82 KERNEL=51 BACKEND=80
  scripts/check-gate-commands.py                   116 gated, 31 runnable
  tests/scripts/test_check_gate_commands.py        26/26
  scripts/check-now-current.py                     OK

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: ClaudeCode:claude-opus-5 [ClaudeCode]
localai-bot pushed a commit that referenced this pull request Aug 11, 2026
… re-gated

`origin/main` advanced 11 commits WHILE PRs #324, #282 and #267 were being
gated -- #249 (a huge `logprobs` crashed the server), #168 Tekken and #347
GPT-4o pre-tokenizers, #359 (Muse Glimmer Q/K RoPE row order), and their two
merge commits. A plain `git push` would have been refused as non-fast-forward,
which is git protecting those merges, so this fetches, re-merges, re-measures
every budgeted record against the page that actually results, and re-gates
before the push. No force, no rebase of a published branch.

PRODUCT MERGE. `src/vllm/v1/sample/sampler.cpp` is the one file where main and
this landing both changed live code, and it auto-merged into the correct
result -- verified by inspection, not accepted on git's word. #249's
defense-in-depth clamp survives VERBATIM at `sampler.cpp:107`
(`const int k = static_cast<int>(std::min<int64_t>(num_logprobs, vocab))`, with
its comment), and #267's `want_token_ids` predicate, combined
`want_logprobs` and `GatherSpecificTokenLogprobs` call all survive. The only
lines DROPPED are the two #267 intended to drop: the stale
"logprob_token_ids (generative-scoring) is a deferred stub" comment and the
narrower `want_logprobs = num_logprobs.has_value()`. The two changes are
orthogonal -- #249 bounds the top-k path's `k`, #267 adds the explicit-id path
-- and #267 had already said in its own commit that #249's instance was
deliberately not touched.

KEYED RECORDS. Main's version taken wholesale and the landing's scoped edits
reapplied; 28 of the 30 paths main touched were proven byte-identical to main's
own edit set, and the two exceptions are the ratchet pair below.

  .agents/NOW.md     CONFLICT. Main's newer `Muse Glimmer (#333)` row
                     ("#347+#359 FIXED: GGUF COHERENT") replaces the older one
                     wholesale; the landing's compaction of the MiniMax-H3 cell
                     is reapplied on top, because that compaction is part of
                     what paid for PR #282's row. 5,972 of the 6,000-char
                     budget, 94 of 100 lines.
  STATUS ratchet     CONFLICT. FOUR rationale histories now sit in
                     `scripts/check-public-doc-tables.py` -- main's own
                     concurrent Tekken/GPT-4o pair, #282's and #267's -- and ALL
                     FOUR are kept, append-only. None of their numbers survives,
                     because no two were measured against the same page: main
                     re-pinned to 243186 after both branches had measured
                     against `5812b8b6`. RE-MEASURED:
                     `len(open("docs/STATUS.md").read())` == 243117. Byte-tight,
                     strictly DOWN from main's 243186, which is the only
                     direction it may move. Ceiling lowered to 243117 in this
                     same change.
  docs/BENCHMARKS.md 44,839 of the hard 45,000. Both landed rows still fit
                     inside the headroom PR #282's merge bought by MOVING the
                     superseded 2026-08-08 `BENCH-VK-LLAMA` row into
                     `.agents/benchmark-record.md`; main's own -15 since is
                     carried, and no further row moved here.
  docs/FEATURES.md   27,385 of 30,000. docs/STATUS.md, docs/USAGE.md,
                     .agents/roadmap_v1.md, .agents/specs/muse-glimmer.md and
                     tests/CMakeLists.txt all auto-merged and were each verified
                     line-for-line against main's edit set before being accepted.

CORRECTION to the PR #267 merge commit immediately below this one. It attributed
`test_llm_engine`'s 492 assertions (against the 493 the branch measured) to
main's sixteen changed engine files. That was wrong, and the correction is
recorded here rather than by rewriting the commit: three consecutive runs of the
SAME unmodified binary gave 493, 493 and 492. The count is run-to-run
NONDETERMINISTIC in this binary. Every run is 24/24 cases, 0 failed, 0 skipped,
so no case is unreached and none of the three runs is a killed process. Nothing
regressed, and the honest statement is that this binary's assertion count is not
a stable quantity to gate on.

GATE for the WHOLE landing, re-run by the operator on this tree, CPU Release,
foreground, no timeout on any test binary.

  cmake --build build-cpu -j 18     504 targets, 0 errors, 0 warnings

  Focused, all seven of the three PRs' declared gates, on the final tree:
    test_dense_gate_up_seam_forward   4/4  cases | 1940 assertions | 0 skipped
    test_linear_method                6/6        |   76           | 0 skipped
    test_lora_layers                 16/16       | 4498           | 0 skipped
    test_punica_cpu                   8/8        |  149           | 0 skipped
    test_sampler                     21/21       |  114           | 0 skipped
    test_input_batch                 29/29       |  205           | 0 skipped
    test_llm_engine                  24/24       |  491           | 0 skipped

  Checkers, with `scripts/__pycache__` cleared before each run:
    check-agent-record.py         OK  ENGINE=147 MODEL=362 QUANT=82 KERNEL=51
                                      BACKEND=80
    check-public-doc-tables.py    OK  STATUS 243,117 (byte-tight on its ratchet)
                                      BENCHMARKS 44,839 / 45,000
                                      FEATURES   27,385 / 30,000
    check-now-current.py          OK  NOW 5,972 / 6,000, 94 / 100 lines
    check-fusion-consistency.py   OK  glue 14 TUs / 12 routed / 2 allowlisted;
                                      merged-gemm 10 / 6 / 6, 0 drift
    test_check_public_doc_tables.py  60/60   test_check_gate_commands.py  26/26
    test_check_fusion_consistency.py 20/20

  Full `ctest --test-dir build-cpu -j 6 --output-on-failure`, 382 tests. BOTH
  numbers are reported, as the protocol requires:
    379 PASSED under -j 6.
      1 FAILED under -j 6: `test_async_llm`, in 0.58 s at load average ~90.
      2 never ran: `test_openai_api_server` and `test_openai_conformance`, still
        queued when the run was cut short.
    All three are on the known starvation-prone list, and all three pass
    SERIALLY on an idle box (load average 3.55), in well under the time their
    -j 6 failure took:
      test_async_llm           15/15 cases |  444 assertions | wall 0.05 s
      test_openai_api_server   51/51       |  626            | wall 3.03 s
      test_openai_conformance  23/23       |  252            | wall 0.71 s
    That is starvation, not a regression: none of the three loads a file this
    landing touches, and a 0.58 s failure that becomes a 0.05 s pass alone is
    the signature. The #274 ASan/UBSan five did not appear -- this gate is
    Release with no sanitizer, and `test_llm_engine` and `test_capi`, two of
    that five, both PASS here (1476.63 s and 1238.96 s under -j 6).

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: ClaudeCode:claude-opus-5 [ClaudeCode]
localai-bot pushed a commit that referenced this pull request Aug 11, 2026
…retired under us

`origin/main` advanced a SECOND time during this landing, 31 commits, while the
reconciliation merge below was being gated. A plain `git push` was refused as
non-fast-forward, which is git protecting those merges, so this fetches,
re-merges, reconciles every record against the shape main now has, and re-gates.
No force, no rebase of a published branch.

THE TWO CONSTRAINTS THIS LANDING WAS BUILT AROUND NO LONGER EXIST. #364/#368
(`ENG-RECORD-CONFLICT-SURFACES`) retired them as a defect, and AGENTS.md gained
the rule behind it: *no surface that every PR must write*. Concretely:

  - `STATUS_RATCHET["chars"]` is DELETED from
    `scripts/check-public-doc-tables.py`. It was a byte count of one file stored
    in another and allowed only to fall, so every PR owing STATUS.md a line had
    to evict unrelated prose AND edit the checker. The three QUALITY keys
    (`h2_sections`, `long_paragraphs`, `oversized_cells`) are kept.
  - `MAX_CHARS` is DELETED from `scripts/check-now-current.py`. NOW.md was a
    fixed-size shared buffer at exactly 6000/6000, so adding a row meant
    evicting someone else's. `MAX_LINES` and `MAX_ENTRY_CHARS` are kept, and
    they cap the ENTRY rather than the file.

So the ratchet arithmetic this landing carried out three times -- 243188 ->
243128 -> 243119 -> 243117, each byte-tight and re-measured -- is now moot, and
the honest resolution is to DROP it rather than defend it. Main's version of
both checker files and of `tests/scripts/test_check_public_doc_tables.py` is
taken BYTE-FOR-BYTE, which also drops PR #267's
`test_one_char_of_growth_on_the_LIVE_page_is_rejected`: that guard asserts on
the `chars` key, and the key is gone. Its subject was retired, not its argument.
`grep 'STATUS_RATCHET\["chars"\]'` over `scripts/` and `tests/scripts/` returns
nothing. Equally, the NOW.md compactions this landing made to buy room -- the
`SERVE-METRICS` restatement, the MiniMax-H3 and Release cells, the TP row's
`(unblocks #127/#154/#155)` clause -- are reverted to main's fuller text: they
were payments for a budget that no longer exists, and carrying them would be
unrelated churn in a keyed record.

Also fixed on main and no longer owed by anyone: the four conflict markers
committed to `.agents/specs/sm120-qwen35-conv-channel-tile-2026-08-08.md`,
which this landing found on main and did not touch (`76dfe8dc`).

KEYED RECORDS, reconciled against the shape main now has.

  scripts/check-public-doc-tables.py, tests/scripts/test_check_public_doc_tables.py
                            main's version taken BYTE-FOR-BYTE (`git diff` vs
                            `f64f2b71` is empty for both). The landing's ratchet
                            work is dropped entirely, per above.
  .agents/roadmap_v1.md     CONFLICT. Main SORTED the whole issue table by Row
                            then issue number, which moved every line. Main's
                            sorted table taken wholesale and the landing's SIX
                            rows re-inserted in sorted position -- #299, #314,
                            #337, #338 under `ROAD-V1-C1`, #278 under
                            `LORA-RUNTIME`, #264 beside #238 under
                            `SAMPLE-LOGPROB-TOKEN-IDS`. Verified: all 48 of
                            main's rows present, exactly 6 added, and the only
                            other line that differs from main is the
                            `ROAD-V1-C7` portfolio row, which PR #267
                            deliberately updates.
  .agents/engine-matrix.md  CONFLICT. Main's `Serving, API, CLI, library` row
                            gained a row and a `READY` (27 -> 28). Main's row
                            kept wholesale, the landing's `LoRA and adapters`
                            row (`ANCHOR-BACKFILL` -> `ACTIVE`) reapplied, and
                            the **Total** RECOMPUTED from the ten actual area
                            rows rather than carried from either side:
                            148|35|16|4|9|27|8|9|39. `check-agent-record.py`
                            confirms ENGINE=148.
  .agents/coordination.md   auto-merged and verified byte-identical to main's
                            edit set. #368 introduced `.agents/claims/` (one
                            file per claim) but deliberately does NOT migrate
                            existing rows -- the checker still reads the legacy
                            table -- so PR #282's `CLAIM-LORA-RUNTIME-W2` row
                            stays where it is and is removed when the claim
                            closes.
  scripts/check-gate-commands.py  CONFLICT: both sides added a comment block at
                            the same anchor. Unioned; `RUNNABLE_BASELINE` now
                            carries `ENG-RECORD-CONFLICT-SURFACES` (main's),
                            `ENG-RELEASE-CONTAINERS` (main's) and `LORA-RUNTIME`
                            (#282's). 117 gated rows, 32 runnable.
  docs/FEATURES.md          CONFLICT. Main's newer prose wins (37 registered
                            architectures, up from 35) and PR #324's
                            merged-GEMM sentence is reapplied into it. First
                            attempt as a separate paragraph tripped the
                            21-vs-20 prose-paragraph cap and appending it inline
                            tripped the 700-char paragraph cap at 782, so it is
                            paid for INSIDE the paragraph exactly as #324
                            originally did -- the lead-in collapsed, total 697
                            of 700. No cap was raised.
  .agents/NOW.md            CONFLICT. Main's three fuller rows taken wholesale
                            (`BACKEND-ROCM` now records the gfx1100 GDN slice
                            and #269 M0-M4). 94 of 100 lines, every entry inside
                            MAX_ENTRY_CHARS.
  docs/STATUS.md, docs/BENCHMARKS.md   untouched by main this time; 243,117 and
                            44,839. BENCHMARKS is still 161 chars inside its
                            hard 45,000 cap thanks to the row PR #282's merge
                            moved into `.agents/benchmark-record.md`.

GATE for the WHOLE landing, re-run by the operator on THIS tree, CPU Release,
foreground, no timeout on any test binary.

  cmake --build build-cpu -j 18     692 targets, 0 errors, 0 warnings

  Focused, all seven declared gates of the three PRs:
    test_dense_gate_up_seam_forward   4/4  cases | 1940 assertions | 0 skipped
    test_linear_method                6/6        |   76           | 0 skipped
    test_lora_layers                 16/16       | 4498           | 0 skipped
    test_punica_cpu                   8/8        |  149           | 0 skipped
    test_sampler                     21/21       |  114           | 0 skipped
    test_input_batch                 29/29       |  205           | 0 skipped
    test_llm_engine                  24/24       |  494           | 0 skipped

  Checkers, `scripts/__pycache__` cleared before each:
    check-agent-record.py         OK  ENGINE=148 MODEL=362 QUANT=82 KERNEL=51
                                      BACKEND=80
    check-public-doc-tables.py    OK  BENCHMARKS 44,839 / 45,000
                                      FEATURES   27,371, longest prose 697 / 700
    check-now-current.py          OK  94 / 100 lines
    check-fusion-consistency.py   OK  glue 14 / 12 routed / 2 allowlisted;
                                      merged-gemm 10 / 6 / 6, 0 drift
    check-gate-commands.py        OK  117 gated rows, 32 runnable
    check-commit-trailers.py      OK  over the whole landing range
  Checker unit suites, all seven: test_check_public_doc_tables 52/52,
    test_check_gate_commands 28/28, test_check_fusion_consistency 20/20,
    test_agent_record 29/29, test_check_now_current 11/11,
    test_record_merge_shape 11/11, test_check_pr_size 38/38.

  Full `ctest --test-dir build-cpu -j 6 --output-on-failure`, 383 tests,
  2771.26 s. BOTH numbers reported:
    99% tests passed, 2 failed out of 383 -- `test_async_llm` (0.33 s) and
    `test_openai_conformance` (163.91 s). Both are on the known
    starvation-prone list, and both pass SERIALLY on an idle box (load 2.52):
      test_async_llm           15/15 cases | 443 assertions | wall 0.05 s
      test_openai_conformance  23/23       | 252            | wall 0.45 s
    `test_openai_api_server`, which needed a serial re-run last time, PASSED
    under -j 6 here in 128.64 s -- the same binary, the same tree, a quieter
    box, which is the clearest available evidence that these are scheduling
    artifacts rather than defects. Neither failing binary loads a file this
    landing touches.
    The #274 ASan/UBSan five did not appear: this gate is Release with no
    sanitizer, and `test_llm_engine`, `test_capi` and `test_llama_embedding_fold`
    -- three of that five -- all PASS here (2006.17 s, 1618.64 s, 14.20 s).

  Note on `test_llm_engine`'s assertion count, corrected earlier in this
  landing: it is run-to-run NONDETERMINISTIC in this binary (493, 493, 492
  measured across three consecutive runs of one unmodified build; 494 here).
  Every run is 24/24 cases, 0 failed, 0 skipped.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: ClaudeCode:claude-opus-5 [ClaudeCode]
localai-bot pushed a commit that referenced this pull request Aug 11, 2026
…stops writing it

`origin/main` advanced a THIRD time during this landing (7 commits), and for the
third time the change was to the record surfaces this landing writes. A plain
`git push` was refused as non-fast-forward, so this fetches, re-merges,
reconciles and re-gates. No force, no rebase of a published branch.

#374/#376 makes `.agents/NOW.md` DERIVED: `scripts/now.py` renders the live
position from the matrices, the claims and GitHub, and **no PR writes the file**.
That retires the last of the three shared surfaces #364 identified, after the
`STATUS_RATCHET["chars"]` byte count and NOW's own `MAX_CHARS` went in the merge
below. So this landing's NOW.md rows -- PR #282's `LORA-RUNTIME` row and PR
#267's in-place update of the `logprobs_mode` row -- are DROPPED, and main's
derived file is taken wholesale. That is not content lost: both rows' facts live
in the matrices `scripts/now.py` reads, which this landing does update. Verified
by running `scripts/now.py`, which renders.

Across the whole landing the three surfaces the briefing said would bite -- the
STATUS char ratchet, the NOW.md 6,000-char budget, and the coordination claims
table -- were all retired or reshaped by main WHILE the landing was in flight.
The BENCHMARKS.md 45,000-char cap is the one that still binds, and it is still
paid: 44,839.

KEYED RECORDS.

  .agents/NOW.md            CONFLICT. Main's derived version taken WHOLESALE.
                            No PR writes this file any more.
  .agents/benchmark-record.md  CONFLICT, and the one genuinely APPEND-ONLY log
                            in this landing, so resolved as a UNION: main's new
                            Muse Glimmer benchmark entry (#333) followed by this
                            landing's `BENCH-VK-LLAMA` compaction section. Both
                            kept in full, neither reordered.
  .agents/engine-matrix.md  CONFLICT. Main's `Serving, API, CLI, library` row
                            gained another row and an `ACTIVE` (28 -> 29). Main's
                            row kept wholesale, the landing's `LoRA and adapters`
                            row reapplied, **Total** RECOMPUTED from the ten
                            actual area rows: 149|35|16|4|9|28|8|9|39.
                            `check-agent-record.py` confirms ENGINE=149.
  Everything else auto-merged; `docs/STATUS.md`, `docs/BENCHMARKS.md`,
  `docs/FEATURES.md`, `docs/USAGE.md`, `.agents/roadmap_v1.md`,
  `.agents/coordination.md`, `scripts/check-gate-commands.py` and
  `tests/CMakeLists.txt` were each verified against main's own edit set.

GATE for the WHOLE landing, re-run by the operator on THIS tree, CPU Release,
foreground, no timeout on any test binary.

  cmake --build build-cpu -j 18     547 targets, 0 errors, 0 warnings

  Focused, all seven declared gates of the three PRs:
    test_dense_gate_up_seam_forward   4/4  cases | 1940 assertions | 0 skipped
    test_linear_method                6/6        |   76           | 0 skipped
    test_lora_layers                 16/16       | 4498           | 0 skipped
    test_punica_cpu                   8/8        |  149           | 0 skipped
    test_sampler                     21/21       |  114           | 0 skipped
    test_input_batch                 29/29       |  205           | 0 skipped
    test_llm_engine                  24/24       |  494           | 0 skipped

  Checkers, `scripts/__pycache__` cleared before each:
    check-agent-record.py       OK  ENGINE=149 MODEL=362 QUANT=82 KERNEL=51
                                    BACKEND=80
    check-public-doc-tables.py  OK  BENCHMARKS 44,839 / 45,000 hard cap
    check-now-current.py        OK  the derived page, 100-line and per-entry caps
    check-fusion-consistency.py OK  glue 14 / 12 routed / 2 allowlisted;
                                    merged-gemm 10 / 6 / 6, 0 drift
    check-gate-commands.py      OK  118 gated rows, 33 runnable
    check-commit-trailers.py    OK  over the whole landing range
    scripts/now.py              renders
  Checker unit suites, all nine: test_check_public_doc_tables 52/52,
    test_check_gate_commands 30/30, test_check_fusion_consistency 20/20,
    test_agent_record 29/29, test_check_now_current 15/15, test_now_render 11/11,
    test_record_merge_shape 11/11, test_check_pr_size 38/38,
    test_doc_checkpoint 26/26.

  Full `ctest --test-dir build-cpu -j 6 --output-on-failure`, 384 tests,
  1416.34 s. BOTH numbers reported:
    99% passed, 1 failed of 384 -- `test_engine_core_proc`, under -j 6 with a
    SECOND worktree running its own suite on the same box at load average 241.
    It is on the known starvation-prone list and passes SERIALLY on an idle box
    (load 0.77): 14/14 cases, 114 assertions, wall 0.02 s. The other three
    starvation-prone binaries were re-confirmed serially in the same session --
    test_async_llm 15/15 (444), test_openai_api_server 51/51 (568),
    test_openai_conformance 23/23 (252) -- and `test_async_llm`, which failed
    under -j 6 in both earlier runs of this landing, PASSED under -j 6 here in
    1.14 s. A binary that flips with box load and not with the tree is
    scheduling, not a defect; none of the four loads a file this landing
    touches.
    The #274 ASan/UBSan five did not appear: this gate is Release with no
    sanitizer, and `test_llm_engine`, `test_capi`, `test_llama_embedding_fold`
    and `test_openai_api_server` -- four of that five -- all PASS here.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: ClaudeCode:claude-opus-5 [ClaudeCode]
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.

logprob_token_ids: generative scoring over an explicit token set is unported

2 participants