Skip to content

Ground the MAC address: extdeps.network.mac fires a declared dissolution trigger - #9607

Merged
briansrls merged 4 commits into
mainfrom
session/royal-tern-443-mac
Aug 28, 2026
Merged

briansrls merged 4 commits into
mainfrom
session/royal-tern-443-mac

Conversation

@gunbai-bot

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

Copy link
Copy Markdown
Contributor

extdeps.dhcp.v4.MacAddress is NonEmptyStr where brand("MacAddress") — an anemic brand whose declared dissolution trigger names this module and this parse function by symbol. The trigger was authored; the module never was. This builds it.

It follows extdeps.network.ipv4 exactly rather than inventing a second shape: the octet is the grounded unit, two entry points split model from realization (mac_address for authored literals, parse_mac_address for wire text such as ip link output), and malformed input refuses with a typed located error rather than fabricating an address.

The first octet is not opaque

Decomposing it is why this is worth more than a validated string. IEEE 802 puts two flag bits there — I/G (individual vs group) and U/L (universally vs locally administered) — and both are derived from the octets rather than stored beside them, so they cannot disagree with the address they describe. mac_oui projects the first three octets the same way.

Why that matters to a consumer. Keying a host interface on its address is only stable if the address is the permanent one, and a locally administered address is precisely one that software chose and software can change. A branded string cannot express that difference, so a consumer keying on it cannot tell a burned-in identity from a temporary one — which is the whole reason the DHCP carrier's brand was marked anemic. mac_is_permanent_interface_identity states that predicate once instead of leaving every call site to re-derive two bit tests.

Spelling refuses rather than normalises

Hyphen-separated, dotted-quad and uppercase forms are all common in vendor output, and all three refuse with named causes. Accepting them would make the round trip untrue and erase which spelling a source actually produced — the same reason the digest carriers refuse rather than lowercasing.

Evidence

16/16 green by execution.

The U/L sense is inverted relative to how the name reads (bit set = locally administered), so each flag is pinned in both directions against a concrete address, using srv3's real burned-in address as the universally-administered specimen rather than an invented one. A both-bits-set control separates the two flags — a predicate that read one bit and reported both would pass every single-flag test. Width and hexness are separate refusal causes, because a single-digit group is well-formed hex at the wrong width and collapsing them would report "not hex" for text that is entirely hex.

Round trip is asserted on the value, not against a golden string: a literal comparison shows only that text came back, not that the octets were recovered.

🤖 Generated with Claude Code

…ion trigger

extdeps.dhcp.v4.MacAddress is NonEmptyStr where brand(MacAddress) -- an anemic
brand whose declared dissolution trigger names this module and this parse
function by symbol. The trigger was authored; the module was not. This builds it.

It follows extdeps.network.ipv4 exactly rather than inventing a second shape:
the octet is the grounded unit, two entry points split model from realization
(mac_address for authored literals, parse_mac_address for wire text such as
the output of `ip link`), and malformed input refuses with a typed located error rather
than fabricating an address.

THE FIRST OCTET IS NOT OPAQUE, and decomposing it is why this is worth more than
a validated string. IEEE 802 puts two flag bits there: I/G (individual vs group)
and U/L (universally vs locally administered). Both are DERIVED from the octets,
never stored beside them, so they cannot disagree with the address they describe.

That matters to a consumer rather than being trivia. Keying a host interface on
its address is only stable if the address is the permanent one, and a locally
administered address is precisely one that software chose and software can
change. A branded string cannot express that difference -- so a consumer keying
on it cannot tell a burned-in identity from a temporary one, which is the whole
reason the DHCP carrier's brand was marked anemic. mac_is_permanent_interface_identity
states that predicate once instead of leaving every call site to re-derive it.

SPELLING REFUSES RATHER THAN NORMALISES: hyphen, dotted-quad and uppercase forms
are common in vendor output and all three refuse with named causes. Accepting
them would make the round trip untrue and erase which spelling a source produced.

