R4e (mesh-catalog): build modules push and narrow, the gate stops judging, gitea writes mesh/check from the checker's owed state, and the census fixes #457

Merged
mesh-tools merged 51 commits from feat/r4e into main 2026-10-22 22:12:52 +00:00
Member

Delivery group feat/r4e (R4e of design 47: ADR 0503, 0513, 0514, 0520, 0521; ADR 0498-0501). Members: mesh-sdk, mesh-controller, mesh-delivery, mesh-catalog, all on branch feat/r4e.

This member: mesh-build-go, mesh-build-node and mesh-build-image push what they pack and read manifests with ParseManifestForInputs (ADR 0498; issues 1309, 1751, 1869; K2); mesh-build-image copies upstream images (ADR 0498 §4; issue 1824); the Node fetch and package steps (ADR 0500); the merge gate stops judging and the forge requires mesh/check alone outside hq (ADR 0503 §3; issues 1301, 1302); gitea sets mesh/check only from the checker's owed state by a watch, and no tool can set it (ADR 0521; K1); the census fixes of ADR 0514 (issues 1868 lock files, 1590 xz, 1824); clipmenu and i3 test fixes (issue 1814); every Go member pins mesh-sdk 104533e8 (gitea included, K3).

Tests: unit suites, the TypeScript suites, checks/locks; try PASS on 896bd883 (build-1792698362474618102).

Reviewed-by: review-r4e@shanks at 896bd88380

