diff --git a/.claude/agents/mesh-developer.md b/.claude/agents/mesh-developer.md index 8f359f17..ba9c9e86 100644 --- a/.claude/agents/mesh-developer.md +++ b/.claude/agents/mesh-developer.md @@ -29,7 +29,11 @@ only: never push, never open a pull request, never call a verb that writes on th ssh, never a shell helper for the mesh. Tests: every change carries a test that fails without it (check it); rows or subtests in existing tests where the repository is over the test budget the instructions set; no real sleeping. Run `go vet ./...`, `go vet -tags integration ./...` and `go test ./...` in every touched module as -the running checker places siblings (playbook 07). Use a temporary directory under `/var/tmp` (TMPDIR). Place siblings with `go.work` `use` lines or `replace` directives pointing at their worktree paths; never make a +the running checker places siblings (playbook 07). Before you report a head, also run the integration tests of every +package you touched, and of every package of the same module that imports one, against an embedded bus +(`go test -tags integration -count=1` on those packages), and name them and their results in your report: a compile +with `go vet` does not show an integration test the change breaks. In mesh-sdk run the whole untagged `./...` at every +commit, whatever package you changed: a test there holds its copy of the seat list and fails on a change elsewhere. Use a temporary directory under `/var/tmp` (TMPDIR). Place siblings with `go.work` `use` lines or `replace` directives pointing at their worktree paths; never make a symbolic link anywhere (the mesh's hard rules: nobody creates symlinks), not even under `/var/tmp`. Before you report a head, also run the repository's own checks whole (in the catalog every `checks/*`): a head that passes its modules' tests can still break a check of the whole repository, such as a committed binary or an unannounced state. @@ -38,7 +42,11 @@ program `cmd/mesh-judge` in the indexer's module, built at mesh-delivery's trunk head when that head changes the validator itself (then the indexer's own manifest is also validated at the trunk). Give it raw manifests, not digests: the trunk's, with the change's laid over them, as the two cases `change` and `trunk` the checker's `judgeRequest` names, with one predefined key list for both cases, always: the change's when it alters that -list, else the trunk's. The merge check fails a changed manifest the validator refuses or holds, +list, else the trunk's. Give it, and every catalog check you run, what is live now: the seat list the seat +`mesh-catalog`'s verb `seat-definitions` answers, read in the same turn, with the definitions the change's heads alter +laid over it for the change case, and the catalog at its trunk, fetched fresh, beside it. Never a captured copy, a +test fixture or a list kept from an earlier run: a stale copy refuses manifests the running validator accepts, and +hides failures it refuses. The merge check fails a changed manifest the validator refuses or holds, and also an unchanged one in which the change causes a problem the trunk case lacks; it says so only after a full build, and no module's unit tests run the validator. Report every manifest whose verdict differs between the two cases, with your heads. The reviewer asks for those @@ -46,7 +54,7 @@ verdicts, and a head reported without them is not reviewed. Start no agents of your own: the lead decides who works on what. **Stop at about two thirds of your context.** Commit what is done, write a section under your agent label at the -end of the handover file the caller named (the subtasks done by label, the head of each worktree, what is left in +end of the prepare file (or the handover file the caller named) (the subtasks done by label, the head of each worktree, what is left in order, the findings), and report. A fresh agent continues from that section; work past that point is lost when the context runs out. diff --git a/00-META/glossary.md b/00-META/glossary.md index e2a9b1c5..6d0ef839 100644 --- a/00-META/glossary.md +++ b/00-META/glossary.md @@ -230,7 +230,7 @@ assignment, which was the Placement domain until ADR 0641 §1 retired it into th controller and the store; for module assignment, by the seat `mesh-module-assigner`, in its states on the bus (ADR 0567). **Upstream of** every domain but Module; the others use the bus and the store as they are. **Decided by** ADR 0005, 0006, 0067, 0100, 0106, 0126, 0141, 0175, 0176, 0181, 0207, 0221, 0227, 0229, 0252, 0261, -0289, 0411, 0539, 0549, 0559, 0565, 0567, 0571, 0634, 0641. +0289, 0411, 0539, 0549, 0559, 0565, 0567, 0571, 0634, 0641, 0664, 0668. **Uses:** node, machine, module, seat, manifest (Module), config value (Config), proposal (Operator and conversation). - **controller** — the component that decides what each node should be, holds the mesh's records, and @@ -278,6 +278,21 @@ controller and the store; for module assignment, by the seat `mesh-module-assign one that does not require it has no account on it. Held by the `mesh-broker` seat, which is named after the role rather than the server, so the server can change without the seat doing so. The **bus module** is the module holding `mesh-broker`; it also provides bus state (Data, ADR 0595). +- **transport fault** — a failure of a call or a step because the part it asks did not answer for a moment, not + because of what it asked: a name lookup that timed out; a connection refused, reset or unreachable; a seat verb + answered with no responders while a holder of that seat is named in the assignments (ADR 0664 §1); and, for a call, + its own deadline passing (ADR 0668 §1). A build or check step that meets one is given again by the bus, at most + three runs (ADR 0664 §1, §2); a kept call is called again. A fault in what was asked (a compile error, an unknown + revision, a seat no holder is named for) is not one, and ends the step or the call at once. + *Not:* ~~transient error~~ (hq), ~~network blip~~ (hq) +- **kept call** — a call one part makes to another part's verb or tool whose answer it keeps and acts on, and which + the caller marks safe to repeat when it makes it; only a read, or a write the callee takes once by a key, may be + marked (ADR 0668 §1, §2). The caller calls it again through every transport fault until it is answered or the + caller stops; still unanswered after five minutes, it writes the finding `call-unanswered` into its own findings + state, naming the callee, the verb and since when, and none while the callee's machine is away (§3); and it calls + again on the callee's event saying its answer changed (§4). mesh-sdk carries its form (§7). A call not marked is + made once and its fault said. + *Not:* ~~retried call~~ (hq) - **the deprecated broker** — the lavinmq module. It was the mesh's bus and is not any more. It keeps running as an **ordinary provider** of the `amqp` provision, for modules that need a message broker of their own the way something needs a database @@ -823,7 +838,7 @@ controller (the planner, the rollout) until release 6 of ADR 0429; from each rel **Purpose.** To notice what is wrong with the mesh, say it once, repair what may be repaired unattended, and record what was done by hand. **Recorded by** the controller's condition store. **Upstream of** Delivery (the first-node gate) and Operator and conversation (a condition -becomes a message). **Decided by** ADR 0227, 0231, 0240, 0252, 0283, 0564. +becomes a message). **Decided by** ADR 0227, 0231, 0240, 0252, 0283, 0564, 0668. **Uses:** node, module, node-engine (Core). - **health** — a module's or a core component's statement of how it is alive and ready, which the @@ -842,7 +857,8 @@ becomes a message). **Decided by** ADR 0227, 0231, 0240, 0252, 0283, 0564. - **node health report** — each node-engine's own report of its node's health, a key that node's engine writes and the watchman reads (ADR 0564, as its progressive insight of 2026-10-29 has it); its layout is mesh-sdk's. - **observer** — a part that writes findings for the condition keeper: the watchman, the self-check and the - healers (ADR 0564 §2). An observer never writes a condition. + healers (ADR 0564 §2), and each caller of a kept call, for its `call-unanswered` (ADR 0668 §3). An observer never + writes a condition. - **condition keeper** — the holder of the seat `mesh-conditions`: the one writer of the open conditions, raising each from an observer's finding and clearing it when the finding goes, and saying `condition-raised`, `condition-changed` and `condition-cleared` (ADR 0564 §2, §3). The controller keeps them diff --git a/00-META/process/07-feature-branches.md b/00-META/process/07-feature-branches.md index fbd67027..48afd51d 100644 --- a/00-META/process/07-feature-branches.md +++ b/00-META/process/07-feature-branches.md @@ -253,8 +253,15 @@ is a breach the lead names. acceptance criteria**: one test or more per criterion at the level it names, each test's comment citing the criterion it proves by its label (`// 1118/AC2`), and no criterion left without its test; an integration criterion is a test that compiles and is run by the pull request's one check. The integration tests (those that start a store, a bus - or a process) are compiled with `go vet -tags integration ./...` while developing and run by that check; before the group's push only the tests that exercise the change are run by - name (step 3), nothing else. + or a process) are compiled with `go vet -tags integration ./...` while developing and run by that check. **Before a + developer reports a head, it also runs the integration tests of every package the change touches, and of every + package of the same module that imports one, against an embedded bus** (`go test -tags integration -count=1` on + those packages, not the whole module): on 2026-11-10 a kept call broke an integration test of a fix group whose + developers had run only the untagged suite, and the review's first round found it, not the developers. Before the + group's push the tests that exercise the change are run by name (step 3), nothing else. **In mesh-sdk the whole + untagged `./...` runs at every commit, whatever package the change is in**: a test there holds its copy of the seat + list and fails on a change elsewhere. How it is checked: the developer's report names those packages and their + results, and the reviewer refuses a head reported without them. - **Nothing is pushed and no pull request is opened in this step, and there is no try** (ADR 0548; the operator, 2026-10-26: "every release should only run 1 check or 1 try"). When every issue is committed, the lead brings each feature branch up to the current trunk (fetch by name, then merge) and the review reads the local commits. Never call @@ -265,8 +272,15 @@ is a breach the lead names. message ("issue 805: landing in mesh-catalog"); reach the mesh only through the mesh MCP server, never ssh; never push, open, merge or close a pull request; never call a try; never write to a store's database by hand, a schema change is a numbered migration and the consolidated schema; Go only unless the context file says otherwise; never - move another issue; **leave the integration tests to the check** (no store or bus started by hand): compile them - with `go vet -tags integration ./...`. A single integration test may be run locally against an embedded bus when + move another issue; **leave a module's whole integration level to the check** (no store or bus started by hand): + compile it with `go vet -tags integration ./...`, and run only the touched packages' integration tests against an + embedded bus before you report a head (above). **Judge a manifest and run the catalog's checks against what is live + now:** the seat list the seat `mesh-catalog`'s verb `seat-definitions` answers, read in the same turn, with the + definitions the change's heads alter laid over it for the change's case (ADR 0636 §4), and the catalog at its trunk, + fetched fresh, beside it; never a captured copy, a test fixture or a list kept from an earlier run (2026-11-10: a + stale seat list made eight manifests refused locally that the running validator accepts, and stale copies hid two + failures). **Stop at about two thirds of your context** and write a handover section at the end of the prepare file, + so a fresh agent continues from it (2026-11-10: four developers in turn carried one fix group so). A single integration test may be run locally against an embedded bus when it is the fastest way to find a cause, said in the review report and the pull request; before the group's push the tests that exercise the change are run this way, by name (step 3). After a failed check it usually pays to run that repository's whole integration level locally (`go test -tags integration -count=1 ./...` in each @@ -421,7 +435,7 @@ is a breach the lead names. `internal/beside` says. **Before the push, every member's suites run as the running checker runs them**: each sibling repository placed beside it by main's beside rules, the node-engine at the commit the machines run, and the running manifest validator - over every manifest the change touches. On 2026-11-02 release sdk1 failed four checks one fault at a time (test + over every manifest the change touches, given the live seat list and the catalog's fresh trunk (step 1's brief). On 2026-11-02 release sdk1 failed four checks one fault at a time (test globals left set, a sibling placed otherwise, the checker's manifest archive, a composition step the old checker could not build), each of which a run as the checker places things would have shown before the first push. How it is checked: the pull request's description names the placement, the node-engine commit and the manifest validator run used diff --git a/00-META/process/playbooks.html b/00-META/process/playbooks.html index 237f16ea..e3ed1138 100644 --- a/00-META/process/playbooks.html +++ b/00-META/process/playbooks.html @@ -291,7 +291,7 @@ code{font:12.5px ui-monospace,monospace;background:var(--soft);padding:1px 5px;b
// 1217/AC3).Two levels. Unit tests run all the time on the machine; integration tests (a bus, a store or a process started) are compiled there and never run: the checker's one merge check, asked by the one push after the review, runs them as the gate. There is no try (ADR 0548).
+Two levels. Unit tests run all the time on the machine; integration tests (a bus, a store or a process started) are compiled there whole, and only those of the packages a change touches are run there, against an embedded bus: the checker's one merge check, asked by the one push after the review, runs them as the gate. There is no try (ADR 0548).