A build edge, a core library that is a domain, and 0063 corrected
Three things from walking a real dev cycle through 0063, all of which Jochen caught by pushing on where I had glossed. 0064 -- a build edge is a third kind. Research 011 established presence and instantiation, and both are RUNTIME edges: they answer what a module needs in order to run. Delivery needs a different question -- what has to be rebuilt when this changes -- and that relationship is fixed inside an artifact rather than negotiated when it runs. So the graph as designed could not drive delivery, which is the real reason 0063 was not approvable. It is derived rather than declared, read from what a module actually imports, because a declared list and the imports it describes drift and the imports are the true ones. The runtime edges stay declared, and that asymmetry is not an inconsistency: a runtime edge is an intention somebody has, a build edge is a fact about code that exists. It also makes design quality measurable. A module with many inbound build edges is one whose every change is expensive, and the current shared library is exactly that -- nobody could see it because nothing drew the edges. 0065 -- the core library is the mesh's domain. Jochen disagreed with 0030's "types, not behaviour" and was right: that guard is aimed at the wrong thing. A library everything depends on is a hub whether it holds types or code, and the fan-in is what makes a change expensive. So types ship with the module that owns them -- trading one wide edge for several narrow ones -- and the core library holds what is true of the mesh regardless of context, which research 011 already found: a module, a node, an assignment. The test is "would this still mean the same thing in a context that had never heard of the one it came from". A node does; a pipeline stage does not. Domain-driven is the point rather than the label: "who else might want this" always answers yes, which is how the current one grew. And it changes the check for the better. "The build output contains no runtime code" would have enforced a rule now withdrawn. Inbound build edges is a measurement rather than a prohibition, and it is visible while a hub is forming rather than after. 0063 revised on both counts, plus a third: I had written "the lab judges it" as though that were a step. A lab run takes tens of seconds, occupies a VM, and fails for environmental reasons -- and a shared-library change produces dozens. One expensive non-deterministic gate fails both ways, and neither failure looks like itself. Verdicts are now tiered, and a run that failed environmentally is explicitly not a verdict. 0063 also now carries what must exist before it can be implemented, rather than leaving that to be discovered.
This commit is contained in:
@@ -87,10 +87,12 @@ examined.
|
||||
- **"Is this artifact current?" must be answerable without building it.** A commit recorded
|
||||
against each artifact does it, and that record becomes load-bearing: wrong, and the mesh either
|
||||
rebuilds forever or never rebuilds at all.
|
||||
- **Rebuild storms.** One change to a shared library makes everything out of date at once. The
|
||||
ordering that today's *levels* provide has to come from the module graph
|
||||
([research 011](../01-RESEARCH/011-the-module-graph/00-overview.md)), which is designed and not
|
||||
built.
|
||||
- **Rebuild storms are real and mostly behaviourally empty.** One shared-library commit
|
||||
invalidates nearly everything, and most of those rebuilds produce artifacts that do the same
|
||||
thing they did before — so **the fleet is redeployed for no change in behaviour.** Reproducible
|
||||
builds would stop the cascade at the first module whose output did not move; without them, the
|
||||
storm is in the declarations rather than the builds
|
||||
([ADR 0064](0064-a-build-edge-is-a-third-kind.md)).
|
||||
- **The run identity people actually use is lost.** *Did my change go out?* is answerable today
|
||||
by opening a pipeline. With convergence there is no run to open, and **something has to replace
|
||||
that** — a query over the two comparisons above — or this will be worse to live with than what
|
||||
@@ -101,6 +103,18 @@ examined.
|
||||
the fault this record is removing, reintroduced in a new place. **This is the real risk and it
|
||||
is not solved here.**
|
||||
|
||||
## What must exist first
|
||||
|
||||
Stated as a list because this record cannot be implemented without them, and saying so is better
|
||||
than discovering it:
|
||||
|
||||
1. **The module graph, including build edges** ([ADR 0064](0064-a-build-edge-is-a-third-kind.md)).
|
||||
Designed, not built. Without it there is no rebuild set and no ordering.
|
||||
2. **A recorded input closure per artifact** — its commit and the identity of everything it was
|
||||
built against — so *is this current?* is answerable without building.
|
||||
3. **Something that notices a reconciler is not converging.** Below, and the one that is a risk
|
||||
rather than a cost.
|
||||
|
||||
## Consequences
|
||||
|
||||
- **Detection stops being correctness and becomes latency.** The specific faults the as-is
|
||||
|
||||
Reference in New Issue
Block a user