You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Decide the compiler's structure after the rewrite #361
Stages outside, concept modules inside. The stage folders and their dependency rules stay as they are. Inside model/, check/ and resolve/, each concept chapter (11 Processes, 12 Exposure, 13 Data, 16 Dependencies, 17 Secrets and access, 18 Placement, 19 Observability) gets one module, and each frame chapter that has code keeps or gains its own. The six modules that carry five or six concepts today are split: model/project-intent.ts, check/project.ts, resolve/process.ts, model/resolved-deployment.ts, model/platform-intent.ts and check/composition.ts. A chapter pull request then edits at most one module per stage.
Rejected: concept folders at the top level (all 19 dependency-cruiser rules would be rewritten, and one Deployment object carries four concepts, so every adapter would need a way to merge contributions), and leaving the modules as they grew.
Seams
The document follows the code. The four ports docs/architecture.md names and nothing declares (PinnedInputSet, FragmentSource, FragmentPublisher, DeliverableWriter) leave the document, with the staging-directory rename the writer does not perform. Hasher and Serializer stay as they are. No port is added until a second implementation exists.
Adapters
An adapter is one target vocabulary, in-tree, in a closed registry. The claim that an out-of-tree adapter may pin the port leaves the documents; the model record that makes it is rewritten with chapter 30.
New objects join the adapter that already speaks their vocabulary. Move step Jobs, Stable Address Services, Node Agent DaemonSets, human grants and L4 Services land in kubernetes; alert rules in prometheus. Dashboards add the one new adapter, grafana.
adapters/kubernetes/render.ts is split by object kind, so it does not grow past its 855 lines.
Outputs that are not Deliverables get a step of their own.adapters/ holds registered adapters only. The Flux pin sources (today adapters/flux/, outside the registry) and the generator of the node contract, the k3s label set and the nix host data move to one new step folder, under the rule every step follows: it imports model/ and objects/ and no other step. Its name is settled against CONTEXT.md in the pull request that creates it.
Where the decided concepts land
concept
modules
rendered by
Infrastructure Intent
its own model/, read/ and check/ modules
the new output step (node contract, label set, host data)
Stable Address
the Dependencies modules
kubernetes
Move
the Delivery modules in model/ and resolve/
kubernetes (step Jobs)
node datasets, GPU vendor and model, across: node, the derived priority class
the Placement and Data modules
kubernetes
lifecycle: scheduled, before sidecars, spawn templates, parked
the Processes modules
kubernetes
L4 exposure, egress: internet
the Exposure and Dependencies modules
kubernetes, networking
mongo and s3 engines, the bucket catalog
the Data modules
kubernetes, vso
human grants
the Secrets and access modules
kubernetes
alert rules, monitoring stack roles and receivers
the Observability modules
prometheus
Dashboards
the Observability modules
grafana
the Node Agent catalog
the Platform Intent modules
kubernetes
The 14 architecture records
Rewritten in place:0056 (the chain is complete, and concept modules sit inside the stages); 0058 (the trace was never built and leaves the record; what stays is create-then-link through a local lookup, typed objects, adapters that never read each other, one serializer, and attribution from the registry; the file is renamed to match); 0063 (the mutation scope below).
Stay as written: 0057, 0059, 0060, 0061, 0062, 0064, 0065, 0066, 0067, 0088 and 0089.
None is folded and none is deleted, so no number is retired here.
Gates and ledgers
No gate is cut on the CI record alone. "Never red in CI" is not "never fired": local npm run verify runs first, and each rule's fixture already proves it fires. The gates cost seconds.
Rows go when their subject goes: the emf wiring and the parity table with emf/.
RULE-046 and RULE-047 are enforced, not left pending. RULE-047 points at the Diagnostic type with a type-level fixture. RULE-046 gets a check that every E_ code raised in check/ is an entry of the invariant registry. After that the rule ledger has no pending row.
The behaviour ledger holds no pending rows. A row lands with its test, in the pull request that builds the behaviour. REQ-031, REQ-034, REQ-039, REQ-040 and REQ-044 change in the chapter pull request that changes their behaviour.
From now on, a new repository-contract gate needs a real incident behind it.
docs/architecture.md is held to the graph. One check is added: the Layers table's folders and may import cells equal what .dependency-cruiser.cjs allows. The 14 differences the audit lists are the incident behind it.
The coverage ratchet stays, with its thresholds raised to what the suite reaches.
Mutation testing
A pull request runs Stryker incrementally against the last main report, at a break score of 100. A mutant is tested again when its file changed or a test covering it changed, which also covers a pull request that only weakens a test.
A full run moves to a weekly schedule. It opens an issue on a survivor and gates nothing.
Condition to verify when it is built: that the Vitest runner reports changed test files to Stryker. If it does not, a pull request that touches a compiler test file gets the full run instead.
It lands now, as its own pull request, with 0063 and RULE-064 rewritten in it. This is an exception to "only the handover work and the Estate-root OCL issue land before 30 October": it changes CI, not the model, has no parity cost, and removes a 9 to 18 minute floor from every handover pull request.
The evidence: mutation is 79.8% of CI minutes; all 10 recorded catches were in files the pull request changed, and all 14 spurious red jobs were in files it did not.
Order
One step is added to the order the register decision fixed:
The emf/ deletion.
The spec's move-only pull request.
The register pull request.
The code move-only pull request. It splits the six mixed modules and kubernetes/render.ts, creates the output step, rewrites docs/architecture.md and adds the Layers check, enforces RULE-046 and RULE-047, raises the coverage thresholds, and rewrites 0056 and 0058. It changes no behaviour: the suite, the rendered trees and resolved.json stay byte-identical, the tests are not edited (25 test files import through src/index.ts), and one full mutation run proves no test lost its target.
Chapter 00's rewrite, and the chapters after it.
Consequences for other tickets
The rewrite plan (/to-spec) takes step 4 as an input, and reads the placement table when it orders the code side of each chapter.
The mutation change gets a ticket of its own, outside the map, since it is work and not a decision.
No new fog.
Record
This answer is recorded here, on the ticket. No new ADR: the layout rule goes into 0056 and docs/architecture.md in step 4, the adapter and output-step rule into 0058 there, and the mutation rule into 0063 in the pull request that changes it.
Activity
ExtraToast commentedon Oct 12, 2026
Resolution
Settled with the maintainer on 2026-10-12. The input was the measurement in
docs/research/compiler-at-scale.mdfrom Audit the compiler's modules, seams and architecture rules against the scale premise, read against the layout in Decide the chapter layout of the rewritten spec and the order in Decide how the decision register is renumbered and rewritten.The layout
Stages outside, concept modules inside. The stage folders and their dependency rules stay as they are. Inside
model/,check/andresolve/, each concept chapter (11 Processes, 12 Exposure, 13 Data, 16 Dependencies, 17 Secrets and access, 18 Placement, 19 Observability) gets one module, and each frame chapter that has code keeps or gains its own. The six modules that carry five or six concepts today are split:model/project-intent.ts,check/project.ts,resolve/process.ts,model/resolved-deployment.ts,model/platform-intent.tsandcheck/composition.ts. A chapter pull request then edits at most one module per stage.Rejected: concept folders at the top level (all 19 dependency-cruiser rules would be rewritten, and one Deployment object carries four concepts, so every adapter would need a way to merge contributions), and leaving the modules as they grew.
Seams
The document follows the code. The four ports
docs/architecture.mdnames and nothing declares (PinnedInputSet,FragmentSource,FragmentPublisher,DeliverableWriter) leave the document, with the staging-directory rename the writer does not perform.HasherandSerializerstay as they are. No port is added until a second implementation exists.Adapters
kubernetes; alert rules inprometheus. Dashboards add the one new adapter,grafana.adapters/kubernetes/render.tsis split by object kind, so it does not grow past its 855 lines.adapters/holds registered adapters only. The Flux pin sources (todayadapters/flux/, outside the registry) and the generator of the node contract, the k3s label set and the nix host data move to one new step folder, under the rule every step follows: it importsmodel/andobjects/and no other step. Its name is settled againstCONTEXT.mdin the pull request that creates it.Where the decided concepts land
model/,read/andcheck/moduleskubernetesmodel/andresolve/kubernetes(step Jobs)vendorandmodel,across: node, the derived priority classkuberneteslifecycle: scheduled,beforesidecars, spawn templates,parkedkubernetesegress: internetkubernetes,networkingmongoands3engines, the bucket catalogkubernetes,vsokubernetesprometheusgrafanakubernetesThe 14 architecture records
Gates and ledgers
npm run verifyruns first, and each rule's fixture already proves it fires. The gates cost seconds.emfwiring and the parity table withemf/.Diagnostictype with a type-level fixture. RULE-046 gets a check that everyE_code raised incheck/is an entry of the invariant registry. After that the rule ledger has no pending row.docs/architecture.mdis held to the graph. One check is added: the Layers table's folders andmay importcells equal what.dependency-cruiser.cjsallows. The 14 differences the audit lists are the incident behind it.Mutation testing
mainreport, at a break score of 100. A mutant is tested again when its file changed or a test covering it changed, which also covers a pull request that only weakens a test.The evidence: mutation is 79.8% of CI minutes; all 10 recorded catches were in files the pull request changed, and all 14 spurious red jobs were in files it did not.
Order
One step is added to the order the register decision fixed:
emf/deletion.kubernetes/render.ts, creates the output step, rewritesdocs/architecture.mdand adds the Layers check, enforces RULE-046 and RULE-047, raises the coverage thresholds, and rewrites 0056 and 0058. It changes no behaviour: the suite, the rendered trees andresolved.jsonstay byte-identical, the tests are not edited (25 test files import throughsrc/index.ts), and one full mutation run proves no test lost its target.Consequences for other tickets
/to-spec) takes step 4 as an input, and reads the placement table when it orders the code side of each chapter.check/modules.Record
This answer is recorded here, on the ticket. No new ADR: the layout rule goes into 0056 and
docs/architecture.mdin step 4, the adapter and output-step rule into 0058 there, and the mutation rule into 0063 in the pull request that changes it.