Skip to content

Decide the compiler's structure after the rewrite #361

Closed

Description

@ExtraToast

Question

What structure does the compiler take after the rewrite?

With the audit in hand, decide:

The answer is the input /to-spec needs to order the code side of each chapter's pull request.

Activity

  1. added
    type: docsDocumentation-only change.
    area: deployhomelab-deploy, deploy-v2, manifests, and rollout flow.
    wayfinder:grillingWayfinder ticket resolved by conversation (HITL)
    on Oct 12, 2026
  2. self-assigned this
    on Oct 12, 2026
  3. ExtraToast commented on Oct 12, 2026

    @ExtraToast
    ContributorAuthor

    Resolution

    Settled with the maintainer on 2026-10-12. The input was the measurement in docs/research/compiler-at-scale.md from 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/ 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:

    1. The emf/ deletion.
    2. The spec's move-only pull request.
    3. The register pull request.
    4. 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.
    5. Chapter 00's rewrite, and the chapters after it.

    Consequences for other tickets

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area: deployhomelab-deploy, deploy-v2, manifests, and rollout flow.type: docsDocumentation-only change.wayfinder:grillingWayfinder ticket resolved by conversation (HITL)

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions