diff --git a/04-ISSUES/364-the-gate-refuses-a-module-that-uses-a-seat-another-module-declares/00-report.md b/04-ISSUES/364-the-gate-refuses-a-module-that-uses-a-seat-another-module-declares/00-report.md new file mode 100644 index 00000000..79996cd1 --- /dev/null +++ b/04-ISSUES/364-the-gate-refuses-a-module-that-uses-a-seat-another-module-declares/00-report.md @@ -0,0 +1,48 @@ +--- +status: located +opened: 2026-10-10 +located-in: [mesh-controller cmd/mesh-controller (check.go moduleCheckFor), mesh-controller internal/builder (check.go gateLayer)] +fixed-by: +amended-design: +--- + +# 364. The merge gate refuses a module that uses a seat another module declares + +## Symptom + +On 2026-10-10 the catalogue's pull request for the agent module's proposed instructions +(ADR 0274, still on its own pull request, hq 268, so not linked here) +added `uses: [operator-channel]` to the module's manifest, so the module could ask the operator. Its +`mesh/merge-gate` failed: "a manifest the change touches fails the module check: claude-code uses the seat +"operator-channel", which no module declares and the mesh does not define". Its `mesh/repo-check`, which runs the +same module check over every manifest of the catalogue, passed. The router's module declares that seat. + +## Why it is an issue + +The gate's first step runs the controller's `module check` over **the manifests the change touches** and nothing +else. The rules between manifests then run over that set, so a seat another module declares is "declared by no +module". The command's own documentation says the opposite: "A seat another module declares is unknown unless that +module's manifest is passed too. Both are printed as a note, not as a problem — a check that refused what it could +not see would teach people to ignore it." The code refuses it. + +So **no module can start using a seat a module declares**, the operator channel's above all (ADR 0259 says any module +asks through it), and no channel can claim a kind of the channel bench, unless the pull request also touches the +declaring module's manifest. The searched literal text was in no record. + +## Impact + +Every module that becomes an asker is blocked at the gate. The first is the agent module's proposals (ADR 0274). + +## Cause + +`moduleCheckFor` counts every problem `CatalogueProblems` gives as a failure, and the gate gives it only the touched +manifests. + +## Fix + +The gate says it gives only some of a repository's manifests (an environment variable the judge reads); the module +check then says a seat none of them declares as a note. Given every manifest, as the catalogue's own check and +registration do, it stays a refusal. A judge that predates the variable ignores it and refuses as before, so the fix +takes effect once the controller that carries it is the one the mesh runs. In the controller's pull request for this +issue, with its tests: the module check over one manifest that uses a module's seat refuses it, and notes it when told +it was given only some.