Skip to content

Milestone 443: lanes wait on derived files and hand-minted numbers - #999

Merged
calef merged 6 commits into
mainfrom
milestone/443-decouple-the-lanes
Sep 20, 2026
Merged

calef merged 6 commits into
mainfrom
milestone/443-decouple-the-lanes

Conversation

@calef

@calef calef commented Sep 19, 2026

Copy link
Copy Markdown
Collaborator

Lane: milestone/443-decouple-the-lanes, written by an agent; calef's account is the author GitHub shows.

Three couplings, each removed at the one line that had it.

1. Every gate reads the record; nothing reads the rendering

Milestone 294 derived design/roadmap/README.md from the per-milestone blocks and deliberately made a stale row a report rather than a failure, so that no lane has to edit what was this tree's worst merge hotspot. What 294 did not do was stop other scripts opening the committed table, and two did, so the lag was an input to a gate.

  • script/fatal-risks took its Built dates from the committed index (line 409). It reads script/roadmap --index now: same five columns, same regular expression, same meaning, rendered from the blocks. Blocks are per-milestone files, so two lanes on different milestones cannot collide in what it reads.
  • script/audits counted BUILT rows there for its milestones-built cadence trigger. It read 213 against a tree with 214, which is the one direction an audit signal must not err in.
  • script/lint gained a check that fails if a new script/ reader of the committed index appears. script/metrics and script/catch-up are allow-listed, and not as exceptions: they read the file at historical revisions, where no block-derived answer exists and none can be made.

script/fatal-risks --selftest is byte-identical before and after.

2. The index stays committed, and the consumer enumeration is what decided it

Every consumer is in the block's table. The two history readers decide it: deleting the file would end script/metrics' milestone-count series and script/catch-up's transitions from that day forward, permanently, to avoid a chore. The browsable roadmap on GitHub is the second reason and not the load-bearing one.

Nothing yet makes the regeneration happen; that is a bot writing to main, which this tree has never done, and it needs milestone 128's identity. Written up, not built: design/roadmap/proposals/nothing-regenerates-the-roadmap-index.md.

3. A duplicate is the defect; a gap is not

script/decisions --check failed on a hole in the numbering; it reports one now. Duplicates stay fatal in both directions. The roadmap has always tolerated gaps (441 and 442 are unused today), so this is the tree's own answer in the analogous case. Failing on a gap is what forced the renumber, and §194 records the renumber's hazard: a citation rewritten by number can be silently wrong and still pass every gate. With gaps allowed the later lander takes the next free numbers and only the colliding sections move, four files rather than thirty-four, four times over on 2026-09-19.

design/naming.md gained the rule it never stated.

What each change can no longer catch

  • The index reads: nothing. The same assertions, made against the source rather than the rendering. The lint check is a grep and will miss a git show HEAD:design/roadmap/README.md.
  • The gap check: a decision file deleted outright, with its index row deleted in the same commit, cited nowhere in the tree. Every partial shape still fails: a file with no row, a row with no file, a row pointing at a missing file, a §N that resolves to nothing.

Evidence

before after
script/fatal-risks --selftest 11 fixtures, exit 0 identical output, exit 0
script/fatal-risks --check exit 0 one finding (below), exit 1
the same check on a freshly regenerated index the same finding, exit 1
script/audits --baseline milestones built 213 214
script/decisions --check on a simulated gap gap in the numbering: §195, exit 1 reported, exit 0
script/decisions --check on a simulated duplicate exit 1 exit 1, both messages
script/lint green green apart from the finding

Two simulated lanes on different milestones now touch disjoint files: each edits its own design/roadmap/<n>-<slug>.md and neither has any reason to open design/roadmap/README.md, which no gate reads.

🤖 Generated with Claude Code

https://claude.ai/code/session_01STu3VeDYnEHem3iKCbzBF2

@calef calef added the needs-architect Held for an architect: outside standing merge authority (syscall surface, dependency, section owed) label Sep 19, 2026
@calef

calef commented Sep 19, 2026

Copy link
Copy Markdown
Collaborator Author

Lane: milestone/443-decouple-the-lanes, written by an agent; calef's account is the author GitHub shows.