16/16 green. The U/L sense is inverted relative to how the name reads, so each
flag is pinned in BOTH directions against a concrete address -- srv3's real
burned-in address as the universal specimen -- and a both-bits-set control
separates the two flags, which a predicate reading one bit and reporting both
would otherwise pass. Width and hexness are separate refusal causes, since a
single-digit group is well-formed hex at the wrong width.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@gunbai-bot
gunbai-bot Bot force-pushed the session/royal-tern-443-mac branch from 00915e0 to a9f5d6a Compare August 28, 2026 14:51
@gunbai-bot

gunbai-bot Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor Author

Taken as filed and pushed. Both data … : String rows are now leading // annotations on module-scope declarations. Review 57284 is right: §4c names that convention as debt in as many words, and the module was already using the sanctioned channel ten lines away — landing new instances of a deprecated convention beside its replacement is exactly the parallel-representation debt the section exists to stop.

A second defect surfaced while fixing the first, and it is worse than the one reported. The module note claimed the octet "reuses that module's Octet bound". It did not — it declared MacOctet, a fresh Int where range(min: 0, max: 255). Measured across the corpus, extdeps.network.ipv4.Octet was the only such refinement, so this would have been the second name for one concept: precisely the re-invention §2 tests for ("net concepts must not grow by re-invention"), landed under prose asserting the opposite. The false sentence is what made it invisible — a reader checking the claim would have read "reuses" and moved on.

The byte now grounds on std.integer.UInt8, the universal authority for an 8-bit unsigned integer, which already existed. Importing ipv4's Octet was the other option and is worse: a MAC octet is not an IPv4 octet, and that dependency would ground a link-layer fact on a network-layer module for no reason except that the bound happened to be written there first.

That leaves ipv4's own Octet as a pre-existing duplicate of UInt8 — not touched here, because retyping a public type in a module this change does not otherwise modify is a separate decision with its own consumers. Flagging it rather than silently widening scope.

16/16 still green by execution after both changes.

On the non-blocking second point — the six-deep nested match in parse_mac_address: not changed, and I want to be explicit that this is a judgement rather than a dismissal. The ladder is copied deliberately from extdeps.network.ipv4.parse_ipv4_address, which the module note says it follows exactly; diverging here would leave two shapes for one parse idiom across two sibling modules, which trades a local nesting cost for a cross-module inconsistency. If the ladder should go, it should go in both, and that is a change to ipv4's shape that belongs in its own PR rather than as a silent divergence in the newer file.

— sent from royal-tern-443

…et on UInt8 instead of minting a second bound

Review 57284 is right about the prose rows and I have taken it as filed. Section
4c names hoisted data...String commentary as debt in as many words -- an ordinary
String declaration whose sole purpose is commentary is misplaced or dead data,
undecidable by any lens -- and this module was already using the sanctioned //
channel ten lines away. Landing new instances of a deprecated convention beside
its replacement is the parallel-representation debt the section exists to stop.
Both rows are now leading annotations on module-scope declarations.

AND A SECOND DEFECT THE REVIEW DID NOT CATCH, found while fixing the first: the
module note claimed the octet REUSED extdeps.network.ipv4's Octet bound, and it
did not -- it declared MacOctet, a fresh Int bounded 0..255.
Measured across the corpus, ipv4's Octet was the ONLY such refinement, so this
would have been the SECOND name for one concept: exactly the re-invention section
2 tests for, landed under prose asserting the opposite.

The byte now grounds on std.integer.UInt8, the universal authority for an 8-bit
unsigned integer, which already existed. Importing ipv4's Octet was the other
option and is worse: a MAC octet is not an IPv4 octet, and the dependency would
ground a link-layer fact on a network-layer module for no reason but that the
bound was written there first. That leaves ipv4's own Octet as a pre-existing
duplicate of UInt8, untouched here -- retyping a public type in a module this
change does not otherwise modify is a separate decision with its own consumers.

16/16 still green by execution after both changes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@gunbai-bot
gunbai-bot Bot force-pushed the session/royal-tern-443-mac branch from 028ad33 to f909bfe Compare August 28, 2026 15:29
@gunbai-bot

gunbai-bot Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor Author

The first non-blocking note turned out to be load-bearing, and chasing it found a defect this PR was about to introduce. Pushed a fix.

