diff --git a/00-META/process/07-feature-branches.md b/00-META/process/07-feature-branches.md index f0c4daeb..e12c17bc 100644 --- a/00-META/process/07-feature-branches.md +++ b/00-META/process/07-feature-branches.md @@ -80,7 +80,8 @@ never into the running one, unless it blocks the running one. 4. **Write one context file per repository**, `.work//.context.md`. It is what a fixing agent reads instead of rediscovering the code, and it is reused by every agent and every round: - the issues it builds, in order, each with: the files and functions it changes, the decisions it builds - with (quoted, with where each was decided), the test to write first, done-when in one sentence; + with (quoted, with where each was decided), and its acceptance criteria (item 5), each with the test that + proves it; - the repository's map for this feature: the packages and files involved, with one line each on what they hold, and the patterns to copy (file:line); - what not to touch, and what lands beside it in other repositories; @@ -96,6 +97,16 @@ never into the running one, unless it blocks the running one. modules its delivery plan moves, to which machines); and for a group, its merge order. The context file points to these notes; an issue reread by another session or a later agent then holds what was found. When the reading is large, it starts with a read-only survey agent on the smaller model. + **Each issue carries its acceptance criteria, written by the lead** (the operator, 2026-10-18: the larger + model writes them, and they guide every test). Each criterion is one sentence, given, when, then, about what + the module or the operator observes, never about how the code does it, and names the level of the test that + proves it: unit, integration (a bus, a store or a process started) or end to end (none exist yet, so such a + criterion is proven live after the delivery and said so). Together they cover the issue's done-when and the + cases its life passes through: on 2026-10-18 mesh-delivery's group life (a group of three, a member's own + check, a close in a group, a second pull request at the same commit, a stop and a resend) had no criterion, + and each case was found by a failure on the live mesh. Each criterion is numbered in its note and cited as + `/AC` (`1118/AC2`). They are an `issue-tracker.note` headed `Acceptance criteria`, a revision a new note that replaces the older one, until the tracker holds them as a + field (issue 1118). A criterion the reviewer adds in step 2 is written onto the issue the same way. **The survey sizes each issue, and an issue sized over an hour is split before any agent starts** (the operator, 2026-10-17), into issues of about 30 minutes each, one change each, in the order they land: the bound of a fixing agent's issue is then a real bound. On 2026-10-17 one issue held four changes sized at four to six @@ -111,7 +122,10 @@ never into the running one, unless it blocks the running one. - **Unit tests only, each well under a second** (how-we-build §5, ADR 0391). **The whole unit suite runs before every commit** (the operator, 2026-10-17), not only the tests of what changed: it takes under a second, and a change breaks tests in packages it never touched. Each issue's first test fails before its change and passes - after; `gofmt`, `go vet` and the whole unit suite stay green. The integration tests (`merge-check.sh` with the store and the + after; `gofmt`, `go vet` and the whole unit suite stay green. **The tests are written from the issue's + 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 waits for the check step. The integration tests (`merge-check.sh` with the store and the bus) wait for the check step. - **Nothing is pushed** and no pull request is opened in this step. Never land on a red check: run the checks, read the result, then land in a separate step. @@ -147,12 +161,16 @@ never into the running one, unless it blocks the running one. 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. 4. **Every new integration test is read against the code it drives before the first push.** It has never run: fixing agents only compile it, and its first run is the merge check, so each fault it hides costs a whole check. 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. 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 6 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. -6. **A finding outside the issues' done-when is never a change asked, in any round.** More hardening, a +6. **The reviewer reads every acceptance criterion against its test**: each criterion has a test at its level + that would fail without the change, and no test proves less than its criterion says. A criterion missing + for a case the issue's done-when needs is written onto the issue (step 0, item 5) and is a finding; a test + missing for a criterion is a finding. +7. **A finding outside the issues' done-when and their acceptance criteria is never a change asked, in any round.** More hardening, a further case, a nicer form: the reviewer opens it with `issue-tracker.open` and names the number in its report, and the round does not wait for it. What a round asks is only what makes the change wrong against - its issues and its decisions. + its issues, their acceptance criteria and its decisions. ## Step 3 — Check (no review) @@ -340,6 +358,10 @@ issues in `fixing` that nobody works on reads to the operator as stuck work. - Every issue of a running milestone has a note from the prepare step naming its files and tests (file:line), how it is checked and delivered, and for a group its merge order (`issue-tracker.get`); an issue moved to `fixing` without one is a prepare step skipped. +- Every issue of a running milestone has a note headed `Acceptance criteria` before it moves to `fixing` + (`issue-tracker.get`), each criterion naming its test level, and every criterion's label is cited by a test in the + pushed tree (`git grep -n '/AC'`); an issue without them is a prepare step skipped, and a + criterion no test names is a review that missed it (until issue 1118 makes the tracker refuse it). - Every fixing agent's report gives the whole unit suite's result and time; a report naming only some packages' tests is the whole-suite rule not kept. - The lead's save point names each watcher with its model; a watcher on the smallest model is the failure of @@ -360,7 +382,7 @@ issues in `fixing` that nobody works on reads to the operator as stuck work. of two designs in `fixing` at once is the failure of "one design is built at a time". - More than one open pull request in a repository that share no feature name, or a milestone whose issues stay in `fixing` for more than a working day, is the smell: stop and bring it to the operator. -- A review report that asks a change outside the issues' done-when, or a fourth round, is the failure of the +- A review report that asks a change outside the issues' done-when and acceptance criteria, or a fourth round, is the failure of the review rules; `issue-tracker.list` with `flag: abandoned` lists issues left in `fixing` with nobody on them. - A pull request green for more than 5 minutes with no Approve asked is a fault of mesh-delivery (`mesh-delivery.show`), said to the operator. diff --git a/00-META/process/08-small-fixes.md b/00-META/process/08-small-fixes.md index 2ac4fd48..23015e89 100644 --- a/00-META/process/08-small-fixes.md +++ b/00-META/process/08-small-fixes.md @@ -27,17 +27,22 @@ one delivery**. Everything before the push is local and fast. model answering exact questions with file:line). If a design question is open, it is settled before any code is written: on the issue, through the knowledge base, or by the operator. A fix that turns out to need a second repository, or more than about an hour, stops here and becomes a feature; one that needs a - decision stays a small fix. + decision stays a small fix. **The session's own model (the larger) then writes the issue's acceptance + criteria** as playbook [07](07-feature-branches.md) step 0 item 5 says: each one sentence, given, when, then, + naming the level of the test that proves it, as an `issue-tracker.note` headed `Acceptance criteria`. A + playbook or design edit has none: its check is `sh merge-check.sh`. 2. **Move the issue to `fixing`** with `by` as who@node. 3. **Build on a local branch** `fix/-`, in a worktree of its own branched from `main`, never in the repository's own clone, which stays on `main` (playbook [07](07-feature-branches.md), step 0, item 2). Write the test that fails today first; make the change; keep `gofmt`, `go vet` and the repository's whole unit suite green before every commit (each test well under a second; never a merge check or a database locally: how-we-build §5, ADR 0391). - Commit, naming the issue. For a playbook or design edit, run the repository's own checks (in hq, + 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 (`/AC`, playbook 07 step 0 item 5). Commit, naming the issue. For a playbook or design edit, run the repository's own checks (in hq, `sh merge-check.sh`). 4. **One review of the local commit, before anything is pushed** (a reviewer that did not write it, larger - model; at most 3 rounds, as playbook 07; from round 2 only what is wrong; a finding outside the issue's - done-when is opened as an issue of its own, never asked as a change). The reviewer's findings go back to the same agent that wrote the fix, continued by + model; at most 3 rounds, as playbook 07; from round 2 only what is wrong; it reads each acceptance criterion + against its test, as playbook 07 step 2 item 6; a finding outside the issue's done-when and its acceptance + criteria is opened as an issue of its own, never asked as a change). The reviewer's findings go back to the same agent that wrote the fix, continued by its id, so the fix keeps its context. A playbook or design edit of a few lines may skip the reviewer: the operator's Approve of its merge is its review, and the review record says so. 5. **Push once and open the pull request.** The trunk is what runs and nothing holds merged work back @@ -96,7 +101,10 @@ reading itself and uses one subagent only for the review. - Its issue moves to `resolved` within the hour its delivery plan ends. - A pull request with no review record at its head (the Approve's ask says so first), a fix to a module's running pushed with no integration test of the module whole, or a review report - asking a change outside the issue's done-when, is the failure of steps 4 to 6. + asking a change outside the issue's done-when and acceptance criteria, is the failure of steps 4 to 6. +- A fixed code issue shows a note headed `Acceptance criteria` (`issue-tracker.get`) older than its first + commit, and each criterion's label is cited by a test in the pushed tree + (`git grep -n '/AC'`); one without is step 1 skipped. - An issue in `fixing` with nobody on it shows in `issue-tracker.list` with `flag: abandoned`; a stopped fix moves it back to `open` with its note. - The repository's own clone says `main` (`git -C branch --show-current`); another branch there is a diff --git a/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md b/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md index caee8eb9..22640502 100644 --- a/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md +++ b/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md @@ -4,6 +4,7 @@ status: in-progress code: [mesh-controller, mesh-catalog modules/mesh-delivery] updated: 2026-10-18 decisions: + - "ADR 0426" - "ADR 0421" - "ADR 0420" - "ADR 0419" @@ -555,9 +556,10 @@ when the previous one's delivery is done. | 4 | A delivery backs up the data it moves first, and a failed backup holds it and is said | 3 | mesh-controller, mesh-catalog (mesh-delivery, the backup seat's holder) | 980, split into 1065, 1066, 1067, 1068 | | 3 fix | A group approved together merges in one pass and goes out in one delivery plan, also when its members' tests read each other's repositories | 1 | mesh-catalog (mesh-delivery, gitea) | 1082, 1049, 1047, 1083, 1079 (1084 closed as its duplicate) | | 5 | One read of a module on a node names the commit, build and rollout that put it there | 10, 12 | mesh-controller, mesh-catalog (mesh-config, nats) | 981 | +| 5b | The controller makes no build or deploy plan: building and delivering a change are done outside it, driven by events on the bus, and the controller receives only what each node should run | — (its decision names them) | mesh-controller, mesh-catalog (mesh-delivery) | 1117 | | 6 | Builds use installed toolchains with no container, builders fetch over SSH with their own key, and an SDK change ships in one group with its users | 2, 4 | mesh-catalog (build modules, build-agent, ssh-client, gitea), mesh-controller, mesh-sdk | 979, 971 | -The issues are linked `depends-on` in this order; 976 depends on 975, and 979 also on 971. Milestone 3's first live group (milestone 4's, on 2026-10-17) held one Approve but merged in two passes and went out in two delivery plans: a member's tests read the other member's repository, so the first merge made the second's verdict out of date, and a closed group never asked its composed verdict again (issues 1049, 1082). The operator put a fix of milestone 3 after milestone 4 and before milestone 5 on 2026-10-18; acceptance test 1 is proved again by it. Milestone 2b was +The issues are linked `depends-on` in this order; 976 depends on 975, and 979 also on 971. Milestone 3's first live group (milestone 4's, on 2026-10-17) held one Approve but merged in two passes and went out in two delivery plans: a member's tests read the other member's repository, so the first merge made the second's verdict out of date, and a closed group never asked its composed verdict again (issues 1049, 1082). The operator put a fix of milestone 3 after milestone 4 and before milestone 5 on 2026-10-18; acceptance test 1 is proved again by it. The operator put milestone 5b after milestone 5 and before milestone 6 on 2026-10-18, as an issue rather than a research effort; where the planning goes is settled by a decision record before it is built (issue 1117), and milestone 6's build changes are read against it. Milestone 2b was put before milestone 3 by the operator on 2026-10-17. Milestone 3 builds ADR 0418, ADR 0419 and ADR 0421 (issues 977, 978 and 1022), and splits mesh-controller's unit tests from its integration tests (issue 895, the operator on 2026-10-17), so the unit level holds its bound of ADR 0391; the integration level's sixty seconds