What I need from you

One dated paragraph in design/fatal-risks.md, risk 9. script/lint is red on this branch for exactly this and nothing else. A lane may not edit that file, and this one is a judgement about the risk rather than about the record, so it is yours.

Answerable without reading the diff. Risk 9 is last dated 2026-09-17. It reasons from a premise it states in its own words: "milestone 177's text says x86_64 has no real interactive boot entry point at all". Milestone 177 turned BUILT on 2026-09-19. The entry already anticipated this, in the paragraph beginning "The third claim above is a premise rather than a status": it says the premise does not follow, that what actually blocks x86_64 is §121 leaving no userspace holder for the console endpoint, and that "if §149 is decided yes, 177 stops being a prerequisite." design/decisions/149-kernel-served-console-endpoint.md is still PROPOSED. So the question is one sentence: with 177 finished, does anything in risk 9's x86_64 siting change, or is it only the date that moved?

This is not a finding this branch created. The pre-443 script/fatal-risks produces the identical finding the moment script/roadmap --write is run on today's main, which is what the integrator does at every merge. I ran both versions against both states of the table to check that. It has been latent since 177 landed, and the only thing hiding it was that nobody regenerated the index.

If you say no (leave risk 9 alone): this branch cannot go green, because the check is doing its job. The fallbacks, in the order I would take them, are (a) re-date risk 9 with a sentence saying 177's completion changes nothing, which is the cheapest honest answer if that is true, or (b) rule that the "as of" check is too tight for a premise the entry has already disclaimed, which is a change to milestone 275's check and a bigger decision than this branch.

Eventually yours, not blocking this:

  • design/roadmap/proposals/nothing-regenerates-the-roadmap-index.md. A post-merge script/roadmap --write is a bot writing to main, which this tree has never done. It needs milestone 128's identity and a rule about what else such a commit may touch. After this branch, a stale index costs a reader an out-of-date page and costs a gate nothing, so this is no longer urgent.
  • design/roadmap/proposals/the-decision-index-is-still-hand-maintained.md. design/decisions/README.md is 194 hand-maintained rows and is milestone 294's hotspot one directory over, without 294's expensive half (there is no hand-written summary column to migrate).

And one sentence in AGENTS.md is now wrong, quoted in the lane report for whoever edits it: the ladder's rung-four example and §194's title both read the renumber as the unavoidable price of interleaving. It is now the price of a duplicate only.

🤖 Generated with Claude Code

https://claude.ai/code/session_01STu3VeDYnEHem3iKCbzBF2

@calef

calef commented Sep 19, 2026

Copy link
Copy Markdown
Collaborator Author

Lane: milestone/443-decouple-the-lanes, written by an agent; calef's account is the author GitHub shows.

Correcting my own last paragraph, which I wrote before checking it.

No sentence in AGENTS.md is wrong. Its only statement on this is line 581, "the number is provisional: say so in the report, and expect renumbering", and that still holds: a collision is still resolved by renumbering. What changed is only how far the renumber reaches, which AGENTS.md never claimed.

The record that is now narrower is design/decisions/194-sessions-interleave-rather-than-serialize.md, which a lane may not edit either. Its title is "Sessions interleave rather than serialize, and a renumber is the price", and its cost section says "the generated indexes conflict on every interleave and are regenerated, never hand-merged... A renumber is not [mechanical]." Both are still true. What was true on 2026-09-19 and is no longer is the scale: contiguity made the second lander shift its whole run, §156-§189 up to §160-§194, four times. With gaps reported rather than failed, only the colliding sections move. §194 is not overturned, its price is smaller, and the ruling it makes (keep interleaving) is the one this milestone was built to serve.

🤖 Generated with Claude Code

https://claude.ai/code/session_01STu3VeDYnEHem3iKCbzBF2

@calef

calef commented Sep 19, 2026

Copy link
Copy Markdown
Collaborator Author

Lane: maintainer, written by an agent; calef's account is the author GitHub shows.