The review said the new module "declares this as fast-follow" at mac.dag:22. It declares no such thing — nothing in that file mentions the consumers, the brand's survival, or a follow-up at all. That line is the opening sentence of the module annotation. So the approval rested in part on a statement no file makes. I only noticed because I went to read the declaration rather than accept the characterisation.

What was actually there is worse. The MacAddress frontier row in extdeps/dhcp/v4.dag carried bound_dissolution(parse_mac_address) — a DeclarationAppears condition. The row dissolves the moment that function exists, which is exactly what this PR makes true. But the row's own reason states the capability: MacAddress is a branded NonEmptyStr hiding six grounded octets; deep-decompose it. Landing a parser satisfies neither half — the brand is still NonEmptyStr where brand("MacAddress") and its eight consumer sites still write as MacAddress.

So merging this PR unamended would have retired the row with the capability entirely undone — strictly worse than leaving it open, because an unmet row still ranks for work and a met one does not. DESIGN §4b(3) names this shape precisely: a trigger must state the capability, and one naming an artifact instead is the single direction the machinery structurally cannot see, because it is satisfied honestly while the thing it protected stays dead. Nobody has to be careless for it to happen — which is why it needed the rule rather than diligence, and why the review reasonably read past it.

The trigger is now retires_dissolution on MacAddress itself: the row ends when the brand is gone, in the same words its reason uses.

No consumer is re-homed here, and that is deliberate: eight sites across four modules is a separate change with its own review surface. The difference is that it is now the work the row actually tracks, rather than work the row has stopped asking for.

16/16 mac and 3/3 cr1000a witnesses green by execution.

On the other micro-nit — the Absent arm in parse_mac_octet_at being unreachable through the current caller: kept deliberately. get returns an Optional, so the arm is required for totality rather than being a guard someone chose to add; deleting it is not available, and the function is not private to that one caller in principle. This is the reachable-mechanism/zero-occupancy case rather than a decoration whose red cannot be produced.

— sent from royal-tern-443

…ld have retired the row with the work undone

Found from a non-blocking note on the approving review, arriving from the
opposite direction: the review said the new module DECLARES the brand dissolution
as fast-follow. It declares no such thing -- nothing in that file mentions the
consumers at all. Chasing what the file actually said turned up the real defect.

extdeps.dhcp.v4's MacAddress frontier row carried
bound_dissolution(parse_mac_address), which is a DeclarationAppears condition. So
the row dissolves the moment that function EXISTS -- which is precisely what the
parser PR makes true. The row's own reason states the capability: MacAddress is a
branded NonEmptyStr hiding six grounded octets, deep-decompose it. Landing a
parser satisfies neither half. The brand is still NonEmptyStr where
brand(MacAddress) and its eight consumer sites still cast strings to it.

So the parser PR would have retired the row with the capability entirely undone,
and that is strictly WORSE than leaving it open: an unmet row still ranks for
work and a met one does not. Section 4b(3) names this exact shape -- a trigger
must state the CAPABILITY, and a trigger naming an artifact is the one direction
the machinery structurally cannot see, because it is satisfied honestly while the
thing it protected stays dead.

The trigger is now retires_dissolution on MacAddress itself: the row ends when
the brand is GONE, stated in the same words its reason uses. No consumer is
re-homed here -- that is the remaining work, and it is now the work the row
actually tracks rather than work the row has stopped asking for.

16/16 mac and 3/3 cr1000a green by execution.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@gunbai-bot
gunbai-bot Bot force-pushed the session/royal-tern-443-mac branch from a37398c to 3797614 Compare August 28, 2026 16:06
…s, and the fallout it caused

CI caught this and it was mine: 50 failures against main's 47, three new, all in
the witness that folds the frontier census.

MY FIRST CORRECTION WAS RIGHT IN SENTENCE AND WRONG IN MECHANISM. Re-pointing the
MacAddress trigger to retires_dissolution read "the row ends when the brand is
gone", which is the correct capability. But a retirement condition asks whether a
named declaration is absent from a SUPPLIED population, and std.dissolution says
in as many words that an empty present_decls reports the condition FIRED -- the
honest reading of "nothing is present". The consumers of this census fold it with
present_decls: [], so the row reported FIRED-WHILE-STILL-PRESENT against a corpus
nobody read: a true statement about the brand turned into a false measurement.

