Merge pull request 'Glossary: transport fault and kept call; developers run the touched packages' integration tests once per head and use the live seat list (issue 1966, ADR 0668)' (#533) from agents/1966-lessons into main

This commit was merged in pull request #533.
This commit is contained in:
2026-11-10 07:33:26 +00:00
5 changed files with 70 additions and 24 deletions
+13 -3
View File
@@ -29,7 +29,13 @@ 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); 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 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 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). Once per head you report, not per commit, 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); where the importers are many, run the tests of them that
exercise the change by name (`-run`) and say that choice. Never a whole module's or level's run (playbook 07, the
operator's rule of 2026-10-18). Name the tests 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 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 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. modules' tests can still break a check of the whole repository, such as a committed binary or an unannounced state.
@@ -38,7 +44,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). 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 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 `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 and read again when you report a head, 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 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. 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 Report every manifest whose verdict differs between the two cases, with your heads. The reviewer asks for those
@@ -46,7 +56,7 @@ verdicts, and a head reported without them is not reviewed.
Start no agents of your own: the lead decides who works on what. 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 **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 order, the findings), and report. A fresh agent continues from that section; work past that point is lost when the
context runs out. context runs out.
+19 -3
View File
@@ -232,7 +232,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 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. (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, **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). **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 - **controller** — the component that decides what each node should be, holds the mesh's records, and
@@ -280,6 +280,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 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, 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). 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 - **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 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 of their own the way something needs a database
@@ -886,7 +901,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, **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. 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 **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). **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 - **health** — a module's or a core component's statement of how it is alive and ready, which the
@@ -905,7 +920,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 - **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. 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 - **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 - **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 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 `condition-raised`, `condition-changed` and `condition-cleared` (ADR 0564 §2, §3). The controller keeps them
+28 -10
View File
@@ -60,7 +60,7 @@ opened **once**, after the review, and **one check** (ADR 0548). It runs in five
| Step | What happens | Bound | | Step | What happens | Bound |
|---|---|---| |---|---|---|
| 0. Prepare | the lead reads what exists today in the code and on the live mesh, settles the open questions and writes one context file per repository, opening with what exists, what relies on it and what happens to each | 15 minutes, longer when what exists is large: code never starts on an incomplete answer | | 0. Prepare | the lead reads what exists today in the code and on the live mesh, settles the open questions and writes one context file per repository, opening with what exists, what relies on it and what happens to each | 15 minutes, longer when what exists is large: code never starts on an incomplete answer |
| 1. Develop | one fixing agent per repository builds every issue locally, the whole unit suite before every commit, the integration tests compiled (those that exercise the change are run by name before the push, step 3); nothing is pushed | the milestone's issues, 30 minutes each | | 1. Develop | one fixing agent per repository builds every issue locally, the whole unit suite before every commit, the integration tests compiled, and once per head it reports those of the packages it touched and their importers run against an embedded bus (below); nothing is pushed | the milestone's issues, 30 minutes each |
| 2. Review | one reviewer reads all of it, the local commits, judging the integration tests by reading them against the code; reports go both ways; at most 3 rounds | 15 minutes | | 2. Review | one reviewer reads all of it, the local commits, judging the integration tests by reading them against the code; reports go both ways; at most 3 rounds | 15 minutes |
| 3. Check | push the reviewed heads once and open the pull requests together; the checker's one check runs the integration tests; no further review unless the check fails | one check run | | 3. Check | push the reviewed heads once and open the pull requests together; the checker's one check runs the integration tests; no further review unless the check fails | one check run |
| 4. Deliver | merge; the source revision moves, each module is built once and wanted on its nodes, its canary first | until the view says the source revision `delivered` | | 4. Deliver | merge; the source revision moves, each module is built once and wanted on its nodes, its canary first | until the view says the source revision `delivered` |
@@ -253,8 +253,17 @@ is a breach the lead names.
acceptance criteria**: one test or more per criterion at the level it names, each test's comment citing 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 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 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 or a process) are compiled with `go vet -tags integration ./...` while developing and run by that check. **Once per head it
name (step 3), nothing else. reports, not per commit, a developer 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). Where the importers are many, it runs instead the tests of them that exercise the change
(`-run '<names>'`) and names that choice in its report. It is never a whole module's or level's run, so it stays
within the operator's rule of 2026-10-18 (step 3). 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 have run so at the reviewed heads (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, - **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 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 feature branch up to the current trunk (fetch by name, then merge) and the review reads the local commits. Never call
@@ -265,8 +274,16 @@ is a breach the lead names.
message ("issue 805: landing in mesh-catalog"); reach the mesh only through the mesh MCP server, never ssh; 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 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 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 move another issue; **leave a module's whole integration level to the check** (no store or bus started by hand):
with `go vet -tags integration ./...`. A single integration test may be run locally against an embedded bus when compile it with `go vet -tags integration ./...`, and once per head you report run the touched packages' and their importers' integration
tests against an embedded bus, or by name where the importers are many (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 and read again
when you report a head, 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 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 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 usually pays to run that repository's whole integration level locally (`go test -tags integration -count=1 ./...` in each
@@ -302,7 +319,7 @@ is a breach the lead names.
It says which round it is in ("round 1 of at most 3"). It says which round it is in ("round 1 of at most 3").
3. **The report goes to the same fixing agents** that wrote the code, continued by their ids, so they fix 3. **The report goes to the same fixing agents** that wrote the code, continued by their ids, so they fix
with the context they already hold. Each answers the reviewer: what it changed, per finding, or why not. with the context they already hold. Each answers the reviewer: what it changed, per finding, or why not.
4. **Every new integration test is read against the code it drives.** Fixing agents only compile it, and no run precedes the review (step 1), so the reviewer judges it by reading; the check that follows shows whether it passed but not whether it proves what it says. The reviewer traces each step of each new integration test through the code (fixtures against the manifest rules, what the store keeps and reads back, who holds a seat), and says which steps it could not trace. On 2026-10-17 a new test failed on its first two runs, on a fixture and then on a fault of the change; reading it against the code after the first failure found another fault, which would have failed a run too. A review that finds a fault only by reading is the cheaper run. The reviewer also checks that each new integration test enters through the same path the live trigger takes, not through a state it writes by hand: on 2026-10-17 milestone 4's test saved its delivery plan directly, so it skipped the cut from a batch that every live plan takes, and it passed while the backup step never ran (issue 1086). 4. **Every new integration test is read against the code it drives.** Fixing agents run only the touched packages' integration tests and their importers' (step 1), and no whole module's run precedes the review, so the reviewer judges each by reading too: a passing local run and the check that follows show whether it passed but not whether it proves what it says. The reviewer traces each step of each new integration test through the code (fixtures against the manifest rules, what the store keeps and reads back, who holds a seat), and says which steps it could not trace. On 2026-10-17 a new test failed on its first two runs, on a fixture and then on a fault of the change; reading it against the code after the first failure found another fault, which would have failed a run too. A review that finds a fault only by reading is the cheaper run. The reviewer also checks that each new integration test enters through the same path the live trigger takes, not through a state it writes by hand: on 2026-10-17 milestone 4's test saved its delivery plan directly, so it skipped the cut from a batch that every live plan takes, and it passed while the backup step never ran (issue 1086).
5. **The reviewer reads the answers and the new commits**, and approves or reports again (step 7 says what a round 5. **The reviewer reads the answers and the new commits**, and approves or reports again (step 7 says what a round
may ask). After round 3 the lead stops and brings the operator what is left, with a recommendation. may ask). After round 3 the lead stops and brings the operator what is left, with a recommendation.
6. **The reviewer reads every acceptance criterion against its test**: each criterion has a test at its level 6. **The reviewer reads every acceptance criterion against its test**: each criterion has a test at its level
@@ -371,9 +388,10 @@ is a breach the lead names.
(ADR 0525 §1). **No try:** never call `mesh-controller.try`, `mesh-delivery-checker.try` or `mesh-delivery-checker.checker_try`, except when the (ADR 0525 §1). **No try:** never call `mesh-controller.try`, `mesh-delivery-checker.try` or `mesh-delivery-checker.checker_try`, except when the
operator asks for one. While developing, no `go test -tags integration` run of a whole module or level, and no store or bus started operator asks for one. While developing, no `go test -tags integration` run of a whole module or level, and no store or bus started
by hand on the machine (the operator, 2026-10-18). by hand on the machine (the operator, 2026-10-18).
**Before a group's single push, the integration tests that exercise the change are run locally against an embedded **Before a group's single push, the integration tests that exercise the change have run locally against an
bus**, picked by name (`go test -tags integration -count=1 -run '<names>'`): the tests in the touched packages that embedded bus**, at the reviewed heads: the touched packages' and their importers' tests that each developer ran for
start the part whole, not a whole module's or level's integration run, and not only a compile with `go vet`; a the head it reported (step 1), or those picked by name (`go test -tags integration -count=1 -run '<names>'`) where
the importers are many; never a whole module's or level's integration run, and not only a compile with `go vet`; a
change in how a node composes or applies always has such a test (2026-10-28: a compiled-only group failed in the one change in how a node composes or applies always has such a test (2026-10-28: a compiled-only group failed in the one
check on what a local run shows). How it is checked: the pull request's description names those tests and their check on what a local run shows). How it is checked: the pull request's description names those tests and their
results. results.
@@ -421,7 +439,7 @@ is a breach the lead names.
`internal/beside` says. `internal/beside` says.
**Before the push, every member's suites run as the running checker runs them**: each sibling repository placed **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 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 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 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 checked: the pull request's description names the placement, the node-engine commit and the manifest validator run used
+5 -3
View File
@@ -62,10 +62,12 @@ processing power"). Everything before the push is local and fast, and no try is
caught only by the review); read `git show --stat` before pushing. caught only by the review); read `git show --stat` before pushing.
The tests are written from the acceptance criteria, at least one per criterion at its level, each citing the The tests are written from the acceptance criteria, at least one per criterion at its level, each citing the
criterion it proves by its label (`<issue>/AC<n>`, playbook 07 step 0 item 5). Commit, naming the issue. For a playbook or design edit, run the repository's own checks (in hq, criterion it proves by its label (`<issue>/AC<n>`, playbook 07 step 0 item 5). Commit, naming the issue. For a playbook or design edit, run the repository's own checks (in hq,
`go test ./...` at the root). The integration tests are compiled (`go vet -tags integration ./...`) and not run: `go test ./...` at the root). The integration tests are compiled whole (`go vet -tags integration ./...`), and once
nothing is pushed, no pull request is opened and no try (`mesh-controller.try`, `mesh-delivery-checker.try`, `mesh-delivery-checker.checker_try`) is called, unless the operator asks for per head reported those of the packages the fix touches and of their importers in the module run against an
embedded bus, or the tests of them that exercise the fix by name where the importers are many, named in the report;
never a whole module's or level's run (playbook 07 step 1). Nothing is pushed, no pull request is opened and no try (`mesh-controller.try`, `mesh-delivery-checker.try`, `mesh-delivery-checker.checker_try`) is called, unless the operator asks for
one. A single integration test may be run locally against an embedded bus when it is the fastest way to find a cause; one. A single integration test may be run locally against an embedded bus when it is the fastest way to find a cause;
before the push, the integration tests that exercise the change are run that way, by name before the push, the integration tests that exercise the change have run that way at the reviewed head
(playbook 07 step 3), and the pull request names them and their results. A test fixture writes state in the form its real (playbook 07 step 3), and the pull request names them and their results. A test fixture writes state in the form its real
writer writes it; the review asks it. writer writes it; the review asks it.
4. **One review of the local commit** (a reviewer that did not write it, larger 4. **One review of the local commit** (a reviewer that did not write it, larger
+5 -5
View File
@@ -291,7 +291,7 @@ code{font:12.5px ui-monospace,monospace;background:var(--soft);padding:1px 5px;b
<li>One commit per issue, naming it; tests cite their criterion (<code>// 1217/AC3</code>).</li> <li>One commit per issue, naming it; tests cite their criterion (<code>// 1217/AC3</code>).</li>
<li><span class="tag new">new</span>A test fails first on what the code does. A compile error is no failure: take out the change's effect and see an assertion fail.</li> <li><span class="tag new">new</span>A test fails first on what the code does. A compile error is no failure: take out the change's effect and see an assertion fail.</li>
<li>The whole unit suite before every commit; each test well under a second.</li> <li>The whole unit suite before every commit; each test well under a second.</li>
<li>Integration tests are compiled only: never run on the machine.</li> <li><span class="tag new">new</span>Integration tests compiled whole; once per head reported, those of the touched packages and their importers run against an embedded bus (by name where the importers are many); never a whole module's run.</li>
<li>Never push, open or merge; never move an issue; never ssh.</li> <li>Never push, open or merge; never move an issue; never ssh.</li>
<li>Code that differs from the context file: stop and report, file:line.</li> <li>Code that differs from the context file: stop and report, file:line.</li>
</ul> </ul>
@@ -300,7 +300,7 @@ code{font:12.5px ui-monospace,monospace;background:var(--soft);padding:1px 5px;b
<!-- ============ TESTS ============ --> <!-- ============ TESTS ============ -->
<h2 id="tests">When tests run</h2> <h2 id="tests">When tests run</h2>
<p class="lead">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).</p> <p class="lead">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 once per head reported only those of the touched packages and their importers run there, against an embedded bus, never a whole module's or level's: 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).</p>
<div class="box scroll"> <div class="box scroll">
<svg viewBox="0 0 1080 170" role="img" aria-label="Test levels over a feature's timeline"> <svg viewBox="0 0 1080 170" role="img" aria-label="Test levels over a feature's timeline">
<defs><marker id="ar3" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto"><path d="M0,0L10,5L0,10z" fill="var(--mute)"/></marker></defs> <defs><marker id="ar3" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto"><path d="M0,0L10,5L0,10z" fill="var(--mute)"/></marker></defs>
@@ -312,10 +312,10 @@ code{font:12.5px ui-monospace,monospace;background:var(--soft);padding:1px 5px;b
<circle cx="160" cy="44" r="6"/><circle cx="220" cy="44" r="6"/><circle cx="290" cy="44" r="6"/><circle cx="350" cy="44" r="6"/><circle cx="420" cy="44" r="6"/><circle cx="600" cy="44" r="6"/><circle cx="680" cy="44" r="6"/> <circle cx="160" cy="44" r="6"/><circle cx="220" cy="44" r="6"/><circle cx="290" cy="44" r="6"/><circle cx="350" cy="44" r="6"/><circle cx="420" cy="44" r="6"/><circle cx="600" cy="44" r="6"/><circle cx="680" cy="44" r="6"/>
</g> </g>
<text x="830" y="42" class="mute">whole suite before every commit</text><text x="830" y="56" class="mute">each test under a second</text> <text x="830" y="42" class="mute">whole suite before every commit</text><text x="830" y="56" class="mute">each test under a second</text>
<text x="10" y="104" class="t">Integration</text><text x="10" y="120" class="mute">never on the machine</text> <text x="10" y="104" class="t">Integration</text><text x="10" y="120" class="mute">touched packages only</text>
<g> <g>
<rect x="120" y="96" width="340" height="16" rx="8" fill="var(--mute)" opacity=".18"/> <rect x="120" y="96" width="340" height="16" rx="8" fill="var(--mute)" opacity=".18"/>
<text x="290" y="108" text-anchor="middle" class="mute">compiled only: go vet -tags integration</text> <text x="290" y="108" text-anchor="middle" class="mute">compiled whole; touched packages run</text>
<rect x="770" y="90" width="120" height="28" rx="6" fill="none" stroke="var(--mesh)" stroke-width="2" stroke-dasharray="5 4"/><text x="830" y="109" text-anchor="middle" class="mute">push once</text> <rect x="770" y="90" width="120" height="28" rx="6" fill="none" stroke="var(--mesh)" stroke-width="2" stroke-dasharray="5 4"/><text x="830" y="109" text-anchor="middle" class="mute">push once</text>
<rect x="920" y="90" width="120" height="28" rx="6" fill="var(--mesh)"/><text x="980" y="109" text-anchor="middle" style="fill:var(--bg)" class="t">merge check</text> <rect x="920" y="90" width="120" height="28" rx="6" fill="var(--mesh)"/><text x="980" y="109" text-anchor="middle" style="fill:var(--bg)" class="t">merge check</text>
</g> </g>
@@ -354,7 +354,7 @@ code{font:12.5px ui-monospace,monospace;background:var(--soft);padding:1px 5px;b
<h3 style="margin-top:12px">What every round reads</h3> <h3 style="margin-top:12px">What every round reads</h3>
<ul style="margin:6px 0;padding-left:20px;font-size:14px"> <ul style="margin:6px 0;padding-left:20px;font-size:14px">
<li>Every criterion against its test: a test at its level that would fail without the change.</li> <li>Every criterion against its test: a test at its level that would fail without the change.</li>
<li>Every new integration test traced through the code by reading it: no run exists before the check.</li> <li>Every new integration test traced through the code by reading it: a local run of the touched packages shows only that it passed.</li>
<li>That each integration test enters by the path the live trigger takes.</li> <li>That each integration test enters by the path the live trigger takes.</li>
<li>Where each piece of state lives and how each seam travels: anything but bus state, a stream or a seat's verb is a finding, even if a record put it there.</li> <li>Where each piece of state lives and how each seam travels: anything but bus state, a stream or a seat's verb is a finding, even if a record put it there.</li>
<li>That no repository holds this mesh's setup (node names, placement, settings): repositories are mesh-agnostic.</li> <li>That no repository holds this mesh's setup (node names, placement, settings): repositories are mesh-agnostic.</li>