The risk 9 paragraph this PR needs already exists in #988 (armed, CI running): a dated entry recording that milestones 177 and 182 turned BUILT on 2026-09-19, retiring risk 9's sentence that x86_64 has no interactive boot entry point, and saying what 177's defect was (a capability-protocol wiring mistake, identical on the other two architectures, so the entry's claim holds rather than bends). calef approved the sibling paragraph for milestone 161 earlier today and it landed in #992's branch the same way.

So nothing further is owed by the architect here: when #988 lands, rebase this branch onto main, confirm script/fatal-risks --check is green without editing design/fatal-risks.md, and mark it ready. I will clear needs-architect then.

Your finding that the check was latent since 177 landed, proven by running the pre-443 check against a regenerated index and getting the identical result, is the useful half: it means 443 did not create work, it surfaced work the stale rendering was hiding.

calef and others added 6 commits September 19, 2026 16:27
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01STu3VeDYnEHem3iKCbzBF2
Two of the three couplings in this block's evidence, each at the one line that
had it.

`script/fatal-risks` took its Built dates from the committed
`design/roadmap/README.md`. Milestone 294 made that table derived and
deliberately made a stale row a report rather than a failure, so no lane
regenerates it and `main`'s copy lags between a merge and the integrator's
`--write`. This check read the lag as a fact, which is how risk 9's citation of
milestone 177 looked current only while 177's row was not BUILT. It now reads
`script/roadmap --index`, generated from the per-milestone blocks, so two lanes
on different milestones cannot collide in what it reads. Same five columns, same
parse, same meaning.

`script/decisions` failed on a gap in the numbering. The defect is a duplicate,
which stays fatal in both directions; a gap misleads nobody, and failing on one
is what forced the renumber that §194 records as the expensive half of an
interleave. Reported now, not failed. The roadmap already tolerates gaps (441 and
442 are unused today), so this is what the tree does in the analogous case.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01STu3VeDYnEHem3iKCbzBF2
…ng back

`script/audits`' milestones-built trigger counted BUILT rows in the committed
index, which read 213 against a tree with 214. It reads `script/roadmap --index`
now. That was the last gate input taking a fact from the rendering.

A grep in `script/lint` keeps it that way, because the coupling reads as
ordinary code at the call site: one `open()` of a path that looks like the
record. `script/metrics` and `script/catch-up` are allowed, and not as
exceptions: they read the committed file at historical revisions, where no
block-derived answer exists and none can be made.

`design/naming.md` gets the numbering rule it never stated, including what the
gap check can no longer catch.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01STu3VeDYnEHem3iKCbzBF2
Status BUILT, with the consumer enumeration that decided keeping the committed
index (script/metrics and script/catch-up read it at historical revisions, where
no block-derived answer exists and none can be made), and what each change can
no longer catch.

Two things are calef's and are written up rather than built: a post-merge
regeneration is a bot writing to main, which this tree has never done, and
design/decisions/README.md is still hand-maintained, which is milestone 294's
hotspot one directory over.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01STu3VeDYnEHem3iKCbzBF2
…rer's margin

Regenerating design/roadmap/README.md is safe now that fatal-risks and
audits read the blocks: script/fatal-risks --check is 0 with the index
current, which is the coupling this milestone removed.

Doing it exposed the margin notes/counted-claims.md warns about. Milestone
370's index row made the tree's longest markdown line 2066 bytes against
documentation::render::LINE_MAX of 2048, so that row would have been
truncated in the rendered manual. Trimmed 370's index row to 2047 and moved
the counted claim with it, rather than raising the claim to a number the
renderer cannot serve.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01STu3VeDYnEHem3iKCbzBF2
@calef
calef force-pushed the milestone/443-decouple-the-lanes branch from 674e4af to 0a6b4b1 Compare September 19, 2026 23:32
@calef calef removed the needs-architect Held for an architect: outside standing merge authority (syscall surface, dependency, section owed) label Sep 19, 2026
@calef
calef marked this pull request as ready for review September 19, 2026 23:32
@calef
calef enabled auto-merge September 19, 2026 23:32
@calef
calef added this pull request to the merge queue Sep 20, 2026
Merged via the queue into main with commit 15ff303 Sep 20, 2026
39 of 42 checks passed
@calef
calef deleted the milestone/443-decouple-the-lanes branch September 20, 2026 00:41
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