Repository navigation
FIT STEP 1: the selector stops advertising a runtime-neutral domain it never served - #10358
Conversation
…t never served Structural reclassification only, authorized by side-chat ruling as step 1 of the realization-axis cut. No behaviour changes and no vLLM path appears. WHY IT WAS A LIE BY NAME. gunbc.model.choice presented ServingChoice, QuantizedCandidate, ServingConstraints, ServingRealizationIdentity and ServingRuntimeIdentity as runtime-neutral. They are not, at every load-bearing position: runtime identity is minted solely from Ollama release authority, the configuration is an ObservedOllamaLaunchConfiguration, the fit evidence is a List<OllamaRunnerMemoryObservation>, and the admissible verdict carries that observation. There is no vLLM reference anywhere in the module. The consequence, established earlier this cycle: the live vLLM service has no constructor here at all -- not an unfit candidate, an unrepresentable one. gunbc.model.choice -> gunbc.model.ollama_choice choose_serving_candidate -> choose_ollama_serving_candidate ServingChoice -> OllamaServingChoice QuantizedCandidate -> OllamaQuantizedCandidate ServingConstraints -> OllamaServingConstraints ServingRealizationIdentity-> OllamaServingRealizationIdentity ServingRuntimeIdentity -> OllamaServingRuntimeIdentity CandidateVerdict -> OllamaCandidateVerdict evaluate_candidate -> qualify_ollama_candidate THE ENTRY POINT STAYS A CHOOSER, and that is the correction I needed. I was going to call the module a QUALIFIER. It performs two separable things -- runtime-specific qualification, and maximum-quality selection with release-relative rank and tie refusal -- and only the first is Ollama-specific by nature. Naming the whole module a qualifier would have misdescribed the second half and quietly asserted a decomposition that has not happened. So qualify_ollama_candidate names the half that really is qualification, and the top-level function stays a chooser because it still chooses. WHAT IS DELIBERATELY ABSENT. No neutral kernel extraction, no Vllm arm, no FitEvidence coproduct, no QualifiedCandidate carrier, no decision-order or verdict change. A central coproduct or a generically-renamed OllamaRunnerMemoryObservation would keep realization dispatch inside the selector and make provenance laundering type-correct -- the shape this sequence exists to remove. The first common type belongs AFTER qualification. NO COMPATIBILITY RE-EXPORT. A wrapper preserving the old spelling would retain exactly the misleading public surface this removes, so the compile failures at old import sites are the census (DESIGN section 3 delete-first: in a fail-closed substrate the deletion is what makes real dependents refuse loudly). Censused first -- every renamed concept was contained to this module and its witness, so the blast radius was known before the rename, not hoped for. The annotation on the entry point states that the neutral kernel has NOT been extracted, so this cut cannot later be cited as completing step 2. EVIDENCE: all 42 witnesses in the choice entry pass, changed only in module and symbol references. Every fixture value, decision ordering, rejection axis, unanswerable outcome, winner and tie result is identical -- which is what distinguishes a rename from an edit. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U397y4s3dSBof7vGPAX87G
…ead name is cited Review 59813. My census before the rename covered code -- imports, call sites, type references -- and missed PROSE citations of the module. Four sites still named the dead authority: dag/std/measure.dag dag/gunbc/model/population.dag dag/gunbc/spark/serving_convergence_withholding.dag docs/plans/spark-fleet-hand-edit-gap-analysis.md These are exactly what DESIGN section 3's standing rule protects. It says to cite the SYMBOL rather than the position, on the grounds that a stale name is decidable and enforceable while a stale line is not reachable from the namespace tree at all. A rename that leaves symbol citations pointing at a module which no longer exists spends that guarantee without collecting it: the citations are still decidable, they are just now decidably wrong. Swept in one motion, and the sweep was widened to the renamed SYMBOLS in prose as well, not only the module path -- same rule, same failure. Nothing under the old spellings survives anywhere in the tree. ONE OF THEM IS NOT A MECHANICAL RELABEL. serving_convergence_withholding carries a paragraph whose whole job is to stop that gate being mistaken for the fit gate: "gunbc.model.choice decides whether a candidate fits a host's memory. This decides whether a host may receive serving convergence AT ALL." The rename SHARPENS that distinction rather than merely relabelling it, so the paragraph now says gunbc.model.ollama_choice decides whether an OLLAMA candidate fits, and states that the gate cannot speak to a vLLM realization at all. The new name makes that paragraph's point more forcefully than the old one could. The docs/plans file is hand-authored rather than a generated projection, so it is edited directly rather than through the artifact gate. All four edits are annotation or markdown only -- annotations are erased before every semantic pass, so no behaviour can change. Executed rather than asserted: 42 of 42 witnesses pass, no failures. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U397y4s3dSBof7vGPAX87G
|
Review 59813 is right and it is fixed at That gap matters more than its size suggests. DESIGN §3's standing rule says to cite the symbol rather than the position precisely because a stale name is decidable and enforceable while a stale line is not reachable from the namespace tree at all. A rename that leaves symbol citations pointing at a module which no longer exists spends that guarantee without collecting it — the citations are still decidable, they are just now decidably wrong. So the reviewer's framing is exact: the rename was not complete without them. One is not a mechanical relabel.
The rename sharpens that distinction rather than relabelling it, so it now reads that
All four edits are annotation or markdown only, and annotations are erased before every semantic pass, so no behaviour can change. Executed rather than asserted: 42 of 42 witnesses pass, no failures — same fixtures, same decision ordering, same rejection axes, same winners, same ties as before the rename. — sent from eager-pike-541 |
briansrls
left a comment
There was a problem hiding this comment.
APPROVE exact head d56d291. This is FIT step 1 only: an Ollama-specific structural reclassification, with the top-level surface still truthfully named as a chooser and only the qualification half named qualify_ollama_candidate. The chooser body, decision order, fixtures, rejection axes, winners, and tie behavior are unchanged; all remaining changed files repair stale prose citations. No neutral kernel, vLLM arm, FitEvidence coproduct, compatibility wrapper, or genericized Ollama memory evidence was introduced. Merge authorization remains conditional on required exact-head CI reaching terminal success and this SHA remaining the head.
…1-ollama-choice-reclass
briansrls
left a comment
There was a problem hiding this comment.
APPROVE exact head 76ba0e2. Re-review scope was the merge from main after the prior exact-head approval became stale. The commit's parents are the previously approved d56d291 and main@ce937d0c4d4eac22e7f16eef5ad75305750fc810. Comparing d56d291 to this head shows only main-side files; none of the PR's six reviewed files changed. Comparing current main to this head yields the same six-file step-1 reclassification, with no interaction in choice.dag/ollama_choice.dag or measure.dag and no added neutral kernel, vLLM arm, FitEvidence coproduct, compatibility surface, or behavior change. Merge authorization remains conditional on required exact-head CI reaching terminal success and this SHA remaining the head.
… dead account of review 59866 is correct and the defect is mine. The rename swept docs/plans/spark-fleet-hand-edit-gap-analysis.md section 7 for the module NAME and did not re-read whether the section's CLAIM was still true. It was not. Section 7 said gunbc.model.ollama_choice keys a realization on the runner's argv and therefore cannot distinguish two units differing in context ceiling and slot count -- and the module's own annotation, in the same PR, says that argv key was replaced. Attaching the current authority's name to an obsolete account of it is worse than the stale name it replaced: a stale name is visibly dead, while a live name over a dead claim reads as current. This is the same class as review 59813's four stale prose citations, one level deeper. That one was a name census; this one is a CLAIM census, and a rename does not discharge it. The question a rename must ask at every site is not "does this name still resolve" but "is the sentence containing it still true of what it now names". Section 7 is closed in the document's own idiom, recording three things it did not ask for: the carrier was REPLACED rather than widened, because argv was never the right subject and extdeps.ollama.server_env already holds the variables as typed axes; the partition is owned by the module rather than supplied by the caller, where the predecessor's varied_flags argument let a caller erase a causal axis from the fixed mode and thereby authorize evidence transport across it; and identity runs typed values first and wire second, so the module never parses an observed string. Ordered item 4 is closed with it. It read "This is landing in #9897 rather than waiting", and #9897 has merged -- a plan item describing its own landing in the present tense is stale the moment it lands. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U397y4s3dSBof7vGPAX87G
|
review 59866 is correct and the defect is mine. Fixed in The rename swept This is the same class as review 59813's four stale prose citations, one level deeper. That was a NAME census; this is a CLAIM census, and a rename does not discharge it. The question at every swept site is not "does this name still resolve" but "is the sentence containing it still true of what it now names". §7 is now closed in the document's own strikethrough idiom, recording three things the section did not ask for: the carrier was REPLACED rather than widened (argv was never the right subject — I also closed ordered item 4 with it, which the review did not flag. It read "This is landing in #9897 rather than waiting", and #9897 has merged — a plan item narrating its own landing in the present tense is stale the moment it lands. This moves the head off |
briansrls
left a comment
There was a problem hiding this comment.
APPROVE exact head 3bc2023. Re-review scope is the single commit after the previously approved 76ba0e2: only docs/plans/spark-fleet-hand-edit-gap-analysis.md changed. The correction is necessary and accurate: the section no longer attaches the live gunbc.model.ollama_choice name to the obsolete argv-key account; it records the closed ObservedOllamaLaunchConfiguration projection, module-owned partition, and typed-values-before-wire direction, and closes the already-landed plan item rather than describing it in the present tense. The step-1 code and witness diff remain unchanged. Merge authorization remains conditional on terminal required exact-head CI and this SHA remaining the head.
…ct identity
CI caught what four dashboard reviews, one exact-head review and I all missed. The floor
lane refused, and NOT on a witness -- every witness passed:
FAILED PHASE namespace-wave-admission (255 unadjudicated delta(s), 0 stale, 142 consumed)
adjudication REFUSED standing=measurement_completed blockers=1
Every one of the 255 reads
TargetChanged binding test.claim.model.serving_choice_witness_test::<decl> `<spelling>`
base {gunbc.model.choice} -> head {gunbc.model.ollama_choice}
which is the wall working exactly as gunbc.namespace_wave_admission documents: a run is
ADMITTED only when the UNADJUDICATED set is empty, never when the delta set is empty. A
rename that moves what a spelling binds to IS a namespace wave, and I authored one without
its roster contribution.
WHY EVERY ROW IS ENUMERATED RATHER THAN PATTERNED. The module carrying this roster says a
pattern would admit a genuine rebind that happened to land in the same two modules, and a
rename wave is precisely the change that must not be able to hide one. So each row names
module, enclosing declaration, spelling and target exactly. Every one is a PURE RELOCATION:
not one declaration changes what it denotes.
WHY ONLY THE WITNESS MODULE APPEARS, which is worth recording because it looks like an
omission and is not. The wall's binding channel is authored NAME OCCURRENCES resolved per
module, and test.claim.model.serving_choice_witness_test is the only consumer importing
these spellings by bare name. The other three touched files -- gunbc.model.population,
gunbc.spark.serving_convergence_withholding and std.measure -- carry the old module name
only in PROSE. The binding channel does not observe prose, and should not; that surface is
the claim-census class this same PR already had to repair by hand, and the two are
complementary rather than redundant.
DISSOLUTION IS MANDATORY AND DATED. These rows go when #10358 merges: base and head will
both carry the rename, no run can produce the deltas, and all 255 report STALE -- which
refuses every unrelated PR. The shrink is the fix, not housekeeping.
cargo check -p v1-compiler --lib is green on the remote runner.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U397y4s3dSBof7vGPAX87G
|
Pushed
All 255 read: That is the wall working exactly as Every row is enumerated by exact identity, not patterned. The roster's own note says a pattern would admit a genuine rebind that happened to land in the same two modules — and a rename wave is precisely the change that must not be able to hide one. Each row names module, enclosing declaration, spelling and target. Every one is a pure relocation: not one declaration changes what it denotes. Why only the witness module appears — this looks like an omission and is not. The binding channel resolves authored name occurrences per module, and the witness is the only consumer importing these spellings by bare name. Dissolution is mandatory and dated. These rows go when this PR merges: base and head will both carry the rename, no run can produce the deltas, and all 255 report stale — which refuses every unrelated PR. The shrink is the fix, not housekeeping.
|
…an hand-merging the hunk main's NAMESPACE_TRANSITION_ADMISSIONS moved underneath this branch in two ways at once, and the conflict is at the head of the array where both changes land. main ADDED the gunbc#10197 rung-drop per-row split rows. main DELETED the gunbc#10254 Spark OOBE vendor-interface rows, dissolved on their own trigger when that PR merged. Hand-merging the conflicted hunk would have kept my side's copy of the OOBE rows, which main had already retired. Those rows would have been STALE ADMISSIONS the moment they landed -- a permission standing over a delta no run can produce -- and the wall refuses a stale admission exactly as it refuses an unadjudicated delta, so the resurrection would have blocked every unrelated PR until someone deleted them again. So the resolution takes main's roster WHOLESALE and re-seats my 255 rows on top of it. The authored content is unchanged; what changed is which neighbours it sits beside, which is a fact about main and not mine to merge by hand. THE ROWS ARE STILL THE RIGHT SET. main has not touched dag/test/claim/model/serving_choice_witness_test.dag or dag/gunbc/model/choice.dag since the base this branch measured against, so the wave those 255 rows describe is unchanged. The deltas are a function of what this branch does to that witness, not of what main did elsewhere. cargo check -p v1-compiler --lib green on the remote runner after the merge. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U397y4s3dSBof7vGPAX87G
|
Conflict resolved in The conflict was at the head of
Hand-merging the conflicted hunk would have kept my side's copy of the OOBE rows that So I took The rows are still the correct set.
|
briansrls
left a comment
There was a problem hiding this comment.
REQUEST_CHANGES on exact head 2d1c9bc.
The namespace wave is real and belongs in #10358. The required-floor receipt on #10370 establishes 255 unadjudicated TargetChanged binding deltas and no witness failure. The 255 exact per-binding TransitionAdmission rows are the correct shape; #10370 must not duplicate them. I also checked the merge resolution: current main's serving_choice witness and old choice module are byte-identical to the measured base, and the head takes current main's namespace roster before adding this cohort, so the newly added #10197 rows remain and the retired #10254 OOBE rows do not return. I found no implementation or row-population blocker.
One content blocker remains in the OLLAMA_CHOICE_RECLASS_LABEL lifecycle annotation. It says that after #10358 merges all 255 rows become stale and refuse every unrelated PR. The implementation says otherwise. A binding admission is consumed when the base binds its (module, declaration, spelling) to exactly the admitted singleton target; after this rename lands, these rows bind exactly to gunbc.model.ollama_choice and therefore become consumed. Consumed rows are blocking only when the admission-roster path is touched (consumed_due = roster_touched && !consumed_admissions.is_empty()); unrelated PRs remain admitted. The source itself renders this as “consumed by its own merge; deletion is owed on the roster's next touch.”
Rewrite the trigger paragraph accordingly: the merge consumes the 255 rows; the first subsequent roster-touching change must delete the cohort, and an immediate post-merge cleanup is appropriate. They cannot be deleted in the same PR tree that needs them to admit the rename. This is prose-only. Do not change the 255 identities and do not add them to #10370.
The old exact-head approval on 3bc2023 has been dismissed. Required exact-head CI is pending; no merge authorization.
… due Takes side chat's exact-head REQUEST_CHANGES review 5111479181 on #10358. Two findings, and only the first is prose. ONE: THE LIFECYCLE CLAIM WAS WRONG IN BOTH HALVES. My trigger paragraph said the 255 rows would report STALE once the rename lands and would then refuse EVERY unrelated PR. Neither is what the mechanism implements. A STALE row matches no delta in the run. A CONSUMED row is one the BASE has already satisfied -- admission_consumed_at_base holds when the base binds the exact (module, declaration, spelling) to a singleton set containing the admitted target. After #10358 lands, every one of these spellings binds to gunbc.model.ollama_choice at the base, so they are consumed. Different states, different reporters. Consumed rows are NOT globally blocking. The predicate is consumed_due = roster_touched && !consumed_admissions.is_empty(), so a consumed row comes due on the roster file's OWN next touch and on no other change. An enrolled unit test names exactly that behaviour. The wrong version overstated this cohort's blast radius, which is the same defect class as the argv paragraph this PR already had to repair: a confident sentence about a mechanism, written without reading the mechanism. TWO, AND IT IS NOT PROSE: THIS CHANGE OWED SIXTEEN DELETIONS AND HAD NOT MADE THEM. Because this PR touches the roster, roster_touched is true, so every already-consumed row in the file comes due. main carries sixteen gunbc#10197 rung-drop per-row split rows; #10197 is on main at 0c031e6, and gunbc.design_ledgers there already imports rung_drop_roster from gunbc.rung_drop.roster by name, so the base binds each admitted spelling to its admitted target and all sixteen are consumed. Left in place, this run refuses again -- on consumed_due rather than on unadjudicated deltas, one blocker traded for another. They are deleted with their label, and a twenty-sixth dissolution entry records why THIS change owed it: carrying consumed rows forward while editing the same file is precisely what the predicate exists to prevent. Why the earlier runs did not show this: neither 76ba0e2 nor #10370's head touches namespace_wave_admission.rs, so consumed_due was false there and the 142 consumed rows were reported without blocking. Touching the roster is what makes them due. The 255 identities are unchanged, and none were added to #10370. cargo check -p v1-compiler --lib is green on the remote runner. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U397y4s3dSBof7vGPAX87G
|
Pushed 1. My lifecycle claim was wrong in both halves. I wrote that the 255 rows would report stale once the rename lands, and would then refuse every unrelated PR. Neither is what the mechanism implements:
The wrong version overstated this cohort's blast radius — the same defect class as the argv paragraph this PR already had to repair: a confident sentence about a mechanism, written without reading the mechanism. 2. Not prose — this change owed sixteen deletions and had not made them. Because this PR touches the roster, They are deleted with their label, and a twenty-sixth dissolution entry records why this change owed it. Carrying consumed rows forward while editing the same file is precisely what the predicate exists to prevent. Why earlier runs didn't surface it: neither The 255 identities are unchanged and none were added to #10370. |
briansrls
left a comment
There was a problem hiding this comment.
REQUEST_CHANGES on exact head 4ae0b1f.
First, the controlling correction: the stricter interim note was right and my final “prose-only” ruling was materially incomplete. DO NOT restore the sixteen gunbc#10197 rows. This PR touches namespace_wave_admission.rs, so roster_touched is true; every admission already consumed at the base is due on this run.
I rechecked the full base proof rather than extrapolating from gunbc.design_ledgers. #10197's merge 0c031e6 is an ancestor of this PR's base 4f0ad8c, and none of the five relevant consumer files changed in between. The sixteen rows partition 1/2/5/7/1 across gunbc.design_ledgers, deleted_cadence_reference_census_witness_test, rung_drop_declaration_witness_test, rung_drop_standing_partition_witness_test, and tools.ci_gates. At the base, each named declaration still contains the spelling and each module imports that spelling from exactly the admitted target. The candidate set is therefore the admitted singleton for every row, admission_consumed_at_base holds sixteen times, and leaving them would trade the unadjudicated blocker for consumed_due. The deletion and label removal are REQUIRED and ACCEPTED.
The exact-head delta is one file, +30/-165. It removes exactly those sixteen rows and their label, corrects the Ollama cohort lifecycle prose, and does not touch any of the 255 identities or #10370. The 56 KB near-miss did not enter the commit; the existing ledger remains present.
Two prose blockers remain in the new dissolution entry:
-
It creates a duplicate ordinal. The file already contains
TWENTY-SIXTH DISSOLUTION (2026-09-04, gunbc#10197)for the 142 #10254 OOBE rows immediately above. The new entry is alsoTWENTY-SIXTH DISSOLUTION, and there is no TWENTY-SEVENTH entry. Rename the new one toTWENTY-SEVENTH DISSOLUTION (2026-09-04, gunbc#10358). This ledger itself states that the ordinal exists to make an entry citable and records duplicate ordinals as a defect; repeating one here is not harmless numbering. -
The proof paragraph names only gunbc.design_ledgers importing rung_drop_roster and then concludes that each of sixteen rows is consumed. That evidence establishes one row, not sixteen; the other fifteen span four modules and four additional target/spelling groups. Record the actual grouped join, for example: 1 design_ledgers; 2 deleted-cadence witness; 5 rung-drop-declaration witness; 7 standing-partition witness; 1 tools.ci_gates, with each group's exact imported target. The deletion is correct; the written proof is presently narrower than its conclusion.
These corrections are prose-only. Do not restore the sixteen rows, do not alter the 255-row cohort, and do not add anything to #10370. Run 33860809090 is pending but will become superseded when this head moves; the replacement exact-head run must establish zero unadjudicated, zero stale, and no consumed-due blocker. No merge authorization.
…rrate the #10197 deletion main moved again while this branch was open: gunbc#10344 landed (61274d0) and did BOTH halves of the roster treadmill in one change -- it deleted the sixteen gunbc#10197 rows that its own roster touch had made due, and added nineteen of its own for the asset-identity extraction. TWO CONSEQUENCES, AND NEITHER IS A PLAIN MERGE. FIRST, #10344's NINETEEN ROWS ARE NOW CONSUMED AT THIS BRANCH'S BASE, so this change owes their deletion for the same reason it owed #10197's. gunbc.fleet_physical_inventory on main already imports chassis_srv1 and its twelve siblings from gunbc.fleet_asset_identity -- the admitted target -- and that file is not in this diff, so base equals head for it and admission_consumed_at_base holds on every row. consumed_due is roster_touched && !consumed.is_empty(), this change touches the roster, so leaving them refuses the run. Deleted. The treadmill is deliberate, not an accident of timing: each roster-touching change discharges the cohort the previous one left consumed. #10344 did exactly this to #10197, and the next roster-touching change will do it to the cohort below. SECOND, MY OWN TWENTY-SIXTH ENTRY HAD TO BE REWRITTEN RATHER THAN CARRIED. The previous head of this branch deleted the #10197 rows and narrated that deletion. main deleted the same sixteen independently. Carrying my entry would double-record one event -- the failure the TWENTY-THIRD and TWENTY-FOURTH entries in this same ledger already call out and refuse. My entry is dropped in favour of main's action, and the rewritten entry records the #10344 discharge with a sentence saying explicitly why #10197 is not narrated here. RESOLUTION SHAPE, unchanged from the previous merge and for the same reason: main's roster is taken WHOLESALE and the 255-row cohort is re-seated on it. Hand-merging the hunk would have preserved my side's copy of rows main had already retired, which is how a resolution manufactures stale admissions. The 255 identities are untouched and none were added to #10370. cargo check -p v1-compiler --lib is green on the remote runner after the merge. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U397y4s3dSBof7vGPAX87G
…rdinal was wrong twice over Takes side chat's exact-head REQUEST_CHANGES review 5111687963. It also confirms the sixteen-row deletion was REQUIRED -- it re-derived consumption across all five consumer modules rather than the one specimen I cited -- and forbids restoring them. Both remaining findings are prose, and both survived the #10344 merge in altered form. ONE: THE ORDINAL. Side chat found my entry duplicating TWENTY-SIXTH. On the merged tree it is worse: #10344 trimmed the ledger, so the highest surviving ordinal is TWENTY-THIRD and my entry was SKIPPING twenty-four and twenty-five. A skipped ordinal is the same defect as a duplicated one -- the number exists to make an entry citable by its own name, and it does that only if it is exactly the next one. Now TWENTY-FOURTH. TWO: THE PROOF WAS NARROWER THAN ITS CONCLUSION, and the criticism transferred exactly across the rewrite. Side chat caught my #10197 paragraph citing the design_ledgers row and concluding all sixteen; the entry I wrote for #10344 reproduced the shape, citing fleet_physical_inventory importing chassis_srv1 and concluding all nineteen. Establishing one row and asserting nineteen is precisely what this ledger refuses. The actual partition, computed rather than assumed: 15 gunbc.fleet_physical_inventory -> gunbc.fleet_asset_identity 4 test.claim.cooling_qualification_witness -> gunbc.fleet_asset_identity The fifteen resolve directly. The four are the ones I would have recorded wrongly: the cooling witness imports cooler_srv3 from gunbc.fleet_physical_inventory, NOT from the asset authority, so the row looks like it names the wrong target until the binding channel is read correctly -- it follows the re-export chain to the module that actually DECLARES the name. Same admitted target, one hop further out. The entry now states that separately, because a reader checking the row against the witness's import list would otherwise conclude the row was mis-authored. Neither consumer file is in this diff, so base equals head for both and admission_consumed_at_base holds on all nineteen. The 255 identities are untouched and none were added to #10370. cargo check -p v1-compiler --lib is green on the remote runner. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U397y4s3dSBof7vGPAX87G
|
Pushed 1. The ordinal. Side chat found my entry duplicating 2. The proof was narrower than its conclusion, and the criticism transferred exactly across the rewrite. Side chat caught my #10197 paragraph citing the The real partition, computed rather than assumed: The four are the ones I'd have recorded wrongly. The cooling witness imports Neither consumer file is in this diff, so base equals head for both and Also on the record from that review: the sixteen-row #10197 deletion was required, verified independently across all five consumer modules rather than the single specimen I cited, and restoring them is forbidden. On the current head that deletion is main's (via #10344), not this PR's — the entry says so explicitly rather than double-recording one event. The 255 identities are untouched and none were added to #10370. |
briansrls
left a comment
There was a problem hiding this comment.
APPROVE exact head 12b0e57.
Both blockers from review 5111687963 are discharged on the merged ledger actually present at this head. #10344 changed the roster before this branch rejoined main: it deleted the sixteen #10197 rows and introduced nineteen asset-identity admissions. The highest surviving dissolution ordinal at the join is TWENTY-THIRD, so this head correctly records the next event as TWENTY-FOURTH rather than preserving the pre-merge 26/27 prescription.
The consumption proof now owns the full population rather than one specimen: 15 binding identities in gunbc.fleet_physical_inventory resolve directly to gunbc.fleet_asset_identity, and 4 in test.claim.cooling_qualification_witness resolve through the imported fleet namespace to that same declaring authority. The base import carries all 13 asset constants used by the repeated direct binding identities; the witness imports cooler_srv3 through fleet_physical_inventory; neither consumer file is in this PR diff, so base and head agree and admission_consumed_at_base holds for all nineteen. Their deletion on this roster touch is correct. The independently deleted #10197 cohort is not double-narrated.
The Ollama lifecycle paragraph now says consumed rather than stale and scopes the deletion obligation to the next roster-touching run. The 255 exact admission identities remain unchanged, and none were copied to #10370. No implementation, selector behavior, or step-2 content changed.
Required exact-head run 33868113495 is pending. Merge authorization remains conditional on terminal success and this SHA remaining the head.
The grouped 15/4 partition is correct -- verified against the base roster, which holds exactly 19 rows: 15 in gunbc.fleet_physical_inventory and 4 in test.claim.cooling_qualification_witness, both targeting gunbc.fleet_asset_identity. The prose around it was not. It said the fifteen were `chassis_srv1` "and its twelve siblings". That is 13, not 15, and it silently reintroduced the grain error this entry exists to refuse -- counting CONSTANTS where the admission key counts OCCURRENCES. The key is (module, in_declaration, spelling), so one constant referenced from two declarations is two rows. Measured: the fifteen are 10 distinct spellings across 8 declarations. cooler_srv3 alone contributes three rows (installed_cooler_containments, installed_cooling_realizations, srv3_cooler_asset) and chassis_srv1 two (fleet_host_spatial_facts, srv1_chassis_asset). The four cooling-witness rows are the same grain from the opposite direction: one spelling, cooler_srv3, in four different declarations. The label's "13 PhysicalAssetIdentity constants" is the moved population, not this cohort. All ten admitted spellings are among the thirteen; the three that never appear -- ams_01, pi_controller, printer_01 -- moved with the others but are referenced by no admitted occurrence. So 13, 10 and 15 count constants moved, names referenced, and occurrences admitted, and none is a restatement of another. No admission row changes; the 255-row Ollama cohort is untouched. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U397y4s3dSBof7vGPAX87G
briansrls
left a comment
There was a problem hiding this comment.
APPROVE exact head 8ef903f.
The sole commit after 12b0e57 changes only the consumption-proof prose in namespace_wave_admission.rs (+22/-7); no TransitionAdmission row changes. It closes the count-versus-grain seam in my superseded review.
The measured populations are distinct and now stated distinctly. The base cohort has 19 exact admission keys: 15 (module, in_declaration, spelling) keys in gunbc.fleet_physical_inventory and 4 in test.claim.cooling_qualification_witness, all targeting gunbc.fleet_asset_identity. The 15 direct keys contain 10 distinct spellings across 8 declarations: repeated uses such as cooler_srv3 in three declarations and chassis_srv1 in two are separate occurrence-grain rows. The four witness keys are one spelling, cooler_srv3, in four declarations. Separately, fleet_asset_identity declares 13 moved PhysicalAssetIdentity constants; ams_01, pi_controller, and printer_01 are in that moved population but in no admitted occurrence. Thus 13 constants moved, 10 names referenced, and 15 direct occurrence keys are three different denominators.
The TWENTY-FOURTH ordinal, grouped 15/4 consumption proof, deletion of the inherited consumed cohort, consumed-not-stale lifecycle, and all previously reviewed FIT step-1 content remain accepted. The 255 Ollama admission identities are unchanged and none are copied to #10370.
Required exact-head run 33869134455 is pending. Merge authorization remains conditional on terminal success and this SHA remaining the head.
…action shape #10358 renamed gunbc.model.choice -> gunbc.model.ollama_choice on main. Git tracked the rename, so this branch's kernel extraction landed in the renamed file and only the hunks where the two changes genuinely disagree conflicted. dag/gunbc/model/ollama_choice.dag -- four hunks, resolved to THIS BRANCH. Main carries the pre-extraction body because #10358 was a rename and nothing else: it still declares WithinReleaseQuality, compare_within_release, verdict_quality and the distinct_release_count diagnostic. This branch deleted all of them when the runtime-neutral maximum moved to gunbc.model.release_relative_selection. Taking main's side would have restored the very duplication step 2 exists to remove, so the extracted form wins every conflicting hunk. Verified after resolution: verdict_quality, quality_maximum, verdicts_at_quality, distinct_release_count, verdict_release, QualityMaximum, compare_within_release and WithinReleaseQuality are all absent from this module, the kernel import is present, and ollama_ranked_admissible remains the sole Ollama contribution to selection. Main's own sentence in that file -- "THE RUNTIME-NEUTRAL MAXIMUM/TIE KERNEL HAS NOT YET BEEN EXTRACTED, and this sentence exists so that the rename cannot be cited as though it had been" -- was written to be deleted by exactly this commit. It is now false, and it is gone. docs/plans/spark-fleet-hand-edit-gap-analysis.md -- one hunk, resolved to MAIN. This branch still carried the superseded argv-keyed claim about section 7; main carries the CLOSED correction that #10358 landed, naming ObservedOllamaLaunchConfiguration and ExactRuntimeConfigurationIdentity. Keeping this branch's side would have re-opened the exact defect that review 59866 caught and that #10403 files as a_live_authority_name_carries_a_superseded_claim. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U397y4s3dSBof7vGPAX87G
… and mine is dropped #10358 landed 255 admission rows and, in the same change, paid the roster-touching obligation this branch had just paid: main's own TWENTY-FOURTH DISSOLUTION deletes the same nineteen gunbc#10344 asset-identity rows, by the same trigger, with a 15+4 partition matching the nineteen measured here. ONE EVENT, ONE RECORD -- so THIS BRANCH'S TWENTY-FOURTH DISSOLUTION IS DELETED, not reconciled. Both entries carried the same ordinal for the same deletion; keeping both would be the double-narration this roster refuses in its own prose and which it has already resolved this way twice (the #10011 rows yielded to #10106, the #10218 row yielded to main). Main's record is kept because it is main's, and because it is the better entry: it states the partition rather than generalising from one specimen. The deletion itself is unaffected -- the rows are gone either way, and the adjudicator independently confirmed nineteen on run 33862141548 before either record existed. RESOLVED AS MAIN WHOLESALE PLUS THIS BRANCH'S TRANSITION. The file is not generated: .gitattributes line 65 excludes it from merge=generated-artifact and git check-attr reports "merge: unspecified", so ordinary markers and hand resolution are correct here and the regeneration recipe would have been the wrong ceremony. VERIFIED AGAINST THE NEW DENOMINATOR, because main changed the population the arithmetic was measured on: 255 main rows all present, 2 mine, 257 total, identity 255+2 holds, zero surviving fleet_asset_identity rows, exactly one TWENTY-FOURTH DISSOLUTION, and the TWENTY-FIRST TRANSITION intact. Main's highest transition ordinal is still TWENTIETH, so the ordinal needs no renumber. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015EdHQ244XXdBKRKGX6jrV4
…ssary condition #10358 landed 255 selector-reclass rows. All 255 are consumed at this base -- every one names a spelling DECLARED in its target module -- so they are swept and my 30 stay. BOTH OF MY FIRST TWO PASSES AT THAT JOIN WERE WRONG, in the same shape as the two before them on this branch: an incomplete index answering "not found" indistinguishably from "not declared". The parser missed 11 of 255 rows, requiring module and spelling to be a single string literal when these rows carry continuation-joined ones. A row the parser cannot see is a row the join silently does not adjudicate. The declaration index missed every COPRODUCT VARIANT, reading only data, fn and type at line start. ChoseCandidate, NoCandidateAdmissible and 181 siblings resolved to an EMPTY owner set, which the join read as "the target does not declare this" and reported as 183 OPEN rows. Keeping those would have left 183 stale rows refusing every later unrelated PR. That is three times on this branch that a resolution step was inferred rather than read -- module-to-file transliterated from a module path, spelling-to-owner taken from the import path, and now the declaration set built from a pattern that did not cover the language. Each was silent, each was plausible, and each produced a confident answer of the wrong SHAPE rather than an error. An index that can be incomplete must be able to say so, because "absent" and "I did not look there" are different facts. So the ledger now states what the hand join actually is: a NECESSARY condition. The production predicate resolves the full subject through the re-export chain and requires an exact singleton target, which no join I can write by hand establishes. The wall's own run at the exact head is the proof. My transition entry was dropped again by resolving with main's file, and is restored -- renumbered TWENTY-SECOND rather than reusing TWENTY-FIRST, since main has landed its own transitions since and an ordinal should name one thing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9
* An annotation at scope end names nothing, and it has main red main has been failing the required-ci parse phase since #10390 (11:48Z). Every pull request that test-merges main fails required-witnesses-floor with: required-ci: FAILED PHASE parse (16 error(s)) required-ci: FAILED PHASE namespace-wave-admission (no head index) All 16 are one file. #10390 deleted the three workflow-subject rows at the end of test.claim.emit_copy_qualification_witness_test and left their explanatory block behind as a TRAILING epilogue at lines 483-500, with no module item after it. DESIGN section 4c admits only a leading block attached to a module-scope declaration: an annotation names the declaration that FOLLOWS it, so at scope end it names nothing. AnnotationAttachmentRefusal::UnattachedAtScopeEnd is exactly that refusal, and it fires once per line of the block. The second failure is not independent. claim_executor pushes "namespace-wave-admission (no head index)" only when the parse phase produced no index, so the wave never ran at all. One root, two reported blockers. WHY THIS SURFACED LATE, since #10390 landed hours before anything went red and a reader will otherwise suspect a different cause. The parse wall is not new and #10325 only changed which receipt arm carries blockers. The last green run on the old tree, #10358's 33869134455, was CREATED at 11:28 -- twenty minutes BEFORE #10390 merged -- so its merge ref predates the breakage and it never parsed these lines. The first runs to test-merge the broken main were the ones after it. THE REPAIR MOVES THE BLOCK TO THE MODULE HEAD, where the imports that follow give it a subject. Every sentence is preserved. The deictic words are not: "stood here" becomes "stood at the END OF THIS MODULE", "the rows above this comment" and "the mutants below" become "in this module", because a relocated pointer that still says "below" is a false citation of the kind this repository files as a_live_authority_name_carries_a_superseded_claim. A trailing paragraph records why the block sits at the head, so the next author does not move it back. Nothing else changes: no row, no assertion, no rung drop. The content already has a typed home at gunbc.rung_drop emit_copy_qualification_without_a_consumer, and this commit does not touch it. EVIDENCE, executed on this tree rather than argued: before required-ci: FAILED PHASE parse (16 error(s)) required-ci: FAILED PHASE namespace-wave-admission (no head index) after parse phase clean, no parse FAIL lines required-ci: namespace-wave-admission ADMITTED -- every delta is auto-admitted or named by a transition admission Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U397y4s3dSBof7vGPAX87G * The blank line was load-bearing: green parse, wrong subject The previous head made the parse green and gave the annotation the WRONG SUBJECT, which is worse than the refusal it replaced -- a plausible answer standing where a typed refusal used to be is the failure DESIGN section 5 forbids outright, and I shipped it while claiming the fix was verified. std.source_annotation module_header_gap_subject binds a post-module block to the MODULE ROOT only when the block opens immediately after the module line. Its first arm is if preceded_by_blank_line || preceded_by_annotation_line { none } so a blank line between `module ...` and the first `//` deliberately disables the module-root arm and sends the block through ordinary nearest-following attachment. On the previous head that bound this module-wide block to `import std.measure { byte_size }` -- an import it never describes -- instead of to the module it describes throughout. Removed that blank line. The blank line AFTER the block, before the imports, is kept: it ends the block. Nothing else changed. WHAT I HAD AND DID NOT USE. My evidence was "parse clean, wave ADMITTED". Both were true and neither says anything about WHICH SUBJECT the annotation acquired. A greener instrument reading is not evidence about the property I was actually changing, and I generalized from it anyway. EXECUTED: dag/test/claim/source_annotation_attachment_witness_test 13/13 PASS on this tree, and the parse phase reports zero parse FAIL lines. COVERAGE GAP, NAMED NOT FIXED HERE. No enrolled witness covers module_header_gap_subject's blank-line arm -- the exact rule that silently mis-bound this block. The attachment battery covers general leading, trailing, body-grain and block-splitting cases, but nothing discriminates module-root attachment from nearest-following attachment across that one bit. That witness belongs in its own change; this PR is a fleet unblocker for a red main and is deliberately staying one file wide. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U397y4s3dSBof7vGPAX87G --------- Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Step 1 of the realization-axis cut, authorized by side-chat ruling. Structural reclassification only — no behaviour change, no vLLM path.
Why the old names were a lie
gunbc.model.choicepresentedServingChoice,QuantizedCandidate,ServingConstraints,ServingRealizationIdentityandServingRuntimeIdentityas runtime-neutral. They are not, at every load-bearing position: runtime identity is minted solely from Ollama release authority, the configuration is anObservedOllamaLaunchConfiguration, the fit evidence is aList<OllamaRunnerMemoryObservation>, and the admissible verdict carries that observation. There is no vLLM reference anywhere in the module.The consequence established earlier this cycle: the live vLLM service has no constructor here at all — not an unfit candidate, an unrepresentable one.
The entry point stays a chooser
This was the correction I needed from review. I was going to name the module a qualifier. It performs two separable things — runtime-specific qualification, and maximum-quality selection with release-relative rank and tie refusal — and only the first is Ollama-specific by nature. Naming the whole module a qualifier would have misdescribed the second half and quietly asserted a decomposition that has not happened.
So
qualify_ollama_candidatenames the half that really is qualification, and the top-level function stays a chooser because it still chooses.Deliberately absent
A central coproduct, or a generically-renamed
OllamaRunnerMemoryObservation, would keep realization dispatch inside the selector and make provenance laundering type-correct — the shape this sequence exists to remove. The first common type belongs after realization-specific qualification, never around raw memory evidence.No compatibility re-export, deliberately: a wrapper preserving the old spelling would retain exactly the misleading public surface this removes, so compile failures at old import sites are the census (DESIGN §3 delete-first — in a fail-closed substrate the deletion is what makes real dependents refuse loudly). I censused first, so the blast radius was known rather than hoped for: every renamed concept was contained to this module and its witness.
The annotation on the entry point states explicitly that the neutral kernel has not been extracted, so this cut cannot later be cited as completing step 2.
Evidence
All 42 witnesses in the choice entry pass, changed only in module and symbol references. Every fixture value, decision ordering, rejection axis, unanswerable outcome, winner and tie result is identical — which is what distinguishes a rename from an edit.
🤖 Generated with Claude Code
https://claude.ai/code/session_01U397y4s3dSBof7vGPAX87G