diff --git a/02-DECISIONS/0162-a-merge-produces-a-tiered-plan-the-mesh-keeps.md b/02-DECISIONS/0162-a-merge-produces-a-tiered-plan-the-mesh-keeps.md index 7bd7e3c..cb5c1b6 100644 --- a/02-DECISIONS/0162-a-merge-produces-a-tiered-plan-the-mesh-keeps.md +++ b/02-DECISIONS/0162-a-merge-produces-a-tiered-plan-the-mesh-keeps.md @@ -38,7 +38,25 @@ kind of dependency on it: `stands-on` (the module's artifact is built on the oth module's build reads the other's repository), `built-by` (the module is built by the holder of the build-machine seat), and `declared` (a manifest's `build.on`). The relation is answered by one query of the catalogue — the controller's inventory today, the catalogue seat's tool when something outside -the controller needs it — and nothing else computes an edge. +the controller needs it — and nothing else computes an edge. The edges are derived from facts +recorded at two moments and written by nobody: registration records the manifest (`declared`, and +`built-by` for anything with a source), a build's take-in records what the image was built on and +which repositories it read (`stands-on`, `packages`). A module's first build places it by its +declared edges alone; from its second it is placed by what was true. + +**The kinds are three dependencies, not one.** A *code* dependency — B packages A's source — means +B is rebuilt whenever A changes, in the same tier: B's build needs nothing of A's first. A *build* +dependency — B stands on A's artifact, or declares it — means B is rebuilt after A is *built*, the +next tier, and nothing need be deployed in between. A *runtime* dependency — B is built by A — means +B is rebuilt only after A is built *and running*, the next tier with a gate on the machines' reports. +One cycle is real and resolved by the kinds themselves: the runtime image is built by the build +machine, and the build machine stands on the runtime image; the image comes first, built by the +build machine that is running, which is the only one there could be — a `built-by` edge never orders +a module after a build machine that stands on it. A provision is not a dependency of this relation: +a consumer binds to its provider through what the push renders, and a change to the provider's image +changes nothing in the consumer's; a consumer whose build does read a provider's source declares it. +"A was deployed, so restart B" is the push's domain — B is replaced when what it reads changed — and +not the plan's. **2. A merge produces a plan, and the plan is a record.** The controller takes the modules the merge changed and everything reachable from them along `depends-on` edges, and sorts that set into tiers: @@ -50,8 +68,8 @@ outcome in, advances the plan it belongs to; a controller replaced mid-plan resu **3. A tier is done when it is built, and when what the next tier needs from it is running.** A module whose roll-out policy says *roll out* is sent to its machines when it moves, as today. The next tier is asked only once every module in this tier is built and every rolled-out module of this tier -that a later tier is `built-by` or `packages` has been applied by the machines running it — the -machines' reports say so. A module whose policy says *record* is built and not waited for. So a merge +that a later tier is `built-by` has been applied by the machines running it — the machines' reports +say so. A module whose policy says *record* is built and not waited for. So a merge touching the build machine and the controller builds the build machine, waits until it is the build machine that is running, and only then asks for the controller's build. @@ -78,7 +96,8 @@ A plan that has waited past a bound is named red there, which is the first fact | Rule | Checked by | |---|---| | Dependencies are one relation, each edge with its kind | an inventory test over a fixture catalogue: a runtime image, a module on it, a module packaging the controller's source, and the build machine; the four kinds come back from one call | -| A merge's set is sorted into tiers, each depending only on earlier ones | a unit test on the tiering: the runtime, a module on it, a plugin on that, and an unrelated module left out | +| A merge's set is sorted into tiers along the three kinds: a code dependency in the same tier, a build dependency after its base is built, a runtime dependency after the build machine; the build machine's own base first | a unit test on the tiering over the mesh's real shape: the runtime image, the build machine on it, modules built by it, a plugin declared on one, the proxy packaging the controller, an unrelated module left out; a cycle is one last tier and said | +| Only a runtime dependency gates on deployment, and only for a module that rolls out | the same test's gate cases | | The plan is written before any build is asked, and the handler returns | a controller test: a merge announcement produces a plan row with its tiers and one asked build per tier-0 module, and the handler is back before any outcome | | An outcome advances its plan; a complete tier asks the next; a tier with a rolled-out base waits for the machines' reports | store-backed tests over a two-tier plan: the first outcome marks built; the tier's roll-out gate holds until the report; the next tier is asked after | | A controller restarted mid-plan resumes it | a test that opens a plan, drops the handler, and advances from the store alone |