Take in round 3's second pass on design 47's G amendment: put-stands timed by the watchman, the put ends by done
A new step would read as a running put to a reverted assigner, the running-before-assigner order is no edge of the module graph, put-stands needs a writer that survives a stopped assigner, and the tool runner's revision rests on ADR 0663, now required before the push beside ADR 0661. Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
This commit is contained in:
@@ -4,6 +4,7 @@ status: in-progress
|
||||
code: [mesh-controller, mesh-catalog modules/mesh-delivery-gate, mesh-catalog modules/gitea, mesh-delivery, mesh-host, mesh-sdk, mesh-vault, mesh-contracts, hq 00-META/checks]
|
||||
updated: 2026-11-09
|
||||
decisions:
|
||||
- "ADR 0663"
|
||||
- "ADR 0661"
|
||||
- "ADR 0660"
|
||||
- "ADR 0659"
|
||||
@@ -786,17 +787,20 @@ Findings 11). How each is kept, read and retained is this design's choice under
|
||||
(a gap in the revisions it heard) asks `revision` once more, said in its log (ADR 0615 §5). The design's choice
|
||||
under ADR 0656 §6: one form of the fact, never `modules` kept beside the catalog graph for these readers, which
|
||||
would be a second source of the same fact. How it is checked: test 61.
|
||||
- **The forge module's tools come from mesh-sdk's TypeScript side.** mesh-sdk's TypeScript side serves the proved
|
||||
caller, a verb's `callers`, a seat's publish, and a view's read and ask-again tools, so the forge module, reading
|
||||
through the seat's TypeScript contract, answers `<module>_first_views` and `<module>_first_view_again` as the Go
|
||||
parts do from `go/views`, with no follower or tool of its own.
|
||||
- **The forge module's tools come from mesh-sdk's TypeScript side.** mesh-sdk's TypeScript side has no view
|
||||
today; milestone G adds there a view follower with its read and ask-again tools, beside the proved caller, a
|
||||
verb's `callers` and a seat's publish, so the forge module, reading through the seat's TypeScript contract,
|
||||
answers `<module>_first_views` and `<module>_first_view_again` as the Go parts do from `go/views`, with no
|
||||
follower or tool of its own. Its cost: a release of the TypeScript side rebuilds every TypeScript module, which
|
||||
the delivery carries like any change of a package its users build in.
|
||||
- **The order is the module graph's, and the foundation's own rule where the graph has no edge.** Six of the
|
||||
readers declare the verb in their `invokes`, so the served-verb edge delivers none of them to any node before a
|
||||
build serving `revision` runs (ADR 0615 §2, ADR 0614). Two are left out of the graph's order (ADR 0614 §3, ADR
|
||||
0615 §2): the tool runner, a foundation part, and the forge module, on a cycle with the indexer, which reads the
|
||||
forge through the seat `git`. For both the order is carried by ADR 0615 §4 and §6: the owner answers at once from
|
||||
what it holds, and a reader started before it waits, saying so. The tool runner asks `revision` of the indexer's
|
||||
own runtime, never through itself, the tool's `callers` list naming it (ADR 0615 §3, ADR 0621 §1, §2); the forge
|
||||
own runtime, never through itself, the tool's `callers` list naming it (ADR 0663, which changes ADR 0621 §1, §2 and
|
||||
ADR 0615 §3; proposed, to be accepted before G's push); the forge
|
||||
module answers the indexer's reads through the seat `git` before it has a first view of its own, so neither waits
|
||||
on the other.
|
||||
- **With no view, a reader waits; it never reads "no modules".** All eight follow *A part with no view says it
|
||||
@@ -982,7 +986,7 @@ say another runs a build (ADR 0363 §2); the gate's events are granted to the ga
|
||||
|
||||
| Step | Event | Owner: the seat, then the module | Subject | Declared in |
|
||||
|---|---|---|---|---|
|
||||
| a catalog graph revision kept | `catalog-revision` | `mesh-catalog`, the indexer | `mesh.seat.mesh-catalog.event.catalog-revision` | the seat's definition in `mesh-delivery-contracts` |
|
||||
| a catalog graph revision kept, saying whether it is a trunk revision or a candidate's | `catalog-revision` | `mesh-catalog`, the indexer | `mesh.seat.mesh-catalog.event.catalog-revision` | the seat's definition in `mesh-delivery-contracts` |
|
||||
| an assignment graph revision kept | `assignment-revision` | `mesh-wants`, the assigner | `mesh.seat.mesh-wants.event.assignment-revision` | the seat's definition in `mesh-delivery-contracts` (ADR 0641 §2) |
|
||||
| a difference worked out | `difference` | `mesh-wants`, the assigner | `mesh.seat.mesh-wants.event.difference` | the same |
|
||||
| an entry taken in | `take-in.taken`, which gains the entries | the indexer's own | `mesh.stream.mesh-delivery-indexer.event.take-in.taken` | the indexer's manifest |
|
||||
@@ -1009,7 +1013,7 @@ on another node's subject is refused by the bus.
|
||||
|
||||
| Line | The assigner | The indexer |
|
||||
|---|---|---|
|
||||
| read everything it holds | `assigner_revision` (one assignment graph revision whole, with the revisions of its inputs), `assigner_revisions` (every kept revision with what pins it, and the store's fill against its cap), `assigner_entry` (one entry, with the seat rule that gave each edge), `assigner_difference` (a change's difference), `assigner_waits` (*Order without a person*), `assigner_candidate_graphs` (every candidate's graphs: its heads, its revisions, since when), `assigner_consumer` (its consumer of the gate's events: the last applied, the waiting), `assigner_puts` (each put with its step, since when, the `running` that ended it, and whether it stands: past its 30 minutes or older than the trunk's newest build) | `indexer_catalog_revision` (one catalog graph revision), `indexer_catalog_revisions` (every kept revision with what pins it, and the store's fill against its cap), `indexer_candidate_graphs` (every candidate's catalog half), `indexer_consumer` (the same as the assigner's) |
|
||||
| read everything it holds | `assigner_revision` (one assignment graph revision whole, with the revisions of its inputs), `assigner_revisions` (every kept revision with what pins it, and the store's fill against its cap), `assigner_entry` (one entry, with the seat rule that gave each edge), `assigner_difference` (a change's difference), `assigner_waits` (*Order without a person*), `assigner_candidate_graphs` (every candidate's graphs: its heads, its revisions, since when), `assigner_consumer` (its consumer of the gate's events: the last applied, the waiting), `assigner_puts` (each put with its step, since when, held or not, the `running` that ended it, and for a put without hold whether it is past its 30-minute bound; a put older than the trunk's newest build of its module said so) | `indexer_catalog_revision` (one catalog graph revision), `indexer_catalog_revisions` (every kept revision with what pins it, and the store's fill against its cap), `indexer_candidate_graphs` (every candidate's catalog half), `indexer_consumer` (the same as the assigner's) |
|
||||
| do by hand what it does itself | `assigner_recompute` (compute a revision again from its named inputs and compare it with the one kept) | `indexer_recompute` (compute a catalog graph revision again from its source revision and compare it with the one kept) |
|
||||
| recover without help | `assigner_drop_candidate_graph` (drop a candidate's graphs whose gate event never came), `assigner_release` (*Order without a person*) | `indexer_drop_candidate_graph` (the same for its half) |
|
||||
| one seat, many tools | `mesh-wants`: `revision`, `entry`, `difference` | `mesh-catalog`: `revision`, beside `seat-definitions` |
|
||||
@@ -1330,7 +1334,9 @@ the gate no longer watches the checker's verdicts for a hold. **Its record is to
|
||||
0548 §2 to §4, §9 and §10, ADR 0551 and ADR 0534 §4's judgement of `mesh/check` by the merge are in force, and ADR
|
||||
0661, which ends the first two and changes the third (proposed, needs the operator's Approve), is to be accepted before
|
||||
milestone G's pull requests are pushed; until it is accepted, the rule below holds as those records have it. ADR 0662
|
||||
is withdrawn; G builds ADR 0661. How it is checked: in the gate's whole-module test an approved merge into a
|
||||
is withdrawn; G builds ADR 0661. Beside it, ADR 0663 (proposed: the indexer answers `revision` in its own runtime to
|
||||
exactly the parts that invoke it, the tool runner among them) is to be accepted before the push too, since the tool
|
||||
runner's first view of the catalog half rests on it (*Every other reader of which modules exist*). How it is checked: in the gate's whole-module test an approved merge into a
|
||||
repository under a running check is handed at once, and the gate's manifest declares no `turns` and no setting
|
||||
`check-gates-merge`; in the checker's, a check claims at once with no gate state granted to read.
|
||||
|
||||
@@ -2084,23 +2090,31 @@ later change of a kept data's form, not as a case of this milestone.
|
||||
pins a want by being forgotten, as a session's puts of a node-engine build did for seven hours on 2026-11-09 (issue
|
||||
1966), and milestone G's one logged put of its own indexer ends by itself.
|
||||
- **Until milestone G, from the have; from G, from `running`.** The issue 1966 recovery ends the put by the read of
|
||||
the node's have the assigner already makes, and keeps that end until G. In G the end moves to the node-engine
|
||||
seat's `running.<node>.<module>` naming the put's fingerprint, which milestone G gives that event, heard through a
|
||||
durable consumer of the assigner's own declared in its `consumes`, the one its composing waits hear too
|
||||
(*Composing waits per node*); from then it never reads the node's have across the seam (ADR 0596 §2). The order is
|
||||
an edge of the module graph: the node-engine that says `running` with its fingerprint before the assigner that
|
||||
ends a put on it.
|
||||
the node's have the assigner already makes, and keeps that end until G. That read crosses the seam against ADR
|
||||
0596 §2, kept on purpose until G, because no `running` event carries a fingerprint before G. In G the end moves
|
||||
to the node-engine seat's `running.<node>.<module>` naming the put's fingerprint, which milestone G gives that
|
||||
event, heard through a durable consumer of the assigner's own declared in its `consumes`, the one its composing
|
||||
waits hear too (*Composing waits per node*); from then it never reads the node's have. A `running` without a
|
||||
fingerprint, as a node-engine from before G says it, ends no put: a put on a node whose node-engine is from before
|
||||
G ends on the first `running` with a fingerprint from that node's new node-engine, which the composing waits move
|
||||
first on that node, and `put-stands` says it meanwhile.
|
||||
- **Ended at once when the node already runs it.** At the put's ask, and at the assigner's start for every put not
|
||||
ended (one written before the upgrade among them), a put ends at once when the last `running` the assigner holds
|
||||
for that node and module names its fingerprint; a put of the running build pins nothing. A `running` naming
|
||||
another fingerprint ends nothing.
|
||||
- **The end is its own step.** The put's end is the step `ended`, written on its key and said as the assigner's
|
||||
event `put`, carrying the fingerprint and the `running` that ended it (or the release that did).
|
||||
- **A put that stands is said.** A put not ended 30 minutes after its want was written, or one older than the
|
||||
trunk's newest build of its module, is said by `assigner_puts` and as the finding `put-stands`, naming the node,
|
||||
the module and the fingerprint, which the condition keeper raises (ADR 0564 §2); it clears when the put ends.
|
||||
Thirty minutes is many times a module's start window and the canary's wait, so a put moving normally raises
|
||||
nothing. How it is checked: test 62.
|
||||
- **The end is a step the put already has.** The put ends with its existing step `done`, or `released` when a
|
||||
release ends it, written on its key and said as the assigner's event `put`, carrying the fingerprint and the
|
||||
`running` that ended it. No new step is added, so a reverted assigner, which knows `done`, `released` and
|
||||
`refused` as ended, never reads an ended put as running.
|
||||
- **A put without hold that stands is said, by the watchman.** When a put without hold has its want written, the
|
||||
assigner says `wait-held` on the seat `mesh-wants` for it (node, module, fingerprint, since when) with a bound of
|
||||
30 minutes, and `wait-ended` when it ends. The watchman times it as it times every wait, and past the bound writes
|
||||
the finding `put-stands`, naming the node, the module and the fingerprint, which the condition keeper raises
|
||||
(ADR 0564 §2) and clears on `wait-ended`; at its own start the watchman seeds its open puts from `assigner_puts`,
|
||||
as it seeds `acting-part-late`, so a put whose assigner stopped after writing its want is still timed. Thirty
|
||||
minutes is many times a module's start window and the canary's wait, so a put moving normally raises nothing. A
|
||||
held put is listed by `assigner_puts` as held, with since when, and raises nothing: holding is what it was asked
|
||||
for. `assigner_puts` also lists a put older than the trunk's newest build of its module. How it is checked: test 62.
|
||||
- **The bus module is wanted like any module; only a warranted want replaces its server** (ADR 0594, changing
|
||||
ADR 0539 §14 and §15, ADR 0546 §8 and ADR 0565 §7 for the bus module). The assigner writes the bus module's want by
|
||||
the same rules as every module's, and the node agent applies what that want brings (its files, its processes' bus
|
||||
@@ -2713,18 +2727,22 @@ What milestone G's prepare found, and its test:
|
||||
names the module (in `meshcatalogclient`'s test and the forge module's); a candidate's `catalog-revision` changes
|
||||
nothing in any reader, and the forge module grants no write before its first view nor from a candidate; the tool
|
||||
runner started before the indexer says it waits, takes no empty view as no modules, raises `view-waits` after five
|
||||
minutes, and once it has its first view keeps answering while the indexer is stopped (each module's existing tests,
|
||||
a row each; whole, tool runner; live, a search of the catalog's and mesh-tools' code and manifests finds no
|
||||
minutes, and once it has its first view keeps answering while the indexer is stopped; the forge module answers
|
||||
`<module>_first_views` with the revision it holds and the one it waits for (each module's existing tests, a row
|
||||
each; whole, tool runner and forge module; live, a search of the catalog's and mesh-tools' code and manifests finds no
|
||||
`indexer_read_modules` and no view `modules`, and after milestone G's first merge that adds a module the status
|
||||
view's `view_reach` and the watchman's manifest findings name it, as the operator sees them).
|
||||
62. **A put without hold ends itself.** A put with `hold` false of a fingerprint the node does not run yet ends on that
|
||||
node's `running` naming its fingerprint, at the step `ended` with the fingerprint and that `running`, and the next
|
||||
pass of the rules writes the want, so a later build is wanted with no `assigner_release`; a `running` of another
|
||||
fingerprint ends nothing; a put of the build the node already runs ends at its ask; a put written before the
|
||||
node's `running` naming its fingerprint, at the step `done` carrying the fingerprint and that `running`, and the
|
||||
next pass of the rules writes the want, so a later build is wanted with no `assigner_release`; a `running` of
|
||||
another fingerprint ends nothing; a `running` without a fingerprint ends no put, and the node's new node-engine's
|
||||
`running` with one ends it; a put of the build the node already runs ends at its ask; a put written before the
|
||||
assigner's start, whose node already runs it, ends at that start; a put whose `running` was said while the
|
||||
assigner was stopped ends after its restart; a put not ended within 30 minutes, and one older than the trunk's
|
||||
newest build, is listed as standing by `assigner_puts` and raises `put-stands`, which clears when it ends;
|
||||
`assigner_release` ends a put without hold; a held put stays until released (whole, assigner; live,
|
||||
assigner was stopped ends after its restart; a reverted assigner reads the ended put as ended; a put without hold
|
||||
not ended 30 minutes after its want says `wait-held` and the watchman raises `put-stands`, which clears on its
|
||||
`wait-ended`, and with the assigner stopped after the want is written `put-stands` is still raised; a held put
|
||||
past 30 minutes raises nothing and is listed by `assigner_puts` as held with since when; `assigner_release` ends a
|
||||
put without hold at the step `released`; a held put stays until released (whole, assigner and watchman; live,
|
||||
`assigner_puts` after milestone G's put of its own indexer).
|
||||
|
||||
## What retires
|
||||
@@ -3016,7 +3034,7 @@ and what answers it:
|
||||
| tools | no fill read; the repair tool's path; the indexer's hand tool; the data set aside at a restore | fill in each read tool; `gate_record_repair` names each owner's verb; `indexer_recompute`; `backed-up` lists it and `discard-aside` removes it |
|
||||
| running qualities | storage that grows without limit; the build module's wait ended two ways; a checking program built per check; the wait clocks; a revert whose assigner starts before its indexer catches up | 90-day records, unpinned revisions removed, entries stored once, caps with `filling`, `full` and `room`; the agreed toolchain; one build per fingerprint; clocks from the build's end, composing per node; the ordering edges of a revert |
|
||||
| testing | a revert test that needed a second check; the view with the assigner down | whole-module revert tests on the real builds from before milestone G; the assigner stopped and a cold control-node |
|
||||
| health and events | waits with no event or bound; a record that never ends; parts waiting for the view unreported; when a wait is first said | `wait-held` at the start with its bound, timed by the watchman; held and failed outcomes and `record-ended`; `view-waits` after five minutes |
|
||||
| health and events | waits with no event or bound; a record that never ends; parts waiting for the view unreported; when a wait is first said; a put that never ends | `wait-held` at the start with its bound, timed by the watchman; held and failed outcomes and `record-ended`; `view-waits` after five minutes; `put-stands`, timed by the watchman from the put's `wait-held` |
|
||||
| security | a checking program hiding a removed rule; forged events; the `run` ask's grant; a kept build overwritten by the program it built; the review line retired before the review verb's grant | the running checker names every change of the checking program's fingerprint; the node in event subjects and grants per account; builds kept only from a step that runs nothing; the review verb left to issue 1782 |
|
||||
| upgrade | a newer indexer never wanted after milestone G; a revert across a change of kept data's form | the stand-in catalog graph revision; restore points taken before a move across a `form` change, restored at a revert before the reverted build starts, the node-engine back last |
|
||||
|
||||
|
||||
Reference in New Issue
Block a user