Hold a delivery-system release's push on a dry run with no item open
mesh/check checking 010a93d6bc69 on 2b39e39385b6
mesh/delivery merged: source.main moved to novox/hq@2b39e39385b6
mesh/check checking 010a93d6bc69 on 2b39e39385b6
mesh/delivery merged: source.main moved to novox/hq@2b39e39385b6
Milestone G was pushed with its dry run's take-in item still open; once merged, the running indexer refused G's own indexer with the live seat list, and its trunk builds waited on renamed packages only the take-in publishes. Playbook 07 gains step 2b: the live take-in run whole, every build against the published packages, the gate's merge path read for the group, and a dry run with an open item is not a pass. The glossary gains "dry run"; the playbooks page lists the step. Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
@@ -696,6 +696,12 @@ controller (the planner, the rollout) until release 6 of ADR 0429; from each rel
|
||||
It keeps the verdicts of the packages it passed for the check to take (ADR 0637). Asked only when the operator
|
||||
asks for one (ADR 0637 §6). Goes at milestone G's delivery, the **run on request** in its place (ADR 0666 §18); the
|
||||
word goes to that entry's *Not:* line with the as-is update after that delivery.
|
||||
- **dry run** — a session's run, before a release is pushed, of the parts that will take it in, build it and merge it,
|
||||
as they run live, on the revision as the merge will make it: in process on the session's machine, reading the mesh
|
||||
and writing nothing there. It holds four items: the live take-in run whole with the seat list it will read, every
|
||||
build against the packages as published, the gate's merge path read for the group, and no item left open (hq
|
||||
playbook 07, step 2b). Not a **try** nor a **run on request**, which the mesh runs and which deliver a verdict; a dry
|
||||
run owes the forge nothing and is not a check.
|
||||
- **trunk commit** — the commit of the trunk a merge check's verdict was judged against: the trunk's head when
|
||||
the build module cloned it. The verdict holds for that commit only, goes out of date when the trunk moves, and
|
||||
is then carried to the new commit (ADR 0323, ADR 0548). Goes at milestone G's delivery with the merge check: a pipeline
|
||||
|
||||
@@ -62,13 +62,18 @@ A small fix (one repository, one issue, about an hour of work) follows
|
||||
take, or assuming a part already built that was not. The prepare had read the design alone. It now reads the code
|
||||
each design line lands in as well, and lists every place where the two disagree before any developer starts
|
||||
(step 0, items 3 and 10; the operator, 2026-11-11).
|
||||
- **A dry run with an open item, taken as a pass.** On 2026-11-13 milestone G of design 47 was pushed with its dry
|
||||
run's item "the take-in's seat path is not run" still open; once merged, the running indexer refused the milestone's
|
||||
own indexer and five more modules with the live seat list, and its trunk builds waited on renamed packages only the
|
||||
take-in would publish. The dry run (step 2b) now runs the live take-in, the builds against what is published and the
|
||||
gate's merge path, and holds the push while any item is open.
|
||||
- **A module proven only after it reached the machines.** The mail modules were delivered with unit tests
|
||||
only, then failed live three times (issues 859, 865, 868) and took five more hours of fixes.
|
||||
|
||||
## The shape
|
||||
|
||||
One feature is **one branch name**, **one worktree per repository**, **one pull request per repository**,
|
||||
opened **once**, after the review, and **one check** (ADR 0548). It runs in five steps, with the design completed between the first two (step 0b), and its time is bounded. A milestone has no phases
|
||||
opened **once**, after the review, and **one check** (ADR 0548). It runs in five steps, with the design completed between the first two (step 0b) and, for a change of what judges, builds or merges it, a dry run between the review and the check (step 2b), and its time is bounded. A milestone has no phases
|
||||
(the operator, 2026-10-17): these are its steps, and a report names the step it is in:
|
||||
|
||||
| Step | What happens | Bound |
|
||||
@@ -77,6 +82,7 @@ opened **once**, after the review, and **one check** (ADR 0548). It runs in five
|
||||
| 0b. Design complete | every design question and every place where design and code disagree is answered: by the lead in one line against the principles, or, where no principle settles it, by the operator or `hq-design-writer` (step 0); each answer is written down (the lead's in the milestone's lead-answers file, the others into the milestone part, playbook 02) and its build map rows added | until the list is empty: develop never starts before |
|
||||
| 1. Develop | one fixing agent per repository builds every design line of its build map locally, each commit citing the lines it builds, 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 |
|
||||
| 2b. Dry run | for a release that changes a part judging a change, or a module path, a package or a manifest form the take-in reads: the live take-in run whole with the seat list it will read, every build against the packages as published, the gate's merge path read for the group, and no item left open | until no item is open: nothing is pushed before |
|
||||
| 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` |
|
||||
|
||||
@@ -505,10 +511,74 @@ an answer no hq commit holds, is a finding of the review (step 2, item 2a).
|
||||
in the design. How it is checked: the review report has a line for each question with its answer, and the lead reads both before the
|
||||
push; a report without them is not an approval.
|
||||
|
||||
## Step 2b — Dry run (a change of the delivery system, or of what the take-in reads)
|
||||
|
||||
**When it runs.** After the review approves the heads and before the push of step 3, for every release that changes a
|
||||
part judging a change (step 3, item 3: the indexer and its manifest validator, the gate, the builder, a build module,
|
||||
the checker or the pipeline runner, the node-engine, a seat definition), and for every release that adds or renames a
|
||||
module path or a package other modules take, or changes the form of manifests the take-in reads. The prepare step's
|
||||
milestone file says per release whether it runs and why (`Dry run: yes` or `no`, with the reason); the review refuses a
|
||||
group that lists a judging part with no such line. The operator, 2026-11-13: "remember the mistake and make sure our
|
||||
pipeline catches this".
|
||||
|
||||
**What it is.** A dry run runs the parts that will take the change in, build it and merge it, as they run live, on the
|
||||
revision as the merge will make it: in process on the session's machine, reading the mesh and writing nothing there,
|
||||
asking no try and no check. An agent of hq's definitions runs it, read-only on the mesh and on every working copy; the
|
||||
lead writes only the handover. Everything live it uses (the builds the nodes run, the seat list, the published
|
||||
versions, the trunks) is read in the same hour as the push, and read again, with the dry run run again, when a head,
|
||||
a main or a live build moves before the push. Four items, each held before any push:
|
||||
|
||||
1. **The live take-in, run whole.** The indexer that will take the revision in (the running one, read from the view's
|
||||
reach of its module; for a revision that names another build of the indexer, the running one, which keeps it
|
||||
pending, and the named one, from its start) runs on the revision: every member's head merged onto its base's main as
|
||||
it is now, the other trunks' manifests as the indexer's state holds them, and **the seat list as the take-in will
|
||||
read it**, which is the seat list the seat `mesh-catalog`'s verb `seat-definitions` answers at that moment, not the
|
||||
group's own definitions laid over it (step 1's brief lays them over for the developer's case; the take-in does not).
|
||||
It runs through to the keys the take-in would write (each fingerprint, a pending revision, a group's members
|
||||
gathered), never the manifest validator alone. A manifest refused, a module set aside, or a revision left pending
|
||||
with no indexer that can take it in is a fault of the release: it is fixed in the release, or what the running parts
|
||||
cannot take in is delivered first (step 3, item 3), before the push.
|
||||
2. **Every build against the packages as published.** Every build the revision starts (each module whose fingerprint it
|
||||
moves, as the indexer's run of item 1 lists them) is built with `GOWORK=off` and no `replace` toward a local tree,
|
||||
each mesh package resolved from the registry seat of its language as that seat serves it at that moment (its verb
|
||||
`versions`), never from the group's heads. A new or renamed module path, or a package that only the revision's own
|
||||
take-in or build would publish, shows here as a package with no published version: a circle in which the build
|
||||
waits on a take-in that waits on the build. It is a gap of the build and delivery system, built there before the
|
||||
push (in the same milestone or before it) and said to the operator, never pushed into.
|
||||
3. **The gate's merge path, read for the group.** Before the push, and again before the operator's Approve is asked:
|
||||
each member's base, read with `mesh-delivery.show` (the gate never hands a member whose base is not the branch it
|
||||
merges into, and every member after it in the gate's order waits behind it); the group itself, read with
|
||||
`mesh-delivery.show` on the group's id, open and holding every member (a pull request reopened into a group the gate
|
||||
holds closed joins it as a lone delivery); and every member present before the first ask. The gate merges a group's
|
||||
members one at a time and undoes none, so one member it cannot merge leaves the group half merged. A member on
|
||||
another base is moved to the gate's branch or left out of the group, a group the gate holds closed is pushed under a
|
||||
new branch name, and an Approve ask that names fewer members than the group is ended and said to the operator,
|
||||
never answered.
|
||||
4. **No item open.** The dry run's report says of each item what ran, at which heads and on which live builds, and its
|
||||
counts ("ran: 193 manifests, 0 refused, seat list read at 13:05"). An item said "not run", "not known" or "read, not
|
||||
run" is closed, by running it or by showing why it does not apply, or the push is held: **a dry run with an open
|
||||
item is not a pass**, and no rule is weighed against it. Before the push the lead says to the operator, in one line
|
||||
per item, what each showed.
|
||||
|
||||
The faults it answers, 2026-11-13: milestone G of design 47 was pushed after two dry runs, the second of which said
|
||||
"with the live seat list 26 refused; the take-in's seat path is not run", and the lead pushed with that item open.
|
||||
Once merged, the running indexer took the revision in with the live seat list and refused the milestone's own indexer
|
||||
and five more modules. The milestone renamed module paths, and the trunk builds waited for packages that only the
|
||||
take-in publishes; no dry run had built a trunk module against the published packages alone. The same day the gate
|
||||
merged a group one member at a time with no undo, stopped at a member whose base was not main, and asked an Approve
|
||||
while a group was still forming and per member of a closed group.
|
||||
|
||||
**How it is checked.** The milestone file holds a section `Dry run` with each item's result, the reviewed heads it ran
|
||||
on and its time (`grep -n -A6 '^## Dry run' .work/<slug>/milestone.md`), older than the push (the forge branch's
|
||||
first push of the heads) and with no item open; the pull requests' description names it in one line. A push of a
|
||||
release whose milestone file lists a judging part with no such section, or with an item open, is this step skipped;
|
||||
a fault met after the merge that an item would have shown is named at the next report and written here as a lesson.
|
||||
|
||||
## Step 3 — Check (no review)
|
||||
|
||||
1. **Push the reviewed heads once, then open one pull request per repository, together** (ADR 0548; the operator,
|
||||
2026-10-26: "every release should only run 1 check or 1 try"). **No pull request, draft or not, exists before the
|
||||
2026-10-26: "every release should only run 1 check or 1 try"), after the dry run where step 2b asks one, with no
|
||||
item open. **No pull request, draft or not, exists before the
|
||||
review approves the heads**, and no fix round is pushed to an open pull request: every push to an open pull request
|
||||
asks a new check, of every member for a group, and the mesh's build capacity is spent on it ("we don't have more
|
||||
processing power"). The integration tests run once, in the checker's merge check on the merge with the trunk's head, at the unit
|
||||
@@ -873,6 +943,8 @@ issues in `fixing` that nobody works on reads to the operator as stuck work.
|
||||
item 6b). A fixing agent started on a file without the section, or an effect of a removed or moved part met only
|
||||
after the delivery, is the prepare step skipped, named in the next detailed report and written into the playbook's
|
||||
lessons here.
|
||||
- A release whose milestone file lists a part judging a change holds a `Dry run` section with all four items closed,
|
||||
older than its push (step 2b); one pushed without it, or with an item open, is that step skipped.
|
||||
- No issue of a running milestone is sized over an hour in its prepare note; an issue whose fixing agent passes
|
||||
twice its bound was not split.
|
||||
- Every issue of a running milestone has a note from the prepare step naming its files and tests (file:line), how
|
||||
|
||||
@@ -476,11 +476,11 @@ 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, read the milestone part and the design's main file whole, then the code each design line lands in. (new)","List every place where a design line and the code disagree, beside the design questions. (new)","Every agent is one of hq's definitions (mesh-preparer, mesh-developer, mesh-code-reviewer, mesh-watcher); the lead writes only the handover. (new)","The prepare's only output: a build map per repository, each row a design line and where it lands, and the design questions. No rulings. (new)","Design complete: the lead answers every question against the principles; one no principle settles goes to the operator or the design writer; then develop. (new)","Read what exists today from the code and the live mesh: every effect of what is removed or moved, every reader of each, what happens to each and its test. No code before it is complete; the review refuses work without it. (new)","The build map opens with what exists today; subtasks ordered contract first, one writer per file.","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, what the one check does not cover. 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 subtask, each citing its design lines; a question stops only its subtask. (new)","A test fails first on behaviour, not on compiling. (new)","Bring each branch up to the trunk; nothing is pushed, no try runs. (new)","Review all of it against the design lines, code no line asks for a finding, reading the integration tests against the code; at most 3 rounds; the report answers the state-and-seams and mesh-agnostic questions. (new)","A group pins the group's own mesh-sdk head in every member. (new)","Push the reviewed heads once and read each forge head against the reviewed commit; no draft pull request, no fix round on an open one. (new)","Open one pull request per repository, together, with Reviewed-by and Pushed-by; the one check runs. A failed check is read, fixed, reviewed, pushed once more. (new)","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-hand-compose and a want. (new)"],
|
||||
steps:["Prepare: name the branch, make the worktrees, read the milestone part and the design's main file whole, then the code each design line lands in. (new)","List every place where a design line and the code disagree, beside the design questions. (new)","Every agent is one of hq's definitions (mesh-preparer, mesh-developer, mesh-code-reviewer, mesh-watcher); the lead writes only the handover. (new)","The prepare's only output: a build map per repository, each row a design line and where it lands, and the design questions. No rulings. (new)","Design complete: the lead answers every question against the principles; one no principle settles goes to the operator or the design writer; then develop. (new)","Read what exists today from the code and the live mesh: every effect of what is removed or moved, every reader of each, what happens to each and its test. No code before it is complete; the review refuses work without it. (new)","The build map opens with what exists today; subtasks ordered contract first, one writer per file.","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, what the one check does not cover. 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 subtask, each citing its design lines; a question stops only its subtask. (new)","A test fails first on behaviour, not on compiling. (new)","Bring each branch up to the trunk; nothing is pushed, no try runs. (new)","Review all of it against the design lines, code no line asks for a finding, reading the integration tests against the code; at most 3 rounds; the report answers the state-and-seams and mesh-agnostic questions. (new)","Dry run, for a change of what judges, builds or merges it: the live take-in run whole with the seat list it will read, every build against the packages as published, the gate's merge path read for the group; an item left open holds the push. (new)","A group pins the group's own mesh-sdk head in every member. (new)","Push the reviewed heads once and read each forge head against the reviewed commit; no draft pull request, no fix round on an open one. (new)","Open one pull request per repository, together, with Reviewed-by and Pushed-by; the one check runs. A failed check is read, fixed, reviewed, pushed once more. (new)","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-hand-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 check, pushed once",
|
||||
prev:["Pull requests as scratchpads","Context bought again and again","A change built on what was remembered, not on what runs","Review rounds spent on what a run would show","A node agent's bus reads, proven only by review"],
|
||||
check:"The checker's one status, mesh/check; the review record; the tracker's move."},
|
||||
prev:["Pull requests as scratchpads","Context bought again and again","A change built on what was remembered, not on what runs","Review rounds spent on what a run would show","A node agent's bus reads, proven only by review","A dry run with an open item, taken as a pass"],
|
||||
check:"The checker's one status, mesh/check; the review record; the dry run's section in the milestone file; 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.",
|
||||
|
||||
Reference in New Issue
Block a user