Merge pull request 'Design 47 G: the lead's answers A-323 to A-334, from the dry run of G on itself' (#601) from design/47-G-lead-answers-26 into main

This commit was merged in pull request #601.
This commit is contained in:
2026-11-13 08:00:18 +00:00
@@ -586,3 +586,76 @@ the principle that settles it, cited as "design 47 G A-n".
catch-all of seat events by one handler per seat it consumes; for the seat `mesh-catalog` it takes each event it
consumes except `registration-changed`, which the branches follower takes, and whatever the watchman needs of that event
it takes from the follower. The SDK's hub keeps one taker per message.
- **A-323** (§49, §268; principle 3) The assigner and the node-engine on one node are an acting cycle of delivery edges
only (compose and place), so they are delivered as one step (§49), never held by each other: the assigner writes that
node's node-engine want first, held by nothing but its build (§268), and holds the node's other wants, its own included,
until the node-engine seat says the new version runs there. The acting-wait check finds a cycle across steps as well as
within one, and a want held on a cycle it cannot break says so as a finding (found in the dry run of G on itself,
2026-11-13).
- **A-324** (§8, §535, §704, design 51; principles 3, 7) An artifact the builder packs or fetches itself, kind `archive` or
`upstream` with no language (design 51), has no lint, unit or integration step to ask: the seed and the runner call no
build seat's `steps` for it, its registration carries those steps as `bypass` (§8's reason), and the runner places no
bypassed step. An artifact that names a language or kind no build seat serves stays a failure as §535 says, naming the
artifact, in the seed as in the runner: the seed leaves that one module out with a finding naming it, never the whole
seed.
- **A-325** (corrects A-324's runner half; §23, §28; principle 3) The runner places a bypassed step as §23 and §28 say:
outcome `bypassed`, asked of no one, said. For an artifact of kind `archive` or `upstream` with no language, its lint,
unit and integration steps are `bypass` whatever its policy says, so no build seat is asked for them; every other step
keeps its policy.
- **A-326** (§47, §49, §51, §270, ADR 0614 §6; principles 3, 8) A cycle through a build module's own inputs is not
§49's: where the build edge (kind 3) goes out of an artifact of a module that holds a build seat into an artifact it
builds, the running version builds the new one (§270), so the cycle is broken at the running version and is allowed.
Every other cycle with a build edge is refused at take-in, naming every artifact on it (§49, §51); the indexer builds
that rule in G, over the catalog graph it keeps. An edge of kind 4 names the artifact that offers the provision (its
`answered-by`), not the module's first process resource.
- **A-327** (§21, §23, §54; principles 1, 3) A pipeline started before its module has a registration is placed when the
registration arrives: the runner, on `registration-changed`, places from the registration the steps of every pipeline of
that module that has none, once each (by compare-and-set), and says it. Until then the pipeline says it waits on the
module's registration.
- **A-328** (§29, §65, §270; principle 5) A take-in that changes the runner holds every other pipeline of the take-in
until the new runner runs (§65), but never the runner's own pipeline: that one runs on the running runner, as a build
module's running version builds its successor (§270), so its pass lets the new runner be wanted (§29) and its running
releases the held ones. The bound stays only as a failure bound, with its finding.
- **A-329** (A-324, §8; principles 3, 7) The module the seed leaves out raises the indexer's finding `seed-left-out`,
scope `module`, id the module's name, naming the artifact and its language or kind, and is named in the seed's ask
beside the unprotected branches (`Left`, §8). It clears only when a later seed finds a build seat for every artifact of
it, or the module leaves the catalog; the seed being applied without it does not clear it.
- **A-330** (sharpens A-323; §268; principles 3, 8) A want the assigner holds on a cycle it cannot break raises its finding
`acting-cycle`, scope `module`, id `<node>.<module>` of the held want, naming the cycle with each edge's step; the next
pass that finds the want held on no cycle clears it. "Held by nothing but its build" means held by no acting edge: the
node-engine's want on a node (the holder of the seat `node-engine` there, read from the acting edges' seat) keeps every
other rule of a want (grant, hold, canary, composition).
- **A-331** (amends §272 by A-323; §49; principle 3) §272's "a cycle across two steps is none" no longer holds: a cycle of
acting waits across steps is a cycle (A-323), delivered as one step where it has delivery edges only (§49), and a want
held on one no rule breaks raises `acting-cycle` (A-330).
- **A-332** (withdraws A-326's last sentence; §47; principle 7) A manifest names no artifact for a provision (`answered-by`
is `helper` or unsaid), and the delivery waits cut edges down to module names, so the artifact a kind-4 edge starts from
changes no order: it stays the module's first process resource, as built, and G changes nothing there.
- **A-333** (sharpens §49 and A-326; §47; principles 3, 7) Two more cycles are not §49's. (1) A cycle of package edges
(kind 1) alone: a real import cycle is refused by the language's own build, and one found only because imports are
given to every artifact of a module is not a cycle of what is built. (2) No delivery edge (kinds 2, 4, 5, 6) ends at a
package artifact: a package is delivered only inside what uses it, which a kind-1 edge carries, so such an edge is not
made and cannot close a cycle. How it is checked: the indexer's cycle rule accepts today's trunk catalog and G's own
(the dry run's entries, kept as test data), and refuses a cycle with a build edge among delivered artifacts, naming
them.
- **A-334** (sharpens A-328; §29, §65, §268; principle 5) In a group take-in that changes the runner, the runner is the
acting part the other members wait on, so it goes first as the node-engine does (§268): its member is wanted on its own
pipeline-ended once that passed, ahead of the group. The other members keep §29: their pipelines run on the new runner
once it runs, and they are wanted together on group-ended. The bound stays a failure bound only.
- **A-335** (§368, §583; principle 5; the operator, 2026-11-13 about 02:30 CET: yes) Every module on the trunk joins G's
form, not only G's own: the ten repositories whose 24 manifests still say `"version": "1"` (mesh-media-catalog,
Link2Pay, de-spiegel, photos, okioki, car-hunter, f1-circuits, snake, txt-game, amqp-email-forwarder) are members of
G's group, each manifest's `version` written as §583 says (the `MAJOR.MINOR` of its newest published version through
`builder_versions`, `0.1` for one with none). §368's rule keeps no old form. How it is checked: G's judge accepts every
trunk manifest at G's heads (the dry run's mesh-wide read, again before the push).
- **A-336** (A-327, §200; principles 3, 7) Any start of a pipeline (a take-in, a package published) heard before its branch's catalog half is held starts its pipelines
with no steps, never with steps placed from empty entries (§200: nothing new of a branch is acted on until its half is
held); the path of A-327 places them once the half is held.
- **A-337** (§712, ADR 0579 §2; principles 3, 7) "Refusing only what the revision causes" takes the trunk case as it
stands: the manifest validator counts old sections and finds the declaring modules over every trunk-case manifest that decodes,
accepted by its own rules or not, so a trunk manifest the new rules refuse still counts and still declares. A trunk-case
manifest that does not decode is named in the verdict's report. How it is checked: G's manifest validator on G's heads against
today's unmigrated trunk refuses none of G's 169 manifests for a count or a declarer (the dry run's re-creation).
- **A-338** (A-335, ADR 0233; principle 7; the operator, 2026-11-13 about 03:50 CET: "it's a poc") The two trunk manifests
the manifest validator refuses once they change, for a written directory with no data declared, declare it in G's
change: f1-circuits' `cache` and Link2Pay's `logs`, both class `cache`.