From 0cd0cfd778807fdf5d560447886599b968187586 Mon Sep 17 00:00:00 2001 From: jochen Date: Tue, 3 Nov 2026 10:49:43 +0100 Subject: [PATCH] Design 25 names the signed caller and what the watchman newly hears; design 55 checks the database at every start before the drop --- 03-DESIGN/01-to-be/25-the-bus-on-nats.md | 12 +++++++----- 03-DESIGN/01-to-be/55-the-knowledge-base.md | 14 ++++++++------ 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/03-DESIGN/01-to-be/25-the-bus-on-nats.md b/03-DESIGN/01-to-be/25-the-bus-on-nats.md index a2af9d1b..de03b258 100644 --- a/03-DESIGN/01-to-be/25-the-bus-on-nats.md +++ b/03-DESIGN/01-to-be/25-the-bus-on-nats.md @@ -705,8 +705,9 @@ raises that module's condition and leaves the bus module healthy. state `memberships`, so no part writes another's state and a binding outlives the 30 days its event is kept. 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 already - hears the judge's verdicts, never by the bus module, which cannot raise it while it is down; it names the module + five minutes of an accepted verdict that asks for the entry. The condition is raised by the watchman, which today raises the judge'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 for the entry. - **Only the owner reaches it** (ADR 0596 §2). The membership grants the owner's account its own entries and no @@ -758,8 +759,9 @@ and the entry: `full` (cleared below 75 percent), `drifted` (cleared by `drift-c bus module created and its fill, and `history` its events for one entry; `create` and `apply`, marked acts, and `recreate` and `drop`, marked dangerous and so granted only by name (ADR 0386 §6, ADR 0387), are its tools for a person. Such a tool, in the bus module's bundle, holds no grant of those verbs' subjects, and neither does the tool -runner's account: it hands the request to the process on the process's own tool subject, carrying the caller the -bus proved, and the process acts only for a caller whose role grants that tool, for `recreate` and `drop` only once +runner's account: it hands the request to the process on the process's own tool subject, carrying the caller as +the token the identity seat signed (ADR 0386 §8), whose signature the process checks, so no account granted that +subject can name another caller; the process acts only for a caller whose role grants that tool, for `recreate` and `drop` only once the operator's warrant is held, and answers what it did. The bus seat's `apply` (a difference that grows) and the ledger's `apply` (§ 12.4) are two verbs on two subjects, granted apart; this design writes them qualified. Its health names the process's last pass, the entries it could not create, and the entries over 75 percent. @@ -857,7 +859,7 @@ are tracked by 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 75 percent and cleared below | | 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: 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 | +| 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 | | A person's tools reach the process, and only by role | live: a role without the dangerous grant is refused `drop`'s tool; the tool runner's account holds no grant of `create`, the seat's `apply`, `recreate` or `drop` | | The author is the proven caller | the ledger's integration test: an `apply` naming another module's tool call is refused; the author stamped is the caller the tool runner proved, whatever the module passed | | 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 | diff --git a/03-DESIGN/01-to-be/55-the-knowledge-base.md b/03-DESIGN/01-to-be/55-the-knowledge-base.md index 2b8e9b96..e2a92351 100644 --- a/03-DESIGN/01-to-be/55-the-knowledge-base.md +++ b/03-DESIGN/01-to-be/55-the-knowledge-base.md @@ -554,11 +554,13 @@ The records leave the store once, and the database is dropped only after a check them, and never answers the author that the write was refused; the module's health is unhealthy while it stands, the drop (step 8) is refused while it stands, and the catch-up tool copies the records again from the ledger and clears it. A rollback is a person's act, and the condition is what tells them it is unsafe. **After a rollback**, - the older module wrote to the database alone: beside `database.sequence` the module keeps the newest version the - database held when it last wrote there, and a forward delivery that finds a newer version in the database refuses - every writing verb, - copies the changed records from the database onto the ledger as operations, runs the check of step 4 again, and - serves writes only once it is clean. A rollback is safe + the older module wrote to the database alone, and not only versions: acceptances, verdicts, asks, warrants, + reservations and changed clauses too. So until the drop, every start of the module refuses every writing verb + and runs the check of step 4 before it serves writes; a difference it finds is copied from the database onto the + ledger as operations, and the check runs again, so writes are served only once it is clean. A record changed on + both sides (an operation the database never took, and a change the older module made) never checks clean: it is + told to the operator at once, naming the record and both changes, so the refused writes read as a decision + waiting and not as a stall. A rollback is safe only until the drop. This settles the rollback ADR 0597 §13 left to the design. 7. **Tell and ask.** Once the check is clean, the operator is told its result and asked, once, whether the database may be dropped, because dropping it removes data. @@ -708,7 +710,7 @@ table-driven; one integration test starts the module whole against the real bus | a form-only version | unit: accepted when only names and links changed and each target resolves; refused otherwise | | an unproven caller | unit: `open`, `write`, `submit`, `propose` and `take-over` refuse it | | the index behind | unit: health unhealthy while the index's sequence is behind the ledger's state; `ask` refuses "index not built" | -| a forward delivery after a rollback | unit: a database changed by the older module is found, the writing verbs refused, the changes copied and checked, then writes served | +| a forward delivery after a rollback | unit: an acceptance and a verdict made by the older module are found by the check at start, the writing verbs refused meanwhile, the changes copied and checked, then writes served; a record changed on both sides is told to the operator | | a restart between `apply` and the database write | unit: the module is stopped after `apply` and before the database write, restarted, and the database matches the history; health showed it behind meanwhile | | the database refuses past its tries | unit: `database-behind` names the record; the drop is refused while it stands; the catch-up tool clears it | | a restart between `apply` and its event | unit: the module is stopped after `apply` of a `review`, restarted, and sends one `reviewed`; a second start sends none |