Design 47 G: the lead's answers A-44 to A-70 #559

Merged
mesh-tools merged 23 commits from design/47-G-lead-answers-5 into main 2026-11-11 22:01:50 +00:00
@@ -165,3 +165,113 @@ names the principle that settles it, and is cited as "design 47 G A-n".
`<owner>.views.<state>` family is followed by `Reader.Follow`, the follower's `Ask` set after (`Adopt` is for a seat's
events); and the tool runner's held writer is given its JetStream, the writer's own defaults publishing and
listening, so `bus.Conn` gains no publish method.
- **A-44** (§681, §691; principle 7) `snapshot-remove` answers the one acting form of §691 (exactly one of `accepted` with
the act's id, `busy` with the running act's id, or `error` with why), and records its caller as `by` from the proved
caller (`by-caller`), as every acting verb does. mesh-sdk's seat definition reader gains the verb field `chunks`
(§681) in the same change, with the bootstrap copies of `mesh-broker` laid again byte for byte.
- **A-45** (§681, ADR 0675; principle 7 and the standing rule that a process answers no call, mesh-sdk 1171/AC3) The bus
module answers the seat `mesh-broker`'s verbs through its tools bundle, as every bundle answers a seat verb
(`SeatAnswer`, the proved caller from the runtime), and sends a snapshot's chunks and hears their acks from there
(`SeatPublish`, its subscription); the keeper's process does the work that needs the bus and the files (taking,
restoring, removing), handed over and answered through the bus module's own `requests` record, as the bundle hands
the keeper its requests today. Where §681 says "the keeper's process serves", read "the bus module serves".
- **A-46** (§368, §372, §411; principle 7) The `version` G's change writes into each manifest is read once now from the
same source §372 fills from: the highest `published` version over the module's artifacts in the builder's
`versions` (`builder_versions`), as its MAJOR.MINOR (mesh-sdk `0.1`), and `0.1` for a module with none published.
The developer reads it through `builder_versions` and writes it into every manifest of every repository in the
group, one commit per repository, listing the values in the commit.
- **A-47** (§421, §683, §698, ADR 0593 §6; principle 7) The node-engine reads by fingerprint only (§421), so it follows
no branch: it uses the shared follower's entry cache alone (`Entries`, A-5, A-15) over its own `entry` calls on its
link session. It keeps the entries and wants of §683 in its `composed-<node>` bucket, keys `entry.<fingerprint>` (the
entry as `entry` answers it) and `want.<module>` (the want as `wanted` says it), beside the composition. Its other
users of `compose/frombus` keep that reader until their own lines move them; only the node-engine's own reads of the
indexer's and builder's states go in this change.
- **A-48** (§706, §276; principle 7, one way per part) The assigner's outside waits: a state `waits`, declared in the
same form as the assigner's other states, key `<node>.<module>.<fingerprint>`, read by `assigner_waits` and written by
the process and by `assigner_release`; the ask goes the way the assigner asks everything, through its state `asks`
as a new kind `outside` (key `outside.<node>.<module>.<fingerprint>`, options go on and count as failed), its answer
read as the others are; `assigner_release` with `how` releases an outside wait and without it ends a put as today;
a want held for M's own network says `RuleNotHeld` with words naming the open `machine.<M>.network`. As the
developer proposed on mesh-delivery feat/47-G-outside5.
- **A-49** (§518, §576; principle 7) A put or get session's bound is the call's bound the runner already uses,
`launch.CallTimeout` (30 seconds), counted from its first chunk; a session also ends when its bundle's channel closes
(the child's exit), as §518 says. The runner answers `mesh/capabilities` with `{words}` (§576), so a bundle's
capability check passes.
- **A-50** (§421, §379, §466; principle 7) The node-engine makes each artifact's reference from the want's part digest
in the form the store is already addressed by, `artifact-store://<module>/<artifact>/blobs/<digest>`, and the rest
of the resolved manifest (languages, launchers, template texts) from the entry and the parts fetched by digest; its
read of the builder's done key goes.
- **A-51** (§388; principle 7) The grants part moves to the writer only the four kinds §388 names (`view-waits`,
`first-view-unanswered`, `first-view-empty`, `binding-unlisted`), through the held writer of a process (A-29, A-40)
with the foundation stream form of §529; its other conditions stay as they are.
- **A-52** (§200, §388, §614, §684, A-26; principle 7) The grants part's `view-waits` is the one its reader raises for the
catalog half views the branch follower adopts (A-5): the part waits on the catalog half of the revision it composes
for, through those views, and writes no `view-waits` of its own.
- **A-53** (§681, ADR 0675; principles 3 and 7) A snapshot's record never ages out before its file: the bus module's
`requests` state keeps its records 91 days (one more than `snapshot-keep-days`), and the keeper removes a snapshot's
record together with its file at expiry, so no file is left without a record and no record without its file.
- **A-54** (§584, ADR 0363; principle 8) Distribution's old-section stream takes the old form's name beside
`<module>-findings`: `distribution-events`, never the mesh's own `events`.
- **A-55** (§672, ADR 0348 §5; principle 7) The builder's `toolchain-wait-minutes` reaches it the way the mesh fills a
part's settings, as mesh-conditions reads its own (the runtime's settings read at start, the manifest marking it
`runtime`), never through the process's environment.
- **A-56** (ADR 0573 §2, §4; principle 5, everything ships the same way) The locks check treats every `@novox/mesh-*`
package as it treats the SDK's, since the builder builds a module against the latest published version of each mesh
package as it does for Go; the order between the contracts' publish and gitea's build is the delivery plan's.
- **A-57** (§466, §52, §334, §349, §371; principle 7) BL1 is the whole `package-published` emission, built after BL5's
watched-branch half: the builder says it per artifact when it hears the registry seat's `published`, carrying
`resolved` and `toolchain` from the step's result (`dependencies`, §673), `branch` the watched branch of the catalog
revision whose entry the build came from, and `source` that revision, both kept on the build's reservation from the
candidate it built.
- **A-58** (§540, §685, §8; principle 8, one word per thing) An owner change is said as `condition-changed` with a new
`change` value `owner`, added to the seat `mesh-conditions`' enum in mesh-contracts; `words` stays for a change of the
text. `seed-waits` waits on the operator through the finding's own `waiting-on`, which the indexer sets and the keeper
copies, with no rule of the keeper's for that kind.
- **A-59** (§681, A-45; principle 7, and who may do what is no question) The bus module's snapshots directory is made
readable by its tools bundle's account in its manifest (a group read, nothing more), so the bundle reads a
snapshot's file and sends its chunks as A-45 says; the keeper still writes and removes the files, and a protected
snapshot is still never handed out, by the bundle's own check.
- **A-60** (§681, A-45; principle 7) The chunk subjects of a `chunks: true` verb are granted to the principal that
answers the verb: for the bus module, the tool runner's principal for its tools bundle (A-45); the restore subjects of
restricted streams to the keeper's process account, standing (ADR 0675 §2).
- **A-61** (§693, §683, §556, §113's form; principles 1 and 7) The assigner says `wanted` for every want it writes and in
the same write that removes one, on `mesh.seat.mesh-wants.event.wanted.<node>.<module>` (each escaped as a name, §73),
the seat's stream kept last per subject, so each want's last word stands; `revision` is the assignment graph revision
of the pass that writes or removes it, and `source` that pass's source revision. The seat's definition gains the
subject's two tokens and its keep-last setting.
- **A-62** (§704, §402; principles 7 and 8) The seat `mesh-module-assigner` gains the verb `placement`, class `read`:
input `{module}`, answer the module's placements as its `assignments` rows hold them (`{placements: [{branch,
nodes}]}`); the assigner serves it. An `unwatch` of a branch a placement names is refused with the new reason
`placed`, naming the placement. §675's *Kept while named* and §700's read of the router's record are the indexer's
in G, built with these rows.
- **A-63** (§706; principle 7) As built in mesh-delivery 76fce4bd and 640191d4: "a module the delivery moved to M" is
one whose want on M names a fingerprint its have there does not yet run healthy; a wait's `clock-from` is the
failing check's time, also when it first rests on `conditions-unread`; while the keeper has not answered, a first
failing check holds as the settle and becomes `conditions-unread` only after it, and a standing wait keeps its cause
while a new read is out.
- **A-64** (§681, A-45; principles 7 and 8) As built in mesh-catalog 47aaee12: a chunk's body is `{n, of, data}`; a
restore's act id is the id of the request the bundle hands the keeper; `verify` answers `accepted` with that id and
says no event; an unprotected snapshot's restore refuses nothing further; each chunk is acknowledged by a request,
since the runtime answers only calls with a reply. One change: `snapshots-filling` takes an existing scope word,
scope `module`, id `nats.snapshots`.
- **A-65** (§387, §529; principle 1, a module's data lives on the bus) mesh-knowledge's findings go through the writer
like every observer's: it gains the `finding-events` stream and a writer over the `findings` state it already
requires, and its findings no longer live in its database.
- **A-66** (§704; principles 7 and 3) The seed's `steps` call names the artifact by the contract's key
`<module>.<artifact>`, `module` beside it; its `fetch` is composed from the entry (repository, commit, path, the
artifact's paths, and `packages` and `beside` where the entry carries them); the time since a seat first failed to
answer is kept in the indexer's own state, so a restart keeps it, and the finding is written at the next seed attempt
past five minutes.
- **A-67** (§292 and G-5's *wants follow the assignment graph*; principle 7) (c): the design has the assigner write each
want from an assignment graph revision it keeps, so the pass keeps that revision first (assigngraph.Compute and Keep
per catalog revision taken in), and `wanted`'s `revision` and `source` are that kept revision's and its catalog's.
No stand-in value.
- **A-68** (§375, A-66; principles 1 and 7) The indexer keeps what `outdated` compares against in its own state, as it
hears the events: `toolchain.<language>` the newest `toolchain-agreed` per language, and `delivered.<module>` the
newest `version-delivered` per module, in the same own state as A-66's keys; no new state, no field of `VersionEntry`,
no scan of the streams at a call.
- **A-69** (§349; principles 3 and 7) The artifacts published so far at a version not yet released are kept in the
indexer's own state under `pending.<module>.<version>`, beside A-66's keys, and removed when the version is released.
- **A-70** (§572, A-45; the rule that a process answers no call) The builder's tools bundle serves `reserved` and
`builder_versions`, following the catalog half's view itself as other bundles follow views; the builder's process
serves no call.