This is the controller part of hq ADR 0251 and to-be 51 (hq PR #200). It adds three new verbs to the mesh-controller seat. The controller is the seat's only holder, so the verbs are required from the start.
artifacts only reads. It lists every artifact the mesh recorded making in its artifact store, with its repository, digest and kind (image or archive). Each one also has a state: kept (with why: definition, recent-build or unaddressable), eligible, or collected. Collected artifacts are always counted, but listed only with collected, because that list only grows and a verb answers in one bus message (issue 314). repository narrows the list; the counts stay whole.
collect is the after-build sweep, run on demand. Without confirm it is a dry run: kept archives are checked with HEAD requests only, what would be let go is listed (at most 1000, with not_listed), and nothing is held or deleted. With confirm and why, every kept archive is held first, then the eligible artifacts are let go oldest first and recorded as collected. It stops at the store's first refusal. It is bounded by most (500 by default, at most 5000) and 45 seconds. A real run is recorded as a hand act (handActVerbs, as a person's decision). confirm without why is refused, and why without confirm is refused too.
images only reads. For one machine, it lists every container image in the declaration the mesh would send now and in the one last sent (scheduled steps included), with the resources that name each image. The sent summary now keeps a container's image. A summary kept before this change gives sent_known: false.
Refactor: the inventory has one reading of the records, Artifacts (with KeepSet carrying reasons), and ToCollect and KeptArchives are built on it. The after-build sweep and collect share one sweep with different bounds.
I ran gofmt, go vet and the whole suite under -race against a throwaway postgres. Everything passes.
This is the controller part of hq ADR 0251 and to-be 51 (hq PR #200). It adds three new verbs to the mesh-controller seat. The controller is the seat's only holder, so the verbs are required from the start.
- **artifacts** only reads. It lists every artifact the mesh recorded making in its artifact store, with its repository, digest and kind (image or archive). Each one also has a state: kept (with why: `definition`, `recent-build` or `unaddressable`), eligible, or collected. Collected artifacts are always counted, but listed only with `collected`, because that list only grows and a verb answers in one bus message (issue 314). `repository` narrows the list; the counts stay whole.
- **collect** is the after-build sweep, run on demand. Without `confirm` it is a dry run: kept archives are checked with HEAD requests only, what would be let go is listed (at most 1000, with `not_listed`), and nothing is held or deleted. With `confirm` and `why`, every kept archive is held first, then the eligible artifacts are let go oldest first and recorded as collected. It stops at the store's first refusal. It is bounded by `most` (500 by default, at most 5000) and 45 seconds. A real run is recorded as a hand act (handActVerbs, as a person's decision). `confirm` without `why` is refused, and `why` without `confirm` is refused too.
- **images** only reads. For one machine, it lists every container image in the declaration the mesh would send now and in the one last sent (scheduled steps included), with the resources that name each image. The sent summary now keeps a container's `image`. A summary kept before this change gives `sent_known: false`.
Refactor: the inventory has one reading of the records, `Artifacts` (with `KeepSet` carrying reasons), and `ToCollect` and `KeptArchives` are built on it. The after-build sweep and `collect` share one `sweep` with different bounds.
I ran gofmt, `go vet` and the whole suite under `-race` against a throwaway postgres. Everything passes.
mesh/merge-gate pass: builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step; every machine composes with the change as it…
The store's tools and a machine's image pruning decide from the records, so
the controller says them: artifacts (every recorded artifact, kept and why,
eligible, collected on request), collect (the after-build sweep on demand,
a dry run unless confirmed with a why, recorded as a hand act) and images
(what a machine's declaration names, now and as last sent). The sweep is one
implementation with two sets of bounds.
build-agent keeps data (ADR 0233): what it holds is backed up before it moves
route-proxy provides route: its consumers are sent again after it
route-proxy keeps data (ADR 0233): what it holds is backed up before it moves
Machines
mesh-controller on novox: judging — 0 healthy judging(s) so far
Transitions
2026-10-08 10:05 (new) → proposed (announced): novox/mesh-controller#140's head announced
2026-10-08 10:10 proposed → checked (checked): the verdict names this commit
2026-10-08 10:10 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
2026-10-08 11:05 ready → published (merged): on the trunk its modules follow: merged there, and its walk opened — or nothing for a walk to move
2026-10-08 11:05 published → delivering (go): its walk started: let go by this owner in its group's order, by a person, or on the controller's own path
2026-10-08 11:07 delivering → superseded (superseded): a newer delivery to the same trunk took over its walk
The commit's note under refs/notes/mesh-plan keeps every transition: git log --notes=mesh-plan.
<!-- mesh-delivery:view -->
**Delivery** `novox/mesh-controller@557b23d43f35` — **superseded** since 2026-10-08T11:07:03Z
**Delivery plan** — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step
- tier 0: mesh-controller
- tier 1: build-agent
- tier 2: route-proxy
- ace: receives build-agent, route-proxy
- g14: receives build-agent
- novox: receives mesh-controller, build-agent, route-proxy
- shanks: receives build-agent
- build-agent keeps data (ADR 0233): what it holds is backed up before it moves
- route-proxy provides route: its consumers are sent again after it
- route-proxy keeps data (ADR 0233): what it holds is backed up before it moves
**Machines**
- mesh-controller on novox: judging — 0 healthy judging(s) so far
**Transitions**
- 2026-10-08 10:05 (new) → proposed (announced): novox/mesh-controller#140's head announced
- 2026-10-08 10:10 proposed → checked (checked): the verdict names this commit
- 2026-10-08 10:10 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
- 2026-10-08 11:05 ready → published (merged): on the trunk its modules follow: merged there, and its walk opened — or nothing for a walk to move
- 2026-10-08 11:05 published → delivering (go): its walk started: let go by this owner in its group's order, by a person, or on the controller's own path
- 2026-10-08 11:07 delivering → superseded (superseded): a newer delivery to the same trunk took over its walk
The commit's note under `refs/notes/mesh-plan` keeps every transition: `git log --notes=mesh-plan`.
build-agent keeps data (ADR 0233): what it holds is backed up before it moves
route-proxy provides route: its consumers are sent again after it
route-proxy keeps data (ADR 0233): what it holds is backed up before it moves
Run by the build seat on ace as build-1791453916600824343 (builds --log build-1791453916600824343).
--- the gate: build-agent, mesh-controller, route-proxy
mesh-controller: ok, 50 tool(s); WARNING: controller stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
long-running resources without health: 1
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-08T10:04:03Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-08T10:04:03Z
modules the change moves:
- mesh-controller (changed)
machines:
- a machine (f35): composes
- holds mesh-dns-resolver (idt): composes
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
- a machine (yvbpsm): composes
a merge would rebuild 3 module(s) in 3 tier(s): build-agent, mesh-controller, route-proxy
--- its merge-check.sh (go toolchain)
ok github.com/novox/mesh-controller/cmd/mesh-builder 1.030s
ok github.com/novox/mesh-controller/cmd/mesh-controller 140.385s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.011s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.018s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.014s
ok github.com/novox/mesh-controller/examples/route-proxy 1.112s
ok github.com/novox/mesh-controller/internal/artifacts 1.030s
ok github.com/novox/mesh-controller/internal/broker 2.432s
ok github.com/novox/mesh-controller/internal/builder 1.738s
ok github.com/novox/mesh-controller/internal/catalogue 3.931s
ok github.com/novox/mesh-controller/internal/conditions 2.036s
ok github.com/novox/mesh-controller/internal/envfile 1.068s
ok github.com/novox/mesh-controller/internal/facts 1.075s
ok github.com/novox/mesh-controller/internal/identity 4.064s
ok github.com/novox/mesh-controller/internal/inventory 66.884s
ok github.com/novox/mesh-controller/internal/lease 17.702s
ok github.com/novox/mesh-controller/internal/licences 3.710s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.072s
ok github.com/novox/mesh-controller/internal/link 42.872s
ok github.com/novox/mesh-controller/internal/lint 1.872s
ok github.com/novox/mesh-controller/internal/outward 1.097s
ok github.com/novox/mesh-controller/internal/overlay 1.085s
ok github.com/novox/mesh-controller/internal/secrets 1.437s
ok github.com/novox/mesh-controller/internal/store 3.303s
ok github.com/novox/mesh-controller/internal/testbus 1.249s
ok github.com/novox/mesh-controller/internal/token 1.018s
**Merge check** at `557b23d4`
- `mesh/merge-gate`: **PASS** — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller, route-proxy)
- `mesh/repo-check`: **PASS** — its merge-check.sh passed
**Delivery plan** — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step
- tier 0: mesh-controller
- tier 1: build-agent
- tier 2: route-proxy
- ace: receives build-agent, route-proxy
- g14: receives build-agent
- novox: receives mesh-controller, build-agent, route-proxy
- shanks: receives build-agent
- build-agent keeps data (ADR 0233): what it holds is backed up before it moves
- route-proxy provides route: its consumers are sent again after it
- route-proxy keeps data (ADR 0233): what it holds is backed up before it moves
Run by the build seat on ace as `build-1791453916600824343` (`builds --log build-1791453916600824343`).
```
--- the gate: build-agent, mesh-controller, route-proxy
mesh-controller: ok, 50 tool(s); WARNING: controller stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
long-running resources without health: 1
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-08T10:04:03Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-08T10:04:03Z
modules the change moves:
- mesh-controller (changed)
machines:
- a machine (f35): composes
- holds mesh-dns-resolver (idt): composes
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
- a machine (yvbpsm): composes
a merge would rebuild 3 module(s) in 3 tier(s): build-agent, mesh-controller, route-proxy
--- its merge-check.sh (go toolchain)
ok github.com/novox/mesh-controller/cmd/mesh-builder 1.030s
ok github.com/novox/mesh-controller/cmd/mesh-controller 140.385s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.011s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.018s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.014s
ok github.com/novox/mesh-controller/examples/route-proxy 1.112s
ok github.com/novox/mesh-controller/internal/artifacts 1.030s
ok github.com/novox/mesh-controller/internal/broker 2.432s
ok github.com/novox/mesh-controller/internal/builder 1.738s
ok github.com/novox/mesh-controller/internal/catalogue 3.931s
ok github.com/novox/mesh-controller/internal/conditions 2.036s
ok github.com/novox/mesh-controller/internal/envfile 1.068s
ok github.com/novox/mesh-controller/internal/facts 1.075s
ok github.com/novox/mesh-controller/internal/identity 4.064s
ok github.com/novox/mesh-controller/internal/inventory 66.884s
ok github.com/novox/mesh-controller/internal/lease 17.702s
ok github.com/novox/mesh-controller/internal/licences 3.710s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.072s
ok github.com/novox/mesh-controller/internal/link 42.872s
ok github.com/novox/mesh-controller/internal/lint 1.872s
ok github.com/novox/mesh-controller/internal/outward 1.097s
ok github.com/novox/mesh-controller/internal/overlay 1.085s
ok github.com/novox/mesh-controller/internal/secrets 1.437s
ok github.com/novox/mesh-controller/internal/store 3.303s
ok github.com/novox/mesh-controller/internal/testbus 1.249s
ok github.com/novox/mesh-controller/internal/token 1.018s
```
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
This is the controller part of hq ADR 0251 and to-be 51 (hq PR #200). It adds three new verbs to the mesh-controller seat. The controller is the seat's only holder, so the verbs are required from the start.
definition,recent-buildorunaddressable), eligible, or collected. Collected artifacts are always counted, but listed only withcollected, because that list only grows and a verb answers in one bus message (issue 314).repositorynarrows the list; the counts stay whole.confirmit is a dry run: kept archives are checked with HEAD requests only, what would be let go is listed (at most 1000, withnot_listed), and nothing is held or deleted. Withconfirmandwhy, every kept archive is held first, then the eligible artifacts are let go oldest first and recorded as collected. It stops at the store's first refusal. It is bounded bymost(500 by default, at most 5000) and 45 seconds. A real run is recorded as a hand act (handActVerbs, as a person's decision).confirmwithoutwhyis refused, andwhywithoutconfirmis refused too.image. A summary kept before this change givessent_known: false.Refactor: the inventory has one reading of the records,
Artifacts(withKeepSetcarrying reasons), andToCollectandKeptArchivesare built on it. The after-build sweep andcollectshare onesweepwith different bounds.I ran gofmt,
go vetand the whole suite under-raceagainst a throwaway postgres. Everything passes.Delivery
novox/mesh-controller@557b23d43f35— superseded since 2026-10-08T11:07:03ZDelivery plan — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step
Machines
Transitions
The commit's note under
refs/notes/mesh-plankeeps every transition:git log --notes=mesh-plan.Merge check at
557b23d4mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller, route-proxy)mesh/repo-check: PASS — its merge-check.sh passedDelivery plan — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step
Run by the build seat on ace as
build-1791453916600824343(builds --log build-1791453916600824343).