Repository navigation
HOST-0: program-scoped host assimilation (unblocks srv5/srv6 enrollment) - #7876
Conversation
…rived First slice of the local-inference economics lane. Lands the receipt carrier that makes the hardware question measurable, in the observing product layer (DESIGN external-upstream-decomposition: extdeps.llm.* owns provider wire contracts, this owns what WE observed when we ran something). Mechanism: - TokenCount instantiates the std.measure Count axis (HardwareThreadCount / CharacterCount precedent), declared here not in std.measure because an LLM token is domain vocabulary and std/measure.dag is seed-emitted. - No throughput, rate, or cost field exists in the record. Tokens-per-second and accepted goodput are DERIVED as exact FieldOfFractions<Nat> over the same authority gunbc.econ.acquisition ConversionRate consumes; the floor projection is a declared lossy view, total by typed refusal. - Usage is three-valued: an attempt whose provider reported no usage is not an attempt that consumed nothing. Missing usage refuses the economic derivation without refusing the attempt or its disposition. - Goodput counts ACCEPTED dispositions only, so a host that doubles token rate while halving acceptance shows no gain. - Admitted sessions and active sequences are separate observations; a server sustaining four sequences can admit considerably more sessions. - SubstrateIdentity binds the compiler revision, because escalation rate is endogenous to both the model improving and gunbc needing less judgment. Evidence: 13 witnesses green by execution, incl. RED controls for zero and absent decode duration (no fabricated throughput), unobserved usage, empty roster, and zero observation window. Honest limits recorded in-carrier, both measured rather than assumed: - TokenCount is structurally identical to HardwareThreadCount, so it buys reading clarity, not a construction wall. - Requested/resolved model brands do NOT wall substitution. A scratch probe passing RequestedModelIdentity into a ResolvedModelIdentity parameter resolved and ran green. An earlier draft of the note claimed a typecheck refusal and cited a witness that was never written; both were false and are retracted in the carrier with the next-rung trigger named. No cost derivation lands here: the token-rate rows are not yet cited, and fabricating a rate to make the arithmetic run is what the follow-on prevents. This slice declares its frontier rather than claiming a production consumer. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…y, don't fork it review 48816 found the merge-blocking defect and was right. TokenCount was declared locally in gunbc.econ.llm_attempt_receipt as Measure<Count, One, Nat>, citing extdeps.pricing.billing_units as precedent for downstream placement. Verified against the tree, the citation does not cover it. The billing_units aliases introduce their own phantom markers (PerStoredUnitMonth et al), so MoneyRate<PerStoredUnitMonth> is a genuinely new point in the type space that cannot be written in std without importing vendor vocabulary. Measure<Count, One, Nat> takes only arguments std.measure already owns, and that module already names the shape three times: HardwareThreadCount, CharacterCount, AmortizationMonths. A local fourth name was therefore a DESIGN section 3 fork, not a downstream instantiation. The review offered a tracked deferral as an alternative. Not taken: the only argument for deferring was the seed-regeneration cost, which is the cost of doing this correctly rather than a reason to avoid it, and deferring for the author's convenience is the unmarked-workaround shape DESIGN section 5 names as a line-stop signal. - TokenCount, token_count, token_count_value now live in dag/std/measure.dag beside their three siblings, under token_count_note, which records the billing_units distinction so the reasoning is not rediscovered, and repeats the siblings' honest limit: all four are structurally identical, so the family buys reading clarity and one construction site each, never a wall. - llm_attempt_receipt consumes them and retracts the bad citation in llm_token_count_authority_note. - src/v1/stage0/src/std_measure.rs regenerated (seed-emitted module). Evidence: regen_stage0 wrote 132 generated files with exactly one changed; the regenerated seed compiles; regen_stage0 --verify reports regen_divergence_count=0 with a binary rebuilt FROM the new seed, so the self-host fixed point holds rather than being self-confirmed by a stale seed. All 13 witnesses re-run green against the std-homed carrier. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
llm_model_identity_brand_note cited llm_token_count_placement_note, which the tree no longer contains: the previous commit renamed that note to llm_token_count_authority_note while re-homing TokenCount, and the honest-limit claim the sentence points at moved to std.measure token_count_note. Verified as dangling — the citation was the only occurrence of the name anywhere in dag/. Now cites std.measure token_count_note, where the Count-axis family's mitigatable-rung limit actually lives. This is the DESIGN section 3 stale-citation class in a note whose own subject is a false citation, and it is the failure mode that rule predicts: a rename invalidated a name-level reference with nobody touching the referring line. A symbol citation is at least decidable by grep, which is how review 48829 caught it; the positional form would not have been reachable at all. Swept the rest of both files for the same defect rather than fixing only the reported instance: dispatch_execution_receipt_bar_note, token_count_note, llm_token_count_authority_note, llm_attempt_receipt_frontier_note, ConversionRate, FieldOfFractions, character_count_note, HardwareThreadCount, CharacterCount, AmortizationMonths, dispatch_usage_unobserved, DispatchUsageObserved, MoneyRate and PerStoredUnitMonth all resolve. Witnesses re-run green. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… spine cross-product Two DGX Spark inference appliances (srv5, srv6) are on order. Enrolling them against the current model would manufacture obligations they can never satisfy: host_standup_spine is ONE universal list -- BMC credential convergence, virtual-media OS install, Actions runner slots, build cache, green-place pinning -- and host_phase_status crossed every enrolled host with all of it. An appliance has no BMC and no runner user, so those cells could never be converged and could never honestly be marked so. A completeness number computed over invented obligations is worse than no number. The correction is program scoping, NOT an Applicable | NotApplicable verdict. A verdict arm would keep the false cells and label them -- the parallel representation shape (DESIGN section 3) -- and leave every consumer to remember to filter. Participation now SELECTS which obligations exist, so an obligation that does not apply is not a labelled cell, it is not a cell. - New gunbc.host_assimilation_program: FleetParticipation (CiRunner | InferenceServing), HostEnrollmentIntent, HostAssimilationProgram, assimilation_program_for. Participation is a LIST because the axes are independent, and it is a role rather than a hardware kind, so a future Altra dedicated to serving does not inherit BMC obligations from what it is made of. - Phase-to-participation classification is an EXHAUSTIVE match over both closed phase enums, so a newly added phase cannot silently default into or out of a program -- it does not compile until classified. Construction, not validation. - It lives in the new module rather than as a field on HostStandupStep: that would reshape fourteen rows in load-bearing host_standup.dag, and that module's own gap-ledger note already ruled its row-reshaping change stays separable. - The program is DERIVED by filtering the spine, never a second hand-authored step list that could drift. - host_phase_status is enrollment-driven; the global-spine path is DELETED, not retained beside the new one. fleet_subsumption_hosts is now a projection of fleet_subsumption_enrollments, so consumers that only care which hosts exist are untouched and the two lists cannot disagree. Evidence, green by execution (12 witnesses on the refactored module): - IDENTITY: a CI enrollment selects the whole spine, and the runner-fleet matrix is still hosts x spine. Every pre-existing regression witness passes unchanged -- no-producer-is-UnknownRefused, the absorbing-fallback RED control, the reconcile upsert/teardown/noop diff, observation coverage, remaining work. - SCOPING: an inference enrollment carries zero BMC/runner/build-cache/ green-place/session-placement cells and exactly the four shared obligations. - TOTALITY: no spine step is unclaimed by any participation. - Downstream consumers re-run green: host_swap_backing, host_network_diagnosis, host_toolchain_components. Prefix phases are CI-runner only, deliberately. A Spark has real arrival obligations, but they are its own and get authored where that arrival is modeled; inheriting a differently-shaped host's provisioning steps because they sound generic is the exact false-obligation defect this removes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… slices Autocommit committed the in-progress HOST-0 files onto this branch before I branched them off, so PR #7851 carried a load-bearing fleet-assimilation refactor under a description that only covered the LLM attempt receipt, and it reached 2/2 approvals in that state. A reviewer approving a described receipt change is not approving an undescribed host_phase_status refactor, so the content is restored to match the description rather than the description widened after the fact. HOST-0 lives in #7876 on its own branch, where it is described and witnessed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Stacking note — read the diff against #7851, not against main. This branch was cut from
The other four — Related correction, for the record: autocommit had also pushed these HOST-0 files onto #7851, so that PR was briefly carrying this refactor under a description that did not mention it, at 2/2 approvals. That has been reverted — #7851 is now strictly the receipt work, and HOST-0 lives only here. Since #7851 squash-merges, I'll merge main into this branch afterward and re-verify, rather than rebasing. — sent from bold-eagle-107 |
…rived (#7851) * WIP: blackwell * Typed LLM attempt receipt: counts and durations stored, every rate derived First slice of the local-inference economics lane. Lands the receipt carrier that makes the hardware question measurable, in the observing product layer (DESIGN external-upstream-decomposition: extdeps.llm.* owns provider wire contracts, this owns what WE observed when we ran something). Mechanism: - TokenCount instantiates the std.measure Count axis (HardwareThreadCount / CharacterCount precedent), declared here not in std.measure because an LLM token is domain vocabulary and std/measure.dag is seed-emitted. - No throughput, rate, or cost field exists in the record. Tokens-per-second and accepted goodput are DERIVED as exact FieldOfFractions<Nat> over the same authority gunbc.econ.acquisition ConversionRate consumes; the floor projection is a declared lossy view, total by typed refusal. - Usage is three-valued: an attempt whose provider reported no usage is not an attempt that consumed nothing. Missing usage refuses the economic derivation without refusing the attempt or its disposition. - Goodput counts ACCEPTED dispositions only, so a host that doubles token rate while halving acceptance shows no gain. - Admitted sessions and active sequences are separate observations; a server sustaining four sequences can admit considerably more sessions. - SubstrateIdentity binds the compiler revision, because escalation rate is endogenous to both the model improving and gunbc needing less judgment. Evidence: 13 witnesses green by execution, incl. RED controls for zero and absent decode duration (no fabricated throughput), unobserved usage, empty roster, and zero observation window. Honest limits recorded in-carrier, both measured rather than assumed: - TokenCount is structurally identical to HardwareThreadCount, so it buys reading clarity, not a construction wall. - Requested/resolved model brands do NOT wall substitution. A scratch probe passing RequestedModelIdentity into a ResolvedModelIdentity parameter resolved and ran green. An earlier draft of the note claimed a typecheck refusal and cited a witness that was never written; both were false and are retracted in the carrier with the next-rung trigger named. No cost derivation lands here: the token-rate rows are not yet cited, and fabricating a rate to make the arithmetic run is what the follow-on prevents. This slice declares its frontier rather than claiming a production consumer. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * WIP: local inference * Re-home TokenCount onto std.measure (review 48816): consume the family, don't fork it review 48816 found the merge-blocking defect and was right. TokenCount was declared locally in gunbc.econ.llm_attempt_receipt as Measure<Count, One, Nat>, citing extdeps.pricing.billing_units as precedent for downstream placement. Verified against the tree, the citation does not cover it. The billing_units aliases introduce their own phantom markers (PerStoredUnitMonth et al), so MoneyRate<PerStoredUnitMonth> is a genuinely new point in the type space that cannot be written in std without importing vendor vocabulary. Measure<Count, One, Nat> takes only arguments std.measure already owns, and that module already names the shape three times: HardwareThreadCount, CharacterCount, AmortizationMonths. A local fourth name was therefore a DESIGN section 3 fork, not a downstream instantiation. The review offered a tracked deferral as an alternative. Not taken: the only argument for deferring was the seed-regeneration cost, which is the cost of doing this correctly rather than a reason to avoid it, and deferring for the author's convenience is the unmarked-workaround shape DESIGN section 5 names as a line-stop signal. - TokenCount, token_count, token_count_value now live in dag/std/measure.dag beside their three siblings, under token_count_note, which records the billing_units distinction so the reasoning is not rediscovered, and repeats the siblings' honest limit: all four are structurally identical, so the family buys reading clarity and one construction site each, never a wall. - llm_attempt_receipt consumes them and retracts the bad citation in llm_token_count_authority_note. - src/v1/stage0/src/std_measure.rs regenerated (seed-emitted module). Evidence: regen_stage0 wrote 132 generated files with exactly one changed; the regenerated seed compiles; regen_stage0 --verify reports regen_divergence_count=0 with a binary rebuilt FROM the new seed, so the self-host fixed point holds rather than being self-confirmed by a stale seed. All 13 witnesses re-run green against the std-homed carrier. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Fix stale symbol citation left by the previous rename (review 48829) llm_model_identity_brand_note cited llm_token_count_placement_note, which the tree no longer contains: the previous commit renamed that note to llm_token_count_authority_note while re-homing TokenCount, and the honest-limit claim the sentence points at moved to std.measure token_count_note. Verified as dangling — the citation was the only occurrence of the name anywhere in dag/. Now cites std.measure token_count_note, where the Count-axis family's mitigatable-rung limit actually lives. This is the DESIGN section 3 stale-citation class in a note whose own subject is a false citation, and it is the failure mode that rule predicts: a rename invalidated a name-level reference with nobody touching the referring line. A symbol citation is at least decidable by grep, which is how review 48829 caught it; the positional form would not have been reachable at all. Swept the rest of both files for the same defect rather than fixing only the reported instance: dispatch_execution_receipt_bar_note, token_count_note, llm_token_count_authority_note, llm_attempt_receipt_frontier_note, ConversionRate, FieldOfFractions, character_count_note, HardwareThreadCount, CharacterCount, AmortizationMonths, dispatch_usage_unobserved, DispatchUsageObserved, MoneyRate and PerStoredUnitMonth all resolve. Witnesses re-run green. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * WIP: local inference * Remove HOST-0 from the receipt branch: autocommit mixed two separable slices Autocommit committed the in-progress HOST-0 files onto this branch before I branched them off, so PR #7851 carried a load-bearing fleet-assimilation refactor under a description that only covered the LLM attempt receipt, and it reached 2/2 approvals in that state. A reviewer approving a described receipt change is not approving an undescribed host_phase_status refactor, so the content is restored to match the description rather than the description widened after the fact. HOST-0 lives in #7876 on its own branch, where it is described and witnessed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
… HOST-0 files)
|
Merged main — this PR's diff is now exactly its change. #7851 squash-merged, so the receipt files it carried are on main. As stated in the earlier stacking note, I merged main rather than rebasing (per the repo's merge policy: avoids force-pushes, identical end state). The diff is now three files, which is what the description covers:
Re-verified by execution after the merge, since main moved substantially underneath this branch — a green result from before the merge is not evidence about the merged tree: Both conjuncts hold: the CI enrollment still selects the whole spine and the runner-fleet matrix is unchanged (identity), and an inference enrollment carries no BMC/runner/build-cache/green-place/session-placement obligations (scoping). The merge moved the head, so the prior approvals and CI now point at a superseded commit and will need to re-run against this one. — sent from bold-eagle-107 |
|
CI failure on run 31052132609 diagnosed; it is not this diff, and the rerun is not a silent retry. Failure: Why it is not this diff: that witness enumerates Why it is load, not content: on the last green main run (31047301932) the same witness measured 3819.9ms — 76% of budget — over the same corpus. It is an at-the-edge live-tree scan that tips or clears depending on runner thread-CPU pressure. Separable defect worth an owner (NOT fixed here, to keep this PR's scope): every sibling — sent from bold-eagle-107 |
…that was redding this PR's ci)
|
Correction to my previous comment, and the actual fix. I attributed the failure to runner thread-CPU pressure and reran on that basis. The rerun refuted it: the same witness failed again at 6179ms, worse than the first 5687ms. It was reproducibly over budget, not load-dependent. The 3819.9ms green-main measurement I cited was real but did not support the conclusion I drew from it. What was actually true: the cost was real and had already been fixed on main. Fix applied here: merged main ( The observation about shared-cost attribution in my previous comment still stands on its own (the enumeration memoizes, so the whole scan is billed to whichever witness runs first), but it is now a remark about a fixed case rather than a live defect, and it needs no owner from me. — sent from bold-eagle-107 |
d6131e3 to
17a02b0
Compare
|
Force-pushed this branch to repair contamination I caused. Disclosing it rather than letting it look like a normal update. While answering an unrelated question I ran Repair: reset to the last good head This is the second scope-contamination event on this PR today and both had the same root: this worktree autocommits whatever is dirty, so any inspection command that writes to the working tree lands in the PR. Inspection of other branches belongs in a scratch clone, not here. — sent from bold-eagle-107 |
… not list-shaped HostEnrollmentIntent.participation has set semantics -- step selection asks only whether SOME participation claims a step, so order and duplicates were already invisible to which obligations exist. Identity did not agree: it joined the raw list, so [Ci, Inference], [Inference, Ci] and [Ci, Ci, Inference] selected identical steps while deriving three different identities -- a second representation of one program (DESIGN section 3). Identity now projects through a fixed canonical roster filtered by membership, so a duplicate or a reordering cannot reach it by construction; there is no canonicalization step for a caller to forget. Roster completeness is the residue construction cannot remove, so it is walled by an exhaustive match (fleet_participation_in_canonical_roster): a new participation does not compile until stated, and its witness reds if stated but omitted from the roster. Green by execution, 10 witnesses. The discriminating control pins identity to independently authored literals -- the duplicated enrollment must derive "ci-runner+inference-serving" and must NOT derive "ci-runner+ci-runner+inference-serving", which is exactly what the replaced derivation produced -- so the repair is falsifiable rather than satisfied by any constant-returning function. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Operator raised two structural defects in this PR. Approvals on this PR predate the repair — it needs re-review on head Defect 2, participation set-semantics vs list identity — fixed here. Confirmed exactly as reported: step selection was already order- and duplicate-blind ( The fix projects identity through a fixed Controls, all green by execution (10 witnesses):
The first four would all pass against a function returning a constant, so they are not sufficient on their own. The discriminating control pins identity to independently authored literals: the duplicated enrollment must derive Defect 1, terminal gate still carrying runner semantics — real, and discharged in #7877, not here. That PR converts — sent from bold-eagle-107 |
…anonical-participation repair) # Conflicts: # dag/gunbc/host_assimilation_program.dag # dag/test/claim/host_phase_status_witness_test.dag
…ge main - 'No code edits' contradicted the deliberate doc_graph_roots registration; now 'no review-system implementation edits'. - GROUNDING-POP-0 acceptance now requires that source order cannot change the population's canonical IDENTITY or emitted ordering, not merely its membership. Otherwise one mathematical candidate set stays representable by several order-sensitive lists -- the HOST-0 list-identity defect in its general form, which #7876 just closed for participation. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…, no code edits (#7912) * Review-surface subject map (declaration grain, planning worksheet) Establishes which review declarations are evidence producers, external-artifact ingestion, native typed criteria, composition, recommendation, workflow admission, or presentation -- and which have a real producer/consumer rather than a claimed one. Every cell established by search against the current tree. Three findings: - v2.lens.registry.completeness exempts grounding_ledger from enrollment by citing consumption by v2.lens.grounding that does not exist; the module it protects has no consumer at all. - Producer/consumer gaps run both directions: grounding_ledger has a producer and no consumer; MergeReadinessTally has a real consumer in code_change_workflow and no producer outside fixtures; ReviewVerdictReport has neither. - std.claim_evidence has 8 production consumers, not 1 -- stronger as substrate than assumed. No code edits follow until the rows are agreed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Revise review-surface map: liveness grain, six new/corrected rows Adds a four-level liveness vocabulary (DeclaredOnly | FixtureExercised | SemanticEdge | LiveObserved) -- 'real producer/consumer' caused every inaccurate row in the first revision by conflating 'could run', 'another domain function calls it', and 'observed executing'. Corrections, each verified against the tree: - MergeReadinessTally: NOT a live gate. decide_code_change_transition has no in-tree caller, so it is a dormant admission kernel missing producer AND driver. - approval_count is never read: authored 2 in five fixtures, and the kernel checks only head_sha, request_changes_count, blocking_finding_count, mergeable_clean. A zero-approval tally would permit ChangeMergeReady. No RED plants this. - grounding downgraded to FixtureExercised with no findings consumer; records the first_coincident_target first-wins pick and string-not-DeclarationRef identity as the blocker on exclusive-candidate review. - ReviewArtifact/ReviewVerdictReport: DeclaredOnly. GitHub objects are upstream sources, not in-tree constructors -- previous revision conflated the two. - claim_evidence census: 7 non-test importing modules, not 8 production (the eighth path was the module itself). - LlmAttemptReceipt consumers are inside its own module only. - provider types decomposed: four DIFFERENT meanings, not four names for one. New rows: pr_digests.MergeReadinessVerdict, the merge_admission family (the existing LiveObserved CI/check-freshness authority, omitted entirely before), digest_render, PullReview reviewer-identity fidelity gap (no user field). Adds a dissolve-on and reorders the sequence: grounding population repair is the next code PR, not the tally producer. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Register the review-surface map as a plan-doc root with a dissolution trigger CI caught the map as an orphan doc (doc_graph_has_no_orphan_docs). The gate is correct: its own module note records that a false SubstrateInputsOnly stamp once let a docs-only PR mint an orphan with green CI, which is exactly what this would have been. Registered via HandAuthoredDocBind rather than linked from an unrelated doc, because the map already is what that carrier models: a worksheet with a declared end state. The four bound works are its load-bearing subjects, each verified to resolve: the completeness roster note carrying the false exemption, the inert LedgerEntry it protects, first_coincident_target's first-wins pick, and MergeReadinessTally with its unread approval_count. Green by execution: doc_graph_has_no_orphan_docs, doc_graph_registered_plan_roots_all_admitted, hand_authored_works_refs_all_carry_symbols. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Map corrections: six rows, per operator review - ReviewVerdict: SemanticEdge with fixture-only execution, not DeclaredOnly -- demo_spine_green/unknown construct Approve/ApproveWithComments/RequestChanges and review_to_reduce consumes them; the ABSENT thing is the parser realization. - digest_render: DeclaredOnly, no consumer. format_model_reconciliation only names it in prose inside an li(text: ...) backlog item -- verified it does not import, call project_pull_request_digest or either renderer, or consume PullRequestDigestView. Counting a prose mention as a consumer edge is the same stale-citation class this worksheet exists to detect. - Grounding proposition space marked NOT established (new finding 3a): the six ledger arms mix reference targets with leaf-retention reasons on different axes with no disjointness construction. GROUNDING-DECIDE-0 defines the space; GROUNDING-POP-0 must not carry the coproduct forward. - MergeReadinessTally count carriers: all three are Int, so a negative value behaves like zero and permits the transition. Derive counts from retained populations; negative-count RED beside the zero-approval RED. - merge_admission family names corrected: four modules under gunbc, four under tools -- the {,_capture,...} shorthand wrongly placed three under gunbc.merge_admission. LiveObserved now names the executed capture receipt. - Liveness vocabulary: recorded that FixtureExercised and SemanticEdge are cumulative, not exclusive; cells record the highest level plus an execution qualifier. Sequence names the slices: GROUNDING-POP-0 (population only, with its exclusions), GROUNDING-DECIDE-0, REVIEW-SHADOW-0, SPARK-JUDGE-0, REVIEW-COMPOSE-0, REVIEW-ADMIT-0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Map: wording contradiction, canonical-identity acceptance clause, merge main - 'No code edits' contradicted the deliberate doc_graph_roots registration; now 'no review-system implementation edits'. - GROUNDING-POP-0 acceptance now requires that source order cannot change the population's canonical IDENTITY or emitted ordering, not merely its membership. Otherwise one mathematical candidate set stays representable by several order-sensitive lists -- the HOST-0 list-identity defect in its general form, which #7876 just closed for participation. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Doc-bind refs: cite functions rather than types, matching every existing bind Neither form resolves today -- doc_graph_works_refs_all_resolve is red on main independent of this branch (proven by removing this row entirely and re-running from the long-lane entry that actually imports it). Function refs are kept because every other HandAuthoredDocBind in the file cites a fn or data, not because the swap was measured to fix anything. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Foundational correction ahead of two DGX Spark inference appliances (srv5, srv6) arriving. It lands before any physical fact is authored, so the arrival is honest rather than retrofitted.
The problem
host_standup_spineis ONE universal list — BMC credential convergence, virtual-media OS install, Actions runner slots, build cache, green-place pinning, session placement — andhost_phase_statuscrossed every enrolled host with all of it. That was correct while every enrolled host was the same kind of thing: srv1–srv4 are Ampere Altra CI runner hosts.It stops being correct the moment a host of a different kind is enrolled. A Spark appliance has no BMC to converge, no virtual media, no runner user, no Actions slots, no build cache. Crossing it with the universal spine manufactures obligations that can never be satisfied and can never honestly be marked converged — and a fleet-completeness number computed over invented obligations is worse than no number.
Why program scoping and not an applicability verdict
An
Applicable | NotApplicablearm on the cell would keep the false cells and label them. That is the parallel-representation shape (DESIGN §3), and it leaves every downstream consumer to remember to filter. Participation instead selects which obligations exist at all: an obligation that does not apply is not a cell with a label, it is not a cell.What changed
gunbc.host_assimilation_program—FleetParticipation(CiRunnerParticipation | InferenceServingParticipation),HostEnrollmentIntent,HostAssimilationProgram,assimilation_program_for.HostStandupStep: that would reshape fourteen rows in load-bearinghost_standup.dag, and that module's own gap-ledger note already ruled its row-reshaping change stays separable from its status-axis change.host_phase_statusis enrollment-driven. The global-spine path is deleted, not retained — a kept cross-product is an inert second answer some consumer eventually reads.fleet_subsumption_hostsis now a projection offleet_subsumption_enrollments, so consumers that only care which hosts exist are untouched and the two cannot disagree.Evidence — green by execution, 12 witnesses
Identity (the refactor did not change the runner fleet): a CI enrollment selects the whole spine; the runner-fleet matrix is still hosts × spine; and every pre-existing regression witness passes unchanged — no-producer-derives-UnknownRefused, the absorbing-fallback RED control, the reconcile upsert/teardown/noop diff, observation coverage, remaining-work count.
Scoping (the refactor did what it is for): an inference enrollment carries zero BMC / runner-slot / build-cache / green-place / session-placement cells, and exactly the four shared obligations (identity converge, reach secrets, compute-fabric enroll, assimilation complete).
Totality: no spine step is unclaimed by any participation.
Downstream:
host_swap_backing,host_network_diagnosis,host_toolchain_componentsall re-run green.Both halves are needed — the identity conjunct alone would pass a no-op, the scoping conjunct alone would pass a refactor that broke srv1–srv4.
Deliberate scope
Prefix phases are CI-runner only. A Spark has real arrival obligations — physical binding, network convergence, baseline observation — but they are its own, authored where that arrival is modeled. Inheriting a differently-shaped host's provisioning steps because they sound generic is the exact false-obligation defect this removes.
No Spark host is enrolled here, and no physical fact is asserted. This only makes honest enrollment possible.