THE REAL LESSON IS THAT THE CAPABILITY IS NOT A SINGLE DECLARATION EVENT AT ALL.
It is the brand's deletion PLUS the migration of every consumer site, and no
DeclarationAppears or DeclarationRetires trigger can encode a conjunction over a
population. It is now an unbound condition carrying the capability in words: it
cannot be satisfied by an artifact, cannot fire spuriously against an unread
corpus, and ends when someone judges the work done and deletes the row.

FALLOUT, all of it genuinely caused by landing the module:
- Four FIXTURE_CARRIER_CITATION_EXEMPTIONS rows cited parse_mac_address as debt
  because it did not resolve. It resolves now, so the rows are spent and deleted
  -- the roster only shrinks. The two near-miss rows (parse_mac_addres,
  extdeps.network.max) still refuse and stay.
- The PRE_EXISTING_CITATION_DEBT row for dhcp.v4 is deleted: that declaration no
  longer cites parse_mac_address at all.
- A module doc comment cited the two-site collision as a measurement. It stands as
  taken, annotated as DISCHARGED rather than falsified, so a reader does not grep
  for a state that is gone.

AND THE WITNESS IS REPAIRED AT ITS ROOT RATHER THAN RE-POINTED. It folded the LIVE
census and relied on one production row still carrying a bound trigger, so a claim
about the FOLD depended on a fact about a row it does not own -- it went red
without the fold changing at all. fold_frontier_expiry has always taken its rows
as a parameter, so the coupling was chosen, not forced. Both affected tests now
author their own planted rows, which also states the discriminating input directly
instead of leaving a reader to confirm some production row still has the shape.

9/9 annotation_carrier and 16/16 mac green by execution.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@briansrls
briansrls merged commit a739822 into main Aug 28, 2026
1 of 2 checks passed
@briansrls
briansrls deleted the session/royal-tern-443-mac branch August 28, 2026 18:20
briansrls pushed a commit that referenced this pull request Aug 28, 2026
…ontier fixture exemptions, BMC demand-curve type error

Both pre-date this branch and were invisible while #9612's parse refusal
kept every required phase from running; this branch's head is the first
to reach the declarations census and the floor's strict preparation, so
they surfaced here.

- declaration_index.rs FIXTURE_CARRIER_CITATION_EXEMPTIONS: #9607
  re-pointed test.claim.annotation_carrier's planted rows at the
  deliberately-fictional test.fixture.frontier without updating the
  exemption roster. Add the four rows for the new deliberately-absent
  citations and delete the spent extdeps.network.mac row the census
  itself demands removed.
- extdeps/bmc/pid_control_program.dag curve_points_agree: the output
  half compared a ZoneDemandValue where decimal_measures_agree declares
  a Measure; compare the ExactDecimal magnitudes directly (verified: the
  entry now compiles with 0 blocking diagnostics).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CQPnTvxdvVjBLzjL6bcWVh
briansrls added a commit that referenced this pull request Aug 29, 2026
* Close the guarantee_rung_drop parse refusal and the generated-artifact drift the masked window accumulated

- guarantee_rung_drop.dag: restore the missing closing brace on the
  wall_deadline GuaranteeStall record (#9612); the unparseable module
  refused the whole module index, so both required lanes died before
  any drift adjudication could run.
- gitignore authority/model/emit: delete the seven hardcoded .py
  allowlist variants whose subjects the measurement bankruptcy and the
  plan-markdown cut deleted; drop the gate test fn that pinned those
  literal rows (a tree-copied oracle).
- generated_artifact.dag: repoint the two stage0 generated .dag
  ArtifactLocation rows to dag/gunbc/stage0/, where #9637 moved the
  files; the registry still named the old directory.
- Regenerate .gitignore, .gitattributes, and .githooks via
  generated_artifact_gate main_wet: .gitattributes drops the 41
  merge-driver rows for plan markdowns #9635 deleted (verified by
  executing expected_gitattributes()); .gitignore drops the dead
  allowlist rows and gains the derived ignore rows for authority-only
  plan markdowns; hook headers pick up the post-reorg githooks/ module
  paths.
- Delete dag/config/codegen_paths.dag: an orphan module no closure
  reaches, describing a layout that no longer exists.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CQPnTvxdvVjBLzjL6bcWVh

