Design 25 names the signed caller and what the watchman newly hears; design 55 checks the database at every start before the drop

This commit is contained in:
2026-11-03 10:49:43 +01:00
parent c033592509
commit 0cd0cfd778
2 changed files with 15 additions and 11 deletions
+7 -5
View File
@@ -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 |
+8 -6
View File
@@ -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 |