From 7e158c739ebc2aed4e81d55a9eb2a850ff41488a Mon Sep 17 00:00:00 2001 From: jochen Date: Thu, 8 Oct 2026 18:40:58 +0200 Subject: [PATCH] Say how a module of its own account is served, and how the root probe is checked --- ...annel-answers-it-and-the-asker-acts-on-a-warrant.md | 10 ++++++---- .../01-to-be/46-the-conversation-with-the-operator.md | 8 ++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/02-DECISIONS/0259-an-ask-is-a-message-on-the-bus-any-channel-answers-it-and-the-asker-acts-on-a-warrant.md b/02-DECISIONS/0259-an-ask-is-a-message-on-the-bus-any-channel-answers-it-and-the-asker-acts-on-a-warrant.md index e4ac4cc4..61d732b4 100644 --- a/02-DECISIONS/0259-an-ask-is-a-message-on-the-bus-any-channel-answers-it-and-the-asker-acts-on-a-warrant.md +++ b/02-DECISIONS/0259-an-ask-is-a-message-on-the-bus-any-channel-answers-it-and-the-asker-acts-on-a-warrant.md @@ -286,8 +286,9 @@ The revision rests on three rules. - The **router** (`operator-channel`'s holder) and **every channel that declares `verified-sender`** run as their own process, as their own service account (`messenger`, `telegram`), with a bus account of their - own: an own secret `broker`, owned by that account, mode 0600. They are not carried by the tool runner. - Their tools are served by their own process on their own tool subjects. + own: an own secret `broker`, owned by that account, mode 0600. The manifest says so with `runs-as`; the + controller composes for such a module a runtime of its own — the machine's runtime program, run as that + account, serving that module alone on that credential — and the machine's runtime never carries it. - **The controller refuses to compose** into any runner's user, or into any principal whose process runs as the node's operator account: - publishing on a by-caller event of `operator-channel` (a warrant); @@ -345,7 +346,7 @@ router issues no approve warrant, and the condition says what to change. caller-named and per-kind grants; `proof` subjects; the asker's read of its own prefix. 2. **The tool runner (mesh-tools)** carries a bundle's seat traffic: publishing an accept or an event with its own name or kind, taking a held seat's work, asking and answering a proof, a compare-and-set - on its state, and starting a bundle as its own account. + on its state, and serving one module alone when it runs on that module's own account. 3. **The shared library (mesh-sdk):** an asker's client (ask, cancel, read its state, take its warrants) and a channel's (take show, edit and send for a kind; publish a choice or a link; send a proof). 4. **The messenger** becomes the router of this record: asks, tokens, identities, judging, warrants, @@ -397,7 +398,8 @@ Telegram, or from the mesh MCP server." The asker's words never name a channel. | `verified-sender` reaches the router only from a holder with its own account on a machine no agent can become root on | controller test stripping the capability; self-check probe raising the condition | | Unlinking and a relink within a day are approve asks answered on the linked account; the notice reaches it first | router tests, with a fake channel that honours the addressee | | No bus variable reaches a bundle | tool runner test over a bundle's environment | -| The `telegram` bundle runs as its own account, never root or the operator's | tool runner tests: a bundle naming `MESH_RUN_AS` is started as that account; root and the operator's account refused; the manifest's owners checked by the catalogue's manifest test | +| A module of its own account is served by a runtime of its own, as that account, on its own bus credential, and never by the machine's | controller composition test (`runs-as`); registration refuses root, an account the module does not make, secrets it does not own, no broker; the tool runner test that such a runtime serves that module alone | +| While an agent can become root without a person where the router or a verified channel runs, it is said and nothing proven there approves | controller probe test (fails with agents as the operator's account, and with the login shell running as an account with passwordless sudo; passes once neither holds); the sudo module's `sudo_escalation` test; router test refusing approval | | A tool call never publishes an intake event or a proof | tool runner test: only a bundle's own channel reaches the seat publish, for its own kind | | The asker acts once per warrant and records the warrant | shared library test; controller test reading the hand-act after a warrant | | The controller holds no channel code | review; the controller's module imports no channel package | diff --git a/03-DESIGN/01-to-be/46-the-conversation-with-the-operator.md b/03-DESIGN/01-to-be/46-the-conversation-with-the-operator.md index e0ba5f0d..65af49a9 100644 --- a/03-DESIGN/01-to-be/46-the-conversation-with-the-operator.md +++ b/03-DESIGN/01-to-be/46-the-conversation-with-the-operator.md @@ -482,10 +482,10 @@ needs the lost factor's code. So: placed, on a machine where no agent's account can become root without a person. - **Its own module**, `telegram`, holding the bot token as its own secret; the router keeps no Telegram client. *Amended 2026-10-08, ADR 0259:* **it runs on the control node under its own account `telegram`**, - never root or the operator's: the tool runner starts its bundle as that account, its state directory and - token belong to it, and the bus credential stays the runner's. If an agent holds root there, none of - this holds; the self-check raises a condition when the operator's account can become root without a - person. + never root or the operator's: a runtime of its own serves it as that account, on a bus account of its own + (`runs-as`), and its state directory, token and bus credential belong to it. If an agent holds root there, + none of this holds; the self-check raises a condition while an agent can become root without a person, by + its own account or through a tool that runs its command as one that can. - **Long polling**, never a webhook; the update offset kept in its own state. - **Buttons** carry only the router's one-time token (Telegram allows 64 bytes); everything else is in the router. A tap is dropped and reported unless both the user and the chat are