Design 47, the glossary and playbooks 04, 07 and 08 for release 6: wants and signed compositions, no plans (ADR 0539, issue 1130)

Release 6 deletes delivery plans, batches, the merge window and tiers, so
design 47's sections that described them as current are rewritten to the
assigner's seven rules, the controller's signed compositions per node, the
node agent, credentials on a done build, the switch as release 5's last plan,
the hand path by mesh-compose and a want, and the view's delivered, moving,
settled and stuck events. The glossary gains composition and restates want,
declaration, send and apply; the playbooks follow a delivery by the view and
the have keys and call no plans, plan, push or what-if.
This commit is contained in:
2026-10-24 21:01:24 +02:00
parent c12d503b2e
commit 4b514e4d69
6 changed files with 504 additions and 353 deletions
+11 -8
View File
@@ -9,7 +9,7 @@ an hour, and said to the operator if it runs past.
A design becomes **milestones**, and each milestone becomes **issues**:
- **A milestone is usable on its own.** Once its delivery plan is done, the operator or the mesh can do
- **A milestone is usable on its own.** Once it is delivered, the operator or the mesh can do
something new, said in one sentence ("a Claude Code session is mirrored into a thread on the bus").
A milestone that changes nothing anyone can use is not a milestone; fold it into the next.
- **A milestone is one release** of playbook [07](07-feature-branches.md): prepared, developed whole, reviewed,
@@ -17,9 +17,10 @@ A design becomes **milestones**, and each milestone becomes **issues**:
- **A milestone is one piece of functionality, never cut by an order between its parts** (the operator, 2026-10-21:
a milestone may span several modules, repositories and dependencies such as an SDK change; 2026-10-22: "a milestone
is a milestone, we shouldn't cut it"). Which of its modules reaches the machines first (a reader of a new manifest
word before the modules that use it, an SDK change before its users) is the delivery plan's, drawn from the module
graph. The parts such an order touches are found in playbook [07](07-feature-branches.md) step 0 item 6 and become
issues of the same milestone; an order the plan cannot keep is an issue of the build and delivery system, not a cut.
word before the modules that use it, a provider before its consumers) is the assigner's rules' (design 47); an SDK
change is built into its users. The parts such an order touches are found in playbook [07](07-feature-branches.md)
step 0 item 6 and become issues of the same milestone; an order those rules cannot keep is an issue of the build
and delivery system, not a cut.
Until 2026-10-22 this rule cut milestones by release order (design 47's release 1-2 became six milestones).
- **An issue is one repository's part of a milestone,** sized so a fixing agent finishes it inside the
milestone's development time. Issues that must land in order are linked `depends-on`.
@@ -37,8 +38,9 @@ A design becomes **milestones**, and each milestone becomes **issues**:
4. **Break it into milestones.** Write them into the design, in a section *Milestones*: for each, its number,
its one-sentence outcome, the acceptance tests of the design it proves, the repositories it touches, and
what it depends on. Order them so each is usable as soon as it is delivered, the smallest useful one
first. A milestone is named by what it lets someone do; how it ships is shaped by the plan its changes would
have, asked through `mesh-delivery.what-if`: the modules it moves and their fan-out (ADR 0401 §6).
first. A milestone is named by what it lets someone do; how it ships is shaped by the modules its changes move
and the nodes that run them (ADR 0401 §6), read from the indexer's fingerprints through the status view's
`indexer_modules` and `indexer_candidates`, and from the nodes' haves (`node_haves`).
5. **Ask the operator to confirm the milestones**, in a short table: number, outcome, the acceptance tests it
proves, repositories, the parts each repository builds. Change what they change.
6. **Open the issues.** For each confirmed milestone, `issue-tracker.open` one issue per repository part, its
@@ -48,7 +50,7 @@ A design becomes **milestones**, and each milestone becomes **issues**:
7. **Flip the status.** `status: in-progress`, `updated:` today; the design change goes through playbook
[08](08-small-fixes.md) (one hq pull request).
8. **Hand each milestone to playbook 07, one at a time.** The milestone is one release of playbook 07; its issues
are the release's issues; the next milestone starts when the previous one's delivery plan is done. A design waits
are the release's issues; the next milestone starts when the previous one is delivered. A design waits
while another design's milestones are being built: one design is built at a time (playbook
[07](07-feature-branches.md)), so this step starts only when the design before it is delivered.
9. **On completion of the last milestone**, run the "when something ships" section of playbook
@@ -72,5 +74,6 @@ Read by the lead and the reviewer today; a check in hq's merge-check is tracked
issues; an in-progress design without one is the smell of building without a breakdown.
- Every issue a milestone names exists in the tracker (`issue-tracker.get`), and an issue in `fixing` names
its milestone in its report.
- A milestone whose issues are all `resolved` has had its delivery plan done; its outcome sentence and
- A milestone whose issues are all `resolved` is delivered (the status view said `delivered` for its source
revision); its outcome sentence and
acceptance tests are proven on the mesh before the next milestone starts.
+66 -51
View File
@@ -19,7 +19,7 @@ A small fix (one repository, one issue, about an hour of work) follows
minutes took forty-one.
- **Finished work that never ships.** A feature that kept taking new issues held thirteen landed issues
undelivered for a day: an issue done at 21:09 was still not on the machines at 15:00 the next day.
- **Work that waits and nobody notices.** Most lost time was not work at all, but a check, a delivery plan
- **Work that waits and nobody notices.** Most lost time was not work at all, but a check, a delivery
or an agent waiting on something that had stopped, unseen.
- **Review that keeps hardening.** One fix went through seven review rounds in five and a half hours, each
asking for more hardening than its issue asked (issue 704, 2026-10-14). A round is for what makes the
@@ -50,26 +50,27 @@ opened **once**, after the review. It runs in five steps, and its time is bounde
| 1. Develop | one fixing agent per repository builds every issue locally, the whole unit suite before every commit; then each branch is pushed and tried | the milestone's issues, 30 minutes each, and one try |
| 2. Review | one reviewer reads all of it with the tries' results; reports go both ways; at most 3 rounds | 15 minutes |
| 3. Check | push the reviewed heads; a head the review changed is tried again; then the pull requests are opened and the forge's merge checks run the integration tests again; no further review | at most one more try and one check run |
| 4. Deliver | merge; the delivery plan builds, publishes and sends the whole feature | its delivery plan |
| 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` |
**One milestone is one release** (the operator, 2026-10-17). A milestone is developed whole, tried before its review, reviewed once,
opened once and delivered once. It is never cut into steps for its size or for time: every cut adds a review, a
merge check, an Approve and a delivery plan of waiting, so the fewest cuts is the fastest. Nor is it cut for an
merge check, an Approve and a delivery of waiting, so the fewest cuts is the fastest. Nor is it cut for an
order between its parts (the operator, 2026-10-22: "a milestone is a milestone, we shouldn't cut it"): which module
reaches the machines before which is the delivery plan's, drawn from the module graph, and that is what the plan is
for. An order the plan cannot keep is a fault of the build and delivery system, opened as an issue there, never a cut
and never a step a session takes by hand.
reaches the machines before which is the assigner's rules' (a build and a composition before the want, a provider
before its consumers, the canary before the rest; design 47), and that is what they are for. An order they cannot
keep is a fault of the build and delivery system, opened as an issue there, never a cut and never a step a session
takes by hand.
A milestone is one piece of functionality, possibly spanning several modules, repositories and dependencies such as
an SDK change (the operator, 2026-10-21). Its pull requests in every repository share the milestone's branch name,
so they are one delivery group (ADR 0482, which holds that a change across repositories is one group, one plan and
one Approve, and that its developer orders no release). Nothing of the milestone merges until every issue of it is
built, reviewed and checked; then the one Approve and one tiered delivery plan release it all, the plan's tiers
keeping a dependency such as the SDK before its dependents. A small fix found during the milestone rides in this
built, reviewed and checked; then the one Approve releases it all as one source revision, the assigner's rules
keep a provider before its consumers, and an SDK change is built into the modules that use it. A small fix found during the milestone rides in this
group, as playbook [08](08-small-fixes.md) says.
**One design is built at a time** (the operator, 2026-10-17). While the milestones of one design are being
built, no milestone of another design starts: its issues stay `open`, and nobody moves them to `diagnosing` or
`fixing`. The next design starts when the last milestone of the one being built has its delivery plan done. A
`fixing`. The next design starts when the last milestone of the one being built is delivered. A
lead who finds another design's milestone already in `fixing` asks its owner before starting its own. A small
fix ([playbook 08](08-small-fixes.md)) and an issue that is in no design's milestones are not held by this rule.
@@ -79,7 +80,7 @@ next milestone or the next feature.
**An issue opened along the way is fixed by the session that opened it** (the operator, 2026-10-21): it is never only
listed under "Opened along the way" and left. A small one (one repository, about an hour) is fixed in between, as a
small fix ([playbook 08](08-small-fixes.md)) while the milestone waits on a check, an Approve or a delivery plan; the
small fix ([playbook 08](08-small-fixes.md)) while the milestone waits on a check, an Approve or a delivery; the
rest are fixed right after the milestone's delivery, before the next milestone starts, together on one branch where
they share a repository. Either way it stays out of the running milestone's branch and pull request, unless it blocks
the running milestone, so the scope above holds. Only an issue in another design's milestones (one design is built at
@@ -121,7 +122,8 @@ issue whether it is being fixed in between, after the delivery, or waits, and on
of record), each with what it does with the new value, and a criterion for each that could treat it wrongly
(2026-10-19: the router's sync with the controller ended every condition the controller did not list, and the
survey, which followed only the new condition's own path, never named it); how the change is checked and delivered end to end (which test proves its done-when, which
modules its delivery plan moves, to which machines); and for a group, its merge order. The context file
modules its merge moves, read from the indexer's candidates of its group, and 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
@@ -148,10 +150,10 @@ issue whether it is being fixed in between, after the delivery, or waits, and on
new verbs were refused on the claim); the node-engine's decoder for a new key on the wire; the route by which a
repository's first module registers; and a part that needs something the bus or a manifest cannot yet give, which
needs its decision first. Each such part is an issue of the milestone and its pull request a member of the group;
the order in which they reach the machines is the delivery plan's (the operator, 2026-10-22), never a cut. Where
the plan cannot keep an order (a node told of a key before it reads it, a module using a word before its readers
are delivered), that is an issue of the build and delivery system, opened with `issue-tracker.open` and said to
the operator.
the order in which they reach the machines is the assigner's rules' (the operator, 2026-10-22), never a cut.
Where those rules cannot keep an order (a node told of a key before it reads it, a module using a word before its
readers are delivered), that is an issue of the build and delivery system, opened with `issue-tracker.open` and
said to the operator.
7. **Write fixtures from the shape the other side writes, never from memory** (2026-10-18: a watchman's tests
mirrored a build key the controller never writes, and every test passed): copy a value from the writer's code or
from the live bus, and name where it came from.
@@ -329,7 +331,7 @@ issue whether it is being fixed in between, after the delivery, or waits, and on
carries an integration test that starts the module whole, its process against the real bus and store, and
shows the milestone's acceptance sentence; the forge's checks run it (ADR 0391 §1, §6). Unit tests alone are not
that proof; the mesh has no end-to-end tests yet, and the lab is not used (the operator, 2026-10-16).
**A new manifest word's test goes through the push that meets it first, not only the verb that fills it.**
**A new manifest word's test goes through the first composition that meets it, not only the verb that fills it.**
On 2026-10-19 release 1 of feature mail-sender tested a process's own bus account through `module issue`
alone; the first push after mesh-mail declared the process composed a random 40-character stand-in for the
account file before anyone issued it, and the process crash-looped until the account was issued and pushed by
@@ -357,36 +359,41 @@ check, judged by the group's controller, is then each member's gate, and the fea
## Step 4 — Deliver
The merge starts the delivery plan: build, publish, send. A merge into a branch other than `main` is not a
delivery: no machine receives it (issue 889 while it still starts one). The lead follows it to done
(`mesh-controller.plans` with `wait` and `until: done`), then resolves the feature's issues with `fixed-by`
naming its pull requests, and removes what is left: no `feat/<slug>` branch and no `.work/<slug>` worktree
survive.
The merge moves the source revision; there is no delivery plan (design 47, ADR 0539). The indexer writes each
module's new fingerprint, the builder builds it once, the controller writes its compositions, credential and grant,
and the assigner writes each node's want when its seven rules hold: the module's canary first, its other nodes once
it runs healthy there. A merge into a branch other than `main` is not a delivery: no machine receives it.
**What a merge moves is read from its plan before the operator is told.** A change to mesh-sdk rebuilds every
module that takes the SDK, with their backups and their asks for a person (issue 721): on 2026-10-20 the lead
said an SDK merge moved nothing, and its delivery plan moved mesh-sdk with 41 dependents to all four machines.
The lead reads the delivery plan in `mesh-delivery.show` and names what it moves before asking an Approve.
**The view follows a delivery; nobody asks the controller.** The lead's watcher waits on the status view's events:
`moving` (a module's want on a node differs from its have), `settled` (the have reached the want, running and
healthy), `stuck` (held, a failed health check, or past the watchman's thirty minutes) and `delivered` (every want of
the source revision equals its fingerprint and every have its want). After each wake it reads the state again from
the view's wants page or its tools: `assigner_wants` and `assigner_want` (a want not yet at the newest fingerprint
names, in `newest` and `rule`, the rule that holds it back, and its words say why), and `node_haves` (the node
agent's haves: fingerprint, composition digest, phase and health). The delivery is done when the view says
`delivered` for its source revision; then the lead resolves the feature's issues with `fixed-by` naming its pull
requests, and removes what is left: no `feat/<slug>` branch and no `.work/<slug>` worktree survive.
**A failed plan's Retry is asked of the operator alone, never beside an Approve.** An Approve's merge starts a
plan, and the controller refuses a Retry while another plan runs; on 2026-10-20 the operator chose both at once,
the merge's plan started first, the chosen Retry was refused and nobody asked it again (issue 1408). So the lead
never tells the operator to answer a Retry while an Approve is open, and reads the failed plan again after the
answer: a Retry refused is asked again once the other plan ends.
**What a merge moves is read before the operator is told.** A change to mesh-sdk rebuilds every module that takes
the SDK, with their backups and their asks for a person (issue 721): on 2026-10-20 the lead said an SDK merge moved
nothing, and its delivery moved mesh-sdk with 41 dependents to all four machines. The lead reads the indexer's
candidates of the group (the view's `indexer_candidates`: each module whose fingerprint the change moves) and the
nodes that run them, and names what it moves before asking an Approve.
**A push by hand is read from its plan first.** `mesh-controller.push` sends a machine everything it is owed, not
only what the lead changed: on 2026-10-21 a push of the control node to tell the bus of two new accounts also moved
mail's module to a build its upgrade policy holds for a person's word, and recreated one of its containers. Before
every push by hand, the lead reads `mesh-controller.plan` with `diff` for that machine, and for the machine holding
the bus when a push issues accounts, and pushes only when the plan names what the lead means to change.
**A held move is the operator's answer, asked by the assigner.** A module of policy `record` whose move would
recreate a container or move data, a failed backup before an apply, and a data module whose new fingerprint failed
its health check on the canary each wait for the operator's answer to the assigner's ask; the view says them
`stuck`, and a condition names the node and the module. The lead reads the ask on the router
(`operator-channel.asks`) before telling the operator it waits, and adds it to the wait list. No session writes a
want to get past a hold.
**A new module's first assignment is its first real composition.** The composition check composes every machine as it is
assigned, so a module that no machine runs yet is composed by no check: on 2026-10-21 the build modules' first
**A new module's first assignment is its first real composition.** The composition check composes every machine as
it is assigned, so a module that no machine runs yet is composed by no check: on 2026-10-21 the build modules' first
assignment found two faults no merge check could see (issue 1537, a template the controller filled for a value the
forge serves only later; issue 1542, the node-engine refusing the module's own `.ssh`). So a new module is assigned
to one machine first, its plan read before the push and its apply read after it (`mesh-controller.node`: the
answer, and `status` for a failed resource), and taken back at once when that machine cannot compose or apply, so
the machine keeps applying everything else; the other machines follow once it runs there.
to one machine first, its have read after the node agent applies it (`node_haves`: phase and health) and its node's
answer read for a failed resource (`mesh-controller.node`), and taken back at once when that machine cannot compose
or apply, so the machine keeps applying everything else; the other machines follow once it runs there.
## Deliver the controller, the builder or a build module without the builder
@@ -397,16 +404,23 @@ step recorded in the hand-act log with its reason:
1. **Revert, with no build.** Revert the change that broke the builder or the build module: the earlier source's fingerprint has a done key naming
references, so the revert's delivery builds nothing. Read first that the artifact store still holds the earlier artifact
(`mesh-controller.artifacts`): it keeps a recorded build while it is among its module's five newest or a definition names it.
(`mesh-controller.artifacts`): it keeps a recorded build while it is among its module's five newest or a definition names it, and the
controller keeps its composition while it is among the five newest too, so the assigner's want delivers it.
2. **A build by a session's call.** Call the build module's fetch and build tools on one named build node (for Go, `build_go_fetch` and then
`build_go_build` with `publish: true`); the build module pushes the artifact and answers its reference. `mesh-pack` in mesh-sdk gives a
hand build the build module's form; write the Go version of each hand build down, since another version gives another digest.
3. **Register by reference, at the controller's terminal only.** The operator names the module, its repository, its path and each artifact's
reference there; no verb reaches it. Say before you ask that this is a terminal step, and which notifications it raises; check that the
command exists on the node before you hand it over.
4. **A controller that cannot take its own fix** is put on the control-node by hand: register its hand build as in step 3, read the control-node's
plan, then `mesh-controller.push`. Only in the worst case does the operator send a declaration by hand at the terminal (its source and
digest the hand build's) and register it as in step 3 so the next push keeps it.
4. **A controller that cannot take its own fix** is put back by keys the operator writes at the terminal, with the operator's administrator
account (the operator's credential), never by a declaration sent by hand (ADR 0539 §10). To an earlier controller: the operator writes
`want.<control-node>.mesh-controller` naming a fingerprint whose composition is kept and that composition's digest; a controller
composes the one it replaced at its start, so that one is always kept. To a hand build never composed: register it as in step 3, then
`mesh-compose` (in mesh-sdk, beside `mesh-pack`) composes the module for the control-node from the controller's kept inputs, signs it
with the operator's key, and with `-write` and the operator's credential writes the composition into `composed-<node>` and its digest
into `mesh-controller_composed`; the operator then writes the want naming that digest. Read the composition `mesh-compose` prints
before `-write`. Each act goes into the hand-act log with its reason; say before you ask that these are terminal steps, and which
notifications they raise.
5. **Before a switch that moves the controller, the builder or a build module,** the lead keeps the running versions' artifacts outside the
artifact store, by digest on two nodes, with module, artifact, commit, Go version and the steps that put each back; the store's nightly
collection removes a blob the controller did not record.
@@ -439,20 +453,21 @@ on, with when it started and its bound.
| a merge check | 15 minutes | read `mesh-delivery.show` (its state and verdict), then the check's log; the check stream's backlog and the age of its oldest ask are in the delivery view (ADR 0525 §9) |
| the Approve's ask | 5 minutes after both checks pass | read `mesh-delivery.show`: an ask not raised is a fault, said to the operator |
| a merge after the Approve | 5 minutes | read `mesh-delivery.show` for the delivery |
| a delivery plan | its class's budget (`mesh-delivery.times`), at most 30 minutes | read `mesh-controller.plans`, then `mesh-delivery.stalled` |
| a delivery | its class's budget (3 minutes for a leaf module, 10 for a core module), at most 30 minutes | read the view's wants page, or `assigner_wants` against `node_haves`: a want held back names its rule, a `stuck` module its words |
**Every wait on the list has a watcher** (the operator, 2026-10-17). A session runs only when a message reaches
it, so a check, a merge, a delivery plan, a record's review or the operator's Approve on a channel that lands
it, so a check, a merge, a delivery, a record's review or the operator's Approve on a channel that lands
while the lead's turn has ended wakes nobody: on 2026-10-17 an approved group sat half merged for 14 minutes
unseen (issue 1032). For each wait the lead starts a watcher, an agent on the smaller model that changes nothing,
never the smallest (the operator, 2026-10-17).
It loops `mesh_wait` on the event families of what it watches (`mesh-delivery-gate.transition` and
`mesh-delivery-gate.group` for a delivery, for example; the families a watcher may wait on are those the mesh granted
`mesh-delivery-gate.group` for a merge, `mesh-delivery-view.moving`, `.settled`, `.stuck` and `.delivered` for its
delivery to the nodes, for example; the families a watcher may wait on are those the mesh granted
the tool runner, and a refusal names them) with a timeout under 60 seconds, since the call itself ends near
a minute. After every answer or timeout it reads the state from the verb that owns it (`mesh-delivery.show`,
`mesh-controller.plans`, `knowledge-base.get`), because an event only wakes it (ADR 0367). It finishes, and so wakes
the view's `assigner_wants` and `node_haves`, `knowledge-base.get`), because an event only wakes it (ADR 0367). It finishes, and so wakes
the lead, when the state changes or the wait passes its bound. The lead never sleeps or polls by hand to wait.
**A watcher watches one wait and ends with it.** It is never re-pointed at the next pull request or plan: on
**A watcher watches one wait and ends with it.** It is never re-pointed at the next pull request or delivery: on
2026-10-19 one watcher sent on to three pull requests in turn missed that the third's checks had passed at 04:58,
and the lead told the operator for 15 minutes that they were still running. The next wait gets a fresh watcher,
and before a report the watcher reads the owning verb once more and says only what it says now.
@@ -461,7 +476,7 @@ Approve, a Retry or a Release waits for them, it reads `operator-channel.asks` a
on 2026-10-20 an ask was named to the operator that the router did not hold. A merge the gate passed but whose
ask is not on the router is the fault of the Approve's wait in the table above.
**Every ten minutes (the operator, 2026-10-17), every two minutes while a delivery plan runs, and at once when something lands, stops or
**Every ten minutes (the operator, 2026-10-17), every two minutes while a delivery moves (the view says modules `moving`), and at once when something lands, stops or
needs the operator,** the lead reports, in one of the two layouts below (the operator, 2026-10-16: an overview
of the issues, often). Times are local and absolute, from the clock (`date`), never guessed; every number has its
unit and its bound or baseline; an issue is named by its number and a few words, never by its number alone.
@@ -520,7 +535,7 @@ moments, the same hour, an hq change going through [playbook 08](08-small-fixes.
- **The first milestone starts:** the design's `status: in-progress` ([playbook 04](04-build-handoff.md) step 7),
if it is not already.
- **A milestone's delivery plan is done:** its issues are resolved (step 4), with `fixed-by` naming its pull
- **A milestone is delivered** (the view says `delivered` for its source revision): its issues are resolved (step 4), with `fixed-by` naming its pull
requests. The design's milestone entry is not changed: it names the milestone's issues, and whether they are
delivered, when and by what is read from the issue tracker when it is asked, never copied into the design
(issue 1038; AGENTS.md: cross-cutting views are generated when they are read).
+9 -6
View File
@@ -76,8 +76,11 @@ one delivery**. Everything before the try is local and fast.
integration test starting the module whole against the real bus and store, run by `mesh-controller.try` and the checker's merge check
(ADR 0391 §1, §6); unit tests alone are not that proof, and the lab is not used. The operator's word is waited for only when the fix changes what the operator sees, removes data,
or needs the operator's terminal.
7. **Follow its delivery plan to done** (`mesh-controller.plans` with `wait` and `until: done`), prove the fix on
the mesh (the symptom gone, measured), and resolve the issue with `located-in` and `fixed-by` the same hour.
7. **Follow its delivery to done**: a watcher waits on the status view's events (`mesh-delivery-view.moving`,
`.settled`, `.stuck` and `.delivered`) and reads the view's `assigner_wants` and `node_haves` after each wake, as
playbook [07](07-feature-branches.md) step 4 says; the delivery is done when the view says `delivered` for its
source revision. Then prove the fix on the mesh (the symptom gone, measured), and resolve the issue with
`located-in` and `fixed-by` the same hour.
A fix that stops before its delivery moves its issue back to `open` with a note saying how far it got
(branch, last commit, what is left), as playbook [07](07-feature-branches.md) says.
@@ -111,7 +114,7 @@ code.
| the merge check | 15 minutes | read `mesh-delivery.show`, the check's log and the check stream's backlog in the delivery view |
| the Approve's ask | 5 minutes after both checks pass | read `mesh-delivery.show`: an ask not raised is a fault, said to the operator |
| the merge after the Approve | 5 minutes | read `mesh-delivery.show` for the delivery |
| the delivery plan | its class's budget (`mesh-delivery.times`), at most 30 minutes | read `mesh-controller.plans`, then `mesh-delivery.stalled` |
| the delivery | its class's budget (3 minutes for a leaf module, 10 for a core module), at most 30 minutes | read the view's wants page, or `assigner_wants` against `node_haves`: a want held back names its rule, a `stuck` module its words |
A wait past its bound is said to the operator at once, with what is being done about it.
@@ -126,7 +129,7 @@ reading itself and uses one subagent only for the review.
request with many heads is a fix reviewed after its pull request was opened.
- A pull request merged by hand in a temporary mode names a try with tests `.` at its head in its description
on the forge (`gitea.gitea_get_pull_request`); one without is the step skipped.
- Its issue moves to `resolved` within the hour its delivery plan ends.
- Its issue moves to `resolved` within the hour the view says its source revision `delivered`.
- 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 and acceptance criteria, is the failure of steps 4 to 6.
@@ -136,7 +139,7 @@ reading itself and uses one subagent only for the review.
- 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.
- A fix found during a milestone is named in the lead's report with the group it rides in, or with the reason it
went alone. `mesh-delivery.deliveries` shows the milestone's members in one group and one delivery plan per
milestone; a merge of mesh-sdk or mesh-controller outside the group, with no reported reason, is this rule skipped.
went alone. `mesh-delivery.deliveries` shows the milestone's members in one group, merged as one source revision
per milestone; a merge of mesh-sdk or mesh-controller outside the group, with no reported reason, is this rule skipped.
- The repository's own clone says `main` (`git -C <clone> branch --show-current`); another branch there is a
fix built outside a worktree (issue 1010).
+10 -10
View File
@@ -141,7 +141,7 @@ code{font:12.5px ui-monospace,monospace;background:var(--soft);padding:1px 5px;b
<rect x="950" y="160" width="116" height="74" rx="10" fill="var(--card)" stroke="var(--mesh)" stroke-width="2.5"/>
<text x="1008" y="188" text-anchor="middle" class="t">Delivered</text>
<text x="1008" y="206" text-anchor="middle" class="mute">Approve, merge,</text>
<text x="1008" y="220" text-anchor="middle" class="mute">delivery plan</text>
<text x="1008" y="220" text-anchor="middle" class="mute">wants and haves</text>
<rect x="766" y="160" width="150" height="74" rx="10" fill="var(--card)" stroke="var(--dec)" stroke-width="2" stroke-dasharray="5 4"/>
<text x="841" y="188" text-anchor="middle" class="t">As-is updated</text>
@@ -206,7 +206,7 @@ code{font:12.5px ui-monospace,monospace;background:var(--soft);padding:1px 5px;b
<text x="830" y="20" text-anchor="middle" class="t" style="fill:var(--mute)">3 · Check</text>
<text x="830" y="34" text-anchor="middle" class="mute">≤ 1 more try · 1 check</text>
<text x="1000" y="20" text-anchor="middle" class="t" style="fill:var(--mute)">4 · Deliver</text>
<text x="1000" y="34" text-anchor="middle" class="mute">its delivery plan</text>
<text x="1000" y="34" text-anchor="middle" class="mute">until delivered</text>
</g>
<!-- lanes -->
<g>
@@ -216,7 +216,7 @@ code{font:12.5px ui-monospace,monospace;background:var(--soft);padding:1px 5px;b
<text x="10" y="86" class="t">Lead</text><text x="10" y="102" class="mute">larger model</text>
<text x="10" y="158" class="t">Fixing agents</text><text x="10" y="174" class="mute">smaller model</text>
<text x="10" y="230" class="t">Reviewer</text><text x="10" y="246" class="mute">larger model</text>
<text x="10" y="302" class="t">The mesh</text><text x="10" y="318" class="mute">try, checks, plan</text>
<text x="10" y="302" class="t">The mesh</text><text x="10" y="318" class="mute">try, checks, wants</text>
<text x="10" y="374" class="t">Operator</text><text x="10" y="390" class="mute">Telegram</text>
</g>
<!-- lead -->
@@ -251,8 +251,8 @@ code{font:12.5px ui-monospace,monospace;background:var(--soft);padding:1px 5px;b
<text x="830" y="294" text-anchor="middle" class="t">Forge checks</text>
<text x="830" y="312" text-anchor="middle" class="mute">gate · repo · group</text>
<rect x="930" y="272" width="140" height="52" rx="8" fill="var(--card)" stroke="var(--mesh)" stroke-width="2"/>
<text x="1000" y="294" text-anchor="middle" class="t">Merge · delivery plan</text>
<text x="1000" y="312" text-anchor="middle" class="mute">backups first, tier by tier</text>
<text x="1000" y="294" text-anchor="middle" class="t">Merge · wants</text>
<text x="1000" y="312" text-anchor="middle" class="mute">backups first, canary first</text>
<!-- operator -->
<rect x="860" y="344" width="140" height="52" rx="8" fill="var(--card)" stroke="var(--op)" stroke-width="2.5"/>
<text x="930" y="366" text-anchor="middle" class="t">Approve</text>
@@ -282,7 +282,7 @@ code{font:12.5px ui-monospace,monospace;background:var(--soft);padding:1px 5px;b
<li>Into each issue: every file and test it touches (file:line), how it is checked and delivered, a group's merge order.</li>
<li><span class="tag new">new</span>Every other reader and writer of each value the change touches, each with a criterion.</li>
<li>Acceptance criteria: given / when / then, each naming its test level.</li>
<li>Every part the change reaches is an issue of the milestone; their order is the delivery plan's, never a cut.</li>
<li>Every part the change reaches is an issue of the milestone; their order is the assigner's rules', never a cut.</li>
<li>Fixtures copied from what the other side really writes, never from memory.</li>
<li>An issue sized over an hour is split before work starts.</li>
</ul>
@@ -465,19 +465,19 @@ const P = [
{n:"07",name:"Features",kind:"build",c:"--build",
trig:"Work that changes code across issues or repositories, too large for a small fix.",
who:"A lead (larger model), one fixing agent per repository (smaller), one reviewer (larger).",
steps:["Prepare: name the branch, make the worktrees, settle every question.","Write one context file per repository.","Write the findings and acceptance criteria into each issue.","Survey every other reader and writer of each changed value. (new)","Answer three questions in the milestone file: who deletes each new key and stream, how the switch-over is tried on one node first, how the integration level runs before the pull requests. The review checks them. (new)","List every part the change reaches; copy fixtures from the real writer.","Develop: one agent per repository, one commit per issue.","A test fails first on behaviour, not on compiling. (new)","Bring each branch up to the trunk, push, and try it. (new)","Review all of it with the tries' results; at most 3 rounds.","Push the reviewed heads; try again only what changed.","A merge by hand in a temporary mode first runs a try with tests \".\" and names it in the pull request. (new)","Open one pull request per repository, together, with Reviewed-by and Pushed-by.","The operator's Approve on Telegram; the group merges in one pass.","Follow the delivery plan to done; resolve the issues; clean up.","When the builder cannot deliver its own fix: revert, a build by a session's call, a registration at the terminal, copies kept outside the store. (new)"],
prod:"One pull request per repository, one delivery plan, resolved issues, no branch or worktree left.",
steps:["Prepare: name the branch, make the worktrees, settle every question.","Write one context file per repository.","Write the findings and acceptance criteria into each issue.","Survey every other reader and writer of each changed value. (new)","Answer three questions in the milestone file: who deletes each new key and stream, how the switch-over is tried on one node first, how the integration level runs before the pull requests. The review checks them. (new)","List every part the change reaches; copy fixtures from the real writer.","Develop: one agent per repository, one commit per issue.","A test fails first on behaviour, not on compiling. (new)","Bring each branch up to the trunk, push, and try it. (new)","Review all of it with the tries' results; at most 3 rounds.","Push the reviewed heads; try again only what changed.","A merge by hand in a temporary mode first runs a try with tests \".\" and names it in the pull request. (new)","Open one pull request per repository, together, with Reviewed-by and Pushed-by.","The operator's Approve on Telegram; the group merges in one pass.","Follow the delivery in the status view (moving, settled, stuck, delivered) to done; resolve the issues; clean up. (new)","When the builder cannot deliver its own fix: revert, a build by a session's call, a registration at the terminal, copies kept outside the store; a broken controller is put back by a want the operator writes, a hand build by mesh-compose and a want. (new)"],
prod:"One pull request per repository, one source revision delivered, resolved issues, no branch or worktree left.",
next:"02 (when it ships)",bounds:"Prepare 15 min · 30 min per issue · review 15 min, ≤ 3 rounds · one try and one check",
prev:["Pull requests as scratchpads","Context bought again and again","Review rounds spent on what a run would show"],
check:"The checker's one status, mesh/check; the review record; the tracker's move."},
{n:"08",name:"Small fixes",kind:"build",c:"--build",
trig:"One issue in one repository, about an hour of work.",
who:"The session, with one reviewer on the larger model.",
steps:["Read the issue and the code; settle any open question.","Write the acceptance criteria.","Move the issue to fixing.","Build on fix/<issue>-<slug> in its own worktree.","A test that fails today first, on behaviour. (new)","Push and try before the review. (new)","One review of the commit and its try.","Push the reviewed head; open the pull request.","The operator's Approve; the merge; the delivery plan.","Prove the fix live and resolve the same hour.","During a milestone: ride in its delivery group, unless broken for the operator now. (new)"],
steps:["Read the issue and the code; settle any open question.","Write the acceptance criteria.","Move the issue to fixing.","Build on fix/<issue>-<slug> in its own worktree.","A test that fails today first, on behaviour. (new)","Push and try before the review. (new)","One review of the commit and its try.","Push the reviewed head; open the pull request.","The operator's Approve; the merge; the delivery, followed in the status view. (new)","Prove the fix live and resolve the same hour.","During a milestone: ride in its delivery group, unless broken for the operator now. (new)"],
prod:"One pull request, one delivery, a resolved issue.",
next:"—",bounds:"About an hour · one try before the review, one review, one check",
prev:["A fix reviewed after its pull request opened","A long part run twice","A fix waiting on someone else's delivery","Ten SDK merges and eight controller merges in a day, one per fix"],
check:"The checker's status; the review record; the tracker's move; one delivery group and one delivery plan per milestone."},
check:"The checker's status; the review record; the tracker's move; one delivery group and one source revision per milestone."},
{n:"09",name:"Cleanup",kind:"side",c:"--side",
trig:"The operator asks, or merged branches, stale pull requests and old worktrees pile up.",
who:"A session on the operator's word; the operator decides every deletion.",