Skip to content

HOST-0: program-scoped host assimilation (unblocks srv5/srv6 enrollment) - #7876

Merged
briansrls merged 13 commits into
mainfrom
session/host-0-program-scoped-assimilation
Aug 6, 2026
Merged

briansrls merged 13 commits into
mainfrom
session/host-0-program-scoped-assimilation

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

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_spine is ONE universal list — BMC credential convergence, virtual-media OS install, Actions runner slots, build cache, green-place pinning, session placement — and host_phase_status crossed 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 | NotApplicable arm 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

  • New gunbc.host_assimilation_program — FleetParticipation (CiRunnerParticipation | InferenceServingParticipation), HostEnrollmentIntent, HostAssimilationProgram, assimilation_program_for.
  • Participation is a list, because the axes are independent — nothing forbids a host that both runs CI and serves inference, and a coproduct would force a fused third variant the first time that happened.
  • It is a role, not a hardware kind. Binding obligations to hardware would mean a future Altra dedicated to serving inherits BMC obligations from what it is made of rather than what it is for. srv5/srv6 stay opaque identities for the same reason.
  • Phase-to-participation classification is an exhaustive match over both closed phase enums. A newly added phase cannot silently default into or out of a program — it does not compile until classified. Construction, not validation.
  • Classification 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 from its status-axis change.
  • 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 — a kept cross-product is an inert second answer some consumer eventually reads.
  • fleet_subsumption_hosts is now a projection of fleet_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_components all 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.

gunbc-ci-auto-heal and others added 8 commits August 5, 2026 14:52
…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>
gunbai-bot Bot pushed a commit that referenced this pull request Aug 5, 2026
… 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>
@gunbai-bot

gunbai-bot Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

Stacking note — read the diff against #7851, not against main.

This branch was cut from session/bold-eagle-107 while that branch still carried the LLM attempt receipt work, so git diff origin/main...HEAD here shows seven files. Only three are HOST-0:

  • dag/gunbc/host_assimilation_program.dag (new)
  • dag/gunbc/host_phase_status.dag (refactored)
  • dag/test/claim/host_phase_status_witness_test.dag (updated + 6 new witnesses)

The other four — gunbc.econ.llm_attempt_receipt, the TokenCount addition to std.measure, its witness, and the regenerated std_measure.rs — belong to #7851 and will disappear from this diff once that merges.

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

briansrls pushed a commit that referenced this pull request Aug 5, 2026
…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>
@gunbai-bot

gunbai-bot Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

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:

  • dag/gunbc/host_assimilation_program.dag (new, 135 lines)
  • dag/gunbc/host_phase_status.dag (refactored)
  • dag/test/claim/host_phase_status_witness_test.dag

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:

PASS witness_ci_program_selects_the_whole_spine
PASS witness_inference_enrollment_carries_no_runner_or_bmc_obligation
PASS witness_inference_enrollment_keeps_the_shared_obligations
PASS witness_every_spine_step_is_claimed_by_some_participation
PASS witness_program_scoping_preserves_the_runner_fleet_matrix
PASS witness_matrix_is_hosts_times_spine
PASS witness_no_producer_derives_unknown_not_converged
PASS witness_red_control_widen_on_absent_rejected_by_gate

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

@gunbai-bot

gunbai-bot Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

CI failure on run 31052132609 diagnosed; it is not this diff, and the rerun is not a silent retry.

Failure: witness_parse_only_extract_nonempty_in_scoped_pool (src/v2/test/claim/concept_index_enumeration_test.dag) at 5687ms thread-CPU against the 5000ms fast-lane budget — FloorFailed{class:Structural{reason:BudgetExceeded}}.

Why it is not this diff: that witness enumerates concept_index_enumeration_pool_roots = ["src/v2/test/claim"]. This PR's three files are all under dag/gunbc/host_*. The scanned corpus is byte-identical with and without this change.

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 parse_only_* witness in that file costs 0.1–0.5ms because parse_only_idx() memoizes after its first call. So the whole corpus scan is billed to whichever witness happens to run first, while that witness's own claim is length() > 0 plus one qualified-name lookup — cheap by construction. The budget is charged against the wrong subject, and the charge grows with unrelated merges into src/v2/test/claim. The sibling witness_coproduct_arms_parse_only already hit this at 6065ms (PR #7756) and was rehomed to the long lane with a cadence row; per the operator ruling that relocation does not discharge the cost, and the runner's own message says so. The real fix is to price the shared enumeration explicitly rather than to move a file, and it belongs in its own change.

