A module's directory is never shared code, held or not (hq issue 278) #93

Merged
mesh-admin merged 1 commits from fix/a-module-directory-is-never-shared-code into main 2026-10-06 18:28:47 +00:00
Contributor

What happened. The mesh-catalog merge 7f99fb4a rebuilt 103 modules, with build-agent in tier 0. ADR 0236 recorded that as "a change to the build agent rebuilds most of the catalogue". It wasn't the build agent: the merge touched modules/showcase/index.ts. showcase is the catalogue's reference module and no machine holds it. The merge didn't change its module.json, so whatTheMergeTouched read the file as shared code and rebuilt every module built from the repository (88 came out byte-identical). build-agent was in tier 0 only because everything else is built by it. You can reproduce it read-only: plans repository=novox/mesh-catalog paths=modules/showcase/index.ts plans 103 modules.

Fix. Whether a directory is a module is a fact of the repository at the merge commit, so the forge's announcer now says it (mesh-catalog, same branch name):

  • SourceMoved gains module_dirs (the changed files' directories that hold a module.json at the commit) and module_dirs_said.
  • A changed file inside one of those directories is that module's business. Only a file in no such directory counts as shared code.
  • An announcer that doesn't send the fields keeps the old rule (compatible both ways).
  • The plans what-if takes the same list as module-dirs.

The builder, ADR 0236's open question. Nothing depends on the build agent except through built-by edges, and built-by never widens a plan (reachableFrom). So a change to the agent, whether to its manifest or its program, rebuilds the agent alone. Modules that moved beside it are ordered after it. No builder fingerprint is needed.

Tests:

  • TestAChangeInsideAModuleIsThatModulesHeldOrNot: said / not said, nested paths, a directory with no manifest, the root never counting, removed manifests.
  • TestTheAnnouncerSaysWhichDirectoriesAreModules: the wire format, and an old announcement reading as not said.
  • TestAChangeToTheBuildAgentRebuildsTheBuildAgentAlone: manifest-only and program changes both plan one module in one tier; with redis moved beside it, the agent comes first and redis follows.
  • TestNothingStandsOnTheBuildAgentOnlyIsBuiltByIt: over the real dependenciesOf.

The full suite passes against throwaway postgres:17 + nats:2.11. vet and gofmt are clean. -race passes on cmd/mesh-controller and internal/inventory.

Roll out the controller before the announcer; either order is safe.

hq: issue 278, plus a progressive-insight note on ADR 0236. Do not merge without a human approval.

**What happened.** The mesh-catalog merge 7f99fb4a rebuilt 103 modules, with build-agent in tier 0. ADR 0236 recorded that as "a change to the build agent rebuilds most of the catalogue". It wasn't the build agent: the merge touched `modules/showcase/index.ts`. showcase is the catalogue's reference module and no machine holds it. The merge didn't change its `module.json`, so `whatTheMergeTouched` read the file as shared code and rebuilt every module built from the repository (88 came out byte-identical). build-agent was in tier 0 only because everything else is built by it. You can reproduce it read-only: `plans repository=novox/mesh-catalog paths=modules/showcase/index.ts` plans 103 modules. **Fix.** Whether a directory is a module is a fact of the repository at the merge commit, so the forge's announcer now says it (mesh-catalog, same branch name): - `SourceMoved` gains `module_dirs` (the changed files' directories that hold a `module.json` at the commit) and `module_dirs_said`. - A changed file inside one of those directories is that module's business. Only a file in no such directory counts as shared code. - An announcer that doesn't send the fields keeps the old rule (compatible both ways). - The `plans` what-if takes the same list as `module-dirs`. **The builder, ADR 0236's open question.** Nothing depends on the build agent except through built-by edges, and built-by never widens a plan (`reachableFrom`). So a change to the agent, whether to its manifest or its program, rebuilds the agent alone. Modules that moved beside it are ordered after it. No builder fingerprint is needed. **Tests:** - `TestAChangeInsideAModuleIsThatModulesHeldOrNot`: said / not said, nested paths, a directory with no manifest, the root never counting, removed manifests. - `TestTheAnnouncerSaysWhichDirectoriesAreModules`: the wire format, and an old announcement reading as not said. - `TestAChangeToTheBuildAgentRebuildsTheBuildAgentAlone`: manifest-only and program changes both plan one module in one tier; with redis moved beside it, the agent comes first and redis follows. - `TestNothingStandsOnTheBuildAgentOnlyIsBuiltByIt`: over the real `dependenciesOf`. The full suite passes against throwaway postgres:17 + nats:2.11. vet and gofmt are clean. `-race` passes on cmd/mesh-controller and internal/inventory. Roll out the controller before the announcer; either order is safe. hq: issue 278, plus a progressive-insight note on ADR 0236. Do not merge without a human approval.
mesh-admin added 1 commit 2026-10-06 17:56:05 +00:00
The merge of mesh-catalog 7f99fb4a rebuilt 103 modules with the build agent in tier 0, and ADR
0236 recorded it as "a change to the build agent rebuilds most of the catalogue". The agent had
not changed: modules/showcase/index.ts had. showcase is the catalogue's reference module, held
by no machine, and its manifest was not in the merge, so whatTheMergeTouched read the file as
shared code and rebuilt everything built from the repository (88 came out byte-identical). The
agent stood first only because everything is built by it.

Whether a directory is a module is a fact of the repository at the merge commit, so the forge's
announcer now says it: module_dirs, the changed files' directories holding a module.json there,
with module_dirs_said. A changed file inside one is that module's business; only a file in no
such directory is shared. An announcer that does not say keeps the old rule. `plans` what-if
takes the same list as module-dirs.

And a regression for the open question: nothing depends on the build agent except by being
built by it, and built-by never widens a plan, so a change to the agent - manifest or program -
rebuilds the agent alone; what moved beside it is ordered after it.
mesh-admin merged commit 0090bf6af7 into main 2026-10-06 18:28:47 +00:00
mesh-admin deleted branch fix/a-module-directory-is-never-shared-code 2026-10-06 18:28:47 +00:00
Author
Contributor

Delivery novox/mesh-controller@0090bf6af797 — delivered since 2026-10-06T23:05:28Z

Machines

  • build-agent on ace: passed — healthy 3 times over 2m27s
  • build-agent on the rest running it: sent
  • mesh-controller on novox: passed — healthy 3 times over 8m51s
  • mesh-controller on the rest running it: sent
  • route-proxy on ace: passed — healthy 3 times over 2m32s
  • route-proxy on the rest running it: sent

Transitions

  • 2026-10-06 23:05 (new) → proposed (announced): novox/mesh-controller#93 merged; its head was not heard by this owner, so it is made from the forge's word
  • 2026-10-06 23:05 proposed → held (merged-unchecked): merged without a passing check — a verdict known with it is taken first: only a person decides that it goes on
  • 2026-10-06 23:05 held → delivering (go): its walk started on a word that was not this owner's: the controller's own path, which waits for nobody, or a person's plans go
  • 2026-10-06 23:05 delivering → delivered (done): its walk is done: every machine of its deploy plan passed, or was left as its policy says

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

<!-- mesh-delivery:view --> **Delivery** `novox/mesh-controller@0090bf6af797` — **delivered** since 2026-10-06T23:05:28Z **Machines** - build-agent on ace: passed — healthy 3 times over 2m27s - build-agent on the rest running it: sent - mesh-controller on novox: passed — healthy 3 times over 8m51s - mesh-controller on the rest running it: sent - route-proxy on ace: passed — healthy 3 times over 2m32s - route-proxy on the rest running it: sent **Transitions** - 2026-10-06 23:05 (new) → proposed (announced): novox/mesh-controller#93 merged; its head was not heard by this owner, so it is made from the forge's word - 2026-10-06 23:05 proposed → held (merged-unchecked): merged without a passing check — a verdict known with it is taken first: only a person decides that it goes on - 2026-10-06 23:05 held → delivering (go): its walk started on a word that was not this owner's: the controller's own path, which waits for nobody, or a person's `plans go` - 2026-10-06 23:05 delivering → delivered (done): its walk is done: every machine of its deploy plan passed, or was left as its policy says The commit's note under `refs/notes/mesh-plan` keeps every transition: `git log --notes=mesh-plan`.
This repo is archived. You cannot comment on pull requests.
No Reviewers
1 Participants
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: novox/mesh-controller#93