From ac294e7b862849802cea4be318992d5bb32897f7 Mon Sep 17 00:00:00 2001 From: jochen Date: Thu, 12 Nov 2026 11:49:19 +0100 Subject: [PATCH 1/2] Design 39 parts: build the licence manager as four parts of one manifest and let the finished carry-over leave The operator asked for the manager built as clean as possible, one manifest of several parts. The seat's verbs stay on the runtime of its own, since a process account answers none; the tools that only read get a bundle of their own so they answer while the manager fails; the carry-over ran live, so its code and the store database's and grant-key's requirements leave now and retire on the operator's Approve. The glossary names the two senses of part. --- 00-META/glossary.md | 2 + 03-DESIGN/01-to-be/39-milestones/parts.md | 216 ++++++++++++++++++ .../39-the-anthropic-licence-manager.md | 48 +++- 3 files changed, 256 insertions(+), 10 deletions(-) create mode 100644 03-DESIGN/01-to-be/39-milestones/parts.md diff --git a/00-META/glossary.md b/00-META/glossary.md index a454bc47..3c41dd69 100644 --- a/00-META/glossary.md +++ b/00-META/glossary.md @@ -1527,6 +1527,8 @@ renaming one sense, the old sense moves to a *Not:* line and becomes mechanical. | | the notice that mail matters | **mail signal** | Mail | | conversation | the domain *Operator and conversation* | the domain's name | Operator and conversation | | | the mail questions and answers on the mail page | **mail conversation** | Mail | +| part | one independent process of the delivery domain with its own bus credential (ADR 0429 §1) | the part by its name (the **indexer**, the **gate part**, the **grants part**) | Delivery | +| | one of the pieces a module is built of: a bundle, or a resource that places or runs one, in one manifest (ADR 0040; design 20 *What a module is built of*) | **a module's part** (its manager bundle, its tools bundle, its settings file) | Module | ## How this page is kept diff --git a/03-DESIGN/01-to-be/39-milestones/parts.md b/03-DESIGN/01-to-be/39-milestones/parts.md new file mode 100644 index 00000000..3714011f --- /dev/null +++ b/03-DESIGN/01-to-be/39-milestones/parts.md @@ -0,0 +1,216 @@ +--- +layer: to-be +design: 39 +milestone: parts +updated: 2026-11-12 +code: [mesh-catalog modules/claude-licence-manager] +decisions: + - "ADR 0183" + - "ADR 0050" + - "ADR 0054" + - "ADR 0040" + - "ADR 0192" + - "ADR 0198" + - "ADR 0259" + - "ADR 0349" + - "ADR 0436" + - "ADR 0570" + - "ADR 0230" + - "ADR 0595" + - "ADR 0672" + - "ADR 0675" +--- + +# Design 39, milestone parts — the licence manager built of its parts + +**What it builds.** The module holding the seat `anthropic-licence-manager` is one manifest built of four parts, +each in a form the manifest validator accepts and the builder, the node-engine and the tool runner honour today +([design 20](../20-writing-a-module.md) *Who reads a manifest* and *What a module is built of*; playbook +[06](../../../00-META/process/06-writing-a-module.md) *Where the parts of the mesh read a manifest differently*): the +manager bundle, which runs long and answers the seat's verbs and every act; the tools bundle, which answers the +module's reading tools; the settings file; and the module's account with its directory. The carry-over from the store +database, done live, leaves the module whole in this milestone, with its requirement of the database and of the secret +`grant-key`, and both provisions then retire on the operator's Approve. The whole shape is in the design's main file +([39](../39-the-anthropic-licence-manager.md)); this part holds every line the milestone builds, cited as "design 39 +parts §n". + +**Why now.** The operator, 2026-11-12: "build the anthropic-licence-manager as clean as possible"; a module is one +manifest with several parts; the seat stays named for the vendor (ADR 0183 §4, ADR 0050, ADR 0054), and a second +vendor is a module of its own. That morning the operator had said "the licence manager module should have a service +part and a tools part" (design 39 bus-and-switch C1). Today, after milestone bus-and-switch, one Go bundle `code` does +everything in one program: it runs long, answers the seat's ten verbs and the module's eight tools, and keeps the +carry-over's code, which ran once, live, at 2026-11-12 09:44:59Z, carrying every row of every table (issue 1409's note +of that morning); for that code alone the module still requires `postgres-database` and the secret `grant-key` +(bus-and-switch A3, B15). + +**Where.** One repository, mesh-catalog, and one of its modules, `claude-licence-manager`; hq carries this part, the +main file and the glossary. No other module changes: every verb, event and provision the manager uses is served today +(§17). + +**The shape at a glance.** + +| a module's part | its artifact | how it runs | its account | what it keeps or reads | +|---|---|---|---|---| +| the manager | `manager`, a Go bundle, binary `claude-licence-manager` | loaded by the module's runtime of its own; runs long and answers the seat's ten verbs and the three acting tools | the module's account `claude-licence-manager`, on the runtime's bus account | writes all its kept data (bus-and-switch §1 to §9) and its two logs; reads its key pair and settings file | +| the tools | `tools`, a Go bundle, binary `claude-licence-manager-tools` | loaded by the same runtime; answers the four reading tools | the same | reads the kept data and the logs, writes nothing | +| the settings | `files`, an archive of the templates directory | the `settings` file resource, written by the node-engine | owned by the module's account | holds the eleven settings mesh-config sets | +| the account and its directory | none | the `user` resource `account` and the `directory` resource `state` | `claude-licence-manager` | the key pair, the settings file, the runtime's `broker` secret | + +## The module's parts + +1. **The module is four parts in one manifest, and runs no process resource, container or run-once step of its + own.** `build.artifacts` names exactly `manager`, `tools` and `files`; `resources` names exactly `account`, + `state` and `settings`, in that order; the module's runtime of its own is the process the node-engine composes for + `runs-as` (design 20 *A runtime of its own*), never one the manifest writes. Why: the operator, 2026-11-12; a module + is one piece of software built of parts (ADR 0040); principle 7 (fewer parts). How it is checked: the manifest + validator accepts the manifest at the change's check, and the composition step composes it for the manager's + machine; a catalog test of the module reads its manifest and fails on any other artifact or resource, a `process` + or `container` resource, or a `run-once` field. +2. **The manager bundle runs long and answers the seat's verbs.** The artifact `manager` (today's `code`, renamed): + kind `bundle`, `language` go, `system` arch, `from` `cmd/manager`, `binary` `claude-licence-manager`, `loads` + that binary, and `env` with exactly two words, `MESH_LICENCE_STATE` (`${dir:state}`) and `MESH_LICENCE_SETTINGS` + (`${dir:state}/settings.json`). It is loaded by the module's runtime of its own and runs long (ADR 0198 §1, §2: a + bundle may serve tools, run long, or both): its usage timer, its refresh cadence, the switch rule on each reading, + its consumption of `claude-code.holdings-changed`, the conditions it judges at its start, and every event of + bus-and-switch §21 to §27. It registers the seat's ten verbs (`licences`, `bindings`, `bind`, `switch`, + `release`, `refresh`, `usage`, `adopt`, `current`, `public-key`) under the seat and the three acting tools of §4 + under the module. It is the only part that writes the module's kept data and logs, emits, calls the vendor, calls + the vault, tells the operator and reads the key pair. Why: one rotation source (ADR 0183 §6); the binary keeps its + name so the runtime's journal and the loaded entrypoint stay as they are. How it is checked: unit tests as + bus-and-switch has them, moved with the code; the catalog test of §1 reads the artifact's fields. +3. **The tools bundle answers the module's reading tools, and writes nothing.** The artifact `tools`: kind `bundle`, + `language` go, `system` arch, `from` `cmd/tools`, `binary` `claude-licence-manager-tools`, `loads` that binary, and + no `env`: the runtime hands a module's words to all its bundles (ADR 0192), so it reads `MESH_LICENCE_SETTINGS` + from the manager bundle's words, and a word two bundles gave different values would be refused at composition. It + registers under the module the four reading tools, `licences_switches`, `licences_settings`, `licences_kept` and + `licences_conditions`, with the arguments and answers of bus-and-switch §37, §40, §41 and §43. It reads the + module's kept data with the runtime's bus-state calls and the logs `usage` and `audit` with the runtime's log + calls, each answered as the module whose bundle asks; it calls `seat:mesh-config.config` for `licences_settings` + (bus-and-switch B18). It writes no key, appends to no log, emits nothing, subscribes to no event, asks no + heartbeat, calls neither the vendor nor the vault and opens neither the key pair nor a secret. Why: principle 4 + (everything a module holds can be read): the runtime serves the tools of every bundle of a module that loaded, so + these four still answer while the manager bundle fails to load or stops; C1 (the tools act only through the running + manager) holds, since these do not act; principle 1 governs reading between modules, and both bundles are the one + module reading its own data. How it is checked: a unit test of the tools bundle runs each tool against a fixture + of the runtime's calls and fails on any write, append, emit or subscribe; whole, with the manager bundle refusing to + start, `licences_kept` answers every entry. +4. **Every act is the manager's.** The three tools that act, `licences_read_usage`, `licences_switch_now` and + `licences_resync` (bus-and-switch §38, §39, §42), are registered by the manager bundle beside the seat's verbs, and + no act is answered by the tools bundle. A person's act on a consumer or a licence stays a seat verb (`bind`, + `switch`, `release`, `refresh`, `adopt`). Why: C1 (no tool keeps a second copy of what the manager does); + ADR 0183 §6; principle 7 (no call between the two bundles, so no path the mesh lacks). How it is checked: the + catalog test of §1 finds the module's `tools` to be exactly the four of §3 and the three of this line; a unit test of each + bundle lists what it registers. +5. **The code both bundles share is one package of the module.** The package `internal/licences`, in the module's + one Go module, holds the layouts of the kept data and of the log entries (bus-and-switch §2 to §9), the key form + (§10), the names of the entries, and the settings with their defaults, bounds and validity (§33, B37); `cmd/manager` + and `cmd/tools` each import it, and neither holds a copy of what it holds. Why: a layout in one place, so the reading + tools never read a form the manager no longer writes; it is code the module owns alone (design 20 *Where a seat's + code goes*: a module's own package). How it is checked: the review reads that no type of a kept entry is declared + in either command package; `go vet ./...` at the module's root builds both. +6. **The settings file stays, without the database's template.** The resource `settings` (a `file` at + `${dir:state}/settings.json`, mode 0600, owner `claude-licence-manager`, `template` `files/settings.json`, + `merge` json, `takes-config` the eleven settings of bus-and-switch §33 and today's five) and the archive `files` + (`from` `files`, the one archive the templates are read from, ADR 0349 §2) stay as they are. The template + `files/database.url` is deleted. Why: the manager reads its settings at every reading (bus-and-switch §33); the + database's address has no reader once §9 holds. How it is checked: the composition step writes the file; the catalog + test of §1 finds no file under `files` but `settings.json`. +7. **The account, its directory and the runtime's secret stay.** `runs-as` `claude-licence-manager`, `secrets-owner` + the same, the own secret `broker` at `${dir:state}/broker`, the `user` resource `account` and the `directory` + resource `state` (mode 0700, owner the account, `place` `.`, `unknown` `program`) stay as they are; the key pair + `manager-key.json` stays in that directory, read and made only by the manager bundle (C2). No `runtime-health` is + added: the node-engine's judgement that the runtime is alive stands as its health. Why: design 20 *A runtime of its + own*; principle 7. How it is checked: the catalog test of §1. +8. **The seat's verbs are answered on the bus account of the runtime of its own, never by a process account.** The + manager bundle answers the verbs through the runtime that `runs-as` gives the module (ADR 0259 §8; ADR 0436 §5: + `runs-as` is unchanged and still gets a runtime of its own), as the router answers the operator channel's. The + manager is not a `process` resource with `bus`: a process account is granted no subject on which a tool or a seat's + verb is answered and holds no seat (ADR 0436 §3), which only ADR 0672 §7 lifts, for the recovery module, and + ADR 0675 §1 and §2, for the bus module's keeper; and a process account's grant names events, work queues, states, + asks and calls (ADR 0436 §1), never the old-section logs `usage` and `audit` the manager appends to (C3). Why: these + records. How it is checked: the catalog test of §1 finds no `process` resource and no `bus` key in the manifest; + whole, after the delivery, `anthropic-licence-manager.licences` answers through the mesh MCP server. + +## The carry-over leaves + +9. **The carry-over is done, and its code leaves the module now.** The carry-over (bus-and-switch §11 to §13) ran on + 2026-11-12 at 09:44:59Z, every table's count equal and no lease live (issue 1409's note of 10:4x CET). In this + milestone the code that reads the store database, the carry-over itself, the opening of grants at rest with + `grant.key`, the gate that answers "the carry-over has not ended", the condition `carry-over-failed` and its + recovery go, with the postgres driver in the module's `go.mod`. No run-once step is built for it: no row is left to + carry, a fresh install has no database (bus-and-switch §11: read as no rows), and a run-once process with a bus + account could not append to the logs (§8). Why: bus-and-switch A3, B15 and §14 named this change as the module's + next; principle 7. How it is checked: the module's `go.mod` requires no postgres driver; a unit test fails on the + words `DATABASE_URL_FILE` or `MESH_LICENCE_KEY_FILE` anywhere in the module's code. +10. **What leaves the manifest, and what stays of the carry-over.** `requires` loses `postgres-database` and `secret`; + `contributes`, `binds` and the whole `secrets` section go; `env` loses `DATABASE_URL_FILE` and + `MESH_LICENCE_KEY_FILE`; the resource `database-url` goes; the tool `licences_carried` goes. The kept-data entry + `carried` stays, with its one key `postgres` as the record of the carry-over, read by `licences_kept`; nothing + writes it again. Why: removing the entry would drop kept data, which needs a warrant and a snapshot (ADR 0595 §5), + for nothing gained; principle 7. How it is checked: the catalog test of §1; after the delivery `licences_kept` + with `entry` `carried` answers the record of 09:44:59Z. +11. **The manager starts without waiting for a carry-over.** At its start the manager bundle judges each kind of + condition anew from its own state and says cleared each key of `conditions` it no longer holds (bus-and-switch + §9), `carry-over-failed` among them when present; then it says `holdings.asked` (B12) and starts its timers. It + reads `carried` never. Why: bus-and-switch §9, B12. How it is checked: unit, a start with a `carry-over-failed` key + in `conditions` says it cleared once and deletes the key. +12. **The pull request waits on two readings.** Before the push, the lead reads `licences_carried` of the running + build answering `carried.postgres` with every table's read equal to its written, and `mesh-vault.secret_holders` + listing `licence..grant` and `licence..access` for every licence `licences` answers, and writes both + readings in the milestone file. Why: bus-and-switch §14 and §20 (the database's requirement goes only once the + carry-over is done and no grant is left outside the vault); principle 3. How it is checked: the code review finds + both readings in the milestone file. + +## The store database retires + +13. **Both provisions retire, each on the operator's Approve, asked by the provisioner.** Once the new build's want + moves, no want needs this module's `postgres-database` nor its secret `grant-key`, so the holder of + `mesh-provisioner` marks both keys `retiring` and raises one ask each on the operator channel, saying what is + removed from which provider on which node (ADR 0570 §5). On the warrant postgres retires the consumer's account of + the database `claude_licences` and the vault removes `grant-key`; on a decline both stay retiring. The module asks + nothing. Before the delivery starts, the lead tells the operator that these two asks will come and what each + removes. Why: ADR 0570 §5; this replaces bus-and-switch §20's `mesh-vault.retire` of `grant-key`. How it is + checked: after the delivery `operator-channel.asks` holds both asks; after each warrant the provision's key is gone. +14. **The database's data is removed only by the operator.** Retiring keeps the database `claude_licences` and its + data (ADR 0570 §5). Its removal is a person's act, the postgres module's tool `provisioner_delete` called through + the mesh (ADR 0230 §5, §34): after both warrants the lead asks the operator for it, saying it removes the store's + copy of the licences, bindings, grants sealed with `grant-key`, usage and audit, whose every row is on the bus or + in the vault (§12). Why: ADR 0570 §5, ADR 0230; data removed is the operator's. How it is checked: + `mesh-store.databases` lists `claude_licences` until the operator's call and not after it. +15. **The files the database's requirement wrote leave the state directory with it.** `database.url` is the + resource `database-url`, which the node-engine removes as it removes every resource that leaves a declaration + (playbook 06, step 5); `database.json`, `database.secret` and `grant.key` are the files it wrote for the + requirements of §10, and whether it removes such a file when its requirement leaves is not known (a guess that it + does). A file left behind is a fault of the node-engine, noted on its issue and never removed by hand. Why: + principle 2. How it is checked: after the delivery, `node-reads.list` of the module's state directory on the + manager's machine lists none of the four. + +## Delivery + +16. **One pull request in mesh-catalog, with hq.** The module's change is one mesh-catalog pull request; hq's pull + request carries this part, the main file and the glossary. Why: one milestone, one release (the operator's + instruction on designing a change as it should be). +17. **No order between modules; within the module, the node-engine's.** The change adds no served verb, provision + or event and drops none another module uses: the manager still calls `seat:mesh-vault.licence-put` and + `seat:mesh-vault.get`, `seat:operator-channel.tell`, `seat:mesh-config.config` and `claude-code.claude_code_grant`, + and consumes `claude-code.holdings-changed`, each served or said today, so the delivery plan derives no edge. On + the manager's machine the node-engine writes the state directory and the settings file, unpacks both bundles, and + restarts the module's runtime once, since its `restart-on` names every bundle's archive; the runtime then loads + both. The kept data keeps its names and form, so no restore point is taken (ADR 0672 §1 is for a form change), and + the delivery itself moves no data; a node's agent keeps its last token, which lives hours, while the runtime + restarts. Why: the module graph orders deliveries; ADR 0595 §11. How it is checked: the delivery plan names one + module and no edge. + +## Acceptance + +18. **The tests of the milestone**, each run in the module's suite or live after the delivery: + - the manifest is accepted by the manifest validator, built by the builder and composed by the node-engine for + the manager's machine, with the artifacts and resources of §1 and nothing else (§1 to §8); + - after the delivery the runtime serves the seat's ten verbs and the module's seven tools, the four reading tools + from the tools bundle (§2 to §4); + - with the manager bundle refusing to start, the four reading tools still answer (§3); + - the module's code names no database and no `grant.key` (§9), and `licences_kept` answers the carry-over's record + (§10); + - after the delivery the provisioner holds both retiring asks, and after the operator's call the database is gone + (§13, §14); + - the state directory holds none of the database's files (§15). diff --git a/03-DESIGN/01-to-be/39-the-anthropic-licence-manager.md b/03-DESIGN/01-to-be/39-the-anthropic-licence-manager.md index fa9209a8..174d2009 100644 --- a/03-DESIGN/01-to-be/39-the-anthropic-licence-manager.md +++ b/03-DESIGN/01-to-be/39-the-anthropic-licence-manager.md @@ -2,7 +2,7 @@ layer: to-be status: in-progress code: [mesh-catalog modules/claude-licence-manager, mesh-catalog modules/claude-code, mesh-catalog modules/mesh-vault] -updated: 2026-11-11 +updated: 2026-11-12 decisions: - "ADR 0550" - "ADR 0595" @@ -25,6 +25,13 @@ decisions: - "ADR 0126" - "ADR 0132" - "ADR 0159" + - "ADR 0040" + - "ADR 0192" + - "ADR 0198" + - "ADR 0259" + - "ADR 0436" + - "ADR 0672" + - "ADR 0675" --- # 39 — The Anthropic licence manager @@ -56,13 +63,29 @@ sections below hold as first written.* A module, `claude-licence-manager`, holding the mesh-scoped seat **`anthropic-licence-manager`**. One holder, on the node the operator assigns it to — the control node is the natural one, and nothing in the -definition says so. It requires a database for its own store and the bus; it claims the seat; it serves -the seat's verbs. It has no port, no route, no file under anyone's home. +definition says so. It claims the seat and serves the seat's verbs. It has no port, no route, no file under anyone's +home. + +**It is one manifest built of four parts** (ADR 0040; milestone parts, its part +[39-milestones/parts.md](39-milestones/parts.md)), each in a form the manifest validator accepts and the builder, the +node-engine and the tool runner honour today ([20](20-writing-a-module.md)): + +| a module's part | its artifact | how it runs | +|---|---|---| +| the manager | a Go bundle | loaded by the module's runtime of its own (`runs-as`), under the module's account: it runs long (the usage timer, refreshes, the switch rule, the conditions), answers the seat's verbs and every tool that acts, and alone writes what the module keeps (ADR 0198 §1, §2) | +| the tools | a Go bundle | loaded by the same runtime: the tools that only read the module's kept data and logs, served while the manager fails | +| the settings | the templates' archive | the settings file the node-engine writes from the template and mesh-config's values | +| the account and its directory | none | a `user` and a `directory` resource | + +The seat's verbs are answered on the bus account of the runtime of its own (ADR 0259 §8, ADR 0436 §5), never by a +process account, which answers no seat's verb (ADR 0436 §3, lifted only for the recovery module, ADR 0672 §7, and the +bus module's keeper, ADR 0675 §1, §2). **It keeps all its data in the bus's own storage, by the kept-data templates, and requires no database** (ADR 0595, ADR 0596; the operator, 2026-11-11). Built in milestone bus-and-switch (§1 to §14 of its part), which carries -today's store database over at the manager's first start, reading it and never writing it; the module's next change -drops the database, which is then retired on the operator's Approve (principle 7; its answer A3): +today's store database over at the manager's first start, reading it and never writing it (done live on +2026-11-12); milestone parts drops the carry-over's code and the database's requirement, which then retires on the +operator's Approve (ADR 0570 §5), its data removed only by the operator (principle 7; its answer A3): | entry | template | holds | |---|---|---| @@ -72,12 +95,13 @@ drops the database, which is then retired on the operator's Approve (principle 7 | `offered` | state | one key per grant a node offered, with its outcome | | `usage` | log | every reading, raw beside normalised (ADR 0054), 35 days | | `audit` | log | every adoption, refusal, rotation, binding, switch and setting, kept for good | -| `carried` | state | the record of the one carry-over from the store database | +| `carried` | state | the record of the one carry-over from the store database, kept and never written again (milestone parts §10) | | `conditions` | state | each condition it said on the operator channel, so a restart can clear what it said | -Every grant and token is the vault's (*Every grant in the vault*, above). Until the milestone is delivered, the -module keeps its store database, its tables `licence` (with the grant encrypted at rest with a key the vault made for -the manager, ADR 0050's carve-out), `binding`, `lease`, `offered`, `usage` and `audit`. +Every grant and token is the vault's (*Every grant in the vault*, above). Until milestone parts is delivered, the +module still requires its store database, its tables `licence` (with the grant encrypted at rest with a key the vault +made for the manager, ADR 0050's carve-out), `binding`, `lease`, `offered`, `usage` and `audit`, read by the +carry-over's code alone and written by nothing. ## 2. The licences it manages today @@ -237,13 +261,17 @@ through mesh-config. | a reading at the threshold moves every consumer of that licence to the one with the most room, said as an event and to the operator | bus-and-switch §26 to §28 | | no licence with room raises one condition, cleared by a reading with room; a licence near its limit is warned about once | bus-and-switch §29, §30 | | every entry the manager keeps is read by a tool, and every act it takes by itself is started by one | bus-and-switch §37 to §45 | +| the manifest names the manager bundle, the tools bundle, the settings and the account, and no process, container or run-once step; the validator accepts it, the builder builds it and the node-engine composes it | parts §1 to §8 | +| with the manager bundle refusing to start, the tools that read still answer | parts §3 | +| the module names no store database and no `grant.key`; both provisions retire on the operator's Approve, and the database goes only by the operator's call | parts §9 to §15 | ## Milestones | Milestone | What it builds | State | |---|---|---| | the manager and its consumer | §1 to §8 as first written: the module, its seat, its store database, adoption and the sealed hand-over (ADR 0183, ADR 0206, ADR 0209) | delivered; built as design [40](40-building-the-operators-agent-and-its-licence-manager.md) describes | -| bus-and-switch | its kept data on the bus and its store database carried over and retired; every grant and token in the vault (ADR 0550 §3); bindings and holdings as events; the switch on its own usage, its warning and its condition; its tools. mesh-catalog's `claude-licence-manager`, `claude-code` and `mesh-vault` in one pull request, on what main holds today | designed; its part is [`39-milestones/bus-and-switch.md`](39-milestones/bus-and-switch.md), its four questions answered by the principles (A1 to A4) | +| bus-and-switch | its kept data on the bus and its store database carried over and retired; every grant and token in the vault (ADR 0550 §3); bindings and holdings as events; the switch on its own usage, its warning and its condition; its tools. mesh-catalog's `claude-licence-manager`, `claude-code` and `mesh-vault` in one pull request, on what main holds today | delivered 2026-11-12; its part is [`39-milestones/bus-and-switch.md`](39-milestones/bus-and-switch.md), its four questions answered by the principles (A1 to A4) | +| parts | the module as four parts in one manifest: the manager bundle (running long, the seat's verbs, every act), the tools bundle (every tool that reads), the settings, the account; the carry-over's code and the requirements of the store database and `grant-key` leave, both retiring on the operator's Approve and the database removed by the operator. mesh-catalog's `claude-licence-manager` alone | designed; its part is [`39-milestones/parts.md`](39-milestones/parts.md) | ## What this does not settle -- 2.54.0 From 6141d7b5d1776a5f8d94c11b8a150036ae840e05 Mon Sep 17 00:00:00 2001 From: jochen Date: Thu, 12 Nov 2026 12:21:10 +0100 Subject: [PATCH 2/2] =?UTF-8?q?Design=2039=20parts:=20the=20lead's=20answe?= =?UTF-8?q?rs=20D1=20(the=20vault=20reading)=20and=20D2=20(=C2=A717's=20wo?= =?UTF-8?q?rding)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 03-DESIGN/01-to-be/39-milestones/parts.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/03-DESIGN/01-to-be/39-milestones/parts.md b/03-DESIGN/01-to-be/39-milestones/parts.md index 3714011f..73e61e0b 100644 --- a/03-DESIGN/01-to-be/39-milestones/parts.md +++ b/03-DESIGN/01-to-be/39-milestones/parts.md @@ -214,3 +214,13 @@ main file and the glossary. No other module changes: every verb, event and provi - after the delivery the provisioner holds both retiring asks, and after the operator's call the database is gone (§13, §14); - the state directory holds none of the database's files (§15). + +## The lead's answers + +- **D1** (§12's vault reading, review round 1: no vault tool lists licence secrets, so `secret_holders` cannot show + `licence..grant` and `.access`): the reading that proves bus-and-switch §20's condition is, for every licence + `licences` answers, a rotation after the carry-over with no failure (`rotatedAt` later than `carried.postgres.at`, + `failures` 0), since a rotation reads the grant from the vault and puts both secrets back; and the vault's journal + handing `licence..access` to a bound node. Both go in the milestone file before the push (P3, P7). +- **D2** (§17's wording): the manager calls `seat:mesh-config.config` no more; the tools bundle does (§3). `invokes` + is the module's, so the manifest is unchanged (P8). -- 2.54.0