Merge pull request 'ADR 0275 slice 3: issue reports carry only opened; the tracker holds every status' (#283) from process/issue-reports-carry-only-opened into main

This commit was merged in pull request #283.
This commit is contained in:
2026-10-10 15:48:29 +00:00
374 changed files with 71 additions and 1660 deletions
+3 -1
View File
@@ -26,7 +26,9 @@ and says they disagree.
1. Write the decision record. If it reverses an earlier one, that record gets
`status: superseded` and `superseded-by:` — its text is never edited.
2. Edit the design; set `updated:` to today.
3. If this came from an issue, set that issue's `amended-design:`.
3. If this came from an issue, give the issue the document in the issue tracker: `amended-design` on its
`issue-tracker.move` to `resolved`, or `issue-tracker.link` with kind `design` before then. Never in the
report's frontmatter (ADR 0275).
## Amending the as-is layer
+1 -1
View File
@@ -52,7 +52,7 @@ Decide the shape first:
then `# NNN. The title`, the title given to the tracker. **No status key**: the issue's status, owner and fix
live in the tracker (ADR 0275), and `cycle.py` refuses `status:`, `located-in:`, `fixed-by:`,
`amended-design:`, `replay:` or `replay-none:` in a report opened after the import. Notes and links go to the
`amended-design:`, `replay:` or `replay-none:` in any report. Notes and links go to the
tracker.
4. Write the symptom **as observed**, in plain terms, with the evidence that it happened.
5. Say why it matters beyond the instance. An issue that is only one occurrence is a knowledge
+2 -3
View File
@@ -21,9 +21,8 @@ generated on demand and never written back to disk.
## Steps
1. Read the frontmatter block from every file above — a grep across each tree is enough, no
need to load bodies — and the issues from the tracker. The `status:` keys the reports numbered
001 to 364 still carry are the import's snapshot of 2026-10-10 (ADR 0275), not where an issue
stands.
need to load bodies — and the issues from the tracker. An issue report carries no status;
where an issue stands is only in the tracker (ADR 0275).
2. Render what was asked as Markdown tables. Group and sort sensibly. The **ADR index** is one
of these views, and it is the only place the list of records is shown
([ADR 0248](../../../02-DECISIONS/0248-the-decision-index-is-generated-when-it-is-read-and-never-stored.md)):
+8 -6
View File
@@ -55,14 +55,16 @@ whose failure has never been observed is a guess about its own correctness.
## cycle.py
The development cycle, checked ([ADR 0080](../../02-DECISIONS/0080-the-development-cycle-is-checked.md)):
a to-be design names a decision, an in-progress/implemented design names its owning code, a
located/fixed issue names its owner, a fixed/resolved issue says what fixed it, a graduated
a to-be design names a decision, an in-progress/implemented design names its owning code, a graduated
research overview says what it became, and no two issue records share a number (issue 155 — the
number is how a record is cited, and `main` lags every open pull request, so two people reading it
allocate the same one). And a core issue — one opened from 2026-10-07 whose `located-in` names a core
repository — resolves only with `replay:` (an id in mesh-lab's replays register) or `replay-none:` saying
why none is possible ([ADR 0237](../../02-DECISIONS/0237-a-change-is-judged-against-the-mesh-that-runs-before-it-merges-on-the-build-seat.md));
it failed on a resolved core issue carrying neither before it passed. And an accepted record that puts work
allocate the same one). An issue report carries the day it was `opened:` and no status key — `status:`,
`located-in:`, `fixed-by:`, `amended-design:`, `replay:`, `replay-none:` or `resolved:` — because an issue's
status lives in the issue tracker ([ADR 0275](../../02-DECISIONS/0275-the-mesh-numbers-and-tracks-its-issues-in-a-module-of-its-own-and-hq-keeps-only-the-narrative-of-a-design-or-governance-issue.md));
it failed on all 361 reports that carried them before they were removed. The rules on an issue's status this
check held until then — an owner for a located issue, a fix for a resolved one, and a core issue's `replay`
or `replay-none` ([ADR 0237](../../02-DECISIONS/0237-a-change-is-judged-against-the-mesh-that-runs-before-it-merges-on-the-build-seat.md))
— are refused at the write by `issue-tracker.move`. And an accepted record that puts work
off — "until renamed", "left for later", "not decided here", "postponed", "future work", "deferred", "a later
change" — names the issue that tracks it, as tracking it ("tracked by issue N", or "issue N tracks"), in that
paragraph or list item, or in a dated progressive insight that speaks about it: one in the same section, or one
+12 -13
View File
@@ -17,10 +17,11 @@ What is enforced:
tracker since the import of slice 3 (ADR 0275, to-be 53), where `issue-tracker.move`
refuses at the write what this check refused at merge until then: a status outside
the five, `located` without an owner, `resolved` without a fix, a core issue
resolved without its replay (ADR 0237), `wontfix` without a reason. A report opened
after the import carries none of those keys -- the tracker holds them, and two
places holding one fact drift. The reports opened before keep theirs as the dated
snapshot the import took; they are not judged, and not kept up to date.
resolved without its replay (ADR 0237), `wontfix` without a reason. A report
carries none of those keys, only the day it was `opened:` -- the tracker holds
them, and two places holding one fact drift. The keys the reports opened before
the import carried were removed once the import held them; the commit it read
is on every imported issue.
research a known `status:`; a `graduated` overview says what it `became:`, and every
target it names exists.
decisions every accepted record is REACHABLE from the cycle: cited by a design doc's
@@ -44,12 +45,10 @@ ROOT = os.path.normpath(os.path.join(os.path.dirname(__file__), "..", ".."))
DESIGN_STATUSES = {"proposed", "designed", "in-progress", "implemented", "abandoned"}
RESEARCH_STATUSES = {"active", "graduated", "abandoned"}
# The keys an issue report carried while its status lived here, and the day from which a report carries
# none of them: the issue tracker holds them (ADR 0275, slice 3 of to-be 53), and `issue-tracker.move`
# enforces the cycle's rules on them at the write. A report opened on or after this day with one of these
# keys is a status written in two places. The reports opened before keep theirs as the import's snapshot.
STATUS_IN_TRACKER_FROM = "2026-10-11"
TRACKER_KEYS = ("status", "located-in", "fixed-by", "amended-design", "replay", "replay-none")
# The keys an issue report carried while its status lived here. The issue tracker holds them now (ADR 0275,
# slice 3 of to-be 53), and `issue-tracker.move` enforces the cycle's rules on them at the write. A report
# carrying one of them is a status written in two places, whenever it was opened.
TRACKER_KEYS = ("status", "located-in", "fixed-by", "amended-design", "replay", "replay-none", "resolved")
# A decision that defers work names the issue that tracks it (issue 354). ADR 0244 left the code
# renames of the node-engine and the tool runner "for a later rename", with no issue, owner or date;
@@ -227,8 +226,8 @@ def main():
seen_records[number] = name
# Since the import of slice 3 (ADR 0275), an issue's status, owner, fix and replay live in the issue
# tracker, and its `move` refuses at the write what this check refused at merge. A report opened from
# STATUS_IN_TRACKER_FROM carries none of those keys; one opened before keeps the import's snapshot.
# tracker, and its `move` refuses at the write what this check refused at merge. A report carries none
# of those keys.
for path in sorted(glob.glob(os.path.join(ROOT, "04-ISSUES", "*", "00-report.md"))):
front = frontmatter(path)
if front is None:
@@ -239,7 +238,7 @@ def main():
bad(path, "opened: says nothing -- the day the issue was opened, YYYY-MM-DD")
continue
carried = [key for key in TRACKER_KEYS if key in front]
if opened >= STATUS_IN_TRACKER_FROM and carried:
if carried:
bad(path, "carries %s, but an issue's status, owner, fix and replay live in the issue tracker "
"(ADR 0275): move it with `issue-tracker.move`, and keep no copy here"
% ", ".join("`%s:`" % key for key in carried))
+4 -2
View File
@@ -45,8 +45,10 @@ A design changes only through a decision.
corrected in place and marked in the record rather than superseded
([`02-DECISIONS/README.md`](../../02-DECISIONS/README.md)).
2. Edit the to-be design document and set `updated:` to today.
3. If the amendment came from an issue, set that issue's `amended-design:` to the document
path.
3. If the amendment came from an issue, give the issue the document path in the issue tracker:
`amended-design` on its `issue-tracker.move` to `resolved`, or `issue-tracker.link` with kind
`design` before then — never in the report's frontmatter
([ADR 0275](../../02-DECISIONS/0275-the-mesh-numbers-and-tracks-its-issues-in-a-module-of-its-own-and-hq-keeps-only-the-narrative-of-a-design-or-governance-issue.md)).
## When something ships
+13 -10
View File
@@ -38,12 +38,15 @@ An issue takes one of two shapes:
reviewed in a pull request. The folder holds the report and the diagnosis; the tracker holds everything else.
- **Wholly in the tracker** — every other issue. Nothing is written here.
**The reports written before the tracker** (the folders numbered 001 to 364) still carry `status:`, `located-in:`,
`fixed-by:`, `amended-design:`, `replay:` and `replay-none:` in their frontmatter. Those keys are the snapshot the
import of slice 3 took from `main` on the day it ran (the note in ADR 0275 says which day and which commit), and
they are not kept up to date: the tracker is. They are left in place because they are the record of what was known
then, reviewed in pull requests at the time, and because removing 361 keys would say nothing the tracker does not.
Nobody edits them.
**`04-ISSUES/` stays, for the narrative only.** It keeps the public narrative of a design or governance issue: the
symptom as observed, the diagnosis, what was ruled out, and why. A plain bug — a defect whose fix needs no design
question answered — needs no folder; it is whole in the tracker.
**The reports written before the tracker** (the folders numbered 001 to 364) carried `status:`, `located-in:`,
`fixed-by:`, `amended-design:`, `replay:` and `replay-none:` in their frontmatter until the import of slice 3 had
taken them into the tracker and been checked against it, field by field; then one pull request removed them, so
that no status is held in two places. What they said that day is in this repository's history at the commit the
import read, which every imported issue names (`imported.commit` in `issue-tracker.get`).
## Steps
@@ -64,8 +67,8 @@ Nobody edits them.
Then `# NNN. The title`, the title as the tracker holds it, and the symptom as observed, as in the tracker's
report. **No status key**: `cycle.py` refuses `status:`, `located-in:`, `fixed-by:`, `amended-design:`,
`replay:` or `replay-none:` in a report opened after the import, because the tracker holds them and two places
holding one fact drift.
`replay:` or `replay-none:` in any report, because the tracker holds them and two places holding one fact
drift.
**An issue wholly in the tracker** is done at this step.
2. Investigate. The trail goes in `issue-tracker.note`, and, for a folder-backed issue, in `01-diagnosis.md` in the
@@ -97,5 +100,5 @@ Nobody edits them.
- **A rule states how it is checked.** The cycle's rules on an issue — a status one of the five, `located` with an
owner, `resolved` with a fix, a core issue with its replay, `wontfix` with a reason — are refused at the write by
`issue-tracker.move` (mesh-catalog `modules/mesh-issues`, its table test over the rules). `cycle.py` checks what
this repository still holds: no two folders share a number, every report has frontmatter, and a report opened
after the import carries no status key.
this repository still holds: no two folders share a number, every report has frontmatter with the day it was
`opened:`, and no report carries a status key.
@@ -124,6 +124,10 @@ decision records, issue reports.
> numbers collided and statuses were hard to see. Research overviews, design documents and decision
> records carry their state here as before.
> **Progressive insight — 2026-10-10, later.** The reports written before no longer keep their keys: once
> the import was checked against every folder, one pull request removed them (ADR 0275's last note), and
> `cycle.py` refuses a status key in any report.
**There are no central status files.** Every cross-cutting view — a status matrix, a decision
index, an open-issue list — is generated from frontmatter when asked for, never written to disk.
Two places holding one fact drift, and the written one wins by being closer to hand.
@@ -56,6 +56,10 @@ The development cycle is enforced mechanically, to the extent frontmatter can ca
> refuses a status key in a report opened after the import. The decision stands: the cycle is checked,
> not trusted; which program checks each rule is a fact that moved.
> **Progressive insight — 2026-10-10, later.** `cycle.py` refuses a status key in any report, not only one
> opened after the import: the keys the older reports carried were removed once the import was checked
> against every folder (ADR 0275's last note).
[`00-META/checks/cycle.py`](../00-META/checks/cycle.py) refuses violations, beside `records.py`
and `index.py`; all three run before any merge here. What frontmatter cannot see — that code work
actually started from a handoff — remains held by playbooks 04 and 07: a feature branch exists
@@ -154,6 +154,15 @@ along the way".
> operator confirms before it is applied, done through `move`, `link` and `note` on the imported issues, not by
> the import, which only ever creates. The decision stands as written.
> **Progressive insight — 2026-10-10, the status keys removed.** The insight above said the status keys stay in the
> reports as a dated snapshot. They did not stay: every folder was compared with `issue-tracker.get` after the import
> (status, `located-in`, `fixed-by`, `amended-design`, `replay`, `replay-none` and the closing day), no report had
> changed since the commit the import read, the tracker held every field the reports held, and one pull request then
> removed the keys from all 361 reports, as §8 decided. A snapshot kept in the reports was a second copy every reader
> had to be told not to believe; the record of what was known that day stays in this repository's history at that
> commit, which every imported issue names. `cycle.py` refuses a status key in any report, not only one opened after
> the import. The decision stands as written.
## Consequences
- Collisions end at the source: a number is taken from one counter, not read from a repository many branches write.
@@ -664,7 +664,8 @@ replay covers what must not be done to it on purpose, and every rule keeps a liv
- **Replays live where their incident is**: a component's logic in its repository as `TestReplay<issue>`,
what the mesh runs (the bus's release, the resolver under musl and glibc) in mesh-lab's `replays/`, all
named in its register and proved by `replays/cmd/prove`. A core issue opened from 2026-10-07 resolves only
with `replay:` or `replay-none:` (`cycle.py`).
with `replay` or `replay-none`, refused without one by the issue tracker's `move` (ADR 0275; `cycle.py` held it
until then).
- **The controller's tests run a bus of their own per test**, linked in at the release the mesh runs and held
to it by a test, so the suite runs in parallel and under the race detector.
+2 -2
View File
@@ -145,7 +145,7 @@ the events sees a change as it happens. No event carries a secret, and an issue
| `wontfix` | a reason |
A refused move changes nothing and says which rule refused it. `cycle.py` checked the folders that carried status until
slice 3; since then it refuses a status key in a report opened after the import, and judges no issue's status.
slice 3; since then it refuses a status key in any report, and judges no issue's status.
## 6. How the operator and agents use it
@@ -173,7 +173,7 @@ in one call, from any session, and the responder on a channel answers from it on
|---|---|---|
| 1 | The `mesh-issues` module: `open`, `get`, `list`, `move`, `note`, `link`; a counter by compare-and-set in the SDK; playbook 03 takes its numbers from it | an agent opens an issue and gets the next number; two agents opening at the same moment never get the same one |
| 2 | Decision and research numbers from the tracker, each its own key in `counters`; a number is reserved when a branch starts | two agents writing a decision at once get two numbers, and no hq pull request is renumbered |
| 3 | `import`: every issue folder in hq read through the records module and written as an issue with its own number, idempotent and showing what it would change before it does (built 2026-10-10; the status keys stay in the reports as a dated snapshot, and one pull request changes playbook 03 and `cycle.py` and adds dated notes to ADR 0019, 0080 and 0275); then the four consolidation passes of research 042 (fixed, duplicates, owners, grouping; the duplicates pass is the duplicate check's `groom`, § 9, judged rather than by shared words), each a list confirmed before it is applied through `move`, `link` and `note`, and an audit of `fixed-by` against the forge | the not-closed list comes from one call and shrinks by what was already fixed or duplicated, each with its reason |
| 3 | `import`: every issue folder in hq read through the records module and written as an issue with its own number, idempotent and showing what it would change before it does (built and run 2026-10-10; one pull request changed playbook 03 and `cycle.py` and added dated notes to ADR 0019, 0080 and 0275, and once every folder was checked against the tracker a second removed the status keys from every report, as § 3 says); then the four consolidation passes of research 042 (fixed, duplicates, owners, grouping; the duplicates pass is the duplicate check's `groom`, § 9, judged rather than by shared words), each a list confirmed before it is applied through `move`, `link` and `note`, and an audit of `fixed-by` against the forge | the not-closed list comes from one call and shrinks by what was already fixed or duplicated, each with its reason |
| 4 | Conditions and pull requests linked: an issue links a condition by its key and the controller shows the link; a merged pull request notes every issue it names; after a week of that, the controller opens one issue per `healer-wanted` condition key by itself | a condition shows its issue, and a merge notes the issues it names |
| 5 | A read-only view onto the `issues` bucket over the bus | the operator reads issues in a browser without an agent |
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-08-22
located-in: [mesh-host]
fixed-by: mesh-host — a package is read back from the package database after installing
amended-design:
---
# 001 — A failed package install does not fail the job
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-08-22
located-in: [mesh-host]
fixed-by: mesh-host — a stale package index is named rather than reported as a failed install
amended-design:
---
# 002 — A declared package can fail purely because the node's index is stale
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-08-22
located-in: [mesh-control]
fixed-by: mesh-control — a machine's filtering is computed from what it was assigned
amended-design: 03-DESIGN/01-to-be/08-connectivity.md
---
# 003 — A firewall rule's `scope:` is read by no code
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-08-22
located-in: [hal]
fixed-by: hal — ACME_CA_SERVER selects the authority, and defaults to staging
amended-design:
---
# 004 — Certificate issuance always targets the authority's production endpoint
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-08-22
located-in: [hal, mesh-lab]
fixed-by: mesh-lab — a run leaves a receipt, and the receipt says what it covered
amended-design: 03-DESIGN/01-to-be/01-end-to-end-testing.md
---
# 005 — The end-to-end pipeline harness has not built since the workspace was removed
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-08-23
located-in: [mesh-catalog modules/records, mesh-catalog modules/mesh-console]
fixed-by: ADR 0153; mesh-catalog PR 183 (records), PR 185 (a phrase that wraps)
amended-design: 03-DESIGN/01-to-be/35-reading-the-record.md
---
# 006 — This repository is not indexed into the knowledge base, and the claim that it is holds up a decision
@@ -1,12 +1,5 @@
---
status: resolved
opened: 2026-08-23
located-in: [hal (the instance), mesh-host internal/bootstrap (preflight asks the daemon), mesh-controller internal/catalogue (capabilities)]
fixed-by:
- "the instance only: PR #962 — incus hook. Merged, ran on one node in 6s of a 60s budget; pipeline #6832 green in 48s. The class remains open."
- "partly, on the mesh: mesh-host 73c010e, 9d8239a — preflight and the profile detectors ask the daemon, not the package (installed-but-broken reports absent)"
- "the class, on the mesh: a manifest declares capabilities, an action declares verify (ADR 0005), and a module's own assertions are the lab's verdict (design 01). The old arrangement is replaced module by module, so its count is never taken"
amended-design: 03-DESIGN/01-to-be/01-end-to-end-testing.md
---
# 007 — An installed package is not an available capability
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-08-28
located-in: [hal]
fixed-by: hal — the script says it is manual, because it is
amended-design:
---
# 008 — The documented automatic node rescue does not exist
@@ -1,10 +1,5 @@
---
status: resolved
opened: 2026-08-28
located-in: [mesh-lab, mesh-host]
fixed-by:
- "mesh-lab: a registry raised inside the scenario. Verified in a sealed machine — all four shapes applied with the image pinned by digest, idempotent, read back from the machine."
amended-design:
---
# 009 — A digest-pinned image cannot be placed in the lab, so `container` cannot be tested there
@@ -1,10 +1,5 @@
---
status: resolved
opened: 2026-08-29
located-in: [mesh-host, mesh-control]
fixed-by:
- "mesh-host: the store records where each resource came from — carried or declared — and each origin removes only its own. Verified in the lab on the exact scenario that caused this: the substrate survived, and a later declaration still removed what it had itself declared."
amended-design:
---
# 010 — The first declaration a node receives destroys the substrate it raised
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-08-30
located-in: [mesh-host]
fixed-by: mesh-host — apply attempts every resource and reports every failure
amended-design:
---
# 011 — One broken module stops every module after it, for ever
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-08-30
located-in: [mesh-lab]
fixed-by: mesh-lab — scenario machines stay at 1 GiB, and the scenario now stocks seven images
amended-design:
---
# 012 — Raising a scenario machine's memory stops the substrate coming up
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-08-31
located-in: [mesh-control]
fixed-by: mesh-control — what the mesh computes is applied before what the module declared
amended-design:
---
# 013 — A file the mesh computes arrives after the service that needs it
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-08-31
located-in: [mesh-host]
fixed-by: mesh-host — a node's serving key is stored in the format a server reads
amended-design:
---
# 014 — A node's serving key was present, correct, and unusable
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-08-31
located-in: [mesh-lab]
fixed-by: mesh-lab — a command with no marker is a failure, not a success
amended-design:
---
# 015 — A command that said nothing was read as having succeeded
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-08-31
located-in: [mesh-host]
fixed-by: mesh-host — something after the declaration is refused whole
amended-design:
---
# 016 — Anything after the declaration in a file was ignored
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-08-31
located-in: [mesh-host]
fixed-by: mesh-host — the store's readiness is checked over TCP, not the socket
amended-design:
---
# 017 — An action succeeded into a state its own verify rejects
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-08-31
located-in: [mesh-control]
fixed-by: mesh-control — something answered on this machine is still bound
amended-design:
---
# 018 — A provider on the same machine was never announced to its consumer
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-08-31
located-in: [mesh-control]
fixed-by: mesh-control — the resolver module's claims about machines are checked on a machine
amended-design:
---
# 019 — A comment asserting a fact about a machine, which nothing checked
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-08-31
located-in: [mesh-control, mesh-lab]
fixed-by: mesh-lab multiple-fixes — the bed, not the proxy: its backend stub never listened and its check read a subject the authority leaves empty; against both Pebble and the catalogue's step-ca the same proxy now orders, answers the challenge, is issued and serves
amended-design:
---
# 020 — A certificate is issued and never collected
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-01
located-in: [mesh-control]
fixed-by: mesh-control df62bb5
amended-design:
---
# 021 — A consumer on the provider's machine is given no credential
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-01
located-in: [mesh-control]
fixed-by: mesh-control 0af3ea1
amended-design:
---
# 022 — A credential belongs to a node and a provision, so a second consumer refuses
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-01
located-in: [mesh-control]
fixed-by: mesh-control 122680b
amended-design:
---
# 023 — A consumer is given every part of a connection except the two it cannot invent
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-01
located-in: [mesh-lab]
fixed-by: mesh-lab 3503ad9
amended-design:
---
# 024 — A run stalls before the host is placed, and says nothing while it does
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-01
located-in: [mesh-control, mesh-host]
fixed-by: mesh-controller ee3cc1b (pinned() refuses a placeholder at compose), 43c9c97 (the builder publishes digests); proven by one-node-mesh.test.ts (the catalogue holds no placeholder digest). Six placeholders remain in three manifests deferred under issue 064
amended-design:
---
# 025 — A module must pin a digest, and nothing produces one
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-01
located-in: [mesh-control]
fixed-by: mesh-controller f5b03e1 (the fourteen declared); ADR 0091 and mesh-controller feat/multiple-fixes (the check, back, with the three declarations — the socket by capability, the operator's by accesses)
amended-design: 03-DESIGN/01-to-be/18-building-a-module.md
---
# 026 — The data directories are mounted and never declared
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-01
located-in: [mesh-host, mesh-control]
fixed-by: mesh-host aa441ba, 652984b (container restart-on, PR #2, under issue 009); proven by mesh-lab runtime-restart-on-config.test.ts
amended-design:
---
# 027 — A container cannot follow a file, and a rotated credential is the case
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-01
located-in: [mesh-control, mesh-host]
fixed-by: mesh-control 1f5b70a, 41f7c51; mesh-host b91342a
amended-design: 02-DECISIONS/0038-the-mesh-assigns-the-port.md
---
# 028 — Two things want one port, and nothing says so until the machine
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-01
located-in: [mesh-control]
fixed-by: mesh-control be62f49; mesh-lab f85dbb0
amended-design:
---
# 029 — The artifact store cannot be delivered by the artifact store
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-01
located-in: [mesh-control]
fixed-by: mesh-control 38d4e77
amended-design:
---
# 030 — Asking what a machine should be re-signed its certificate
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-02
located-in: [mesh-host]
fixed-by: mesh-host #16 (internal/link/run.go: the host prefetches a window of declarations, applies the newest and sets the rest aside, each reported as superseded); mesh-controller #36 (the link records a superseded report as a word that the node is there)
amended-design: 03-DESIGN/01-to-be/05-the-node-host.md
---
# 031 — A machine becomes each thing it was told, in turn
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-04
located-in: [mesh-sdk, mesh-catalog]
fixed-by: mesh-sdk src/provisioner rework + redis/postgres/minio/umami adapters (ADR 0048)
amended-design: 0048-a-provider-creates-the-credential-the-mesh-minted.md
---
# A provider's provisioner seals with a key the mesh has no way to deliver — and does not need to
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-04
located-in: [mesh-host internal/apply (restart-on), mesh-catalog]
fixed-by: mesh-host aa441ba (restart-on); mesh-catalog 550393b (runtime config as a mergeable file + restart-on); proven by mesh-lab runtime-restart-on-config.test.ts
amended-design:
---
# Changing a module's settings does not restart its runtime — config is stale until recreated
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-05
located-in: [mesh-control, mesh-catalog]
fixed-by: ADR 0049 (a slug for the login) + a shorter minted secret (mesh-control)
amended-design: 0049-a-consumers-identity-fits-the-tightest-backend.md
---
# The mesh's derived login does not fit every backend's identity rules — S3 rejects it
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-02
located-in: [mesh-host internal/apply (file create-once), mesh-host examples]
fixed-by: ADR 0087; mesh-host #16 (a file resource may say create-once; kept, never corrected); proven by the apply tests and the vault bed
amended-design: 03-DESIGN/01-to-be/18-building-a-module.md
---
# 035 — Reconciling a seed file wipes what grew in it
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-02
located-in: [mesh-control, mesh-catalog, mesh-host]
fixed-by: ADR 0051 access: mesh-controller aeb65a3, mesh-host f06eea5, mesh-catalog 69c8a5e; proven by mesh-lab assigned-catalogue-media.test.ts (sonarr and radarr share one operator-owned directory)
amended-design: 02-DECISIONS/0051-shared-data-is-the-operators.md
---
# 036 — Six modules own what they must share
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-05
located-in: [mesh-control, mesh-host, mesh-catalog]
fixed-by: ADR 0052 run-once container: mesh-host 19e5dd8, PR #5 24e9ae4; ADR 0053 scheduled twin 9d1f001; proven by mesh-lab assigned-catalogue-mqtt.test.ts
amended-design: 02-DECISIONS/0052-a-step-that-runs-once-before-a-container.md
---
# 037 — A module cannot run its own code at a lifecycle phase
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-09
located-in: [mesh-control]
fixed-by: mesh-control — a same-node provider is announced at the port it is published on
amended-design:
---
# 038 — A provider is announced at a name its port is not bound to
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-10
located-in: [mesh-catalog]
fixed-by: mesh-catalog — the operator's own images are pinned by digest
amended-design:
---
# 039 — The lab's registry was pinning what the catalogue left unpinned
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-10
located-in: [mesh-host cmd/mesh-bootstrap, mesh-lab test/integration/genesis.ts]
fixed-by: mesh-host cmd/mesh-bootstrap (ADR 0067); mesh-lab genesis.ts is the one description of genesis both beds call. Still open: a running mesh cannot say it was raised by the installer
amended-design:
---
# 040 — The only description of how a mesh is stood up is a test
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-10
located-in: [mesh-controller internal/catalogue, mesh-catalog modules/mesh-controller]
fixed-by: ADR 0086; mesh-controller feat/secret-not-in-environment (envfile twins for the broker settings, catalogue refusal of secrets in env / undeclared env-file); mesh-catalog (the controller reads its six credentials from files; 35 containers declare their exception); mesh-host (the installer delivers any MESH_…_FILE own secret)
amended-design: 03-DESIGN/01-to-be/13-credentials-and-their-rotation.md
---
# 041 — A credential the mesh took care to seal ends up in the process environment
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-11
located-in: [mesh-controller, mesh-catalog]
fixed-by: mesh-controller PR 29 (98aea8b); mesh-catalog PR 26 (1891b09); gated by mesh-lab PR 34
amended-design: 02-DECISIONS/0082-the-registry-is-reached-by-name-and-trusted-by-the-overlay.md
---
# 042 — Nothing gives a node an account for a registry
@@ -1,10 +1,5 @@
---
status: resolved
opened: 2026-09-12
resolved: 2026-09-12
located-in: [mesh-controller (the verb existed)]
fixed-by: nothing — the capability already existed and the wrong verb was used
amended-design:
---
# 043 — A module cannot be given an account for the mesh's own queues
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-13
located-in: [mesh-tools, mesh-sdk]
fixed-by: mesh-tools feat/run-once-entry, mesh-sdk feat/adr-ref-resync
amended-design:
---
# 044 — The runtime every module builds on cannot be built by the mesh
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-13
located-in: [mesh-host internal/apply (container spec digests)]
fixed-by: mesh-host e7f94e0 (restart-on digests folded into the container spec, a standing comparison); unit-tested in apply_test.go, no lab assertion yet
amended-design:
---
# 045 — A container keeps the values it started with
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-14
located-in: [mesh-controller internal/builder (upstream artifacts)]
fixed-by: ADR 0096; mesh-controller multiple-fixes (the builder copies the index and its manifests between registries over the registry API); proven by a test against a fake upstream serving an index over two platforms
amended-design: 03-DESIGN/01-to-be/18-building-a-module.md
---
# 046 — An upstream image cannot be mirrored into the mesh's own registry
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-14
located-in: [mesh-controller (the derived filter)]
fixed-by: mesh-controller c8d8211 (forward chain drops by default, never closes ssh), 25e42b3; proven by one-node-mesh.test.ts (a machine filters exactly what its modules declared)
amended-design:
---
# 047 — The firewall does not cover published container ports
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-14
located-in: [mesh-controller, mesh-catalog]
fixed-by: mesh-controller PR 29 (98aea8b); mesh-catalog PR 26 (1891b09); gated by mesh-lab PR 34
amended-design: 02-DECISIONS/0082-the-registry-is-reached-by-name-and-trusted-by-the-overlay.md
---
# 048 — Nothing makes a machine trust the mesh's own registry
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-14
located-in: [mesh-controller cmd/mesh-controller (ask), mesh-controller internal/link]
fixed-by: ADR 0095; mesh-controller multiple-fixes (ask: the control plane publishes the request with a private reply queue and prints the answer); proven by the confluence bed
amended-design: 03-DESIGN/01-to-be/19-the-module-protocol.md
---
# 049 — A module can serve tools, and nothing is allowed to call them
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-14
located-in: [mesh-controller (the catalogue), mesh-catalog]
fixed-by: mesh-controller 3ae7b88, 2b82872; mesh-catalog d2dce34; proven by one-node-mesh.test.ts (the catalogue holds every module the control plane built)
amended-design:
---
# 050 — The catalogue knows nothing that was built before it
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-14
located-in: [mesh-host, mesh-catalog]
fixed-by: mesh-host 56124c3; mesh-catalog 5e4dc37; mesh-lab 440e265
amended-design: 03-DESIGN/01-to-be/07-the-foundation.md
---
# 051 — The mesh can update everything except what it depends on
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-14
located-in: [mesh-controller (the derived filter)]
fixed-by: mesh-controller dda001d (the firewall opens the port the mesh itself runs on), 25e42b3; TestTheBrokersPortIsOpenedThoughNoModuleDeclaresIt
amended-design:
---
# 052 — The firewall closes the port the mesh runs on
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-15
located-in: [mesh-tools, mesh-host, mesh-sdk]
fixed-by: mesh-tools b618057 (the SDK resolved by version from the registry, one pin); mesh-host 7986306; mesh-controller 4b9bc50. Caveat: the base image still builds with npm install and no lock, so the build is not reproducible
amended-design:
---
# 053 — The SDK is pinned twice, and the two disagree
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-16
located-in: [mesh-host examples/foundation-first-node.lock, mesh-host internal/bundle]
fixed-by: ADR 0088; mesh-host #16 (the foundation bundle installs nftables and loads a base ruleset before the store); proven by the bundle test and the genesis bed probing from outside during the install
amended-design: 03-DESIGN/01-to-be/07-the-foundation.md
---
# 054 — The adopted store and broker are open before the packet filter exists
@@ -1,11 +1,5 @@
---
status: resolved
opened: 2026-09-16
located-in:
- mesh-controller
- mesh-catalog
fixed-by: mesh-controller PR 27 (5718add); mesh-catalog PR 24 (a24362b)
amended-design:
---
# 055 — The adopted store and broker may be reachable on the control-node only
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-17
located-in: [mesh-controller, mesh-catalog]
fixed-by: mesh-catalog + mesh-controller (the foundation modules claim mesh-scoped seats)
amended-design: 02-DECISIONS/0079-the-foundation-seats-are-named-after-their-servers.md
---
# 056 — An adopted module assigned to a second node raises a second server
@@ -1,10 +1,5 @@
---
status: resolved
opened: 2026-09-17
located-in:
- mesh-controller
fixed-by: mesh-controller PR 31 (5dd2432); ADR 0083; proven by the built-store-cross-node bed
amended-design: 02-DECISIONS/0083-one-push-leaves-the-mesh-consistent.md
---
# 057 — A cross-node consumer is provisioned only when the provider is pushed again
@@ -1,10 +1,5 @@
---
status: resolved
opened: 2026-09-17
located-in:
- mesh-tools
fixed-by: mesh-tools PR 10 (0ea3db3); proven by the built-store-cross-node bed (restart count 0)
amended-design:
---
# 058 — A provisioner runtime crash-loops until the overlay is up
@@ -1,10 +1,5 @@
---
status: resolved
opened: 2026-09-17
located-in:
- mesh-controller
fixed-by: mesh-controller PR 30 (79a9e17); gated by mesh-lab built-store-cross-node
amended-design:
---
# 059 — The broker credential names the hub, not the node holding the broker
@@ -1,11 +1,5 @@
---
status: resolved
opened: 2026-09-17
located-in:
- mesh-catalog
- mesh-controller
fixed-by: mesh-catalog feat/the-mesh-builds-its-catalogue (965c58f); proven by the built-store-cross-node bed and direct builds
amended-design:
---
# 060 — The mesh cannot build most of its own catalogue
@@ -1,10 +1,5 @@
---
status: resolved
opened: 2026-09-18
located-in:
- mesh-catalog
fixed-by: mesh-catalog PR 26 (1891b09); gated by mesh-lab PR 34
amended-design:
---
# 061 — A module container that names no command runs the wrong thing
@@ -1,10 +1,5 @@
---
status: resolved
opened: 2026-09-18
located-in:
- mesh-controller
fixed-by: mesh-controller PR 29 (98aea8b); gated by mesh-lab PR 34
amended-design:
---
# 062 — A failed lookup composes the network without the registry trust
@@ -1,11 +1,5 @@
---
status: resolved
opened: 2026-09-18
located-in:
- mesh-controller
fixed-by: mesh-controller fix/one-push-is-enough (25e42b3); gated by the built-store-cross-node bed
amended-design:
---
# 063 — The foundation's ports are accepted on input but not forwarded
@@ -1,11 +1,5 @@
---
status: resolved
opened: 2026-09-18
located-in:
- mesh-catalog
- mesh-controller
fixed-by: ADR 0097 and mesh-controller #38 (a vendor image is a declared build input; a recipe copying out of an undeclared image is refused); the package half by the facts on current code — the one recipe that installs a public package (the catalogue module, pg) built and installed through the mesh's builder in the genesis bed on 2026-09-21, and no recipe copies from a public image any more
amended-design: 03-DESIGN/01-to-be/18-building-a-module.md
---
# 064 — A mesh build cannot fetch a module's external dependencies
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-20
located-in: [mesh-controller internal/inventory (node_report), mesh-controller cmd/mesh-controller (status)]
fixed-by: ADR 0090; mesh-controller feat/multiple-fixes (the report counts identical failures; status says stuck after three)
amended-design: 03-DESIGN/01-to-be/10-delivery.md
---
# 065 — A permanently failing resource is retried for ever with no escalation
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-20
located-in: [mesh-host internal/apply, mesh-controller internal/inventory (node_report)]
fixed-by: nothing new — a run-once validator before a service that restarts on the file is the grouping (ADR 0053); the lab's coupled-pair spike proves the service never serves what the validator refused; the visible half was issue 065
amended-design: 03-DESIGN/01-to-be/20-writing-a-module.md
---
# 066 — A partly applied declaration leaves a mixed state, with no rollback
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-20
located-in: [mesh-controller, hq 03-DESIGN/01-to-be/23-choosing-a-provider.md]
fixed-by: graduated — hq fc4ab37 (ADR 0084, to-be design 23)
amended-design: 03-DESIGN/01-to-be/23-choosing-a-provider.md
---
# A provision cannot name which provider serves it
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-20
located-in: [hq 03-DESIGN/01-to-be/24-the-secrets-vault.md]
fixed-by: graduated — hq fc4ab37 (ADR 0085, to-be design 24)
amended-design: 03-DESIGN/01-to-be/24-the-secrets-vault.md
---
# Secrets have no owning module
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-20
located-in: [mesh-controller internal/catalogue (requires/secrets), mesh-controller internal/inventory (secret key)]
fixed-by: ADR 0094; mesh-controller feat/several-secrets (secrets: under local names, the pair keyed on the local name, migration 0027); proven by the vault bed
amended-design: 03-DESIGN/01-to-be/24-the-secrets-vault.md
---
# One `secret` provision yields one value, and a module may need several
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-20
located-in: [mesh-controller internal/inventory (secret), mesh-controller cmd/mesh-controller (secret accept)]
fixed-by: ADR 0092; mesh-controller feat/multiple-fixes (secret accept --provider; origin on the pair; remake and rotate refused)
amended-design: 03-DESIGN/01-to-be/24-the-secrets-vault.md
---
# An operator cannot deliver a pair credential, so the vault's third species has no entry
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-20
located-in: [mesh-host internal/bootstrap, mesh-host examples/foundation-first-node.lock]
fixed-by: mesh-host PR 14 (e30a6b0), mesh-controller PR 34 (6b695c8), mesh-catalog PR 30 (d03520f), mesh-lab PR 39 (7e2e97f); proven by the one-node genesis bed step V5, 22/22
amended-design: 03-DESIGN/01-to-be/24-the-secrets-vault.md
---
# The foundation is raised with fixed credentials, and they stay
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-21
located-in: [mesh-host internal/bootstrap, mesh-catalog modules/mesh-controller/module.json]
fixed-by: mesh-host #17 (genesis registers the manifest its build produced), mesh-catalog #33 (the copy deleted), mesh-lab #42; proven by the genesis-single bed
amended-design: 03-DESIGN/01-to-be/17-raising-a-mesh.md
---
# The controller's manifest exists twice, and nothing keeps the copies equal
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-21
located-in: [mesh-lab test/integration]
fixed-by: ADR 0089; mesh-lab #41 (one loader, eight beds read the catalogue, the receipt claims it, a check refuses inline copies); proven by eight beds green against the catalogue
amended-design: 03-DESIGN/01-to-be/01-end-to-end-testing.md
---
# Beds carry copies of catalogue manifests, so a catalogue change is proven nowhere
@@ -1,8 +1,5 @@
---
status: resolved
opened: 2026-09-21
located-in: [mesh-lab test/integration]
fixed-by: mesh-lab, over three multiple-fixes rounds — nine beds read the catalogue or were retired as duplicate coverage; the three mechanism fixtures wear names that are no catalogue module's; the declared list in test/beds-read-the-catalogue.test.ts is empty of WEARING
---
# A mesh test wears a catalogue module's name
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-21
located-in: [mesh-lab src/rebuild.ts, mesh-lab src/runtimes.ts]
fixed-by: mesh-lab feat/mesh-tests-and-runtimes (the suite compares each stocked runtime against its source and rebuilds it where older, missing or uncommitted); proven by removing an image and watching the run rebuild it
amended-design: 03-DESIGN/01-to-be/01-end-to-end-testing.md
---
# A stocked runtime image is never rebuilt by the run
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-21
located-in: [mesh-catalog modules/step-ca, mesh-catalog modules/route-proxy]
fixed-by: ADR 0098; mesh-catalog multiple-fixes (the authority makes its own root and serves it; the proxy fetches it through a gate); proven by the route-forwarding bed
amended-design: 03-DESIGN/01-to-be/08-connectivity.md
---
# A served fact made at first start cannot be served, so the catalogue's authority cannot start
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-21
located-in: [mesh-host internal/declaration, mesh-controller internal/catalogue, mesh-catalog modules/route-proxy]
fixed-by: ADR 0099; mesh-host and mesh-controller multiple-fixes (a run-once step may name what it reads and runs again when it changed); mesh-catalog multiple-fixes (the proxy's gate names the binding, the server names the gate)
amended-design: 03-DESIGN/01-to-be/08-connectivity.md, 03-DESIGN/01-to-be/20-writing-a-module.md
---
# 077 — A fact fetched at first start is fetched once per declaration
@@ -1,8 +1,5 @@
---
status: resolved
opened: 2026-09-21
located-in: [mesh-controller internal/inventory (secrets), mesh-controller cmd (module issue)]
fixed-by: mesh-controller multiple-fixes (a delivery is refused for a name the module does not declare as an own secret, a requirement it has not got, or a local it does not keep; the refusal names what it does declare); module issue refuses a module with no broker secret before making the account; found one stale delivery in the whole-mesh bed and one orphan account the mesh itself made
---
# 078 — A delivered secret is accepted under any name
@@ -1,8 +1,5 @@
---
status: resolved
opened: 2026-09-22
located-in: [mesh-controller internal/catalogue (facts)]
fixed-by: mesh-controller multiple-fixes (the facts take a name as the control plane keys it, internal or bare, and write each machine once); a unit test holds both keyings to the same files
---
# 079 — Every machine is named twice over in the hosts file and the resolver's zones
@@ -1,8 +1,5 @@
---
status: resolved
opened: 2026-09-22
located-in: [mesh-catalog modules/redis (the provisioner's ACL)]
fixed-by: mesh-catalog multiple-fixes (the consumer's ACL user loses the dangerous command category); proven by the grant end-to-end bed, which now asserts a write outside the consumer's keys and FLUSHALL are refused
---
# 080 — A cache grant lets the consumer flush the server
@@ -1,8 +1,5 @@
---
status: resolved
opened: 2026-09-22
located-in: [mesh-catalog modules/n8n, mesh-catalog modules/baserow]
fixed-by: mesh-catalog multiple-fixes (neither module takes the shared cache — baserow runs its own, n8n in its shipped mode needs none); mesh-lab multiple-fixes (a check that every catalogue module taking the cache presents the login; the two-node bed asserts baserow's own cache answers)
---
# 081 — A cache consumer does not use the login it was granted
@@ -1,8 +1,5 @@
---
status: resolved
opened: 2026-09-22
located-in: [mesh-controller internal/link (serve, enrolment), mesh-controller internal/inventory]
fixed-by: mesh-controller multiple-fixes (a report the store cannot take right now is handed back to the broker after a short pause; any other failure is still acknowledged); unit tests on both halves; the two-node bed
---
# 082 — A report that arrives while the store restarts is lost, and the node is never heard from
@@ -1,8 +1,5 @@
---
status: resolved
opened: 2026-09-22
located-in: [mesh-controller internal/link (serve, enrolment), mesh-controller internal/inventory (tokens), mesh-host internal/link (enrol)]
fixed-by: mesh-controller multiple-fixes (build results, upgrades and catch-ups handed back while the store is away, bounded; an enrolment claims its token and spends it last, and is answered "try again"); mesh-host multiple-fixes (the host asks again with the same request); mesh-lab multiple-fixes (the store-window bed)
---
# 083 — Other control messages are lost while the store restarts
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-22
located-in: [mesh-controller internal/overlay, mesh-host internal/apply]
fixed-by: ADR 0102 (mesh-controller internal/overlay: the runtime file written into, reloaded), issue 128 (the hosts file as a region)
amended-design: 03-DESIGN/01-to-be/05-the-node-host.md
---
# 084 — Taking the networking module on an adopted node restarts every container on the machine
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-22
located-in: [mesh-host internal/bootstrap, mesh-catalog modules/builder]
fixed-by: mesh-host#21, mesh-controller#45, mesh-catalog#39
amended-design:
---
# 085 — The packages port given at genesis is not a setting, and a later module can undo it
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-22
located-in: [mesh-controller cmd/mesh-controller/adoption.go (take previews nothing), mesh-host internal/apply (the comparison and the record)]
fixed-by: mesh-controller 201 (the preview names the narrowing and the port's reach), 206 (`take --yes <digest>` acts on the preview read)
amended-design:
---
# 086 — Taking a module narrows a port the predecessor served, without saying so
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-22
located-in: [mesh-controller internal/link/protocol.go (the report field that was missing), internal/inventory, cmd/mesh-controller (node show and status)]
fixed-by: mesh-controller 7683ba8, corrected by 1d9c102
amended-design:
---
# 087 — The controller cannot tell that a node's host is too old for what it sends
@@ -1,9 +1,5 @@
---
status: resolved
opened: 2026-09-22
located-in: [mesh-catalog modules/gitea, mesh-controller internal/catalogue/declaration.go]
fixed-by: mesh-controller 7352c84, merged in #46 — a module is told its port in a container's environment too, as a file already was
amended-design:
---
# 088 — The forge's own address names a port it may not have

Some files were not shown because too many files have changed in this diff Show More