Say manifest validator, not judge: the operator asked why a new word was needed for the indexer's rules
The glossary gets the entry in the Delivery domain with the records that decide it, and retires the noun in hq's prose on a Not line; the verb stays. Where "judge" named something else, the design now uses that thing's word: the node-engine's look at health, an account or the network; the composition check built from a change; the claude-code module's judgement tool. Five issue narratives keep the word of their day. Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
This commit is contained in:
@@ -28,7 +28,7 @@ field, constant, package or module, the line of that section that places it.
|
||||
|
||||
**Then the work**, as playbook 07's prepare step says: per repository every file and test the change touches,
|
||||
by clause of the record; subtasks of about thirty minutes, one change each, with their acceptance; the test
|
||||
budget (rows in existing tests where a repository is over budget); which parts judge the change (indexer, judge,
|
||||
budget (rows in existing tests where a repository is over budget); which parts judge the change (indexer, manifest validator,
|
||||
checker, builders, grants part, node-engine) and what the running ones accept; for every new state a tool that
|
||||
reads it and for every new behaviour a tool that steers it. Code: read the repositories at `origin/main`
|
||||
(`git fetch`, `git show`, `git grep`), never a working tree.
|
||||
|
||||
@@ -25,7 +25,7 @@ write.
|
||||
What you judge:
|
||||
|
||||
- Security: who may call each new verb, how its grants are scoped (ADR 0363's grant form), which credentials go or remain, what can be replaced or forged (a digest, an author, a tag), what enters from outside the mesh, and every act that removes data.
|
||||
- Upgrade: how what runs today moves to the new shape without a delivery breaking, in which order (mesh-sdk, the grants part, the indexer's judge, the module), what readers see during and after, how each step is rolled back, what a node on an older node-engine does, and bootstrap before the bus.
|
||||
- Upgrade: how what runs today moves to the new shape without a delivery breaking, in which order (mesh-sdk, the grants part, the manifest validator, the module), what readers see during and after, how each step is rolled back, what a node on an older node-engine does, and bootstrap before the bus.
|
||||
|
||||
Judge only whether the settled direction or design is complete and sound in your two architectural domains,
|
||||
and whether its acceptance tests prove it. Never reopen what the operator decided: a finding that would change
|
||||
|
||||
@@ -20,3 +20,8 @@ which keeps a record's words as it was imported.
|
||||
| `04-ISSUES/354-a-decided-rename-was-never-scheduled-and-the-operator-believed-it-live/01-diagnosis.md` | 2027-04-30 | history: the issue's narrative keeps the word of its day, "merge gate" (issue 1303); it is not rewritten |
|
||||
| `04-ISSUES/362-two-merges-seconds-apart-left-their-delivery-waiting-for-a-person/01-diagnosis.md` | 2027-04-30 | history: the issue's narrative keeps the word of its day, "merge gate" (issue 1303); it is not rewritten |
|
||||
| `04-ISSUES/364-the-gate-refuses-a-module-that-uses-a-seat-another-module-declares/00-report.md` | 2027-04-30 | history: the issue's narrative keeps the word of its day, "merge gate" (issue 1303); it is not rewritten |
|
||||
| `04-ISSUES/286-a-merge-check-passed-on-an-agents-machine-and-failed-on-the-build-seat/00-report.md` | 2027-04-30 | history: the issue's narrative keeps the word of its day, "judge" (the composition check's program built from a change; the glossary's manifest validator retired the noun); it is not rewritten |
|
||||
| `04-ISSUES/306-a-check-on-the-control-node-ran-past-its-timeout/01-diagnosis.md` | 2027-04-30 | history: the issue's narrative keeps the word of its day, "judge" (the composition check's program built from a change; the glossary's manifest validator retired the noun); it is not rewritten |
|
||||
| `04-ISSUES/310-a-pull-request-ran-its-own-copy-of-its-check/00-report.md` | 2027-04-30 | history: the issue's narrative keeps the word of its day, "judge" (the composition check's program built from a change; the glossary's manifest validator retired the noun); it is not rewritten |
|
||||
| `04-ISSUES/343-the-controllers-terminal-has-no-command/01-diagnosis.md` | 2027-04-30 | history: the issue's narrative keeps the word of its day, "judge" (a part of the controller's pull request, named so then; the glossary's manifest validator retired the noun); it is not rewritten |
|
||||
| `04-ISSUES/361-the-control-nodes-agent-account-is-never-judged/01-diagnosis.md` | 2027-04-30 | history: the issue's narrative keeps the word of its day, "judge" (the self-check's look at what an account can reach; the glossary's manifest validator retired the noun); it is not rewritten |
|
||||
|
||||
+12
-2
@@ -119,7 +119,7 @@ and repair).
|
||||
seat list's grain (its name, scope, verbs and provision); mesh-sdk's `catalogue` is its one importer in mesh-sdk
|
||||
(ADR 0625 §2, §3).
|
||||
- **contracts marker** — the field `generated-from` of a contracts module's package artifact, naming the directory
|
||||
of the seat definitions its files are generated from; the judge refuses a module carrying it that claims a seat,
|
||||
of the seat definitions its files are generated from; the manifest validator refuses a module carrying it that claims a seat,
|
||||
and the build modules' test step regenerates and compares every module carrying it (design 26).
|
||||
- **package series** — the first two numbers of a package's versions (`0.1`), declared in its manifest and raised
|
||||
only by a reviewed change, for a change that breaks its users; a user's manifest names the package series it
|
||||
@@ -493,7 +493,7 @@ and the operator act. **Recorded by** the controller's `identity` and `licences`
|
||||
back when it fails. The domain is continuous integration and delivery, named **delivery**, and its parts live in
|
||||
the repository `mesh-delivery` (ADR 0429 §2). **Recorded by** the `mesh-delivery` module (deliveries) and the
|
||||
controller (the planner, the rollout) until release 6 of ADR 0429; from each release on, by the parts it builds. **Downstream of** Module, Core, Health and repair and Data.
|
||||
**Decided by** ADR 0162, 0218, 0236, 0237, 0238, 0239, 0250, 0267, 0270, 0276, 0323, 0401–0408, 0428, 0429, 0444–0447, 0524–0530, 0539, 0548, 0551, 0571.
|
||||
**Decided by** ADR 0162, 0218, 0236, 0237, 0238, 0239, 0250, 0267, 0270, 0276, 0323, 0401–0408, 0428, 0429, 0444–0447, 0524–0530, 0539, 0548, 0551, 0571, 0578, 0579, 0593, 0601.
|
||||
**Uses:** module, node, declaration and send (Placement), health (Health and repair), person.
|
||||
|
||||
- **merge check** — what a pull request carries before it may merge, judging the merge of its head into a
|
||||
@@ -661,6 +661,16 @@ controller (the planner, the rollout) until release 6 of ADR 0429; from each rel
|
||||
**status view** (`mesh-delivery-cli` and a web view, writing only its answers to asks and saying the events
|
||||
`delivered`, `moving`, `settled` and `stuck`, derived from the keys). The reviewer is the review
|
||||
agent's session, not a part. Built over releases 1 to 6 of ADR 0429.
|
||||
- **manifest validator** — the indexer's rules that judge each manifest before anything of it reaches a node: strict
|
||||
decoding, the seat and namespace rules, the bus and stream limits and the whole-catalog checks. It refuses a
|
||||
manifest, sets one aside to wait when it uses a field the running validator does not know yet, or accepts it; a
|
||||
manifest it accepted before keeps that verdict when a newer validator finds problems in it, each written as a
|
||||
warning (ADR 0578 §1, ADR 0579 §1, ADR 0601). Its verdict is the indexer's state, and every other part decodes a
|
||||
manifest and takes that verdict, never judging it (ADR 0578 §3). There is one copy, a package of the indexer's
|
||||
module that only the indexer and the checker use, never mesh-sdk's (ADR 0578 §4, ADR 0593 §1): the merge check
|
||||
runs the trunk's in its sandbox over the manifests a change touches, failing only on what the change alters, and
|
||||
a group that changes it runs the one built from its own head (ADR 0578 §2, ADR 0579 §2).
|
||||
*Not:* ~~the judge / a judge / its judge / no judge / judge's / own judge / whose judge / same judge / indexer's judge / trunk's judge / running judge / older judge / newer judge / stricter judge~~ (hq)
|
||||
- **fingerprint** — what identifies a module's build by its content: a hash over its source files, its
|
||||
manifest and the fingerprints of its build-time inputs, so equal content gives an equal fingerprint whatever
|
||||
the commit (ADR 0429 §5). It is today's source fingerprint with a base entering by its module's
|
||||
|
||||
@@ -420,11 +420,11 @@ is a breach the lead names.
|
||||
suite with `MESH_CHECK_BESIDE` naming a directory that holds the catalog's branch, as mesh-controller's
|
||||
`internal/beside` says.
|
||||
**Before the push, every member's suites run as the running checker runs them**: each sibling repository placed
|
||||
beside it by main's beside rules, the node-engine at the commit the machines run, and the running indexer's judge
|
||||
beside it by main's beside rules, the node-engine at the commit the machines run, and the running manifest validator
|
||||
over every manifest the change touches. On 2026-11-02 release sdk1 failed four checks one fault at a time (test
|
||||
globals left set, a sibling placed otherwise, the checker's manifest archive, a composition step the old checker could not
|
||||
build), each of which a run as the checker places things would have shown before the first push. How it is
|
||||
checked: the pull request's description names the placement, the node-engine commit and the judge run used
|
||||
checked: the pull request's description names the placement, the node-engine commit and the manifest validator run used
|
||||
locally; a check that fails on a placement the local run did not use is named by the lead at the next report.
|
||||
2. **The checker's merge check runs the integration tests once, as the gate** (its one status, `mesh/check`). No
|
||||
second review: step 2 reviewed this tree.
|
||||
@@ -444,7 +444,7 @@ is a breach the lead names.
|
||||
which tests run at which level is the build tag's (ADR 0445 §2), and hq's checks are Go tests like any repository's
|
||||
(ADR 0527). The prepare step looks for this: a change to what the checker's build module selects (its recipe, a build
|
||||
tag convention) is cut ahead of the milestone.
|
||||
**The same holds for every part that judges a change**: the checker, the indexer and its judge, the grants part and
|
||||
**The same holds for every part that judges a change**: the checker, the indexer and its manifest validator, the grants part and
|
||||
the build modules. A release that changes one of them is judged by the version that runs, so whatever the running
|
||||
version cannot judge is delivered first as a change of its own, or left out and added back once the new part runs.
|
||||
On 2026-11-02 release sdk1 delivered the build module's relative replaces first, and took the checker's new
|
||||
|
||||
@@ -76,7 +76,7 @@ imports only the contract, never your holder. And a role no other module could e
|
||||
it is your module's own tools and events (ADR 0625 §8).
|
||||
|
||||
*How it is checked:* by the checks design 26 lists: the generators' tests, mesh-sdk's import and package-list tests,
|
||||
the build modules' regenerate-and-compare step, the catalog check of a client and the judge's refusal of a
|
||||
the build modules' regenerate-and-compare step, the catalog check of a client and the manifest validator's refusal of a
|
||||
contracts module that claims a seat; a role made a seat, or a seat left as one module's tools, by the review of the
|
||||
pull request that adds it.
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ code:
|
||||
- mesh-sdk src (the protocol's NATS binding, step 3)
|
||||
- mesh-tools node-tools/internal/bus (a module's state, ADR 0201; the new calls and apply, ADR 0595, ADR 0597)
|
||||
- mesh-sdk (the typed bus-state entry, its binding and the new calls' package, ADR 0595)
|
||||
- mesh-delivery (the judge's rules and the grants part's binding, ADR 0595)
|
||||
- mesh-delivery (the manifest validator's rules and the grants part's binding, ADR 0595)
|
||||
updated: 2026-11-04
|
||||
decisions:
|
||||
- "ADR 0595"
|
||||
@@ -678,7 +678,7 @@ named: six exist, from the uses counted on main (158 state entries, 6 event stre
|
||||
its own only where no template fits: the bare stream, or a ledger whose history expires.
|
||||
|
||||
**What keeps the data safe is fixed, never an option** (ADR 0595 §3). Each template fixes what happens when it is
|
||||
full, and the judge refuses a manifest that gives it:
|
||||
full, and the manifest validator refuses a manifest that gives it:
|
||||
|
||||
| Template | On | Fixed | Options, their bounds (default) |
|
||||
|---|---|---|---|
|
||||
@@ -688,7 +688,7 @@ full, and the judge refuses a manifest that gives it:
|
||||
| log | stream | refuses when full; never rewritten; an entry at most 256 KiB; one subject per key | cap 1 to 8192 MiB (1024); age 1 to 3650 days (none) |
|
||||
| objects | object store | refuses when full; kept for good | cap 1 to 8192 MiB, required; a grant |
|
||||
| ledger | ledger | as log, plus its type and a snapshot per instance; its state and index buckets as state | cap; keeping days only in a ledger's own configuration |
|
||||
| (none: a bare stream) | stream | the module's own subjects; within the mesh's bounds | its own configuration, which must give "when full" (refuse or drop the oldest), a cap of 1 to 8192 MiB and an age of 1 to 3650 days or none, and may give a grant; the judge refuses one missing any of the three |
|
||||
| (none: a bare stream) | stream | the module's own subjects; within the mesh's bounds | its own configuration, which must give "when full" (refuse or drop the oldest), a cap of 1 to 8192 MiB and an age of 1 to 3650 days or none, and may give a grant; the manifest validator refuses one missing any of the three |
|
||||
|
||||
The template log is the **module log** of ADR 0297. The mesh, never the module, names the bus objects and their
|
||||
subjects (ADR 0201 §4): `<module>_<local name>`, and a local name holding the separator is refused so no two
|
||||
@@ -697,7 +697,7 @@ modules' names meet.
|
||||
### 12.2 Who creates it, and how a module receives it
|
||||
|
||||
```
|
||||
indexer's judge ──verdict: accepted, with the module's bus-state entries whole──▶ bus module
|
||||
manifest validator ─verdict: accepted with the module's bus-state entries whole─▶ bus module
|
||||
│ creates each entry
|
||||
▼
|
||||
grants part ◀──────────────── created (module, local name, bus name, template, settings)
|
||||
@@ -706,12 +706,12 @@ modules' names meet.
|
||||
the tool runner reads the membership ──▶ the module's calls reach its own entries, and only those
|
||||
```
|
||||
|
||||
- **The trigger is the judge's verdict** (ADR 0595 §4), heard as the indexer's event `manifest-accepted`, which
|
||||
- **The trigger is the manifest validator's verdict** (ADR 0595 §4), heard as the indexer's event `manifest-accepted`, which
|
||||
carries the module's entries whole, so the bus module never reads the indexer's state and never polls. The indexer
|
||||
says it for every newly accepted manifest, with its entries empty when it asks for none, and the bus module reads an
|
||||
empty one as "this module asks nothing now", which is what its orphans need. A module whose manifest leaves the
|
||||
trunk (its directory deleted) gets an empty `manifest-accepted` too, so its entries reach `orphans` and raise
|
||||
`orphaned`; a manifest the judge set aside to wait gets none, so its entries stay asked. The indexer's tool
|
||||
`orphaned`; a manifest the manifest validator set aside to wait gets none, so its entries stay asked. The indexer's tool
|
||||
`indexer_say_accepted` says `manifest-accepted` again for one module by hand, from the verdict it holds, recorded as a
|
||||
hand act, for a verdict the bus module is thought to have missed. It goes, as every event of the
|
||||
indexer, on the module events stream (ADR 0363) under the indexer's own subjects. A publish of it that fails is
|
||||
@@ -728,8 +728,8 @@ modules' names meet.
|
||||
act. It keeps
|
||||
what it last heard per module in its own state `asked` (an old `state` section, its own kept data staying there,
|
||||
ADR 0595 §10), from which `list`, `check` and `orphans` answer; a key goes only on an empty `manifest-accepted` for
|
||||
the module, never because a manifest the judge set aside to wait is missing from the first view. Then it runs `check` over what it holds, creating what
|
||||
is missing. The judge checks every entry once, at the merge check and at take-in (ADR 0578; ADR 0595 §8), and also
|
||||
the module, never because a manifest the manifest validator set aside to wait is missing from the first view. Then it runs `check` over what it holds, creating what
|
||||
is missing. The manifest validator checks every entry once, at the merge check and at take-in (ADR 0578; ADR 0595 §8), and also
|
||||
each ledger type's operations: a set-entry or a remove names `into` and `key`, `fields` and an index's `on` name
|
||||
fields of the schema, and `digest-of` names a text field.
|
||||
- **A module that asks bus state waits for the bus module** (ADR 0614 §5). Each bus-state entry of a manifest is a
|
||||
@@ -751,7 +751,7 @@ raises that module's condition and leaves the bus module healthy. **Its process
|
||||
no subject on which a tool or a seat's verb is answered (ADR 0436 §3), and no subscription to any restricted
|
||||
stream's own subjects: the snapshot is the one way a restricted stream's data reaches it, kept only in the bus's
|
||||
snapshot store, and the process reads no message of it. No other account holds those subjects, the tool runner's
|
||||
included. **The snapshot account stays as it is** (ADR 0626 §2, § 3 above). **The judge refuses any other bus
|
||||
included. **The snapshot account stays as it is** (ADR 0626 §2, § 3 above). **The manifest validator refuses any other bus
|
||||
declaration of the bus module** (ADR 0626 §3): anything it would say or hear on the bus beyond its process's `bus`
|
||||
and the bus state the foundation keeps on the old sections (ADR 0595 §10), `keeps` on any other process or module,
|
||||
and a `bus` of its process that names a subject on which a tool or a verb is answered.
|
||||
@@ -762,7 +762,7 @@ raises that module's condition and leaves the bus module healthy. **Its process
|
||||
`memberships`, so no part writes another's state and a binding outlives the 7 days its event is kept on the shared stream (§ 12.3).
|
||||
A module whose binding is missing at start fails loudly, naming the entry; it never starts blind. A `refused`
|
||||
create hands no binding. **A refused or overdue creation is loud**: overdue means no `created` or `refused` within
|
||||
five minutes of an accepted verdict that asks for the entry. The condition is raised by the watchman, which today raises the judge's
|
||||
five minutes of an accepted verdict that asks for the entry. The condition is raised by the watchman, which today raises the manifest validator's
|
||||
refusals as findings and gains, through its `consumes`, the accepted verdicts and the seat `mesh-broker`'s `created`
|
||||
and `refused`; never by the bus module, which cannot raise it while it is down; it names the module
|
||||
and the entry; a later `created` clears it, and so does a later accepted verdict of that module that no longer asks
|
||||
@@ -791,9 +791,9 @@ raises that module's condition and leaves the bus module healthy. **Its process
|
||||
never reads the indexer's state; and `assigner_first_views` and `assigner_first_view_again` cover it. A reader declares each in `invokes`
|
||||
as `<module>.<tool>` only where it is granted, which is the grant the grants part composes as for any tool, and
|
||||
each tool checks the proved caller against a `callers` list holding exactly its readers and refuses any other, the
|
||||
owner itself included. **The judge of the milestone is its own group's** (ADR 0621 §4): since no field is added,
|
||||
the running judge takes the indexer's and the assigner's manifests in as it does today, and the merge check judges
|
||||
them with the judge built from the group's own head; no release of the judge goes ahead of the milestone. **The
|
||||
owner itself included. **The manifest validator of the milestone is its own group's** (ADR 0621 §4): since no field is added,
|
||||
the running manifest validator takes the indexer's and the assigner's manifests in as it does today, and the merge check judges
|
||||
them with the manifest validator built from the group's own head; no release of the manifest validator goes ahead of the milestone. **The
|
||||
owner's runtime answers before any first view of its own** (ADR 0621 §3): at once from its module's own state, as
|
||||
soon as it is connected and before it has asked any other part anything, with the revision of its state it answered at,
|
||||
so the indexer and the assigner, each asking the other at start, never wait on each other (§4). The reader then
|
||||
@@ -878,7 +878,7 @@ the fill (count, bytes, the cap); `drop` and `recreate` carry the warrant and wh
|
||||
| `list` | every entry, its template, its settings, its fill against its cap | any caller whose role grants it (ADR 0386) |
|
||||
| `show` | one entry, the same | the same |
|
||||
| `check` | compares what the bus holds with what was asked, entry by entry | the same |
|
||||
| `orphans` | entries the bus holds that no manifest asks for; never one whose manifest the judge refused or outgrew, nor one of the foundation's old sections | the same |
|
||||
| `orphans` | entries the bus holds that no manifest asks for; never one whose manifest the manifest validator refused or outgrew, nor one of the foundation's old sections | the same |
|
||||
| `create` | creates one entry now, for an entry an accepted manifest asks for | an act of the bus module's process alone, answered on no subject |
|
||||
| `apply` | applies a difference that only grows: a larger cap, a longer age | the same |
|
||||
| `recreate` | rebuilds an entry whose settings differ in a way that cannot grow, from its data where the storage type allows | the same, on the operator's warrant, which the process verifies itself |
|
||||
@@ -1021,7 +1021,7 @@ packages change once for the typed `requires` entry and the binding, rebuilding
|
||||
### 12.6 The move, and the order of the build
|
||||
|
||||
**The build, each step undoable on its own** (ADR 0595 §10): (1) mesh-sdk's typed `requires`, binding and calls
|
||||
package; (2) the judge's rules; (3) the bus module's process, verbs and events, creating only for the new form, with the grants part's writing of
|
||||
package; (2) the manifest validator's rules; (3) the bus module's process, verbs and events, creating only for the new form, with the grants part's writing of
|
||||
the binding on `created`; (4) the tool runner's calls, the ledger's `apply` and its ledger credential among them; (5)
|
||||
modules move, each owner first. Each undo: undoing step 2 refuses the new form again, which no module uses before
|
||||
step 5; undoing step 3 leaves what it created in place, and a module moved after it fails loudly on its missing
|
||||
@@ -1034,7 +1034,7 @@ left to the build of step 4 and tracked on issue 1966.
|
||||
as options, so its bus objects and data stay and no drift is raised. It asks for each entry once: an old section
|
||||
and the new form are never both used for one local name. During the move the grants part keeps creating the old
|
||||
sections' entries, so each entry has one creator. The indexer counts the modules on each old section, a tool reads
|
||||
the count, and the judge refuses a section once its count is 0. The foundation's own kept data (the bus module's,
|
||||
the count, and the manifest validator refuses a section once its count is 0. The foundation's own kept data (the bus module's,
|
||||
the grants part's and the indexer's) stays on the old sections for good and is not counted: those modules cannot
|
||||
wait for a process that needs them first. ADR 0619, extending ADR 0595 §10's foundation, adds the parts the bus module's own composition, placement, build or delivery needs before it can answer:
|
||||
the assigner, the tool runner, the builder, the checker, mesh-config and the vault; their new state and streams of
|
||||
@@ -1053,7 +1053,7 @@ a review reading an owner delivered (ADR 0615 §2). The status view's move keeps
|
||||
asking the owners' read tools of § 12.2. **The node-engine's reads granted in code stay**: the grants part's code
|
||||
grants each node's node-engine, with no manifest declaring them (`CandidateReads` and the composed reads beside it),
|
||||
the indexer's `candidates` and `verdicts` and its own node's keys of the assigner's `wants`. They are not among the
|
||||
23 readers of ADR 0615 §1 and move in the next milestone, queued on issue 1966. The judge still refuses a moved module's subscription to an event
|
||||
23 readers of ADR 0615 §1 and move in the next milestone, queued on issue 1966. The manifest validator still refuses a moved module's subscription to an event
|
||||
its owner does not declare. Every other reader moves when its module is next touched. These moves are tracked by
|
||||
issue 1966.
|
||||
|
||||
@@ -1061,17 +1061,17 @@ issue 1966.
|
||||
|
||||
| Rule | Checked by |
|
||||
|---|---|
|
||||
| A manifest's bus state is valid, once | the judge's unit tests, each refusal naming the field: an unknown template, an option outside its bound, past values 0, "when full" given, a fixed setting given, a name used twice across storage types, two modules' bus names alike, a `reads` in the new form, an effect outside the fixed set (ADR 0595 §8, ADR 0596 §2, ADR 0597 §2) |
|
||||
| A manifest's bus state is valid, once | the manifest validator's unit tests, each refusal naming the field: an unknown template, an option outside its bound, past values 0, "when full" given, a fixed setting given, a name used twice across storage types, two modules' bus names alike, a `reads` in the new form, an effect outside the fixed set (ADR 0595 §8, ADR 0596 §2, ADR 0597 §2) |
|
||||
| The bus module creates, and the binding follows | live, by tool call: a module asking for a state, a log, objects and a ledger in `requires` receives each binding in its membership, written after `created`, never before; `show` gives each entry's template, settings and fill; a module calling `create` is refused |
|
||||
| The bus module runs whole | one integration test in the nats module's repository that starts the bus module whole against the real bus server: a verdict, then `created`, then the binding in the membership; a restart that catches up a verdict given while it was down; a bucket whose settings differ raises `drifted`, the seat's `apply` of a larger cap clears it with `drift-cleared`; a refused create raises its condition and hands no binding; the process connects on its own process account, composed by the grants part with that account's grants and limits, never on an account without them; a `create` handed through `requests` is answered on the same key, which the tool watches; `recreate` and `drop` without the operator's warrant are refused, and a warranted `drop`, its warrant read from the operator channel's own record of the ask under the process's account and never from a stand-in, takes the entry's stream snapshot before it deletes, and acts within seconds of the bus module's `decided`, with no timer between; the same warrant handed in a second request is refused and deletes nothing; each event said is on `mesh.seat.mesh-broker.event.<event>` and appended to the bus module's history stream, and `history` reads it back; an orphan is listed, raises `orphaned`, and goes only by `drop`; each template at a small cap refuses, events drop the oldest, and `full` is raised at the raise mark and cleared only below the clear mark; `recreated` rewrites the binding and `dropped` removes it; at start the first view from `indexer_bus_state` creates what a verdict given while it was down asked; the older remove tools refuse a new-form entry, naming `drop`'s tool |
|
||||
| A module asking bus state waits for the bus module | the module graph's table test: a manifest with a ledger entry has a requirement edge to the module providing `bus-state`, one without has none (ADR 0614 §5) |
|
||||
| A foundation part's first view | unit tests of each owner and reader (ADR 0615's How it is checked), as table cases, and these cases of the whole-module integration tests that exist today (mesh-delivery is over its integration budget, so no new test function): the indexer's (`modules/mesh-delivery-indexer`, its one whole-module test, which the milestone's packages test merges into), the assigner's (`modules/mesh-delivery-assigner`) and the grants part's (`modules/mesh-grants`), and the tool runner's in mesh-tools: the owner answers its verb at once from what it holds, with its revision, before its own first view; the reader asks once at start, then only on a gap in revisions; a reader whose owner is down raises its condition only past the bound and never reads the owner's state, and the owner's answer clears it; an empty answer at revision 0 drops no login; an owner's event carries the changed value whole, and a reader applies a put and a delete from the events alone and never asks the verb; a revision lower than the one held makes the reader ask its first view again; an existing waiter on `manifest-accepted` or on the assigner's `put` does not wake on the new families; for the indexer's `verdicts` (ADR 0622), called by the grants part while the node's tool runner is stopped, it answers, and from any other account, the indexer's own included, it is refused; a missed revision on `manifest-refused` makes the grants part ask `verdicts` once more; the grants part and the indexer started at the same moment, `verdicts` answers within the bound with its revision; with the indexer down past the bound the grants part raises the condition naming the indexer and `verdicts` and never reads the indexer's state, and the answer clears it; for the indexer's `graph` (ADR 0631), called by the assigner it answers with its revision, and from any other account, the indexer's own included, it is refused; a missed revision of the bucket `graph` on `indexer.views` makes the assigner ask `graph` once more; started with the indexer down, the assigner raises past the bound the first-view condition naming the indexer and `graph` and reads nothing of the indexer's state, and the answer clears it; the read tool shows the revision each reader holds, and the re-read tool asks once and records the hand act; in the assigner's whole-module test, the assigner starts before any new-form bus state exists, with no binding of the bus module, and the indexer, the grants part and the tool runner each get their first view of it. Live, after the delivery: the indexer's `indexer_old_sections`, which the milestone extends to count the `reads` entries on each owner's state, reads 0 declared `reads` entries on the indexer's state and 0 on the assigner's, and says the node-engine's reads granted in the grants part's code remain (§ 12.6); and each owner's read tool of § 12.2 answers what its bucket holds, each status view tool answers a session's call as before the move, and `mesh_search` finds each owner's read tool |
|
||||
| The owners' first views are their own tools, in a runtime of their own (ADR 0621) | cases of the indexer's and the assigner's whole-module integration tests: each first-view tool, called from a reader's account while the node's tool runner is stopped, answers (§1); each answers its granted readers and refuses every other account, the owner's own included (§2); the two runtimes started at the same moment, each asking the other's first view at start, both answer within the first-view bound with their revisions (§3); and the milestone's group passes its merge check with no change to the judge's known fields for these verbs (§4) |
|
||||
| The owners' first views are their own tools, in a runtime of their own (ADR 0621) | cases of the indexer's and the assigner's whole-module integration tests: each first-view tool, called from a reader's account while the node's tool runner is stopped, answers (§1); each answers its granted readers and refuses every other account, the owner's own included (§2); the two runtimes started at the same moment, each asking the other's first view at start, both answer within the first-view bound with their revisions (§3); and the milestone's group passes its merge check with no change to the manifest validator's known fields for these verbs (§4) |
|
||||
| A foundation part's first view comes within its bound | live, after the delivery: each reader's read tool (`grants_first_views`, the mesh MCP server's `mesh_first_views`, `indexer_first_views`, `assigner_first_views`) shows, for the indexer's and the assigner's verbs, the time from its ask to the owner's answer under the two-minute bound, and no first-view condition raised by the delivery |
|
||||
| The bus module's first view | cases in the nats module's one integration test: a replayed verdict older than the first view is not applied; an `indexer_bus_state` that does not answer turns the health unhealthy naming it and is asked again on the backoff; a set-aside manifest missing from the first view keeps its `asked` key, an empty `manifest-accepted` removes it; a deleted module's entry, after its empty `manifest-accepted`, is listed by `orphans` and raises `orphaned`, and a set-aside module's entry is neither; `nats_first_view_again` asks at once and records the hand act |
|
||||
| `manifest-accepted` is never lost silently | unit tests of the indexer: a failed publish is published again, and one still failing writes the finding; `indexer_say_accepted` says it again for one module from the verdict held, and refuses a module with no accepted verdict |
|
||||
| A person's request goes through `requests`, and the process verifies the warrant itself and acts on it once (ADR 0626 §4, ADR 0259 §6) | the process's unit tests: a `recreate` and a `drop` written to `requests` with no warrant, with a warrant for another act or entry, with a warrant the operator channel's record does not hold, and with a warrant whose ask id the process already acted on are each refused, delete nothing and say why; a `create` or the seat's `apply` for an entry no accepted manifest asks for is refused; the stamp is the caller the tool runner proved, whatever the request's body names |
|
||||
| The process's account, and the bus module's only bus declaration (ADR 0626 §1 to §3) | the judge's unit test: the bus module's manifest with its process's `bus` and `keeps` is accepted; `keeps` on any other process or module, any other bus declaration of the bus module, and a subject of its process on which a tool is answered are refused; the composition test: the process is granted the create, update, delete and snapshot subjects under modules' names, nothing on which a tool or a verb is answered, and no subscription to a restricted stream's subjects beyond the snapshot request, its acknowledgements and its inbox; the snapshot account is granted the same subjects as before; no tool runner and no tool of the bus module holds the bus's create, update or delete subjects |
|
||||
| The process's account, and the bus module's only bus declaration (ADR 0626 §1 to §3) | the manifest validator's unit test: the bus module's manifest with its process's `bus` and `keeps` is accepted; `keeps` on any other process or module, any other bus declaration of the bus module, and a subject of its process on which a tool is answered are refused; the composition test: the process is granted the create, update, delete and snapshot subjects under modules' names, nothing on which a tool or a verb is answered, and no subscription to a restricted stream's subjects beyond the snapshot request, its acknowledgements and its inbox; the snapshot account is granted the same subjects as before; no tool runner and no tool of the bus module holds the bus's create, update or delete subjects |
|
||||
| The process's fixes of review round 1 hold | the nats module's whole-module integration test and unit rows: an event or condition the bus did not take is kept, named by the health tool and said again at the next fill pass; a second accepted manifest asking for an entry raises no overdue condition; the warrant's wake on `decided` acts within seconds without a call to the pass by the test; a second request naming a spent ask is refused naming the act it spent; an ask past 12 hours is not acted on |
|
||||
| Drift and orphans, live | live, made only by a manifest change: a manifest that shrinks a setting raises `drifted`; the conditions clear as above. Nothing is filled on the live bus, and no orphan is made there |
|
||||
| Overdue and stopped are loud | live, carried by the change of the first module that moves in step 5, never by a merge made for the test alone: with the bus module's process stopped, an accepted manifest asking for an entry raises the overdue condition within five minutes, from the watchman, and a later `created` clears it; the bus module's health turns unhealthy when its pass is more than three minutes old |
|
||||
@@ -1080,12 +1080,12 @@ issue 1966.
|
||||
| Only the owner reaches its data | live: another module's account reading an entry in the new form, a ledger's history, snapshot or state among them, is refused; a raw publish on a ledger's history is refused |
|
||||
| The ledger keeps its promises | one integration test against the real bus (ADR 0597's How it is checked): two writers race and one is refused; two interleaved applies leave the state at the higher sequence; a write cut between history and state is repaired; a full state bucket answers taken with its sequence and catches up; an idle instance whose operations expired rebuilds from its snapshot; `rebuild`, `reindex` and `lag` repair by hand; a forged author is refused; every `apply` leaves the snapshot equal to the state; an index behind raises its condition and `reindex` clears it |
|
||||
| Only the owner applies | the ledger's integration test: another module's ledger `apply` on the knowledge base's ledger is refused |
|
||||
| A bare stream is complete | the judge's unit test: a bare stream missing "when full", a cap or an age is refused, naming the field |
|
||||
| A bare stream is complete | the manifest validator's unit test: a bare stream missing "when full", a cap or an age is refused, naming the field |
|
||||
| The calls rebuild only their users | a read of the delivery plan: only the importers of the calls package rebuild when it changes |
|
||||
| The move keeps data | live: a module moved from `state` keeps its bucket and data and raises no drift; a new entry in an old section is still created by the grants part; the count falls by one; at 0 a manifest using the section is refused and the foundation's are still accepted; a moved module is held off a machine whose tool runner does not read the typed binding |
|
||||
|
||||
**The test budget** (50 integration and 500 unit tests per repository): the design adds one integration test in the
|
||||
nats module's repository and one in mesh-tools (the ledger), and table cases, not new functions, to the judge's unit
|
||||
nats module's repository and one in mesh-tools (the ledger), and table cases, not new functions, to the manifest validator's unit
|
||||
tests in mesh-delivery and to mesh-sdk's decoding tests. Each repository's count against the budget is read in the
|
||||
prepare step of issue 1966, and a repository over it merges tests to stay within it.
|
||||
|
||||
|
||||
@@ -230,7 +230,7 @@ adds verbs or events to, and `node-engine` are the first ten defined whole this
|
||||
nothing a reader sees (ADR 0613 §2). Its messages, events and state layouts are added to
|
||||
a seat's definition when its domain's contract next changes, which moves that domain's seats whole into its contracts
|
||||
module in that change (ADR 0613 §3); which domain moves when is tracked by issue 167 (ADR 0613 §4).
|
||||
- **The seat set has one source.** The judge, the node-engine, the tool runner and claude-code each compile a copy of
|
||||
- **The seat set has one source.** The manifest validator, the node-engine, the tool runner and claude-code each compile a copy of
|
||||
the seat list today; all four import the seat-set package generated in `mesh-contracts` instead, which is where
|
||||
mesh-sdk's seat list moves (ADR 0625 §2), and mesh-sdk's `catalogue` reads the seat set from there. The tool runner's descriptions
|
||||
and claude-code keep that compiled set, equal to the trunk's definition, in this milestone, so neither depends on
|
||||
@@ -265,7 +265,7 @@ adds verbs or events to, and `node-engine` are the first ten defined whole this
|
||||
(the generated types out of step).
|
||||
- **Contracts modules.** A seat's contract is published by a contracts module, which holds the seats' contracts and
|
||||
their client packages and no seat (ADR 0625 §4, §5); the seat's holder implements the contract. **The contracts marker**: a contracts
|
||||
module's package artifact names the directory of its definitions in the field `generated-from`, and the judge
|
||||
module's package artifact names the directory of its definitions in the field `generated-from`, and the manifest validator
|
||||
refuses a module carrying it that claims a seat, naming the seat. `mesh-contracts` declares its packages in Go and
|
||||
TypeScript, cut per seat as *Where a seat's code goes* says, in package series `0.1`, published through the two
|
||||
package seats (design 51) and taken by its users by version, or inside one delivery group by the group's head. No
|
||||
@@ -355,13 +355,13 @@ domain; mesh-sdk keeps what every module shares.
|
||||
|
||||
| Rule | Checked by |
|
||||
|---|---|
|
||||
| One package per seat defined whole, one seat-set package | a unit test of the generator (one program in the Go build module, emitting both languages and run by the Node build module too) emitting one package per seat defined whole and one seat-set package; the generator refuses a seat marked whole in the seat set without its own package; the judge refuses a contracts module whose package holds the generated files of two seats defined whole, naming them |
|
||||
| One package per seat defined whole, one seat-set package | a unit test of the generator (one program in the Go build module, emitting both languages and run by the Node build module too) emitting one package per seat defined whole and one seat-set package; the generator refuses a seat marked whole in the seat set without its own package; the manifest validator refuses a contracts module whose package holds the generated files of two seats defined whole, naming them |
|
||||
| The imports run one way | a mesh-sdk unit test that no package but `catalogue` imports a contracts module, and `catalogue` only the seat-set package; the generator tests check no generated package imports mesh-sdk |
|
||||
| mesh-sdk holds no logic over the seven seats | mesh-sdk's package-list test refuses by name `asks`, the vault's types and its shared calls, the compose-candidate checks and any seat-named publish code, and refuses the seven seats' names in mesh-sdk outside `catalogue`, so a copy kept without importing a contract fails too |
|
||||
| A client uses only its own seat's contract | the catalog check of a client: its own test refuses a client importing another seat's client and one naming a module's tool or subject, and passes the seven clients |
|
||||
| The parts transfer is seat-neutral | its unit test runs both sides against two different subjects and shapes the caller gives, and the seat-name check holds it seat-neutral; the review refuses a holder that takes parts in without it |
|
||||
| Only a client is written by hand in a published package | each build module's regenerate-and-compare test fails on a hand-written file outside a client package and passes a contracts module holding its definitions and fixtures |
|
||||
| A contracts module holds no seat; a role only one module could ever play has none | the judge's refusal of a contracts module that claims a seat; review both ways: a new seat definition's pull request is asked whether another module could take the role over, and a module's pull request is asked the same of each new tool or event family other modules call |
|
||||
| A contracts module holds no seat; a role only one module could ever play has none | the manifest validator's refusal of a contracts module that claims a seat; review both ways: a new seat definition's pull request is asked whether another module could take the role over, and a module's pull request is asked the same of each new tool or event family other modules call |
|
||||
|
||||
Acceptance tests: research 081's 14, 21, 25 and 26; a unit test that the generated seat set equals the seat list
|
||||
mesh-sdk compiled before the move, entry for entry; mesh-sdk's seat-naming test; each build module's compare step
|
||||
|
||||
@@ -295,26 +295,26 @@ replaced by one form, a **provision** of the bus module, as a database is postgr
|
||||
(state, events, work queue, log, objects, ledger) and the template's options, within their bounds; a ledger also
|
||||
names its type (its schema, its operations each with its ledger effect, its indexes). The templates, their fixed
|
||||
settings and their options are [design 25](25-the-bus-on-nats.md) § 12.1. mesh-sdk's catalog package carries the
|
||||
entry's type and its strict decoding; every rule that judges it lives in the indexer's judge (ADR 0595 §8).
|
||||
entry's type and its strict decoding; every rule that judges it lives in the manifest validator (ADR 0595 §8).
|
||||
- **The binding is what the module receives**: the names on the bus for each local name, written into its
|
||||
membership by the grants part once the bus module says `created` (design 25 § 12.2). The module still names only
|
||||
locally (§ 1). A module whose binding is missing at start fails loudly, naming the entry.
|
||||
- **One name, one form.** A module asks for each entry once: an old section and the new form are never both used for
|
||||
one local name, and one name serves one storage type only.
|
||||
- **No readers.** The new form has no `reads`, and the judge refuses one (ADR 0596 §2). Only the owner's account
|
||||
- **No readers.** The new form has no `reads`, and the manifest validator refuses one (ADR 0596 §2). Only the owner's account
|
||||
reaches its bus state. **A module's events are subscribed to; its data is asked for**: what another module needs
|
||||
of a module's kept data it asks through that module's tools or seat verbs (§ 4's tool relationship, `serves`),
|
||||
and what a module lets others hear is its declared events, heard through `consumes` (ADR 0363, unchanged; ADR 0596
|
||||
§1). A bucket's layout is never a contract another module depends on; a tool or a declared event is.
|
||||
- **A state may be read-only to the module's tools.** A state's declaration may carry `read-only: true`: only the
|
||||
processes of the module whose `bus.state` names that state write it, and the module's tools read it, holding no
|
||||
publish on its subjects. The judge refuses a read-only state that no process of the module names. How it is checked:
|
||||
the judge's unit tests for the refusal, and the composition test that a tools bundle's account holds a read on the
|
||||
publish on its subjects. The manifest validator refuses a read-only state that no process of the module names. How it is checked:
|
||||
the manifest validator's unit tests for the refusal, and the composition test that a tools bundle's account holds a read on the
|
||||
state and no write. The bus module's state `spent` (design 25 § 12.3) is the first user. (A design limit of the
|
||||
milestone's review; no record decides it yet.)
|
||||
- **The move is a module at a time** (ADR 0595 §11, ADR 0596 §3), each when it is next touched, keeping its local
|
||||
names and its old settings as options so its data stays. A reader moves after its owner: the owner declares the
|
||||
event or gains the tool its readers need first, and the judge refuses a moved module's subscription to an event
|
||||
event or gains the tool its readers need first, and the manifest validator refuses a moved module's subscription to an event
|
||||
its owner does not declare. An old section is refused once no module but the foundation's uses it.
|
||||
|
||||
What follows for the paragraphs above: for a module that has moved, ADR 0201 §2 (another module's state read by
|
||||
@@ -492,7 +492,7 @@ complete, because a team that believes it is complete stops reviewing for the ca
|
||||
Go package by the module path of its `go.mod`, a TypeScript package by the name in its `package.json`. The
|
||||
indexer reads that name at each merge, the builder numbers the package under it, the package's registry seat
|
||||
publishes it under it, and a user's `packages` names it so. One name per package across the mesh, because the
|
||||
language's own tools fetch by that name and no other. How it is checked: the judge refuses a name in `packages`
|
||||
language's own tools fetch by that name and no other. How it is checked: the manifest validator refuses a name in `packages`
|
||||
that no package of the shelf is named, or that a member of the change's delivery group does not name at its head.
|
||||
- **Raising a package series** is a reviewed change of the package's manifest, for a change that breaks its users.
|
||||
The checker's verdict names every change of a package series it sees, so the review of the change sees it.
|
||||
@@ -508,9 +508,9 @@ complete, because a team that believes it is complete stops reviewing for the ca
|
||||
condition tells the operator. A group's members are built in the group's check, against the group's tagged version.
|
||||
- **A contracts module's package** names the directory of the seat definitions it is generated from in the field
|
||||
`generated-from`, the contracts marker (design 26).
|
||||
- **The judge reads the new words** (ADR 0578 §1): each package series well formed and only on the four kinds that may
|
||||
- **The manifest validator reads the new words** (ADR 0578 §1): each package series well formed and only on the four kinds that may
|
||||
carry it, a package naming `go` or `typescript`, and each name in `packages` a package some manifest declares. A
|
||||
running judge that does not know a word sets the manifest aside to wait, never refuses it, while a newer indexer
|
||||
running manifest validator that does not know a word sets the manifest aside to wait, never refuses it, while a newer indexer
|
||||
build is merged and not yet delivered; and a node-engine is handed a manifest using these words only once it
|
||||
states the capability to read them (ADR 0614 §4).
|
||||
- **Cost**: the new manifest fields are read through mesh-sdk's manifest types, so their change rebuilds every module
|
||||
@@ -776,7 +776,7 @@ billing existing under that name.
|
||||
- **A module reaches only the state it declared.** The composer's test: an owner's runtime may write
|
||||
its buckets, a reader's may only read, and nothing else is granted; the runtime's test over a real
|
||||
bus: a name not issued and a reader's write are refused with the reason.
|
||||
- **Bus state is asked for once, in one form, and read by its owner alone** (ADR 0595 §8, ADR 0596). The judge's
|
||||
- **Bus state is asked for once, in one form, and read by its owner alone** (ADR 0595 §8, ADR 0596). The manifest validator's
|
||||
unit tests: a `reads` in the new form, a local name used twice across storage types or in an old section and the
|
||||
new form, an unknown template and an option outside its bound are each refused, naming the field. Live: a moved
|
||||
module receives its binding after `created`; another module's account reading its entries is refused; a moved
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
layer: to-be
|
||||
status: in-progress
|
||||
code: [mesh-host, mesh-controller, mesh-catalog]
|
||||
updated: 2026-10-16
|
||||
updated: 2026-11-04
|
||||
decisions:
|
||||
- "ADR 0394"
|
||||
- "ADR 0310"
|
||||
@@ -262,7 +262,7 @@ group**: the lighting daemon's, the container runtime's, a serial port's. It dec
|
||||
│
|
||||
node-engine usermod --append ── recorded on openrazer.account: "the mesh added openrazer"
|
||||
│
|
||||
account judge database lists it? ── running manager holds it? ── no: relogin needed
|
||||
account look database lists it? ── running manager holds it? ── no: relogin needed
|
||||
│ (module openrazer, kind account)
|
||||
controller module.openrazer.<machine>.unhealthy, cleared on the first look after a new login
|
||||
```
|
||||
@@ -280,7 +280,7 @@ group**: the lighting daemon's, the container runtime's, a serial port's. It dec
|
||||
when the resource is undeclared, is given back. It is not given back while another declared resource
|
||||
asks for it. The account is taken out of that one group (`gpasswd --delete`), read back, and a failure
|
||||
is said and is not fatal, as giving back a shell is (WP1).
|
||||
- **The node-engine, looking.** An account judge sits beside liveness and the failed-unit reading
|
||||
- **The node-engine, looking.** An account look sits beside liveness and the failed-unit reading
|
||||
(issue 315). On every look it reads, for each account a module puts in groups, the database's groups
|
||||
and the groups of the account's running manager, from that process's status file. It states each as the
|
||||
module's resource of kind `account`: healthy, or unhealthy with *not in the group* or *relogin needed*.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
layer: to-be
|
||||
status: in-progress
|
||||
code: [mesh-controller, mesh-host, mesh-tools, mesh-catalog, mesh-sdk, mesh-lab]
|
||||
updated: 2026-10-14
|
||||
updated: 2026-11-04
|
||||
decisions:
|
||||
- "ADR 0357"
|
||||
- "ADR 0325"
|
||||
@@ -931,7 +931,7 @@ and "the commit is the build at hand"), on branches, not yet merged:
|
||||
|
||||
| Repository | Delivers |
|
||||
|---|---|
|
||||
| mesh-controller | the planner's one mapping of a changed file onto modules and its one answer of a merge's reach, asked by the merge handler, the what-if, the gate and the check; a file no build reads touches nothing (issue 280's *left open*); every pull request answered — the gate when it reaches a module, the repository's own check for the mesh's repositories, a pass that says so otherwise; the gate run by the build seat with its judge chosen from the graph, composing the plan's definitions only, failing only a manifest problem the change brings; the delivery plan computed and carried with the verdict; a build of a commit off its module's trunk recorded and never registered; its own manifest naming every verb of its seat |
|
||||
| mesh-controller | the planner's one mapping of a changed file onto modules and its one answer of a merge's reach, asked by the merge handler, the what-if, the gate and the check; a file no build reads touches nothing (issue 280's *left open*); every pull request answered — the gate when it reaches a module, the repository's own check for the mesh's repositories, a pass that says so otherwise; the gate run by the build seat with the program it composes with chosen from the graph, composing the plan's definitions only, failing only a manifest problem the change brings; the delivery plan computed and carried with the verdict; a build of a commit off its module's trunk recorded and never registered; its own manifest naming every verb of its seat |
|
||||
| mesh-catalog | the forge's announcer saying, with every pull request, the directories holding a module at its head, the files it deletes and whether it has a `merge-check.sh`; both statuses and the delivery plan on the pull request; `gitea_branch_protection_get` and `gitea_branch_protection_set`; the catalog's own check |
|
||||
| `mesh-host`, mesh-tools, mesh-sdk, mesh-lab, mesh-media-catalog, and the applications built from their own repositories | each its own `merge-check.sh`; mesh-tools' tests each on a bus of their own |
|
||||
| mesh-tools-go, mesh-tools | a C compiler and Python in the Go toolchain, git in the TypeScript one |
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
layer: to-be
|
||||
status: in-progress
|
||||
code: [mesh-controller, mesh-catalog modules/mesh-delivery-gate, mesh-delivery, mesh-host, mesh-sdk, mesh-vault, hq 00-META/checks]
|
||||
updated: 2026-11-03
|
||||
updated: 2026-11-04
|
||||
decisions:
|
||||
- "ADR 0594"
|
||||
- "ADR 0572"
|
||||
@@ -592,7 +592,7 @@ From its delivery, a check is this:
|
||||
providers it alters; for a group, once over every member's change, read from the indexer's candidates of the
|
||||
group, and while the indexer holds none the group's check waits and says why. It composes with the function
|
||||
every node agent composes with, mesh-sdk's composition, so the two agree for one mesh-sdk version; its verdict
|
||||
names the mesh-sdk version it composed with. No judge is built from a change: a change to the
|
||||
names the mesh-sdk version it composed with. No composition check is built from a change: a change to the
|
||||
composition is proved by its own tests, a field only a newer composition reads goes out as optional first, and
|
||||
the running composition refuses a manifest that uses a field it does not read, naming the field. What it fails on, and its warning past twelve rebuilt modules, are the composition check's, as they were the controller's composition check's (ADR 0446, ADR 0237 §2).
|
||||
The assigner writes the verdict under the checker's hash of the heads it judged, in its own bucket, and the checker reads it into the
|
||||
@@ -913,9 +913,9 @@ and `delivered` events.
|
||||
- **Builds and tests run directly**, as the build module's own account on its node, in no container. The
|
||||
build module of each module's language runs its tests by that language's convention; no repository's
|
||||
script or toolchain line decides it, hq's included (ADR 0527).
|
||||
- **A judge has an account of its own, until release 4 is delivered (R4f).** Until then, a judge built from a sibling's
|
||||
- **A composition check built from a change has an account of its own, until release 4 is delivered (R4f).** Until then, one built from a sibling's
|
||||
merge (ADR 0382 §3) is built and run as a second account of the Go build module, whose home, configuration and
|
||||
cache the build seat's account cannot write, so a check's script cannot change it. From R4f no judge is
|
||||
cache the build seat's account cannot write, so a check's script cannot change it. From R4f no composition check is
|
||||
built from a change and the account is not made (ADR 0446 §5).
|
||||
- **A module may ship its own Dockerfile.** A build module of its own builds the module's `image` artifact from it, rootless, with no root and no container runtime socket on the build node; a pull request's image is built and thrown away, and only a merged trunk commit's image reaches the registry, by digest. From R4g that module is the only part that builds an image, and build-agent builds none (ADR 0487 §7, ADR 0524 §5); the other builds
|
||||
are Go and Node programs, which their build modules build.
|
||||
@@ -1187,7 +1187,7 @@ From ADR 0548 and ADR 0551 (issue 568):
|
||||
|
||||
## What retires
|
||||
|
||||
- The "release branches" and the controller's judge of them (ADR 0358, superseded by ADR 0401).
|
||||
- The "release branches" and the controller's check of them (ADR 0358, superseded by ADR 0401).
|
||||
- The toolchain image and its module (ADR 0405).
|
||||
- The window cutter, the merge catch-up timer, the rollout ticker, mesh-delivery's tick, reconcile and
|
||||
ready-mark poll, the forge's poll as a trigger, the queue reordering, the forge-asking cancel, and the forge
|
||||
@@ -1207,9 +1207,9 @@ From ADR 0548 and ADR 0551 (issue 568):
|
||||
group's merges (ADR 0418 §1, §5, §6).
|
||||
- The controller's tables of builds, build requests, rollouts and their tiers, batches and merges, and
|
||||
assignments; the record mirrors, probe D17's audit and healer H6 for those kinds (ADR 0408).
|
||||
- At release 4's deliveries (R4f for the composition check, the judge and the two statuses; R4g for the scripts): `merge-check.sh` and its `# mesh-check-toolchain` line in every repository a module is
|
||||
- At release 4's deliveries (R4f for the composition check, the one built from a change and the two statuses; R4g for the scripts): `merge-check.sh` and its `# mesh-check-toolchain` line in every repository a module is
|
||||
built from, hq's included once the delivery is done (ADR 0445 §6, ADR 0527 §3); the controller's composition check, composing every
|
||||
machine from clones and throwaway stores (ADR 0446 §1, §6); the judge built from a change and the Go build
|
||||
machine from clones and throwaway stores (ADR 0446 §1, §6); the composition check built from a change and the Go build
|
||||
module's second account for it (ADR 0446 §5); and the two statuses `mesh/merge-gate` and `mesh/repo-check`
|
||||
(ADR 0447 §1, ADR 0527 §2).
|
||||
- At R4g's delivery (ADR 0524, ADR 0525): build-agent, its program, its module and its Dockerfile code; mesh-tools's toolchain
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
layer: to-be
|
||||
status: in-progress
|
||||
code: [mesh-host, mesh-controller, mesh-lab, mesh-catalog, mesh-sdk]
|
||||
updated: 2026-10-14
|
||||
updated: 2026-11-04
|
||||
decisions:
|
||||
- "ADR 0292"
|
||||
- "ADR 0283"
|
||||
@@ -44,7 +44,7 @@ core's own health definitions ([to-be 45](45-a-core-that-cannot-fail-silently.md
|
||||
operator's conversation (to-be 46), healers
|
||||
```
|
||||
|
||||
One judge per machine, for every hosting form. Nothing else on the machine judges a module, and nothing
|
||||
The node-engine alone judges health on a machine, for every hosting form. Nothing else on the machine judges a module, and nothing
|
||||
else sets a container's check.
|
||||
|
||||
## 1. Liveness, for everything that stays up
|
||||
@@ -333,7 +333,7 @@ the machine itself, beside its liveness looks, and says it in the same statement
|
||||
that is the module declaring it whole there; the uplink's holder steps back from it. A VPN client's write
|
||||
that the client's module took is undone within seconds, before the second look, and is no finding. One
|
||||
nothing took stands for 90 s, so it is raised as `machine.<m>.systemd-resolved.rewritten`, naming its
|
||||
writer, and cleared when the resolver puts its file back. Nothing in the judge changes for this.
|
||||
writer, and cleared when the resolver puts its file back. Nothing in the node-engine's judgement of health changes for this.
|
||||
- **Asked further through the uplink seat.** `node-uplink` serves `resolvers` (the file, whether it is the
|
||||
mesh's, its writer) and `links` (each link, its default route, the resolvers its manager knows). They are the
|
||||
same from every holder, and optional until both holders serve them: promised, so a holder may serve them,
|
||||
@@ -508,7 +508,7 @@ open:
|
||||
- **The look.** Every 30 s, on the liveness loop's tick. The resolvers are asked concurrently, three
|
||||
questions each, with a reply read over raw UDP so "no such name" and "none" are told apart. The tunnel is
|
||||
read with the tunnel tool's handshake and allowed-address listings, never its dump, which holds the
|
||||
private key. The hub is the peer whose allowed addresses are a range. The judge keeps nothing on disk.
|
||||
private key. The hub is the peer whose allowed addresses are a range. The node-engine's network look keeps nothing on disk.
|
||||
Its two looks start afresh when the engine starts.
|
||||
- **The statement.** A `network` beside `resources` in the health statement. The controller reads the
|
||||
statement leniently, so the engine rolls out first and the controller after, and an older controller
|
||||
|
||||
@@ -211,7 +211,7 @@ the verb.
|
||||
the program, so the port is free when the program starts. **What a pull meets in the swap**: from the registry
|
||||
container's stop until the program listens on the port, the store answers nothing. On main, a failed pull fails that
|
||||
module's apply, and the node agent tries a failed apply again only on the next change of the module's want or
|
||||
composition, on the node-engine's verb `compose` naming the module (by hand), or when its liveness judge finds a
|
||||
composition, on the node-engine's verb `compose` naming the module (by hand), or when its liveness look finds a
|
||||
declared resource missing or down; only a failure of the bus itself is tried again on a clock (a bounded backoff,
|
||||
at most four times before the have says failed). So another module's apply whose pull falls in that window stays
|
||||
failed, its running containers kept, until one of those: its have says failed naming the image.
|
||||
@@ -419,8 +419,8 @@ hand) on the builder's own family beside `numbered`; a waiter on a build's end d
|
||||
|
||||
**When the group is pushed.** Only once the release that adds the node-engine's stated capability (design 47) runs on
|
||||
every node, read from the status view's haves before the push, and once the progressive insights of ADR 0595 and
|
||||
ADR 0597 this design is written to are accepted. No release of the judge goes ahead: the indexer and the assigner
|
||||
serve their first views as tools of their own, in a form the running judge already takes in (ADR 0621 §4; design 25
|
||||
ADR 0597 this design is written to are accepted. No release of the manifest validator goes ahead: the indexer and the assigner
|
||||
serve their first views as tools of their own, in a form the running manifest validator already takes in (ADR 0621 §4; design 25
|
||||
§ 12.2). A node away for weeks does not hold the push for ever: it is left
|
||||
out of that read only by a recorded hand act naming the node and why, as `registry_old_name` drops one, said in the
|
||||
group's pull request; the node then takes the new node-engine as any away node does when it returns.
|
||||
|
||||
@@ -82,7 +82,7 @@ and the knowledge base works out each design's state (ADR 0423, ADR 0424).
|
||||
│ snapshot the latest head per record, never expiring
|
||||
│ state drafts one key per record being written: its author and its sections as title,
|
||||
│ digest and the sequence of their write-section
|
||||
│ state asked one key per part asked of the judge and not yet answered: ticket, node, when
|
||||
│ state asked one key per part asked of the judgement tool, not yet answered: ticket, node, when
|
||||
│ state findings the whole-set findings standing now, and the told marks (told.<topic>)
|
||||
│ state sent per record, the last operation whose event was sent
|
||||
│ stream reviews one message per part reviewed: the digest judged, the verdict, the findings
|
||||
@@ -98,7 +98,7 @@ and the knowledge base works out each design's state (ADR 0423, ADR 0424).
|
||||
│ part-reviewed, reviewed, accepted, changed, moved, checked, formed,
|
||||
│ imported, drafted, confirmed, returned
|
||||
├ consumes the router's warrants: the operator's Approve for a record that needs it (§ 5)
|
||||
├ consumes claude-code's judged: the judge's answer to a part (§ 5)
|
||||
├ consumes claude-code's judged: the judgement tool's answer to a part (§ 5)
|
||||
├ consumes the delivery module's delivery-done announcement: a design's state (§ 9)
|
||||
├ consumes the issue tracker's, mesh-delivery's and the router's events for the overview page (§ 11)
|
||||
└ serves the overview page, read-only, on a port it declares, through the route proxy (§ 11)
|
||||
@@ -171,7 +171,7 @@ Every piece of state has a tool that reads it, and every act the module does by
|
||||
| read a section | one `write-section` operation, by its sequence, its text checked against its digest |
|
||||
| read a draft | one key of `drafts`, with its author and since when |
|
||||
| read a review | the part verdicts of one version, from `reviews` |
|
||||
| in-flight parts | the keys of `asked`: each part waiting on the judge, its ticket and since when; ask one again |
|
||||
| in-flight parts | the keys of `asked`: each part waiting on the judgement tool, its ticket and since when; ask one again |
|
||||
| told marks | the `told.<topic>` keys; clear one, so it is told again |
|
||||
| fill | each bucket's and stream's size and count against its cap |
|
||||
| rebuild the index | the search index, built again from the bus |
|
||||
@@ -272,7 +272,7 @@ costs only the sections it changes; the forms of ADR 0592 §1 to §9 that it rep
|
||||
- **A draft** is a key in the state `drafts` (§ 4). **A part's verdict** is the operation `review` on the record's
|
||||
history first, then a message on the stream `reviews`; a `review` with no message on `reviews` is sent at start
|
||||
with the operation's sequence as its id, so the consumers of `reviews` miss none and hear none twice. A part
|
||||
asked of the judge and not yet answered a key in the state `asked` (§ 5). **The whole-set findings** standing
|
||||
asked of the judgement tool and not yet answered a key in the state `asked` (§ 5). **The whole-set findings** standing
|
||||
now are keys in the state `findings`, and what was told to the operator once is a key `told.<topic>` there. These
|
||||
keep their own forms (ADR 0597 §12), asked for in `requires`: the states by the template state; `reviews`, kept for
|
||||
good and heard only where granted (ADR 0592 §6, §8), as a bare stream with its own configuration (kept for good,
|
||||
@@ -413,7 +413,7 @@ as in force.
|
||||
When a version is submitted (by `submit` or `propose`, a new version of a proposed record included), the knowledge
|
||||
base reviews it itself, **in parts** (ADR 0592 §22 to §28, changing ADR 0290 §4): one judgement per part, each in a
|
||||
separate call, with no tools, that answers `approve` or `changes` with its findings, the way the issue tracker's
|
||||
triage judges an issue. The judgement goes through the agent module's judge (`claude_code_judge`) today, and through
|
||||
triage judges an issue. The judgement goes through the agent module's judgement tool (`claude_code_judge`) today, and through
|
||||
the mesh's inference layer once one exists; nothing in this design depends on which.
|
||||
|
||||
- **The head** is one part: the title, the brief, the clauses (at most 40 KiB together) and the links, judged
|
||||
@@ -421,10 +421,10 @@ the mesh's inference layer once one exists; nothing in this design depends on wh
|
||||
- **Each changed section** is a part of its own, judged with **the frame** of at most 16 KiB: the title, the links,
|
||||
and only what the section names (rows of other sections, clauses, the clauses of linked records), with the digest
|
||||
of the Context section (the Overview, for a research effort) it is read beside. What does not fit is cut, and the
|
||||
question says what was cut. A section is at most 40 KiB, so each question stays under the judge's 60 KiB.
|
||||
question says what was cut. A section is at most 40 KiB, so each question stays under the judgement tool's 60 KiB.
|
||||
- **What is judged again.** A section is judged again only when its own text or what it names changes; the Context
|
||||
only when it changes. So a usual revision judges only the sections it changed.
|
||||
- **At most two judge calls of one version run at once.** A revision of eight sections takes a few minutes, and
|
||||
- **At most two judgements of one version run at once.** A revision of eight sections takes a few minutes, and
|
||||
about four times the tokens of one whole judgement.
|
||||
- **The rules on the whole record** (§ 4) stay code, run at `submit`; no judgement is asked to find a link to nothing.
|
||||
|
||||
@@ -437,11 +437,11 @@ the mesh's inference layer once one exists; nothing in this design depends on wh
|
||||
version 3 stays proposed, with the findings of Direction
|
||||
```
|
||||
|
||||
**The parts wait on the bus** (ADR 0592 §23). Each part asked of the judge is a key in the state `asked` (the part,
|
||||
the judge's ticket, the node, when it was asked), collected again at start, so a restart loses no review. The judge's
|
||||
**The parts wait on the bus** (ADR 0592 §23). Each part asked of the judgement tool is a key in the state `asked` (the part,
|
||||
the tool's ticket, the node, when it was asked), collected again at start, so a restart loses no review. The tool's
|
||||
answer comes as the event `judged`, which the claude-code module emits for each ticket and the knowledge base
|
||||
consumes; until claude-code emits it, the knowledge base polls the ticket, which is not NATS-native and is tracked by
|
||||
issue 1956. The judge is a tool of the claude-code module, not a seat's verb: a seat for judgements (held by the
|
||||
issue 1956. The judgement tool is the claude-code module's own tool, not a seat's verb: a seat for judgements (held by the
|
||||
mesh's inference layer once one exists) is a note on that issue. A part waiting more than 30 minutes asks the
|
||||
operator once through the operator channel, and the ask clears when the part is judged.
|
||||
|
||||
@@ -451,7 +451,7 @@ part. **`reviewed` keeps its meaning**: one event per version, once every part i
|
||||
verdict, so every wait on it keeps working. A part's review is kept for a new version when what it was judged with is
|
||||
unchanged, and for a form-only version (§ 2.2); any other part is judged again. **A version is accepted when every
|
||||
part's review approves.** On `changes`, the record stays proposed, the findings are kept with that version and the
|
||||
part they name, and its author revises it with a new version. A part that cannot be judged (the judge unreachable,
|
||||
part they name, and its author revises it with a new version. A part that cannot be judged (the judgement tool unreachable,
|
||||
or its answer unreadable) leaves the version proposed and says which; it is never taken as an approval. When every
|
||||
part approves:
|
||||
|
||||
@@ -526,10 +526,10 @@ The records leave the store once, and the database is dropped only after a check
|
||||
(ADR 0592 §12 to §16; the forms the records are copied into are those of ADR 0597 §12):
|
||||
|
||||
1. **Order.** The ledger is built first, in the order of ADR 0595 §10: mesh-sdk's typed `requires`, binding and
|
||||
package of the new calls; the indexer's judge's rules; the bus module's process, verbs and events; the tool
|
||||
package of the new calls; the manifest validator's rules; the bus module's process, verbs and events; the tool
|
||||
runner's calls, `apply` among them, with its ledger credential per module assignment (ADR 0597 §9, as its
|
||||
progressive insight of 2026-11-03 has it, waiting for the operator's Approve); then mesh-knowledge moves, asking for
|
||||
its ledger, states and stream in `requires`. An indexer whose judge predates the new form refuses a manifest
|
||||
its ledger, states and stream in `requires`. An indexer whose manifest validator predates the new form refuses a manifest
|
||||
that uses it, and the placement holds the module off a machine whose tool runner does not read the typed
|
||||
binding, so mesh-knowledge cannot be delivered before them. The release sdk1 (issue 1585, ADR 0593 §10), which
|
||||
created object buckets and history streams through the grants part, is no longer needed by the move: the
|
||||
@@ -706,14 +706,14 @@ table-driven; one integration test starts the module whole against the real bus
|
||||
| a text does not hash to its digest | unit: `apply` refuses the `write-section`, and a read refuses it, naming the digest |
|
||||
| a full ledger state | integration: `submit` answers taken with the head behind; health unhealthy naming the cap |
|
||||
| a full ledger history | integration: `submit` refused with the head unchanged |
|
||||
| a judge timeout for one part | unit: that part stays asked and the version proposed, saying which; the others keep their verdicts |
|
||||
| a judgement timeout for one part | unit: that part stays asked and the version proposed, saying which; the others keep their verdicts |
|
||||
| a restart with parts asked | integration: the parts in `asked` are collected again and judged |
|
||||
| `reviewed` once per version | unit: one `reviewed` after the last `part-reviewed`, carrying every verdict |
|
||||
| told once | unit: a whole-set finding told once across a restart, again only after its mark is cleared |
|
||||
| a second run of the move | unit: changes nothing and says so |
|
||||
| the move's check | unit: a changed review, a missing finding and a missing ask, each named |
|
||||
| writes during the switch | unit: every writing verb refused with its reason; reading verbs answer |
|
||||
| an older judge | the indexer's judge test (ADR 0595 §8): a manifest asking for a ledger in `requires` refused by a judge that does not know the template, accepted by one that does |
|
||||
| an older manifest validator | the manifest validator's test (ADR 0595 §8): a manifest asking for a ledger in `requires` refused by a manifest validator that does not know the template, accepted by one that does |
|
||||
| the bus module's forms | the bus module's test (design 25 § 12), against a real bus server: the ledger, states and stream created for their module, `reviews` heard by a module granted it in `readers` and by no other; the condition at 75 percent raised and cleared below |
|
||||
| a reference | unit: "record › title › row" resolves to the section; a nested title is refused |
|
||||
| a form-only version | unit: accepted when only names and links changed and each target resolves; refused otherwise |
|
||||
@@ -768,7 +768,7 @@ done:
|
||||
section adds one `write-section` and one `submit`, not one operation per section.
|
||||
8. During the move's window a `write` is refused saying the knowledge base is moving; after the switch a restart
|
||||
still serves from the bus; the health names the source and the check's result.
|
||||
9. A part's review waiting on the judge survives a restart of the module, and one past 30 minutes reaches the
|
||||
9. A part's review waiting on the judgement tool survives a restart of the module, and one past 30 minutes reaches the
|
||||
operator once.
|
||||
10. Every test of the table above passes in the one check of the pull requests, within the test budget.
|
||||
11. As a ledger (ADR 0597 How it is checked, clauses 11 and 12): `get` answers the same digest for every record
|
||||
@@ -804,7 +804,7 @@ reached which nodes is not on it: a merged group no longer waits on the operator
|
||||
`mesh-delivery`'s `groups` and its `group`, `transition` and `merged` events, a group leaving the block on `merged`;
|
||||
and the seat `operator-channel`'s `asks` and the router's events `offered` and `closed`, an ask entering the block on
|
||||
`offered` and leaving it on `closed`. It never hears an asker's `decided` family. It reads no other module's bus
|
||||
state (ADR 0596 §2), and its manifest holds no `reads` entry, which the judge refuses (ADR 0595 §8).
|
||||
state (ADR 0596 §2), and its manifest holds no `reads` entry, which the manifest validator refuses (ADR 0595 §8).
|
||||
- **The router says when an ask starts and ends** (ADR 0616 §7). The router holding `operator-channel` emits `offered` when it
|
||||
offers an ask on a channel, and `closed` once for every end of an ask: answered, expired, cancelled by its asker,
|
||||
replaced by a newer ask about the same subject, or ended by the router itself on an `unlink` or `allow-link`. Each
|
||||
@@ -872,7 +872,7 @@ review of ADR 0592's fourth version beside), and the lead ruled on every finding
|
||||
| Architectural domain | Found | Answered by |
|
||||
|---|---|---|
|
||||
| security | unproven callers could write or take over; an Approve did not bind the sections shown; readers were named outside ADR 0363's grant (the knowledge base's review of version 6); a proposal waiting on the operator could be taken over; readers' grants and a body's match with its name were unsaid; a draft had no bound | ADR 0592 §4, §8, §9, §17, §19, §20, §21; § 2.1, § 4 |
|
||||
| seams | asked parts lived only in memory; told marks and reservations had no form on the bus; the judge's ticket is polled; who creates buckets and grants was unsaid; the judge is a module's tool, not a seat | ADR 0592 §2, §7, §16, §23; § 1, § 5 (the judge's seat a note on issue 1956), § 8.1 |
|
||||
| seams | asked parts lived only in memory; told marks and reservations had no form on the bus; the judgement tool's ticket is polled; who creates buckets and grants was unsaid; the judgement tool is a module's tool, not a seat | ADR 0592 §2, §7, §16, §23; § 1, § 5 (a seat for judgements a note on issue 1956), § 8.1 |
|
||||
| running qualities | three writes could stop halfway; caps had no figures; a usual revision judged every section again, with no limit on parallel calls; start time unknown | ADR 0592 §10, §22, §25; § 1, § 2.1 (caps), § 5 |
|
||||
| health | a stale index, a missing body, a full bucket and the move's state were not visible; waiting reviews and idle drafts were not counted | ADR 0592 §25, §33; § 1.1 |
|
||||
| events and logs | per-part verdicts would have broken every wait on `reviewed`; events did not say what they touched; a take-over's reason and each section's author were lost after 30 days | ADR 0592 §3, §27, §34; § 1.1 (the events table) |
|
||||
|
||||
Reference in New Issue
Block a user