Design 29: a folder a module owns says how it treats files it did not write (issue 1024) #409

Merged
mesh-tools merged 2 commits from feat/owned-paths into main 2026-10-17 18:14:10 +00:00
4 changed files with 46 additions and 19 deletions
+18 -8
View File
@@ -121,7 +121,10 @@ never into the running one, unless it blocks the running one.
1. **Bring every feature branch up to the current trunk** (fetch by name, then merge), so the reviewed tree is
the tree that is pushed.
2. **One reviewer reads every repository's local commits** together, against the context files and the
decisions. Its report is per repository: each finding as file:line, the failure it causes, and the fix.
decisions. **It is one agent, kept for the whole release** like the fixing agents: the lead continues it by
its id for every later round, for the extra cycle after a failed check (phase 3) and for the ready mark, so it
reads the decisions, the issues, the context files and the commits once (issue 1042). A fresh reviewer per
round or per mark pays for all of that again. Its report is per repository: each finding as file:line, the failure it causes, and the fix.
It says which round it is in ("round 1 of at most 3").
3. **The report goes to the same fixing agents** that wrote the code, continued by their ids, so they fix
with the context they already hold. Each answers the reviewer: what it changed, per finding, or why not.
@@ -142,7 +145,7 @@ never into the running one, unless it blocks the running one.
reviewer first confirms that commit's tree equals the reviewed one.
2. **The forge's merge checks run the integration tests once** (`mesh/merge-gate`, `mesh/repo-check`). No
second review: phase 2 reviewed this tree.
3. **A check that fails** goes back to the reviewer with the failure, for **one more cycle** of phase 2 with
3. **A check that fails** goes back to the same reviewer, continued by its id, with the failure, for **one more cycle** of phase 2 with
the same fixing agents; then push once again. **The failure is read from the check's whole log**, never
reasoned from its summary: `mesh-delivery.show` names the check's build id, and `mesh-controller.builds` with
`log` set to that id prints everything the builder said. A check's summary picks only some failing lines;
@@ -153,7 +156,9 @@ never into the running one, unless it blocks the running one.
carries an integration test that starts the module whole, its process against the real bus and store, and
shows the milestone's acceptance sentence; the forge's checks run it (ADR 0391 §1, §6). Unit tests alone are not
that proof; the mesh has no end-to-end tests yet, and the lab is not used (the operator, 2026-10-16).
5. **The reviewer marks each pull request ready as soon as the acceptance is shown** with
5. **The reviewer marks each pull request ready as soon as the acceptance is shown.** It does not wait for the
checks itself: a watcher waits for them and wakes the lead, who continues the reviewer by its id to mark
(issue 1042). It marks with
`mesh-delivery.mark-ready` (the delivery of the head it approved, who reviewed it and why), which writes the
label `mesh/ready` and then `ready at <full sha>`, the order the forge counts (issue 913); mesh-delivery merges it when its checks pass
and the operator approved the merge into main on Telegram, the channel that proves who answered today (ADR 0364,
@@ -182,7 +187,7 @@ survive.
| The lead (phase 0 decisions, the context files, following and reporting) | larger | judgement |
| Read-only questions about the code for the context files | smaller | reading, answered with file:line |
| Fixing agents (phase 1, and the fixing in phases 2 and 3) | smaller | building to a written context |
| The reviewer (phase 2, and the extra cycle in phase 3) | larger | judgement, once per round |
| The reviewer (phase 2, the extra cycle in phase 3 and the ready mark; one agent, continued by its id) | larger | judgement, once per round |
| Decision records | larger | judgement |
Every agent the mesh runs draws on one weekly allowance shared by every session, and the larger model
@@ -272,8 +277,10 @@ moments, the same hour, an hq change going through [playbook 08](08-small-fixes.
- **The first milestone starts:** the design's `status: in-progress` ([playbook 04](04-build-handoff.md) step 7),
if it is not already.
- **A milestone's delivery plan is done:** its issues are resolved (phase 4), and the design's milestone entry says
it is delivered, with the date.
- **A milestone's delivery plan is done:** its issues are resolved (phase 4), with `fixed-by` naming its pull
requests. The design's milestone entry is not changed: it names the milestone's issues, and whether they are
delivered, when and by what is read from the issue tracker when it is asked, never copied into the design
(issue 1038; AGENTS.md: cross-cutting views are generated when they are read).
- **The building pauses with work left** (another design takes its turn, a hand-over, the session's end): the
design stays `in-progress`, and each issue left gets a note with `issue-tracker.note` saying what it waits
for and what comes after it ("built after design N is delivered, before design M"). The first issue of
@@ -300,8 +307,9 @@ issues in `fixing` that nobody works on reads to the operator as stuck work.
- A design whose milestone issues are partly resolved says `in-progress`, and one whose issues are all
resolved and delivered says `implemented`: read its Milestones section against `issue-tracker.get` for each
issue. A design that says `designed` with a resolved milestone issue is a state not written back.
- A milestone whose issues are all resolved and delivered has the date in its entry in the design's Milestones
section; an entry without it is a delivery not written back.
- A design's Milestones section names each milestone's issues and nothing of their state: a "delivered", a date
or a pull request in an entry is a copy of the tracker's state (issue 1038), read with
`grep -n 'delivered' <design>` over its Milestones section.
- Every open issue of a design that says `in-progress` and has no agent on it shows, in `issue-tracker.get`, a
note saying what it waits for; one without such a note is a pause not written back.
- The milestone issues in `fixing` (`issue-tracker.list`) belong to one design at most: milestone issues
@@ -312,6 +320,8 @@ issues in `fixing` that nobody works on reads to the operator as stuck work.
review rules; `issue-tracker.list` with `flag: abandoned` lists issues left in `fixing` with nobody on them.
- A pull request reviewed and green but not marked ready for more than 15 minutes is a lead that did not
mark it.
- Every ready mark of a release names one reviewer (`mesh-delivery.show`, `ready.by`), and the lead's save point
names one reviewer id per release; a second reviewer within one release is a reviewer not kept (issue 1042).
- A milestone that adds or changes a module marked ready with no integration test that starts the module whole is
the failure of phase 3's fourth step.
- A bed run from `.work/<slug>/mesh-lab` that fails naming a `.work/<slug>/<repo>/…` path it cannot find is a
@@ -5,7 +5,7 @@ code:
- mesh-controller internal/inventory
- mesh-controller internal/catalogue
- mesh-controller cmd/mesh-controller
updated: 2026-10-16
updated: 2026-10-17
decisions:
- "ADR 0181"
- "ADR 0182"
@@ -16,6 +16,11 @@ decisions:
- "ADR 0117"
- "ADR 0399"
- "ADR 0400"
- "ADR 0412"
- "ADR 0415"
- "ADR 0416"
- "ADR 0417"
- "ADR 0422"
---
# 29 — A node has operator accounts, and the mesh owns what lives under a home
@@ -58,6 +63,15 @@ These are a **family**, not one module: an `ssh-client` module, a shell module,
module, each a *universal-tier* consumer of the account fact — assigned wherever a person logs in,
which is every node, unlike the graphical stack that a capability gates.
**A folder a module owns says how it treats a file it did not write** (ADR 0416, ADR 0422). Declaring a
directory under a home owns it (ADR 0182 §1), and the owner alone writes there and reacts to every file
that enters it, never losing what the file held. The manifest says how, on the directory itself:
`unknown` is `move-out` (the node-engine moves every path the manifest does not declare and `knows` does
not name into `~/.local/state/mesh-moved/<module>/`, with a list), `module` (the module's own process
reacts, as ssh-client does in `~/.ssh`) or `program` (everything in it is the program's, as in a
service's data directory). `move-out` is only for a folder under a home, the home of the account the
assignment runs for (ADR 0412 §5). A folder many modules write in is not declared at all.
## 3. The whole of `~/.ssh` is the mesh's — with one boundary drawn inside it
The predecessor owned a single file (`~/.ssh/config`) and left the rest alone; it drifted, because
@@ -84,6 +98,9 @@ ADR 0117 draws for the uplink and the sshd
module draws for the firewall: **the mesh must never be able to arrange the one failure that severs
its own way back in.** The carve-out is not a convenience; it is that rule, in `~/.ssh`.
Since ADR 0415 and ADR 0417 the found class no longer holds in `~/.ssh`: ssh-client moves out what it
does not know into a kept folder, and never moves a key or `authorized_keys`, which keeps this boundary.
## 4. Keys are the mesh's to generate — through a CA, and existing keys are adopted, not replaced
Key *generation* is the mesh's, not each node's improvising its own. The clean form is an **SSH
@@ -547,9 +547,9 @@ when the previous one's delivery is done.
| # | Outcome | Acceptance tests | Repositories | Issues |
|---|---|---|---|---|
| 1 | A merge during a running delivery is never dropped and needs no person's release; the merge window lives on the bus; a rollout that shares nothing with an open one runs beside it | 8, 9, 11 | mesh-controller | 973 (with the rest of 525); delivered 2026-10-17 (mesh-controller #366, #367) |
| 2 | A ready mark is acted on within seconds, and each pull request has at most one waiting check | 5, 6, 7 | mesh-controller, mesh-catalog (mesh-delivery, gitea) | 974, 975, 976; delivered 2026-10-17 in one plan (mesh-controller #368, mesh-catalog #345) |
| II | phase II: build-agent and route-proxy live whole in mesh-controller, in two releases under ADR 0420 (accepted 2026-10-17): release 1 has the controller accept a reviewed move and mesh-delivery announce each merge with its Approve; release 2 is the move | — | mesh-controller, mesh-catalog (mesh-delivery, build-agent, route-proxy) | release 1: 1025, delivered 2026-10-17 (mesh-controller #369, mesh-catalog #348); release 2: 1019 |
| 1 | A merge during a running delivery is never dropped and needs no person's release; the merge window lives on the bus; a rollout that shares nothing with an open one runs beside it | 8, 9, 11 | mesh-controller | 973 (with the rest of 525) |
| 2 | A ready mark is acted on within seconds, and each pull request has at most one waiting check | 5, 6, 7 | mesh-controller, mesh-catalog (mesh-delivery, gitea) | 974, 975, 976 |
| II | phase II: build-agent and route-proxy live whole in mesh-controller, in two releases under ADR 0420 (accepted 2026-10-17): release 1 has the controller accept a reviewed move and mesh-delivery announce each merge with its Approve; release 2 is the move | — | mesh-controller, mesh-catalog (mesh-delivery, build-agent, route-proxy) | release 1: 1025; release 2: 1019 |
| 3 | A feature with a new seat verb across the controller and the catalogue is one group, one batch, one delivery plan and one Approve: no order lines, no ready mark, each module built and sent once | 1, 6 | mesh-controller, mesh-catalog (mesh-delivery, gitea) | 977, 978, 1022; 605 (1021 closed as its duplicate) is resolved by this build (ADR 0419 §7) |
| 4 | A delivery backs up the data it moves first, and a failed backup holds it and is said | 3 | mesh-controller, mesh-catalog (mesh-delivery, the backup seat's holder) | 980 |
| 5 | One read of a module on a node names the commit, build and rollout that put it there | 10, 12 | mesh-controller, mesh-catalog (mesh-config, nats) | 981 |
@@ -339,14 +339,14 @@ retire the word (F4 left it off the *Not:* line for them), design 49 lists the C
## Milestones
Written back on 2026-10-17 (playbook 07, "The design's state is written back"): the packages above were built
as one delivery, not milestone by milestone, so the milestones are what was delivered and what is left.
The packages above were built as one delivery, not milestone by milestone; the milestones group them by what
each makes true. Whether a milestone's issues are delivered is read from the issue tracker (playbook 07).
| # | Outcome | Packages | Issues | State |
|---|---|---|---|---|
| 1 | Config, provisioning, secrets, bindings, collections and runtime asks run the new way; the old forms are still accepted | every package but T6, B3, R1, R2 | 647, 650 to 679 but 659, 681, 684, 685 | merged into main and delivered on 2026-10-16; issues resolved |
| 2 | The media catalogue and the applications carry their file text as templates | T6 | 659 | resolved; delivered on 2026-10-16 |
| 3 | The other providers answer their consumers; the old forms are refused; the record says what runs | B3, R1, R2 | 680, 682, 683 | open: built after design 47's milestones are delivered and before design 58 starts (the operator, 2026-10-17; one design is built at a time, playbook 07) |
| # | Outcome | Packages | Issues |
|---|---|---|---|
| 1 | Config, provisioning, secrets, bindings, collections and runtime asks run the new way; the old forms are still accepted | every package but T6, B3, R1, R2 | 647, 650 to 679 but 659, 681, 684, 685 |
| 2 | The media catalogue and the applications carry their file text as templates | T6 | 659 |
| 3 | The other providers answer their consumers; the old forms are refused; the record says what runs | B3, R1, R2 | 680, 682, 683 |
## What is deliberately not here