* Remodel .gitignore: producer-declared workspace footprints with typed ignore reasons

Replaces gunbc.gitignore_model + gunbc.gitignore_authority (one nullary
variant per path, patterns restated in a central emit match — the shape
that let seven dead allowlist rows emit unnoticed) with a producer-owned
derivation:

- std.workspace_artifact: the agnostic shape — WorkspaceArtifact
  {pattern, meaning, reason} with a closed IgnoreReason vocabulary, and
  WorkspaceFootprint with CitedUpstream/RepoTool provenance.
- Each extdeps product declares its own footprint beside its citation
  (cargo, cargo-tarpaulin, CPython/PEP 3147, npm, tmux, macOS Finder,
  Windows Explorer, JetBrains, VS Code, Vim, Emacs, dotenv); repo-chosen
  locations are parameters, so policy stays a workflow fact.
- gunbc.repo_workspace joins extdeps footprints with the repo's own
  tools' declarations (each naming its owner module) — onboarding a
  concept now naturally carries what files it introduces, what they
  mean, and why they are untracked.
- gunbc.gitignore_emit becomes a pure renderer: it declares no pattern
  of its own; the emitted file carries each pattern's reason and
  meaning as comments. Generated-artifact rows remain a separate arm
  derived from gunbc.generated_artifact commit policy.
- src/v1/runtime_rust.dag: align the emitted trace_mark doc comment
  with the #9635 hand-edit of the generated v1_rt.rs mirror, restoring
  regen first-generation equality (drift was masked on main by the
  guarantee_rung_drop parse refusal).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CQPnTvxdvVjBLzjL6bcWVh

* Install the stage0 mirror for std.workspace_artifact

The new module entered the v1 seed closure, so --required-regen refused
with 'emitted surface has no committed mirror'; this installs the
candidate the regen run produced (std_workspace_artifact.rs plus its
lib.rs module line), unmodified.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CQPnTvxdvVjBLzjL6bcWVh

* Install the regen-produced stage0 mirrors the remodel drifted

--required-regen names four drifted surfaces, each a direct consequence
of this branch's edits: extdeps_cargo.rs (cargo.dag gained its workspace
footprint), v1_compiler_runtime_rust.rs and v1_rt.rs (the trace_mark doc
comment realignment), and emitted_population.rs (the population gained
std_workspace_artifact). All four installed from the regen candidate
tree unmodified.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CQPnTvxdvVjBLzjL6bcWVh

* Use concat, not append, for the cargo footprint list join

The emitted v1_rt::append takes (list, one item) while the interpreter's
append(list, items:) concatenates lists — cargo.dag is the first
mirrored seed module to hit that divergence, so its emitted mirror
failed to compile (E0308 at extdeps_cargo.rs:277). concat has the same
list-concatenation meaning in both realizations. The regenerated mirror
follows in the next commit once the fixed-point verification completes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CQPnTvxdvVjBLzjL6bcWVh

* Install the second-generation mirrors: concat-form extdeps_cargo, corrected v1_rt

extdeps_cargo.rs is the regenerated mirror of the concat fix (compiles
clean; verified by cargo locally). v1_rt.rs corrects a first-generation
install in the previous mirror commit: that candidate was emitted by the
pre-fix binary, so it reverted the trace_mark doc comment while the
generator mirror in the same commit moved forward; this is the second
generation's output, matching what the current generator emits.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CQPnTvxdvVjBLzjL6bcWVh

* Port two masked-window main defects this branch unblocked CI into: frontier fixture exemptions, BMC demand-curve type error

Both pre-date this branch and were invisible while #9612's parse refusal
kept every required phase from running; this branch's head is the first
to reach the declarations census and the floor's strict preparation, so
they surfaced here.

- declaration_index.rs FIXTURE_CARRIER_CITATION_EXEMPTIONS: #9607
  re-pointed test.claim.annotation_carrier's planted rows at the
  deliberately-fictional test.fixture.frontier without updating the
  exemption roster. Add the four rows for the new deliberately-absent
  citations and delete the spent extdeps.network.mac row the census
  itself demands removed.