Delivery group feat/r4e (R4e of design 47: ADR 0503, 0513, 0514, 0520, 0521; ADR 0498-0501). Members: mesh-sdk, mesh-controller, mesh-delivery, mesh-catalog, all on branch feat/r4e. This member: mesh-build-go, mesh-build-node and mesh-build-image push what they pack and read manifests with ParseManifestForInputs (ADR 0498; issues 1309, 1751, 1869; K2); mesh-build-image copies upstream images (ADR 0498 §4; issue 1824); the Node fetch and package steps (ADR 0500); the merge gate stops judging and the forge requires mesh/check alone outside hq (ADR 0503 §3; issues 1301, 1302); gitea sets mesh/check only from the checker's owed state by a watch, and no tool can set it (ADR 0521; K1); the census fixes of ADR 0514 (issues 1868 lock files, 1590 xz, 1824); clipmenu and i3 test fixes (issue 1814); every Go member pins mesh-sdk 104533e8 (gitea included, K3). Tests: unit suites, the TypeScript suites, checks/locks; try PASS on 896bd883 (build-1792698362474618102). Reviewed-by: review-r4e@shanks at 896bd88380b350481cc54f1ea9a8f363a2943302
mesh-tools added 51 commits 2026-10-22 21:51:54 +00:00
ADR 0447 §1 has main require mesh/check alone. The repositories program now
requires it in place of mesh/merge-gate and mesh/repo-check on every listed
repository and on every other one whose main requires mesh/merge-gate, so the
switch needs no hand-kept list (lead decisions L4, L11). A main requiring
mesh/repo-check alone (hq) keeps it until issue 1296 (ADR 0503 §5).
Once main requires mesh/check, a hand that set it could pass a merge past the
checker, the gap issue 293 closed for the two statuses before it.
gitea_commit_status now refuses mesh/check in every state, and the new
gitea_check_status writes it alone; the bus grants that tool only to a module
whose manifest invokes it, the forge bridge (the lead's choice A).
Once main requires mesh/check, nothing writes mesh/merge-gate, and the merge
tool, which judged on it, would refuse every merge. It now judges on the
status the base requires: mesh/check's line names the trunk it judged, an
out-of-date one is refused and nothing is asked (the checker re-checks on a
trunk move, ADR 0447 §4); hq's mesh/repo-check is judged as before. The
announcer, the verdict, a trunk's move and a build's start write the
controller's two statuses only where a base still requires them, so hq keeps
mesh/repo-check and no stale mesh/merge-gate appears anywhere else.
Once main requires mesh/check, the controller publishes no verdict for it and
the gate, which moved deliveries on the controller's checked, would hold every
pull request proposed. A head's mesh/check is now its verdict, from the
forge's status event (gitea now sends the status's words) or its open pull
requests. The Approve is asked only on the checker's verdict at exactly the
heads the ask covers, so a member judged alone never passes its group; a
group on mesh/check asks no composed check and owes no mesh/merge-gate; a
member's mesh/check that changes withdraws the ask. Nothing is asked of the
controller for such a base, and recheck refuses, naming checker_pull. hq's
mesh/repo-check keeps today's path.
The controller's forget-checks goes with the merge gate's checks (ADR 0503 §3)
and 1318 removes the verb in the same group, so the gate must stop calling it
first: a closed pull request is stopped and asks the controller nothing, and
the manifest no longer invokes it. delivery-check stays for hq's base until
R4g (the lead's decision for 1302).
Kept (toolchains, keys, steps, each read by another module today) is said with stdio.Keeps
before the module serves; announcetest.Check holds the announcement equal to the code. The
module is pinned to mesh-sdk feat/r4e-sdk 9cb4d59.
Each run step goes through mesh-sdk's buildstep.Isolated: no network, none of the account,
the workspace read-write, the toolchain read-only, the npm cache beneath a throwaway layer
unless the build step is told publish (a trunk build). The module declares the bubblewrap
package and refuses a step, unhealthy, while bwrap is missing or older than 0.10. The proof
test runs a probe script through the real test step.
Kept (keys, steps, each read by another module today) is said with stdio.Keeps before the
module serves; announcetest.Check holds the announcement equal to the code. Pinned to
mesh-sdk feat/r4e-sdk 9cb4d59. The manifest test's call of the deleted
StateReadsNothingDeclares still has to go (the edit is waiting on the operator's permission).
Kept (toolchains, keys, steps, each read by another module today) is said with stdio.Keeps
before the module serves; announcetest.Check holds the announcement equal to the code. Pinned
to mesh-sdk feat/r4e-sdk 9cb4d59. The manifest test's call of the deleted
StateReadsNothingDeclares still has to go (the edit is waiting on the operator's permission).
Each run step goes through mesh-sdk's buildstep.Isolated: no network, none of the account,
the workspace read-write, the Go caches beneath a throwaway layer unless the build step is
told publish (a trunk build). The integration level runs its store, its bus and its tests in
one shut-off process (this program again, level <spec>), so they reach each other and
nothing else. build_go_test takes a -run pattern (a try's tests). The module declares the
bubblewrap package and refuses a step, unhealthy, while bwrap is missing or older than 0.10.
The proof test runs a probe test through the real unit level.
The xz reader is github.com/therootcompany/xz, declared in go.mod as build-agent declares it,
with build-agent's framing walk copied (xz_framing.go and its tests): too many blocks or
streams are refused before anything is decoded, a dictionary over 64 MiB is refused. The
same release tar under gzip and under xz packs to the build agent's archive.
The fetch writes beside.json naming the siblings it placed; the digest adds a line per
sibling to every package's text and answers them as beside, so a core repository's verdict
is kept only for the siblings it was judged with. DigestVersion 3, once for both changes:
the integration level's tags are integration,isolation, so the bubblewrap proofs run in
every check on a build node.
After the build ended the module pushes the packed bundle or archive with mesh-sdk's
PushBlob under <module>/<artifact> by its digest, a candidate's as a trunk build's, and the
step answers artifact-store://<module>/<artifact>/blobs/<digest> instead of a path. A push
that fails fails the step not stored: <artifact>: <the store's words>. The packed bytes are
never written to the node. The manifest requires artifact-store and places its address.
A package with a build or prepare script and a tsconfig.json is built with tsc -p . in the
shut-off run step, at both levels, instead of the --noEmit type-check; the fetch's
--ignore-scripts never runs those scripts. mesh-sdk's tests import ../dist and failed
ERR_MODULE_NOT_FOUND. The result names the step build.
After the build ended the module pushes the packed bundle with mesh-sdk's PushBlob under
<module>/<artifact> by its digest, a candidate's as a trunk build's, and the step answers
artifact-store://<module>/<artifact>/blobs/<digest> instead of the archive's path. A push
that fails fails the step not stored: <artifact>: <the store's words>; the packed bytes are
never written to the node. The manifest requires artifact-store and places its address.
The integration tests start the distribution registry (the store's own program) in the
test with its in-memory storage and the real PushBlob: the built bundle and archive each
answer a reference ending in its digest, the key the builder would write is valid and
deliverable, and the store serves bytes of that digest at the reference. The registry is
imported by these tests alone (go list -deps of the programs does not name it).
build_go_fetch parses its arguments with buildstep.ParseFetchRequest; with dir and paths
(from the builder, never from a manifest) the tree is narrowed after the fetch and the
merge to those paths, the manifest and the lock files, so a build reads nothing else. The
narrowing waits to move into mesh-sdk as buildstep.Narrow.
build_node_fetch takes buildstep.FetchRequest (dir and paths narrow the workspace) and an
optional package {repository, commit, ref}: the group's package member, built and packed
shut off and published nowhere. Each member's lock decides its SDK: the group's packed
file when the version and integrity are the lock's, else the registry's (integrity
checked); a version the registry lacks fails waits for: @novox/mesh-sdk@<version>. A
package artifact is built by its own script and packed with npm pack, shut off; only a
trunk build publishes it, from this process with the write credential (never in a
workspace): absent is published, the same file is done, another is version taken:. The
registry configuration file now lies outside every workspace.
writeLaunchers takes its entrypoint-to-launcher names from buildstep.Launchers, the rule the
controller reads a bundle by. RecipeSteps goes to 2: a member is now built against the SDK
its own lock names, which can change what a build produces (ADR 0405 §7).
A registry of the test's own speaks npm's publish protocol and asks for the credential: a
candidate's build publishes nothing, a trunk build publishes the packed file the build
digested, and a second trunk build of the same package finds it and publishes nothing.
The local narrowing of mesh-build-go and mesh-build-node moves into mesh-sdk (feat/r4e-sdk
d1af87a), with its tests; each module keeps its fetch-level test on real git. The three
build modules are pinned to d1af87a.
build-agent's check container has no bwrap; the build nodes, where the checker runs from
R4e, do. The sibling test and the real Node build skip naming it, and the pull-head pin
test still runs its fetch half and skips only the shut-off build.
gitea's index.ts conflicted on imports: kept both, the leaf's statesAnnouncement and the gate's checkStatusTool.
mesh-delivery-gate is pinned to the sdk lane's newest head d1af87a (the leaf had a90f523) until the final SDK head.
The build step parsed the manifest as a judge of config values, so claude-code, dunst and xterm, whose
values fall back to a predefined key, got a fingerprint but their tools bundle was refused at the build.
The builder holds no published list of predefined keys; ParseManifestForInputs is its read. mesh-build-node
reads module.json with its own narrow struct and needs no change.
gitea's Go code (cmd/repositories) changes in the R4e group, so it pins the SDK head every other member
pins; it still held 66e8fdaa.
Review finding K1 of R4e, issue 1301 S4 (ADR 0503 §3, ADR 0513 §4: the forge
requires mesh/check alone). gitea_check_status assumed only the bridge could
call it, but a tool is told no caller and node-tools invokes every tool, so any
session could set mesh/check to success and merge past the checker: the fault
issue 293 closed for the two statuses before it.

gitea now consumes mesh-delivery-forge-bridge.check.status, a subject the bus
grants to the bridge's own account alone, and check.ts writes mesh/check from
it: the source is checked, the head's whole sha and the state, and a revision
older than one already written on the head is dropped so a redelivered stale
pending never hides a verdict; a forge refusal throws, so the event is
delivered again. gitea_check_status is removed, and gitea_commit_status keeps
refusing mesh/check.
The catalogue's paths check (ADR 0260) reads every file of a module but its documentation and tests, and
the verbatim manifest names claude-code's own paths; as a constant in a _test.go file it stays a real
capture without being taken for one module reaching into another's state.
Write mesh/check from the checker's owed state, read by a watch (R2-1)
mesh/repo-check head 896bd88380b3 merged into trunk a21da33d4857 beside mesh-controller#441@d51324df — pass: THE CHANGE ALTERS ITS OWN CHECK (merge-check.s…
mesh/check failed: ace: novox/mesh-catalog#457: modules/gitea/go.mod names mesh-sdk 104533e8c0c9, which is neither on mesh-sdk's trunk nor the group's…
mesh/merge-gate head 896bd88380b3 merged into trunk a21da33d4857 — pass: group feat/r4e composed: every machine composes with the change as it did without …
mesh/delivery stopped: its walk plan-1792707174627079192 was stopped by a person (mesh-controller): issue 1886 (the operator, 02:08: fix it right now): s…
mesh/delivery-group group feat/r4e stopped: a member was stopped
896bd88380
R4e round 2 finding R2-1, ADR 0521: the delivery plan draws no edge that
orders the forge module before the forge bridge, and the forge module's
durable consumer keeps its deliver policy when its filters change, so a
check.status the bridge emitted before the forge module consumed it was lost.
An in-memory revision guard also forgot itself on a restart.

The forge module now reads mesh-delivery-checker.owed, which the checker
announces readable, by a watch: the watch hands over the latest value of every
key whenever the module starts, so a status written while it was away is
written then, and only the latest. Each mesh/check is written once per
revision, an older one dropped; a forge refusal is asked again on a bound
until written or overtaken; a refused read is said once and asked again until
granted. No tool writes mesh/check, and no check.status is consumed.
Author
Member

Delivery novox/mesh-catalog@896bd88380b3 — stopped since 2026-10-23T00:01:53Z

Delivery plan — builds gitea, mesh-build-go, mesh-build-image, mesh-build-node, mesh-catalog, mesh-delivery-gate, model-usage, mongodb, mssql, pacman → ace, g14, novox, shanks; no bus step; 3 wait(s) for a person

  • tier 0: gitea, mesh-build-go, mesh-build-image, mesh-build-node, mesh-catalog, mesh-delivery-gate, model-usage, mongodb, mssql, pacman
  • ace: receives mesh-build-go, mesh-build-image, mesh-build-node, pacman; waits for a person: mssql
  • g14: receives mesh-build-go, mesh-build-node, pacman
  • novox: receives gitea, mesh-build-go, mesh-build-node, mesh-catalog, mesh-delivery-gate, pacman; waits for a person: mongodb, mssql
  • shanks: receives mesh-build-go, mesh-build-image, mesh-build-node, pacman
  • gitea provides npm-package-registry, git, gitea-read, forge-account: its consumers are sent again after it
  • gitea keeps data (ADR 0233): what it holds is backed up before it moves
  • mongodb waits for a person: its policy records (module) — unless on a machine its move recreates none of its containers and moves none of its data, which the walk judges and then sends
  • mongodb provides mongodb-database: its consumers are sent again after it
  • mongodb keeps data (ADR 0233): what it holds is backed up before it moves
  • mssql waits for a person: its policy records (module) — unless on a machine its move recreates none of its containers and moves none of its data, which the walk judges and then sends
  • mssql provides mssql-database: its consumers are sent again after it
  • mssql keeps data (ADR 0233): what it holds is backed up before it moves
  • grants step: if this changes what the bus's user list says (a new tool, subject or user), novox is sent that list alone, every build there kept, before mesh-build-go, mesh-build-image, mesh-build-node, pacman is judged on its first machine

Group feat/r4e: novox/mesh-catalog@896bd88380, novox/mesh-controller@d51324df45, novox/mesh-delivery@efca168c55, novox/mesh-sdk@22b70c82b0

  • composed together: pass — every machine composes with the change as it did without (4 of 4 compose)

Machines

  • mesh-controller on every machine running it: sent
  • mesh-sdk on every machine running it: sent
  • pacman on every machine running it: sent
  • route-proxy on every machine running it: sent

Transitions

  • 2026-10-22 21:52 (new) → proposed (announced): novox/mesh-catalog#457's head announced
  • 2026-10-22 21:58 proposed → checked (checked): a verdict names this commit and the trunk's head as its trunk commit
  • 2026-10-22 21:58 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
  • 2026-10-22 22:15 ready → published (merged): on the trunk its modules follow: merged there, and its walk opened — or nothing for a walk to move
  • 2026-10-22 22:15 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 — not a failed walk that carried a later commit for it, after which it waits for a walk of its own commit
  • 2026-10-23 00:01 delivering → stopped (stop): its walk plan-1792707174627079192 was stopped by a person (mesh-controller): issue 1886 (the operator, 02:08: fix it right now): stuck for good on builder keys nothing running can reference; as an open plan it holds every merge check, including the fix mesh-controller #442. The fixed controller goes to novox by the bootstrap act (ADR 0522 §5); R4e's 8 + 40 remaining modules are carried on afterwards by a retry that resumes a hand-stopped plan (follow-up on issue 1886, note 7).

The commit's note under refs/notes/mesh-plan keeps every transition: git log --notes=mesh-plan.

<!-- mesh-delivery:view --> **Delivery** `novox/mesh-catalog@896bd88380b3` — **stopped** since 2026-10-23T00:01:53Z **Delivery plan** — builds gitea, mesh-build-go, mesh-build-image, mesh-build-node, mesh-catalog, mesh-delivery-gate, model-usage, mongodb, mssql, pacman → ace, g14, novox, shanks; no bus step; 3 wait(s) for a person - tier 0: gitea, mesh-build-go, mesh-build-image, mesh-build-node, mesh-catalog, mesh-delivery-gate, model-usage, mongodb, mssql, pacman - ace: receives mesh-build-go, mesh-build-image, mesh-build-node, pacman; waits for a person: mssql - g14: receives mesh-build-go, mesh-build-node, pacman - novox: receives gitea, mesh-build-go, mesh-build-node, mesh-catalog, mesh-delivery-gate, pacman; waits for a person: mongodb, mssql - shanks: receives mesh-build-go, mesh-build-image, mesh-build-node, pacman - gitea provides npm-package-registry, git, gitea-read, forge-account: its consumers are sent again after it - gitea keeps data (ADR 0233): what it holds is backed up before it moves - mongodb waits for a person: its policy records (module) — unless on a machine its move recreates none of its containers and moves none of its data, which the walk judges and then sends - mongodb provides mongodb-database: its consumers are sent again after it - mongodb keeps data (ADR 0233): what it holds is backed up before it moves - mssql waits for a person: its policy records (module) — unless on a machine its move recreates none of its containers and moves none of its data, which the walk judges and then sends - mssql provides mssql-database: its consumers are sent again after it - mssql keeps data (ADR 0233): what it holds is backed up before it moves - grants step: if this changes what the bus's user list says (a new tool, subject or user), novox is sent that list alone, every build there kept, before mesh-build-go, mesh-build-image, mesh-build-node, pacman is judged on its first machine **Group** `feat/r4e`: novox/mesh-catalog@896bd88380b3, novox/mesh-controller@d51324df4518, novox/mesh-delivery@efca168c5522, novox/mesh-sdk@22b70c82b0ab - composed together: pass — every machine composes with the change as it did without (4 of 4 compose) **Machines** - mesh-controller on every machine running it: sent - mesh-sdk on every machine running it: sent - pacman on every machine running it: sent - route-proxy on every machine running it: sent **Transitions** - 2026-10-22 21:52 (new) → proposed (announced): novox/mesh-catalog#457's head announced - 2026-10-22 21:58 proposed → checked (checked): a verdict names this commit and the trunk's head as its trunk commit - 2026-10-22 21:58 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail - 2026-10-22 22:15 ready → published (merged): on the trunk its modules follow: merged there, and its walk opened — or nothing for a walk to move - 2026-10-22 22:15 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 — not a failed walk that carried a later commit for it, after which it waits for a walk of its own commit - 2026-10-23 00:01 delivering → stopped (stop): its walk plan-1792707174627079192 was stopped by a person (mesh-controller): issue 1886 (the operator, 02:08: fix it right now): stuck for good on builder keys nothing running can reference; as an open plan it holds every merge check, including the fix mesh-controller #442. The fixed controller goes to novox by the bootstrap act (ADR 0522 §5); R4e's 8 + 40 remaining modules are carried on afterwards by a retry that resumes a hand-stopped plan (follow-up on issue 1886, note 7). The commit's note under `refs/notes/mesh-plan` keeps every transition: `git log --notes=mesh-plan`.
mesh-tools merged commit 89e15c7bcd into main 2026-10-22 22:12:52 +00:00
mesh-tools deleted branch feat/r4e 2026-10-22 22:12:52 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: novox/mesh-catalog#457