— sent from bold-eagle-107

@gunbai-bot

gunbai-bot Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

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. concept_index_enumeration_test.dag has been moved to its own fixture subdirectory, src/v2/test/claim/concept_index_enumeration/, with concept_index_enumeration_pool_roots narrowed from the whole src/v2/test/claim tree to that directory — the same convention interface_summary/ already uses. This PR was based on a main that predated the move, so it kept scanning the broad pool.

Fix applied here: merged main (556fa2e78df). No change to this PR's own content — the diff against main is still exactly the three HOST-0 files.

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

@gunbai-bot
gunbai-bot Bot force-pushed the session/host-0-program-scoped-assimilation branch from d6131e3 to 17a02b0 Compare August 6, 2026 01:03
@gunbai-bot

gunbai-bot Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

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 git checkout origin/main -- . in this worktree to inspect main's content. That staged newer main's tree on top of this branch; the session autocommit then committed and pushed it as d6131e314b4 "WIP: local inference" — 35 files of other people's work rendered as this PR's diff, on top of two approvals.

Repair: reset to the last good head 556fa2e78df, merged origin/main properly, force-pushed as 17a02b00b3e. The PR's file list is again exactly the three HOST-0 files, and the content is identical to what was approved at c5603611d7b plus a clean main merge. Nothing of this PR's own work was lost, and no reviewer feedback was dropped.

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>
@gunbai-bot

gunbai-bot Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

Operator raised two structural defects in this PR. Approvals on this PR predate the repair — it needs re-review on head 713634e97a5.

Defect 2, participation set-semantics vs list identity — fixed here. Confirmed exactly as reported: step selection was already order- and duplicate-blind (step_serves_any asks only whether SOME participation claims a step), but host_enrollment_program_identity joined the raw list, so [Ci, Inference], [Inference, Ci] and [Ci, Ci, Inference] selected identical steps while deriving three different identities.

The fix projects identity through a fixed fleet_participation_canonical_roster filtered by membership, rather than adopting Set<FleetParticipation>. Reason: std.types defines Set as PointwisePower, but only empty_set/set_insert/set_contains exist as primitives — there is no set_to_list, and keying coproduct values relies on native canonical keying. The roster projection gets the same guarantee with no new primitives and no canonicalization call a caller can forget. Roster completeness is the part 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 reds if stated but left out of the roster.

Controls, all green by execution (10 witnesses):

  • witness_participation_order_does_not_change_program_identity
  • witness_duplicate_participation_is_identity_neutral
  • witness_distinct_participation_changes_identity_and_obligations
  • witness_every_participation_is_in_the_canonical_roster
  • witness_program_identity_is_exactly_the_canonical_projection — the discriminating one
  • witness_single_participation_identities_are_distinct_labels
  • plus the pre-existing ci_program_selects_the_whole_spine, inference_program_is_strictly_smaller, inference_enrollment_carries_no_runner_or_bmc_obligation, program_scoping_preserves_the_runner_fleet_matrix regressions.

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 ci-runner+inference-serving and must NOT derive ci-runner+ci-runner+inference-serving — precisely what the replaced derivation produced. It fails against the code this change removes, and stays enrolled rather than being a one-off probe.

Defect 1, terminal gate still carrying runner semantics — real, and discharged in #7877, not here. That PR converts AssimilationCompleteGate from the fixed four-field product to obligations: List<AssimilationObligation> and derives them per participation, so an inference enrollment receives neither RunnerSlotHealthy nor GreenPlacePinCoherent. #7877 is stacked on this PR and already at two approvals; re-implementing the same repair here would collide with it. Separately flagged there, and since fixed by its owner: assimilation_completion_inputs_for was a priority chain rather than a union over participations — correct only while CI's input set stayed a superset — now folded with dedup by input identity, with an inference-first control that reds if a priority chain returns.

— sent from bold-eagle-107

…anonical-participation repair)

# Conflicts:
#	dag/gunbc/host_assimilation_program.dag
#	dag/test/claim/host_phase_status_witness_test.dag
@briansrls
briansrls merged commit e5fafd4 into main Aug 6, 2026
5 checks passed
@briansrls
briansrls deleted the session/host-0-program-scoped-assimilation branch August 6, 2026 05:08
briansrls pushed a commit that referenced this pull request Aug 6, 2026
…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>
briansrls pushed a commit that referenced this pull request Aug 6, 2026
…, 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>
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.

1 participant