Designs 25, 51: verdicts a first view of its own; every node hears the holder settle
The store's holder runs on one node, so a node-engine elsewhere must hear its settled too, and a pull failed just after it settled must not wait. The grants part's verdicts read is a first view under ADR 0622, not an ordinary read tool, and the node-engine's reads granted in code are said, so the live count of zero declared reads is not taken for more than it is. Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
This commit is contained in:
@@ -16,6 +16,7 @@ decisions:
|
||||
- "ADR 0619"
|
||||
- "ADR 0615"
|
||||
- "ADR 0621"
|
||||
- "ADR 0622"
|
||||
- "ADR 0614"
|
||||
- "ADR 0613"
|
||||
- "ADR 0612"
|
||||
@@ -752,13 +753,18 @@ vault as an own secret: JetStream create and update under modules' names only (s
|
||||
ADR 0621). The four
|
||||
foundation parts that read each other (the grants part, the tool runner, the indexer and the assigner) stop
|
||||
reading the indexer's and the assigner's bus state in the milestone of ADR 0612, with the other 19 readers of that
|
||||
state (ADR 0615 §1). **Each owner serves them as tools of its own module**, the indexer `manifests` and
|
||||
`modules`, the assigner `placement`, `seat-holders` and `wants`, and declares `runs-as`, so its tools bundle runs in
|
||||
state (ADR 0615 §1). **Each owner serves them as tools of its own module**, the indexer `manifests`,
|
||||
`modules` and `verdicts` (ADR 0622 §1), the assigner `placement`, `seat-holders` and `wants`, and declares `runs-as`, so its tools bundle runs in
|
||||
a runtime of its own on the module's own bus account, never in the node's tool runner, and the tool runner never
|
||||
asks through itself (ADR 0621 §1). No new manifest form is added: a process still answers no tool call or seat verb
|
||||
(ADR 0436 §3). **Each verb is granted to exactly its readers** (ADR 0621 §2, as ADR 0615 §3 lists them): `placement`
|
||||
to the grants part, the tool runner and the indexer; `seat-holders` to the tool runner; `wants` to the grants part;
|
||||
`manifests` and `modules` to the grants part, the tool runner and the assigner. A reader declares each in `invokes`
|
||||
`manifests` and `modules` to the grants part, the tool runner and the assigner; `verdicts` to the grants part
|
||||
alone, its `callers` list holding the grants part only (ADR 0622 §1). These six are the first-view tools.
|
||||
`verdicts` follows the first-view rules whole (ADR 0622 §2, under ADR 0615 §4 to §6): its answer carries the
|
||||
revision, the grants part then follows `manifest-accepted` and `manifest-refused` and asks once more on a gap in
|
||||
their revisions, it raises the condition naming the indexer and `verdicts` past the bound and never reads the
|
||||
indexer's state, and `grants_first_views` and `grants_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,
|
||||
@@ -815,20 +821,18 @@ vault as an own secret: JetStream create and update under modules' names only (s
|
||||
part and the tool runner their first views while the bus module still waits on it. The order of owner before reader is kept by the module graph's served-verb edge for the 19 readers (ADR 0614 §2), and,
|
||||
for the four, whose verb edges lie on cycles the graph leaves out (ADR 0614 §3), by the owner's answer at once and
|
||||
the reader's wait (ADR 0615 §2).
|
||||
- **The other 19 readers ask the owners' read tools, one per bucket they read** (ADR 0615 §1, §2). Beside the five
|
||||
first-view tools above, each owner serves a read tool for every bucket of its state one of the 19 reads today, and for the `verdicts` the grants part reads,
|
||||
named `indexer_read_<bucket>` or `assigner_read_<bucket>` and marked as a read. The indexer's ten:
|
||||
`indexer_read_verdicts`, `indexer_read_manifests`, `indexer_read_modules`, `indexer_read_predefined`, `indexer_read_config_candidates`,
|
||||
- **The other 19 readers ask the owners' read tools, one per bucket they read** (ADR 0615 §1, §2). Beside the six
|
||||
first-view tools above, each owner serves a read tool for every bucket of its state one of the 19 reads today,
|
||||
named `indexer_read_<bucket>` or `assigner_read_<bucket>` and marked as a read: fifteen. The indexer's nine:
|
||||
`indexer_read_manifests`, `indexer_read_modules`, `indexer_read_predefined`, `indexer_read_config_candidates`,
|
||||
`indexer_read_candidates`, `indexer_read_packages`, `indexer_read_graph`, `indexer_read_heard` and
|
||||
`indexer_read_taken`. The assigner's six: `assigner_read_placement`, `assigner_read_seat_holders`,
|
||||
`assigner_read_wants`, `assigner_read_findings`, `assigner_read_asks` and `assigner_read_differences`. These are
|
||||
the ten buckets of the indexer and the six of the assigner the readers read (§ 12.6), `modules`, `wants` and
|
||||
`placement` among them for the status view. **The grants part reads the indexer's `verdicts` the same way**: its
|
||||
first view of that bucket is `indexer_read_verdicts`, answered in the indexer's own runtime (ADR 0621 §1), never
|
||||
through the node's tool runner, and then it follows `manifest-accepted` and `manifest-refused`, which carry the
|
||||
module's entries whole (ADR 0595 §4). **They are ordinary module tools**: granted, as any tool is, to every
|
||||
reader that declares it in `invokes`, and callable by a session; ADR 0621 §2's `callers` list covers only the five
|
||||
first-view tools and stays as it is. **The status view keeps all its tools**, their names, arguments and answers
|
||||
the nine buckets of the indexer and the six of the assigner the 19 read (§ 12.6), `modules`, `wants` and
|
||||
`placement` among them for the status view; the indexer's tenth, `verdicts`, is read by the grants part alone,
|
||||
through its first-view tool. **They are ordinary module tools**: granted, as any tool is, to every
|
||||
reader that declares it in `invokes`, and callable by a session; the `callers` list of ADR 0621 §2 and ADR 0622 §1 covers only the six
|
||||
first-view tools. **The status view keeps all its tools**, their names, arguments and answers
|
||||
unchanged, its `indexer_*` and `assigner_*` tools included: as a reader it answers them by asking the owners' read
|
||||
tools instead of reading their buckets. Checked live after the delivery: a session's call of each status view tool
|
||||
answers, and `mesh_search` finds each owner's read tool by its bucket's words.
|
||||
@@ -991,9 +995,12 @@ not by the 19 the first plan counted; and 151 state entries were counted, not 15
|
||||
the first count, which chose the templates). The owners first gain their events, first-view tools and read tools: the
|
||||
indexer a read tool per bucket its readers read, the assigner the same (§ 12.2 lists them). Then all 23 readers move in the milestone of ADR 0612, the
|
||||
four foundation readers included, by the first view of § 12.2 (ADR 0615 §1), the grants part's of the indexer's
|
||||
`verdicts` by `indexer_read_verdicts` and then `manifest-accepted` and `manifest-refused`; their order is the module graph's, not
|
||||
`verdicts` by its first-view tool `verdicts` (ADR 0622) and then `manifest-accepted` and `manifest-refused`; their order is the module graph's, not
|
||||
a review reading an owner delivered (ADR 0615 §2). The status view's move keeps every tool it serves, each answered by
|
||||
asking the owners' read tools of § 12.2. The judge still refuses a moved module's subscription to an event
|
||||
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
|
||||
its owner does not declare. Every other reader moves when its module is next touched. These moves are tracked by
|
||||
issue 1966.
|
||||
|
||||
@@ -1005,10 +1012,10 @@ issue 1966.
|
||||
| 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; `recreate` and `drop` without the operator's warrant are refused, and with it act after a stream snapshot; 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; the read tool shows the revision each reader holds, and the re-read tool asks once and records the hand act; in the
|
||||
| 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; 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; the read tool shows the revision each reader holds, and the re-read tool asks once and records the hand act; in the
|
||||
| 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) |
|
||||
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 for the indexer's state and 0 for the assigner's; 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 |
|
||||
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 |
|
||||
| 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 |
|
||||
|
||||
@@ -201,9 +201,12 @@ the verb.
|
||||
finding of the holder held during its own delivery raises no condition and so no clear (ADR 0564 §13 (c)), and
|
||||
`delivered` waits for every have to equal its want, which the failed have itself blocks (design 47). The status
|
||||
view's `settled`, said once for a module on a node at one composition when its have reaches its want running and
|
||||
healthy (design 47), is blocked by nothing else. So the node-engine hears `settled` for the store's holder on the
|
||||
node it runs on, and then applies once more each module on its own node whose have says failed naming an image of
|
||||
that store, said in its journal. It finds the holder by the seat the failed image came through, read from its
|
||||
healthy (design 47), is blocked by nothing else. `distribution` claims a seat held once for the mesh and runs on
|
||||
one node, so the node-engine on every node hears `settled` for the store's holder, on whichever node the holder
|
||||
runs, and then applies once more each module on its own node whose have says failed naming an image of that store,
|
||||
said in its journal. **No `settled` is missed in a race**: when the node-engine records a pull failed against a
|
||||
store, it checks whether the holder's latest event is already `settled`, and if so applies again at once, so a
|
||||
pull that failed just before the holder settled does not wait for the next one. It finds the holder by the seat the failed image came through, read from its
|
||||
declaration, never by a module's name. **The seam that changes is the grants part's list of what a node-engine
|
||||
hears** (`NodeAgentHears`; the node-engine declares no `consumes` of its own): it gains one entry, the status
|
||||
view's `settled` family, which the node-engine filters for the holder of the seat its failed image names. **At its
|
||||
@@ -482,7 +485,9 @@ test).
|
||||
- **Node-engine, unit** (cases of its apply test, with the runner, the bus and the clock it already fakes): a
|
||||
module whose pull failed, its have failed naming an image of a store, is not applied again with the clock moved
|
||||
past the bus backoff's four tries and no event heard; it is applied once more, and its new image pulled, on a
|
||||
`settled` for the holder of the seat its image came through; a `settled` of another module applies nothing; at the
|
||||
`settled` for the holder of the seat its image came through, a `settled` said for the holder on another node
|
||||
included; a pull that fails after the holder's latest event was already `settled` is applied again at once; a
|
||||
`settled` of another module applies nothing; at the
|
||||
node-engine's start it is applied once more with no event; a module being applied when `settled` arrives is not
|
||||
applied twice; a retry whose pull fails again says failed again and starts no further apply.
|
||||
- **The grants part, unit** (a case of its composition test): a node-engine's subscriptions hold the status view's
|
||||
|
||||
Reference in New Issue
Block a user