Answer the prepare's questions on the approval mark and marked waits
Each of the 25 recommendations becomes a design line with its question id, so the builders find every field, test and source named; the live readings of the credentials go into the gate's stated bound. Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
This commit is contained in:
@@ -65,7 +65,8 @@ that holds its mark reach the machines together.
|
||||
`EventSubjects` answers for its cases is covered by a subject of `EveryEvent`.
|
||||
2. **The manifest loses `waits`.** `catalogue.Manifest.Waits` and its comment go from `go/catalogue/manifest.go`;
|
||||
the comment on `ToolRunner` loses "and the only module that may declare `waits`". `go/catalogue/waits_test.go` is
|
||||
deleted, and one row is added to the decoder's existing table of unknown fields: a manifest
|
||||
deleted, and one row is added to the nearest table over raw manifests, `go/catalogue/invokes_test.go`'s
|
||||
`TestAManifestMaySayWhatItInvokes` (Q-T): a manifest
|
||||
`{"module":"node-tools","version":"1","tool-runner":true,"waits":["a.b"]}` decodes with `UnknownField()` naming
|
||||
`waits` (ADR 0670 §2). The decoder itself is unchanged: a stored manifest that still carries `waits` is read
|
||||
without it (ADR 0578 §3).
|
||||
@@ -182,8 +183,8 @@ that holds its mark reach the machines together.
|
||||
answered after the timeout with §16's words; `TestMeshWaitWithNoFamiliesIssuedWaitsOnNothing` is deleted. In
|
||||
`bus/wait_test.go`, `TestTheBusRefusesAWaitOutsideTheGrant` stays as §16's refusal test, with a timeout of a
|
||||
fraction of a second, its comment citing ADR 0670 §1. The manifest test also holds each change of §11: no `waits`,
|
||||
`operator-channel` in `uses`, the state `approvals` in `requires` with its options, and the finding stream. No test
|
||||
function is added: the module stays within its budget.
|
||||
`operator-channel` in `uses`, the state `approvals` in `requires` with its options, and the finding stream. New
|
||||
test functions are allowed within the module's budget of 500 unit and 50 integration tests (Q-TB).
|
||||
|
||||
## The claude-code module's Stop hook
|
||||
|
||||
@@ -316,7 +317,8 @@ approves, for a marked event or a restricted stream.
|
||||
`from: seat` is never marked.
|
||||
35. **A marked wait runs only on the operator's warrant for that one wait.** The call is an act as design 46
|
||||
7-approval-mark §8 makes one: the address `mesh_wait`, the node, the module `node-tools` and the tool `mesh_wait`,
|
||||
its build (the digest of the tool runner's own artifact), and every
|
||||
its build (the tool runner's own fingerprint, from its catalog entry of the version served; design 46 7-approval-mark
|
||||
§8, Q-BD), and every
|
||||
argument given (`subjects`, `from`, `filter`, `timeout`), so the warrant binds the exact names, the filter and the
|
||||
bound. The tool runner refuses, asks, judges and claims it as that part's §9, §10, §11 and §13 to §17 do for a
|
||||
marked tool, asking on the seat `operator-channel` under its own module's name, `node-tools`, whose manifest gains
|
||||
|
||||
@@ -3,7 +3,7 @@ layer: to-be
|
||||
design: 46
|
||||
milestone: 7-approval-mark
|
||||
updated: 2026-11-11
|
||||
code: [mesh-sdk, mesh-contracts, mesh-delivery, mesh-tools, mesh-catalog modules/zsh, mesh-catalog modules/gitea]
|
||||
code: [mesh-sdk, mesh-contracts, mesh-delivery, mesh-tools, mesh-host, mesh-catalog modules/zsh, mesh-catalog modules/gitea]
|
||||
decisions:
|
||||
- "ADR 0286"
|
||||
- "ADR 0259"
|
||||
@@ -50,26 +50,36 @@ and not a retry on a timer (§16), and a fourth open ask is offered as G makes i
|
||||
not hold for a process that reads the tool runner's bus credential (the file `broker` in its state directory,
|
||||
`own-secrets`) and speaks to the bus itself: that account may subscribe a marked subject, a restricted stream's among
|
||||
them, on a machine whose runner honours the mark. Read on the workstation on 2026-11-11 with `node-reads.stat`, the
|
||||
file is mode 0600, owned by the operator's account, in a directory of mode 0755: every process running as the
|
||||
file is mode 0600, owned by the operator's account, in a directory of mode 0755, and the prepare of 2026-11-11 read
|
||||
the same mode and owner on all four nodes: every process running as the
|
||||
operator's account, every module on the machine's shared account and every agent session among them, can read it and
|
||||
hear a restricted stream without a warrant. This is the same known limit as design 47 G §385 (modules running as the
|
||||
machine's account, issue 1966 note 193, whose fix carries its check), and this milestone does not change it: that a
|
||||
restricted stream is heard only on a warrant holds against every caller once that fix runs modules and sessions on
|
||||
accounts that cannot read the file, and until then against callers that go through the tool runner. The
|
||||
prepare reads the file's mode and owner on every node with `<node>/node-reads.stat` and writes them in the milestone
|
||||
file; a node where the file is readable beyond the operator's account is a finding of the prepare.
|
||||
file; a node where the file is readable beyond the operator's account is a finding of the prepare. The forge module's
|
||||
own credential (§21) lies in a directory of mode 0700, owned by the forge's account, which `node-reads` cannot enter:
|
||||
no tool answers that file's own mode, a missing read tool, said here; the directory's mode is what the prepare read.
|
||||
|
||||
## The mark
|
||||
|
||||
1. **A module marks its tools and verbs in `needs-approval`.** mesh-sdk's `catalogue.Manifest` gains `NeedsApproval`,
|
||||
the manifest key `needs-approval`: a list of strings, each a tool the module serves (`<tool>`) or a seat verb it
|
||||
serves (`<seat>.<verb>`), and, under design 34 every-event §32, one of its events. Absent is no mark. *Why:* ADR
|
||||
0286 §1, §49 (each marking is a manifest change, reviewed like any other). *How it is checked:* unit, a row in the
|
||||
decoder's table test in `go/catalogue`; the manifest reads baseline gains `word:needs-approval`.
|
||||
0286 §1, §49 (each marking is a manifest change, reviewed like any other). Only the contract's manifest reads
|
||||
(`ManifestReads`) gain `word:needs-approval`; the baseline of the engines before any stated what it reads
|
||||
(`manifest_reads_baseline.txt`) is unchanged, since none of them reads the word (Q-BL). *How it is checked:* unit, a
|
||||
row in `go/catalogue/invokes_test.go`'s `TestAManifestMaySayWhatItInvokes`, the nearest table over raw manifests
|
||||
(Q-T): a manifest naming a tool, a seat verb and an event in `needs-approval` decodes all three with `UnknownField()`
|
||||
empty, and one without it has no mark.
|
||||
2. **A seat's definition marks a verb for every holder.** mesh-sdk's `seatdef` reads a verb's `needs-approval`, a
|
||||
boolean, in a seat definition (`seats/<seat>/seat.json` in mesh-contracts); the seat definitions the catalog half
|
||||
carries (design 47 G §194) carry it on the verb. *Why:* ADR 0286 §2. *How it is checked:* unit, a fixture row in
|
||||
`seatdef`'s table test.
|
||||
carries (design 47 G §194) carry it on the verb. The definition format's own schema in mesh-contracts
|
||||
(`format/seat-definition.schema.json`) gains a verb's `needs-approval`, a boolean (Q-SC). Every strict reader of a
|
||||
seat definition reads the word from G's reader release (design 47 G §340), so no reader refuses a definition that
|
||||
carries it (Q-RR). *Why:* ADR 0286 §2. *How it is checked:* unit, a fixture row in `go/seatdef/seatdef_test.go`'s
|
||||
`TestADefinitionIsReadStrictlyNamingWhatIsWrong` (Q-T), and the schema validates the login shell's definition of §21.
|
||||
3. **Marks add up.** A verb is marked when its seat's definition or its holder's `needs-approval` marks it; a holder
|
||||
cannot unmark what its seat marks. *Why:* ADR 0286 §3. *How it is checked:* unit, a row of §5's table.
|
||||
4. **The manifest validator refuses a mark it cannot honour.** The indexer's manifest validator (`judge/rules.go`)
|
||||
@@ -89,20 +99,24 @@ file; a node where the file is readable beyond the operator's account is a findi
|
||||
enforce its own verbs, and no other own-process server has a gate, so such a mark is refused rather than ignored;
|
||||
and an entry that names two things is read one way by one reader and another way by the next (the design's choices
|
||||
under ADR 0286 §4, §40, the refusal kept by lead-47 on 2026-11-11). *How it is checked:* unit, one row per refusal
|
||||
in `judge/rules_test.go`, rows that accept the zsh and forge manifests of §21, and a row of §22's mark table for
|
||||
in `judge/rules_test.go`'s `TestRulesManifests` (Q-T), rows that accept the zsh and forge manifests of §21, and a row of §22's mark table for
|
||||
`mark-unserved`.
|
||||
|
||||
## Where the marks are read, and where they are withheld
|
||||
|
||||
5. **From the catalog half on the bus, never from a bundle.** The indexer's catalog graph entry of a module (design 47
|
||||
G §174) gains its `needs-approval`, its `emits`, and for each stream it declares its events and whether it carries a
|
||||
`grant`; no part but the indexer reads a manifest (the operator, 2026-11-11: "only the indexer uses the manifest to
|
||||
build the module catalog"); the seat
|
||||
G §174) carries the validated manifest whole (design 47 G §443), its `needs-approval`, its `emits` and its streams
|
||||
(their events as the manifest spells them, and whether each carries a `grant`) among it; mesh-sdk's `buscompose`
|
||||
exports `WirePattern`, which a reader uses to turn a stream's events into the bus's subjects, the grants part's own
|
||||
copy going (Q-WP). No part but the indexer reads a manifest: every other part reads the entry of the build concerned
|
||||
from the catalog half (design 47 G §442; the operator, 2026-11-11: "only the indexer uses the manifest to build the
|
||||
module catalog"; Q-MR), the grants part's `declaredFor` among them for every grant, not only the marks; the seat
|
||||
definitions of the catalog half carry the verb marks (§2). The tool runner, which from G takes its first view of the
|
||||
catalog half by `mesh-catalog.revision` and follows `catalog-revision` (design 47 G §196), derives from it, for each
|
||||
module it serves, its marked tools and verbs, in a package of its own, `node-tools/internal/approval`, again on
|
||||
every revision it hears. No module's name is written in its code. The marks follow the running version: the runner
|
||||
applies the marks of the module's version it serves, and, while the newest revision's entry for that module
|
||||
applies the marks of the module's version it serves, read from the assignment half's entry for that module on its
|
||||
node (design 47 G §175; Q-VS), and, while the newest revision's entry for that module
|
||||
differs, the union of both, so a mark is never lost before or after the module moves. A mark added while a call
|
||||
waits applies from the next call, which the answer of §12 says. *Why:* ADR 0286 §5 had the controller issue the mark
|
||||
in a membership so that a bundle could not drop it; no controller issues memberships now, and the judged catalog
|
||||
@@ -111,22 +125,28 @@ file; a node where the file is readable beyond the operator's account is a findi
|
||||
`approval` derives the marks from fixture catalog halves, §3's row, a version change and the union among them.
|
||||
6. **A machine whose tool runner does not honour the mark serves no marked tool or verb.** The tool runner states
|
||||
`approval-mark/1` among its call capabilities (`runtime.CallCapabilities`), which its announcement carries and its
|
||||
node's node-engine takes into the node's record; the assignment half carries it among the capability readings
|
||||
(design 47 G §194). The grants part, composing a runtime's account, reads that runtime's node's readings: where the
|
||||
node's node-engine takes into the node's record; the assignment half carries, for each node, its capability readings
|
||||
and the time each was taken (`at`), which the assigner keeps from the node-engine's reading (design 47 G §194;
|
||||
Q-CR). The grants part, composing a runtime's account, reads that runtime's node's readings: where the
|
||||
tool runner does not state `approval-mark/1`, where the node has no readings, or where its readings are older than
|
||||
the tool runner's version on that node (failing closed as §19), it composes a subscribe deny of every marked
|
||||
subject of every module the runtime carries, the marks read from the catalog half as §5 has them:
|
||||
`mesh.mod.<module>.tool.<tool>` and the same followed by `.*`; the
|
||||
caller-named subject mesh-sdk's `process.Call` sends on first, `mesh.mod.<module>.call.<tool>.>`; and for a marked
|
||||
verb `mesh.seat.<seat>.tool.<verb>`, the same followed by `.<node>`, and `mesh.seat.<seat>.call.<verb>.<node>.>`.
|
||||
verb of a seat held per node `mesh.seat.<seat>.tool.<verb>`, the same followed by `.<node>`, and
|
||||
`mesh.seat.<seat>.call.<verb>.<node>.>`; for a marked verb of a seat held once for the mesh
|
||||
`mesh.seat.<seat>.tool.<verb>` and `mesh.seat.<seat>.call.<verb>.>`, since its subjects name no node (Q-DL).
|
||||
The bus's deny outranks its allow of `mesh.mod.<module>.tool.>` for each. The tool runner's version on a node is read from the
|
||||
same assignment half revision, its entry for `node-tools` on that node (the module version placed there, design 47
|
||||
G §175), against the version the node-engine's `running.<node>.node-tools` last said running (design 47 G §309);
|
||||
readings that revision names from before that version ran are older. Going back to an older tool runner on a
|
||||
readings whose `at` is before that version ran are older. Going back to an older tool runner on a
|
||||
node leaves the window until its readings update, in which the old deny or none stands; that window is accepted. `Permissions` gains `SubscribeDeny`, written into the user list as the server's
|
||||
subscribe deny, as `PublishDeny` is for publishing. The withheld tools and verbs are named in the grants part's read
|
||||
subscribe deny, as `PublishDeny` is for publishing; the user list's `User` gains `subscribe_deny` beside
|
||||
`publish_deny`, in its comparison and in the differences the grants part says (Q-SD). The withheld tools and verbs are named in the grants part's read
|
||||
of that account (`mesh-grants.grants_user_list`, a field `withheld` with each subject and "its tool runner does not
|
||||
state approval-mark/1"), and in the node-engine's `composition` of the module. *Why:* ADR 0286 §7, §8, §9: the bus
|
||||
state approval-mark/1"), and in the node-engine's `composition` of the module, which reads them through a read verb
|
||||
`withheld` that the seat `mesh-grants`'s definition gains (input `node`; answer each module's withheld subjects and
|
||||
why), never from the grants part's state (Q-NE). *Why:* ADR 0286 §7, §8, §9: the bus
|
||||
enforces the mark; the runner's status of ADR 0286 §7 is read from the grants part's account read, since a runner
|
||||
that does not honour the mark is a version that cannot say so. A call that reaches no responder because its
|
||||
subject is withheld is answered by the mesh MCP server naming `withheld` and the grants part's read. *How it is
|
||||
@@ -148,7 +168,7 @@ file; a node where the file is readable beyond the operator's account is a findi
|
||||
|
||||
8. **The act is digested with operator-channel's client.** For a call of a marked tool or verb, the tool runner
|
||||
builds an `operatorchannelclient.Act` with `address` (as called), `node` (the node that serves it), `module` and
|
||||
`tool`, or `seat` and `verb`, `build` (the digest of the bundle it serves the module from), and `arg.<name>` for each
|
||||
`tool`, or `seat` and `verb`, `build` (the module's fingerprint, from its catalog entry of the version served; Q-BD), and `arg.<name>` for each
|
||||
argument given, a string as itself and any other value as its JSON in RFC 8785's canonical form; an argument left
|
||||
out is not in the act. Its digest is `operatorchannelclient.ActDigest`. *Why:* ADR 0286 §10, §11; the digest is in
|
||||
mesh-contracts since ADR 0627 §1. The TypeScript twin ADR 0286 named is not built: the tool runner is Go, and no
|
||||
@@ -164,9 +184,11 @@ file; a node where the file is readable beyond the operator's account is a findi
|
||||
every asker today), is `<node>.`; never before the router's record it reads through `Record` and `Where`, whose key
|
||||
stays `<module>.<id>` in the seat state `asks`; unless an ask for the same act is
|
||||
open there (§13's `act.` key), in which case it asks nothing new. The ask: `about` the act's digest; `who`
|
||||
`operator`; `expires` 60 minutes after; no `on-expiry`; two options, `approve` (label Approve) and `decline` (label
|
||||
`operator`; `expires` 60 minutes after; `on-expiry` "nothing runs; call again to ask anew", since the client's
|
||||
`Check` refuses an authorising ask without it, and no option is taken on expiry (ADR 0286 §22; Q-OC2); two options, `approve` (label Approve) and `decline` (label
|
||||
Decline), both at level `approve`, each binding the act's digest; the headline "Run <tool> on <node>?",
|
||||
"Run <tool>?" when that is longer than the router allows, ending "Part shown" whenever an argument is not shown
|
||||
"Run <tool>?" when that is longer than the router allows (`HeadlineLength`, 60), and, when that too is longer,
|
||||
the names cut with "…" to fit (Q-HL), ending "Part shown" whenever an argument is not shown
|
||||
whole; the explanation: the first line of the tool's own description, the node, that it was called through the
|
||||
mesh's tools, which cannot tell who called, every argument one per line as "name: value", and the act's
|
||||
fingerprint, its digest's first 24 hexadecimal digits in groups of four. *Why:* ADR 0286 §13, §15, §16, §20 to
|
||||
@@ -193,17 +215,19 @@ file; a node where the file is readable beyond the operator's account is a findi
|
||||
## The runner's record, and the same call again
|
||||
|
||||
13. **The runner keeps its asks and claims in a state of its own, per machine.** The tool runner's manifest asks in
|
||||
`requires` for a state `approvals`, template `state`, `per-machine`, `ttl-seconds` 172,800 (48 hours), cap 64 MiB.
|
||||
`requires` for a state `approvals`, template `state`, `per-machine`, `ttl-seconds` 172,800 (48 hours), and no cap of
|
||||
its own: the `state` template's fixed size holds (ADR 0595 §2; Q-CAP).
|
||||
Its keys: `<node>.ask.<id>`, the asked call as the client keeps it (the ask, the act, the whole arguments, when
|
||||
asked, whether acted on, and `recorded` once `warranted` answered, §16), and `<node>.act.<digest>`, the id of the
|
||||
asked, whether acted on, and `recorded` once `warranted` answered, §16; the client's `Kept` gains `act`, `arguments`
|
||||
and `recorded` for it, Q-KP), and `<node>.act.<digest>`, the id of the
|
||||
newest ask for that act. The runner on each machine is the one writer of its machine's keys; a key is deleted by
|
||||
its time to live, never by hand. A per-machine state reaches today only the key named for its machine; mesh-sdk's
|
||||
per-machine form and the grants part's `stateAccess` gain the keys below it, `<node>.>`, for every per-machine
|
||||
state, a bundle's membership (`stateIssuedFor`, ADR 0260 §18) too, in the same form: one more subject per
|
||||
per-machine state on each account, and every module's per-machine keys keep their form; mesh-sdk's rebuild of it
|
||||
rides in G's group. The cap is the bucket's, shared by every machine's keys. A write the bus refuses (the cap
|
||||
rides in G's group. That size is the bucket's, shared by every machine's keys. A write the bus refuses (the size
|
||||
reached, or any other) fails closed under §19 and is said in the answer; `mesh_approvals` reports the bucket's fill
|
||||
against its cap, saying that the fill and the cap are every machine's together. A run still unrecorded (§16) an hour before its key's 48 hours end is written in the runner's log
|
||||
against the template's size, saying that both are every machine's together. A run still unrecorded (§16) an hour before its key's 48 hours end is written in the runner's log
|
||||
as an error naming the ask; this is written only while the runner runs, so a machine asleep through that hour keeps
|
||||
only the `call-unanswered` history of §16, which is accepted.
|
||||
*Why:* ADR 0286 §24, §30 kept the waiting call in the runner's record and claimed a warrant in the node's own file,
|
||||
@@ -211,12 +235,13 @@ file; a node where the file is readable beyond the operator's account is a findi
|
||||
compare-and-set in a module's bus state (ADR 0259 §10, ADR 0627 §1), and a per-machine state (ADR 0595) is one
|
||||
writer per machine, so the file is not built. The keys below the machine's own depart from ADR 0260 §16 (a
|
||||
per-machine state reaches only its machine's key), the design's choice following the operator's answers of
|
||||
2026-11-11 (the gate built in G); the cap and the key form are the design's choices too. *How it is
|
||||
2026-11-11 (the gate built in G); the key form is the design's choice too. *How it is
|
||||
checked:* unit, the manifest test of `node-tools` holds the entry; the grants part's composition table holds the
|
||||
`<node>.>` reach and no other node's; integration, §22's whole test reads the keys.
|
||||
14. **The same call again is judged on the router's record.** When a call of a marked tool comes and `<node>.act.`
|
||||
names an ask, the runner reads the router's own record of that ask under the module's name (`Client.Where`, the
|
||||
seat state `asks`, key `<module>.<id>`), never a record of its own or the caller's; it composes the ask again from
|
||||
seat state `asks`, key `<module>.<id>`, whose value in operator-channel's definition gains the `warrant` it already
|
||||
carries, so the definition names what `Where` reads; Q-OC1), never a record of its own or the caller's; it composes the ask again from
|
||||
the act and holds the warrant to it with `operatorchannelclient.For` (the same asker and ask, the ask's digest, a
|
||||
person's choice, an option offered, at its level, before it expired); it requires the option to be `approve` and
|
||||
the act to be the one it bound (`operatorchannelclient.Performs`: the same node, build and every argument); and it
|
||||
@@ -231,7 +256,7 @@ file; a node where the file is readable beyond the operator's account is a findi
|
||||
16. **The call runs, and its warrant is recorded, across a restart too.** Once the checks pass, the runner runs the
|
||||
call and answers with the tool's own answer and a line naming the approval ("run on the operator's approval via
|
||||
<channel> at <time>, ask <id>"). It then calls `mesh-hand-acts.warranted` with `asker` (the module) and `ask` (the
|
||||
id) as a kept call (ADR 0668 §1, §2: the verb takes it once per ask), and on its answer writes `recorded` on
|
||||
id) as a kept call (ADR 0668 §1, §2: the verb takes it once per ask) through mesh-sdk's `busretry` (Q-KC), and on its answer writes `recorded` on
|
||||
`<node>.ask.<id>`. At each start the runner calls `warranted` again for every acted, unrecorded ask its keys hold,
|
||||
within their 48 hours, each named in its `findings-stated`'s `pending` until it is made (design 47 G §384). One
|
||||
unanswered after five minutes is the runner's finding `<node>.<ask id>.call-unanswered` in its state `findings`,
|
||||
@@ -252,7 +277,8 @@ file; a node where the file is readable beyond the operator's account is a findi
|
||||
fingerprint, read from §13's state, and the marks it applies, each module's marked tools and verbs with their
|
||||
source (its module's entry in the catalog half or its seat's definition) and the catalog revision read; given an ask's id, its whole
|
||||
arguments and the act's digest; given `cancel` and an ask's id, it takes that open ask back (`Client.Cancel`),
|
||||
recorded first in the hand-act log through `mesh-hand-acts.hand-act` with who and why, and refused when the record
|
||||
recorded first in the hand-act log through `mesh-hand-acts.hand-act` with why, the verb taking who from the caller
|
||||
it proves (Q-HA), and refused when the record
|
||||
cannot be written. `mesh_describe` answers, for a marked tool or verb, `needs-approval` with its source. *Why:*
|
||||
ADR 0286 §25 (the runner's `approvals`), named as the mesh MCP server's own tools are; a tool reads everything a
|
||||
module holds and does by hand what it does by itself (the operator's instruction of 2026-10-25). *How it is
|
||||
@@ -266,7 +292,7 @@ file; a node where the file is readable beyond the operator's account is a findi
|
||||
`mesh-delivery-assigner.views.seat-holders`, which the tool runner consumes; the seat list names no holders); the
|
||||
router refuses the ask; the ask cannot be published; the router's record cannot be read; §13's state cannot be read
|
||||
or written, in which case no marked call runs on that machine until it can, the failed read or write being made
|
||||
again as a kept call (ADR 0668 §1) until it succeeds; or the marks are not yet read. Before
|
||||
again as a kept call (ADR 0668 §1, through `busretry`) until it succeeds; or the marks are not yet read. Before
|
||||
the first view of the catalog half is read, a call waits for it within its 5 seconds and is then judged, asking
|
||||
nothing while the marks are unread; still unread, it is refused, naming `mesh_first_views`. When §13's state has
|
||||
been unreadable or unwritable for five minutes, the runner raises its finding `<node>.approvals.approvals-unreadable`
|
||||
@@ -278,8 +304,11 @@ file; a node where the file is readable beyond the operator's account is a findi
|
||||
`views.seat-holders` with none and with one; and a row where the state fails, the finding is raised after five
|
||||
minutes, the state recovers with no further call, and the finding clears.
|
||||
20. **The terminal is not exempt.** A marked tool called through `mesh-cli` or any caller asks as every call does: the
|
||||
runner cannot tell who called. *Why:* ADR 0286 §41. *How it is checked:* the code review reads that the gate sits
|
||||
on the call's handler, before the bundle, and that no path to a bundle passes around it.
|
||||
runner cannot tell who called. *Why:* ADR 0286 §41. The gate wraps every handler the runner serves, a bundle's
|
||||
tools and seat verbs and the runner's own tools beside them (the ledger repairs) alike (Q-LR); the act, the ask,
|
||||
the check, the claim, the recording and the refusals of §8 to §19 are all in `node-tools/internal/approval` (Q-PK).
|
||||
*How it is checked:* the code review reads that the gate sits on every handler, before the bundle, and that no path
|
||||
to a bundle or a runner's own tool passes around it.
|
||||
|
||||
## Marked first
|
||||
|
||||
@@ -290,7 +319,8 @@ file; a node where the file is readable beyond the operator's account is a findi
|
||||
tools on every node (the seat `node-reads`, ADR 0310; issue 418 resolved 2026-10-12, answering on every node since
|
||||
2026-10-16). *How it is checked:* live, as the acceptance says.
|
||||
- **The forge's two acts on a trunk's protection are marked.** The forge module (mesh-catalog `modules/gitea`)
|
||||
gains a tool `gitea_branch_protection_loosen`, marked in its `needs-approval`, which alone performs the two acts
|
||||
gains a tool `gitea_branch_protection_loosen`, marked in its `needs-approval`, taking `owner`, `repo`, `branch`,
|
||||
`act` (`remove-protection` or `allow-force-push`) and `why` (Q-FG), which alone performs the two acts
|
||||
`gitea_branch_protection_set_full` refuses today: removing a trunk's protection, and allowing a force-push onto
|
||||
a trunk; `gitea_branch_protection_set_full` keeps refusing both and its refusal names the new tool. The manifest
|
||||
gains `operator-channel` in `uses`. No other tool or verb is marked in this milestone. *Why:* the forge's own
|
||||
@@ -313,12 +343,15 @@ file; a node where the file is readable beyond the operator's account is a findi
|
||||
operator's Approve written as the router's record, the call again, the run, the hand-act, `mesh_approvals`, and a
|
||||
restart between the run and `warranted`'s answer. The client's `KeyPrefix` (§10) has a row in mesh-contracts'
|
||||
client test: every key of its own `State` written and read carries it, an empty prefix writes today's keys, and
|
||||
with a prefix set `Where` still reads `<module>.<id>`. *Why:* the operator's test budget (one whole test over many small
|
||||
ones). *How it is checked:* the check counts the module's tests against its budget.
|
||||
with a prefix set `Where` still reads `<module>.<id>`. The mesh MCP server's `TestMeshWaitIsAnnouncedAmongSeven` counts eight
|
||||
tools with `mesh_approvals` (Q-T). New test functions are allowed within each module's budget of 500 unit and 50
|
||||
integration tests, and a module over it shrinks toward it with each change (Q-TB). *Why:* the operator's test
|
||||
budget (one whole test over many small ones). *How it is checked:* the check counts each module's tests against
|
||||
its budget.
|
||||
23. **In G's delivery group, ordered by the module graph.** The members are pushed and checked in design 47 milestone
|
||||
G's group, with design 34's milestone every-event. The orders are the module graph's: the indexer's manifest
|
||||
validator and catalog graph entry that read `needs-approval` before any manifest or seat definition carrying it (a
|
||||
reader edge, design 47 G §89); and the grants part that composes the deny of §6 before the seat definition marking
|
||||
reader edge, design 47 G §89, whose list covers `needs-approval`; Q-RE); and the grants part that composes the deny of §6 before the seat definition marking
|
||||
`execute` (an edge of the seat definition's readers), so no machine serves `execute` unasked between the two.
|
||||
*Why:* the operator, 2026-11-11, "Build the gate in G"; the operator, 2026-11-03, a change is designed as it should
|
||||
be and its delivery is the delivery system's. *How it is checked:* the delivery plan names both edges.
|
||||
|
||||
Reference in New Issue
Block a user