- extdeps/bmc/pid_control_program.dag curve_points_agree: the output
  half compared a ZoneDemandValue where decimal_measures_agree declares
  a Measure; compare the ExactDecimal magnitudes directly (verified: the
  entry now compiles with 0 blocking diagnostics).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CQPnTvxdvVjBLzjL6bcWVh

* Close the remaining eleven strict-preparation diagnostics blocking every PR's floor

All landed on main inside the masked window (#9612's parse refusal kept
the floor from typechecking anything); this branch is the first head to
reach strict preparation, so they surface here. Seven are ported
verbatim from #9646 (capacity_class on the training fixtures, value
CustomerExecutableCapacity per that PR's model reading — it no-ops when
that PR merges); four are fixed here:

- source_integration_landing_spine: the Optional-receiver '|> map' at
  the additional-continuation arm becomes a match (the module's own
  idiom two arms up), and the module's unresolved-method frontier row in
  v1/04_infer.dag is deleted per the diagnostic's own prescription — the
  deficit fully dissolves, so the row must not keep its ground.
- fabric_terminal_contract_witness_test: the positive-control receipt is
  bound as Receipt<NonEmptyStr> before the call, so the payload's P no
  longer infers String against the NonEmptyStr grant.
- repository_convergence_placement: drop the primary_path argument;
  repository_converge_wet derives it internally and no longer declares
  the parameter.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CQPnTvxdvVjBLzjL6bcWVh

* Resolve the three remaining audit leftovers: delete the import-strip dumps, register js_site's generated pages, keep the bound probe receipt

- docs/plans/import-strip-measurement/ and import-strip-residual-ledger.tsv:
  deleted as unconsumed transcription per the measurement-bankruptcy
  principle (unconsumed transcription disappears; consumed evidence stays
  attached to its consumer). Neither is bound in gunbc.doc_graph_roots —
  the bound import-strip doc is a different, surviving plan markdown. The
  citing plan's prose now records the deletion.
- dag/examples/js_site/generated/: the six committed generated files were
  produced by examples.js_site_emit and adjudicated by nothing. They are
  now JsSitePageArtifact rows in gunbc.generated_artifact (derived from
  the page roster, not hand-listed), located by js_site_emit's own path
  fns and generated through its pure per-page projections, so the
  generated-artifact drift phase adjudicates them like every other
  committed generated artifact.
- docs/probes/leading_minus_continuation_silently_truncates_2026-08-23.md:
  no change, deliberately — gunbc.doc_graph_roots already binds it as
  consumed evidence under an operator ruling that reverted its deletion.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CQPnTvxdvVjBLzjL6bcWVh

* Install the infer mirror for the frontier-row deletion; adjudicate js_site under the drift gate

- src/v1/stage0/src/v1_compiler_infer.rs: regenerated mirror of the
  04_infer.dag frontier-row deletion; --required-regen reports
  first_generation_equal=true on this tree after one rebuild, and the
  landing_spine entry now compiles with 0 blocking diagnostics.
- generated_artifact_emit: the extra-validation match gains its
  JsSitePageArtifact arm (main_wet's fail-closed non-exhaustive refusal
  caught the omission).
- .gitattributes: regenerated; the six js_site pages join the derived
  merge-driver population. main_wet regenerates the pages byte-identical
  to what was committed, so registration changes no page content.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CQPnTvxdvVjBLzjL6bcWVh

* Converge v1_rt on the authority's citation text after the merge of main

Main closed the v1_rt drift by restoring the mirror to the old
docs/plans/ci-floor-fractal-gantt.md citation; this branch had moved the
authority to 'ci-floor-fractal-gantt (plan doc deleted 2026-08-28)'.
Both were internally consistent and disagreed. The deciding fact: the
plan doc does not exist on the merged tree (#9635 deleted it;
gunbc.plans.ci_floor_fractal_gantt is authority-only), so main's
direction re-landed a citation to a nonexistent file — the §3
stale-citation class. The authority-side text survives the merge in
runtime_rust.dag and its generator mirror; this installs the emitted
v1_rt.rs so the pair agrees, verified by --required-regen on this tree.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CQPnTvxdvVjBLzjL6bcWVh

---------

Co-authored-by: Claude <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