@feigi/fleet-ctl 3.82.13 → 3.82.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agents/fleet-implementer-slow-high.agent.md +1 -1
- package/agents/fleet-implementer-slow-medium.agent.md +1 -1
- package/agents/fleet-implementer-smol-high.agent.md +1 -1
- package/agents/fleet-implementer-task-high.agent.md +1 -1
- package/agents/fleet-implementer-task-max.agent.md +1 -1
- package/commands/review-and-fix.md +1 -0
- package/package.json +1 -1
- package/scripts/ledger.mjs +52 -4
- package/scripts/recipe-check.mjs +260 -0
- package/scripts/report-files.mjs +67 -8
- package/skills/next-ticket/SKILL.md +12 -2
- package/skills/run-team/SKILL.md +35 -514
- package/skills/run-team/briefs/fix-applier.md +13 -3
- package/skills/run-team/briefs/implementer.md +8 -0
- package/skills/run-team/references/isolation.md +1 -1
- package/skills/run-team/references/member-lifecycle.md +46 -0
- package/skills/run-team/references/phase-0.md +2 -2
- package/skills/run-team/references/pull.md +31 -5
- package/skills/run-team/references/reviewers.md +5 -1
- package/skills/run-team/references/shell-traps.md +2 -0
- package/skills/run-team/references/tick-rows.md +32 -3
|
@@ -53,7 +53,7 @@ and `cwdAudit` before any result of the shared test run. Every one of those
|
|
|
53
53
|
rulings is yours — nobody upstream has made one, and the controller never
|
|
54
54
|
reads the findings.
|
|
55
55
|
|
|
56
|
-
**Run
|
|
56
|
+
**Run `recipe-check.mjs` (below) from the worktree before committing.**
|
|
57
57
|
`tests 0` is a FAILED run, not a pass. Red or zero-test → fix it, or move that
|
|
58
58
|
finding to defer; never commit over it. **Never `--no-verify`** on a commit you push, or on the push — a failing
|
|
59
59
|
hook is a finding you report, not an obstacle you route around. Report the test
|
|
@@ -67,11 +67,11 @@ claim, never your patch.
|
|
|
67
67
|
## kind: conflict
|
|
68
68
|
Bring `<branch>` current with `origin/main`, resolving every conflict by the
|
|
69
69
|
**No-undo audit** in `$(~/.fleet/bin/fleet-run --root)/commands/run-merge-bot.md`.
|
|
70
|
-
Run
|
|
70
|
+
Run `recipe-check.mjs` (below) from the worktree before you push, then push with
|
|
71
71
|
`~/.fleet/bin/fleet-run push-sync.mjs --branch <branch>`. Report the new head, or that no conflict was
|
|
72
72
|
left.
|
|
73
73
|
## kind: red-check
|
|
74
|
-
Read the failing job's log and fix the cause. Run
|
|
74
|
+
Read the failing job's log and fix the cause. Run `recipe-check.mjs` (below)
|
|
75
75
|
from the worktree before you push, then push with `~/.fleet/bin/fleet-run push-sync.mjs --branch <branch>`.
|
|
76
76
|
Report the new head and **stop**: do not watch, poll or wait for CI — the
|
|
77
77
|
controller owns the next run on the pushed head. A red that is not yours to
|
|
@@ -90,6 +90,16 @@ runs the hook, so every change still unstaged after it is the hook's alone:
|
|
|
90
90
|
never stage those, `git restore -- <that path>` for each such path alone, then
|
|
91
91
|
rebase and re-run.
|
|
92
92
|
|
|
93
|
+
**`recipe-check.mjs` is how you run `<checkCmd>` and `<testCmd>`:**
|
|
94
|
+
`~/.fleet/bin/fleet-run recipe-check.mjs --member <your name> --testCmd "<testCmd>" --reports <scratch>/reports`,
|
|
95
|
+
from the worktree, after `git add` and before the commit — `<testCmd>` copied
|
|
96
|
+
verbatim as the one quoted argument. It runs the Recipe's Check step,
|
|
97
|
+
`<checkCmd>`, then `<testCmd>`, against the staged tree and records both beside
|
|
98
|
+
your report. Run it again after any content change or rebase: the controller
|
|
99
|
+
refuses an `applied` report whose head's tree has no green record, and a
|
|
100
|
+
message-only amend keeps the record valid. Exit 1 is red; exit 75 is no test
|
|
101
|
+
result — no slot was free and nothing ran — so run it again.
|
|
102
|
+
|
|
93
103
|
Your report is a file, `<scratch>/reports/<your name>.json`, `<your name>` the
|
|
94
104
|
`fix-pr-` name you were dispatched as, in the shape
|
|
95
105
|
`~/.fleet/bin/fleet-run report-schema.mjs print fix-pr` prints. Write it
|
|
@@ -22,6 +22,14 @@ The ticket, pasted verbatim from the controller's own read — its title, the
|
|
|
22
22
|
|
|
23
23
|
The controller's staleness probe: <staleness>
|
|
24
24
|
|
|
25
|
+
Before you commit and push, run
|
|
26
|
+
`~/.fleet/bin/fleet-run recipe-check.mjs --member <your name> --testCmd ./agent-test --reports <scratch>/reports`
|
|
27
|
+
from the worktree, after `git add`: it runs the Recipe's Check step, then
|
|
28
|
+
`./agent-test`, against the staged tree and records both beside your report.
|
|
29
|
+
Run it again after any content change or rebase. The controller refuses a
|
|
30
|
+
report whose head's tree has no green record, and exit 75 from it is no test
|
|
31
|
+
result — run it again.
|
|
32
|
+
|
|
25
33
|
Your report is a file, `<scratch>/reports/<your name>.json`, `<your name>` the
|
|
26
34
|
`impl-<N>[-x]` you were dispatched as, in the shape
|
|
27
35
|
`~/.fleet/bin/fleet-run report-schema.mjs print impl` prints. Write it before
|
|
@@ -200,7 +200,7 @@ kernel — is a session setting a child inherits, not something one dispatch can
|
|
|
200
200
|
set for one member. Isolating a member's kernel is an omp-side change, so
|
|
201
201
|
discipline is the whole of the remedy here — unlike the missing `cwd` field
|
|
202
202
|
above, which `member-write-guard` enforces for `write`/`edit`/`ast_edit` and
|
|
203
|
-
`eval` bypasses. **
|
|
203
|
+
`eval` bypasses. **Dispatching the Pull's member** carries all three rules to every member.
|
|
204
204
|
|
|
205
205
|
## `release-ticket.sh` is not a no-op on omp, and a running member hides nothing from `inflight.sh`
|
|
206
206
|
|
|
@@ -99,3 +99,49 @@ warning is the only reason it did not repeat the stall. Its
|
|
|
99
99
|
the poll it was waiting on was structurally incapable of firing. This file is
|
|
100
100
|
yours, not theirs: the implementer, fix-applier and finisher briefs carry the
|
|
101
101
|
rule, as the line `A member runs its test suite in the foreground and blocks on it.`
|
|
102
|
+
|
|
103
|
+
## No workpool, and no kernel-resident handle
|
|
104
|
+
|
|
105
|
+
A pool's only refill virtue — handing a queued item to a freed worker without a controller turn — is exactly what a Pull forbids, and its completions never arrive per member. `eval`'s `agent()` is not the omp call either: a kernel-resident handle dies with the kernel and needs a `wait`, while a `task` job is process-level and its report auto-delivers on its own, like every other member's.
|
|
106
|
+
|
|
107
|
+
## One claim, one dispatch, no queue
|
|
108
|
+
|
|
109
|
+
The In-flight bound is the fleet's own accounting rather than anything the runtime enforces, and the member is fresh and never a wake of one that already ran. Admission is per slot and never batched, so there is nothing to hand a freed slot its next ticket but the next Pull.
|
|
110
|
+
|
|
111
|
+
## The prompt pastes the Pull's own read
|
|
112
|
+
|
|
113
|
+
The prompt pastes the Pull's own read of the ticket rather than telling the member to re-fetch it, and this still costs one `gh issue view` per ticket, never one per member. The fresh-context design's isolation rationale — "every implementer re-reads its Agent Brief... from scratch" — is about a member never inheriting another ticket's context, not about where the bytes come from. Pasting the Pull's own read into the prompt keeps that: the member still gets the brief verbatim and re-derives nothing from a sibling. What it drops is the unconditional re-fetch of an issue the controller already has open, on every dispatch — the fetch the agent body still carries is the backstop for a brief that turns out to be insufficient, not the default path.
|
|
114
|
+
|
|
115
|
+
## A member settling with nothing is not a bail
|
|
116
|
+
|
|
117
|
+
Each member's outcome arrives as its own job status. Settle (CONTEXT.md § Coordination) is three states on omp — `completed`, `failed`, `cancelled` — and reading `failed`/`cancelled` the same as a `completed` turn that had nothing to report is the exact collapse this line blocks: a member that died never chose to bail, so demoting its ticket on its silence demotes a ticket its member never got the chance to judge. Confirm death first, exactly as the Member-killed row does (Failure handling in SKILL.md) — its mtime discriminator, never silence alone.
|
|
118
|
+
|
|
119
|
+
## The implementer's tier is the definition's
|
|
120
|
+
|
|
121
|
+
The tier lives in that definition's frontmatter (`agents/fleet-implementer-<cell>.agent.md`; `slow-high`, the policy cell, for a row with no `tier=`), which is what an omitted `model` takes first — the session's tier applies only when the definition names none, and a member dispatched with `model` set does not get the declared tier back. Omitting `model` is therefore still the mechanism; what changed is that the tier it resolves to is now declared and pinned rather than inherited by accident. Keep `name: impl-<N>`: the name is what makes a member, and both the spend classifier and `member-outcomes.mjs` read it.
|
|
122
|
+
|
|
123
|
+
## The merge bot's tier buys nothing its backstop does not cover
|
|
124
|
+
|
|
125
|
+
Rebase, wait for green, check the label, merge is checklist work, and a bad merge still needs the label and the per-job CI state to have been read correctly, which is exactly what a wrong merge later surfaces and a human resolves; `no-undo-audit.sh` is the deterministic, script-driven backstop run before every push specifically to catch a wrongly-resolved conflict, so the tier buys nothing that backstop doesn't already cover.
|
|
126
|
+
|
|
127
|
+
## The red-check fixer's three edges
|
|
128
|
+
|
|
129
|
+
The Monitor is edge-keyed on `<run-id>:<attempt>:<conclusion>`, so a red that fired before the review never fires again, and with no push there is no new run — the other edges are the only route there, so do not wait for an event. Edit one of the three finisher-gate edges without the others and what strands is exactly the red-only PR.
|
|
130
|
+
|
|
131
|
+
Take the common case, the implementer's own first CI firing turning red before any review exists: the review is still dispatched against that head as normal, because a red suite is review evidence and not a blocker.
|
|
132
|
+
|
|
133
|
+
## The tier check judges the dispatch-time tier
|
|
134
|
+
|
|
135
|
+
The check reads the installed definition and the live `modelRoles` at check time, not at dispatch time, so a late check judges a member against a tier it was never dispatched under.
|
|
136
|
+
|
|
137
|
+
## The tier check after a /resume
|
|
138
|
+
|
|
139
|
+
A live implementer rotate carried forward with no verdict on its row is unchecked, and once this session has been reopened with `/resume` its transcript sits under the earlier session's directory: the check given this run's `session` finds no `<member>.jsonl` and exits 2, writing nothing.
|
|
140
|
+
|
|
141
|
+
## Dispatching on an unchecked member multiplies the damage
|
|
142
|
+
|
|
143
|
+
Dispatching the next member on top of an unchecked or mismatched dispatch multiplies whatever silently degraded.
|
|
144
|
+
|
|
145
|
+
## Ledger reads and their buffer
|
|
146
|
+
|
|
147
|
+
`board.mjs` reads `ledger.mjs read` with an explicit `maxBuffer`, so a payload past node's default is carried rather than killed mid-flight and reported as an unreachable tool — which is how the blind cockpit came back at HTTP 200 even after the pipe cut was gone.
|
|
@@ -334,7 +334,7 @@ PROVEN`** → re-run both reads above (`derive-testcmd.sh . install` and
|
|
|
334
334
|
below; their output is the Recipe this run uses. **`RECIPE NOT PROVEN`** →
|
|
335
335
|
stall, below.
|
|
336
336
|
|
|
337
|
-
**Where `checkCmd` comes from:** the repository's Check step, out of the same Recipe cache — `~/.fleet/bin/fleet-run derive-testcmd.sh . check` prints it. Pass it to the fix-applier beside `testCmd`; the review does not run it.
|
|
337
|
+
**Where `checkCmd` comes from:** the repository's Check step, out of the same Recipe cache — `~/.fleet/bin/fleet-run derive-testcmd.sh . check` prints it. Pass it to the fix-applier beside `testCmd`; the review does not run it. Neither member runs the two by hand: `recipe-check.mjs` runs the Check step it reads off that cache, then the `testCmd` it is handed, on the member's staged tree, and writes the record `ledger.mjs settle --from-report` requires of an implementer's and a fix-applier's report.
|
|
338
338
|
|
|
339
339
|
**Mid-run, a cache that stops running is re-derived once, then the run
|
|
340
340
|
stalls.** A claim or a review that refuses because the Recipe cache is
|
|
@@ -424,7 +424,7 @@ token, row}]}`:
|
|
|
424
424
|
A `resume` follows the Member-killed row across the run boundary: a new
|
|
425
425
|
member under a new name — `impl-<N>-b`, or one letter past the highest
|
|
426
426
|
`impl-<N>-<x>` in the archive that rotate printed the path of — on the same
|
|
427
|
-
ticket, in the printed worktree and branch, its prompt the
|
|
427
|
+
ticket, in the printed worktree and branch, its prompt the dispatch prompt
|
|
428
428
|
off a fresh read of the issue plus what it inherits (`git -C <worktree> log
|
|
429
429
|
--oneline origin/main..HEAD`, `git -C <worktree> status --short`, and the
|
|
430
430
|
files under `<scratch>/impl-<N>/`). Record it the ordinary way —
|
|
@@ -191,7 +191,7 @@ terminating in exactly one dispatch or an empty shortlist:
|
|
|
191
191
|
without a positive and a negative control misattributes causes rather than
|
|
192
192
|
merely missing defects — one such check needed a purpose-built fixture plus
|
|
193
193
|
both. A ticket no single string settles is a `could not check`: admitted,
|
|
194
|
-
annotated in the dispatch prompt (
|
|
194
|
+
annotated in the dispatch prompt (the Pull's dispatch), never quietly dropped.
|
|
195
195
|
|
|
196
196
|
**This is a consumption gate**, priced for the seat where implementer
|
|
197
197
|
divergence costs a claim, a worktree and a dispatch; at filing time every
|
|
@@ -199,7 +199,7 @@ terminating in exactly one dispatch or an empty shortlist:
|
|
|
199
199
|
`ready-for-agent`.
|
|
200
200
|
|
|
201
201
|
No sizing agent here. `sizing-a-ticket` picks the *process path*, and that is
|
|
202
|
-
|
|
202
|
+
the dispatch's call, after the ticket is claimed.
|
|
203
203
|
4. **Collision scan against open PRs and live branches** — `pull.mjs` runs it
|
|
204
204
|
before Q3 and prints one line per open PR or live worktree branch that shares
|
|
205
205
|
a path with the brief, `no overlap` when none, and `could not look: <which>`
|
|
@@ -227,14 +227,26 @@ terminating in exactly one dispatch or an empty shortlist:
|
|
|
227
227
|
7. **Route, row, then dispatch** — `~/.fleet/bin/fleet-run ticket-router.mjs route
|
|
228
228
|
--session <session> --ticket <N> --arm <A|B> --impl-row <k>[ --chain-head] --issue
|
|
229
229
|
<scratch>/impl-<N>/issue.json --guard .fleet/cost-guard.json` prints
|
|
230
|
-
`POLICY=… CELL=… DRAW=… STRATUM=… REASON=…` (
|
|
230
|
+
`POLICY=… CELL=… DRAW=… STRATUM=… REASON=…` (the router's arguments paragraph below the list
|
|
231
231
|
says what each argument is); then `ledger.mjs row <N> "impl-<N>[ · tier=<CELL>][ · route=<REASON>]"`,
|
|
232
|
-
`tier=<CELL>` exactly when `DRAW` is not `-`; then
|
|
232
|
+
`tier=<CELL>` exactly when `DRAW` is not `-`; then the dispatch at once: claim
|
|
233
233
|
what you are about to dispatch; dispatch what you have just claimed. Router
|
|
234
234
|
exit 2 → no row and no dispatch: release the claim (`release-ticket.sh`, SKILL.md's
|
|
235
235
|
Failure handling row for a claim abandoned mid-run) and emit an event, a probe that could not look — a table the router
|
|
236
236
|
refuses refuses every Pull.
|
|
237
237
|
|
|
238
|
+
**The router's arguments, and nothing past its line.** `--impl-row` is the
|
|
239
|
+
row count the Pull creates — or, while an assignment is rolling (the latest
|
|
240
|
+
row 5k and every row after it carry no `tier=`), that row's number;
|
|
241
|
+
`--chain-head` marks a ticket another open ticket sequences after, which is
|
|
242
|
+
what rolls it. `--arm` is `A` for an even ticket number and `B` for an odd
|
|
243
|
+
one; a B Pull routes exactly as an A one until the table opens arm B.
|
|
244
|
+
`--session` is this run's own session directory. The printed line is the
|
|
245
|
+
whole routing decision — never re-derive `CELL` from the table, the guard or
|
|
246
|
+
this paragraph. A missing or unreadable `.fleet/cost-guard.json` routes the
|
|
247
|
+
default cell only (`REASON=guard-missing`), burn-in included, and `REASON`
|
|
248
|
+
other than `ok` goes on the row as `route=<REASON>`, nowhere else.
|
|
249
|
+
|
|
238
250
|
**The Pull table** — every verdict a Pull can reach, and the one thing each
|
|
239
251
|
does:
|
|
240
252
|
|
|
@@ -250,7 +262,7 @@ does:
|
|
|
250
262
|
| a construct the brief names, or a brief `path:line` reference, lands in or next to a hunk of an open PR or a live branch | exclude `behind-pr:#M`, next entry |
|
|
251
263
|
| `Out of scope` sequences it after an open ticket | exclude `behind-issue:#M`, next entry |
|
|
252
264
|
| `claim-ticket.sh` exit 2 | taken, next entry |
|
|
253
|
-
| decided, live, free, claimed | row, then dispatch
|
|
265
|
+
| decided, live, free, claimed | row, then dispatch |
|
|
254
266
|
|
|
255
267
|
**The shortlist runs out → run `shortlist.mjs` once and Pull again; still
|
|
256
268
|
empty → hold the slot idle until the next refresh trigger.** Within a turn,
|
|
@@ -467,3 +479,17 @@ whatever woke you: a member finishing, a member bailing before implementing, a
|
|
|
467
479
|
merge landing. An edge-triggered loop that only Pulls on completion stalls
|
|
468
480
|
silently the moment the shortlist empties, because 0 implementers emit no
|
|
469
481
|
completion event.
|
|
482
|
+
|
|
483
|
+
## The rate counts Pulls, not members
|
|
484
|
+
|
|
485
|
+
**Count the rate against the ledger, because a Pull is the dispatch unit.** One Pull is one member, so a rate counted per Pull is a rate counted per member — one implementer in five, however the Pulls fall across the run — and the ledger, not your memory, is what still holds the count after a compaction.
|
|
486
|
+
|
|
487
|
+
## Why the exploration pairing is within-run
|
|
488
|
+
|
|
489
|
+
**Why one in five within the run, not a week of one tier then a week of the other:** tier would then be confounded with calendar date and therefore with prompt evolution, which is exactly the state the rows already on disk are in, and why they cannot answer the question they were collected for.
|
|
490
|
+
|
|
491
|
+
The raw split still favours the top tier — 3 failures in 11 `routine`/`sonnet` rows against 3 in 55 `routine`/`opus`. **Do not read that as a tier result.** Tier remains largely confounded with calendar date and therefore with prompt evolution: 8 of the 11 `sonnet` rows fall on 2026-08-13 to 08-17, before the window in which 54 of the 55 `opus` rows were run, and the dispatch prompts gained rules throughout. The confound is **weakened, not resolved.** Three `sonnet` rows now break it rather than one — a maintainer-authorized deliberate control (2026-08-20) and two more (2026-08-21) — all three run against prompts of the same vintage as the `opus` rows, and **all three passed**, which is the direction opposite the raw split. Three is still not a result. **What replaces this argument going forward is the within-run pairing above**: one implementer in five at the alternate tier makes tier orthogonal to date by construction, so the question stops depending on whichever rows history happened to leave. **Orthogonal to date, and to nothing else** — the alternate member is whichever ticket the 5th Pull draws, rolling past every ticket another open one sequences after, while the top tier absorbs all of those, so the pairing trades the calendar confound for a difficulty one that runs in a known direction. That is why the four covariates exist: condition a pair comparison on `sizing`/`profile`/`loc`/`files` before reading it as a tier result, never on the raw split.
|
|
492
|
+
|
|
493
|
+
## What minted_false_claim reads
|
|
494
|
+
|
|
495
|
+
`minted_false_claim` **discriminates and no longer reads "always yes"** — 20 of the 66 `routine` rows carry `no`, 18 at `opus` and 2 at `sonnet`. Read it as a property of the TICKET before the tier: a pure code simplification need not add prose, while a correction ticket adds prose by construction. The honest summary is unchanged and is the reason this paragraph exists: the guard fired on the criterion the maintainer chose in advance, not on a demonstration that the cheaper tier is worse.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Reviewers: the evidence behind the review-side rules
|
|
2
2
|
|
|
3
|
-
Evidence for rules SKILL.md states in
|
|
3
|
+
Evidence for rules SKILL.md states in **Dispatching the Pull's member**, **Dispatching the members a wake names** and **Reading a review result**, keyed by the rule each justifies.
|
|
4
4
|
|
|
5
5
|
## A sizing verdict is a measurement only if it post-dates the run that produced it
|
|
6
6
|
|
|
@@ -131,3 +131,7 @@ The review throws on missing `args.pr`/`args.worktree` and on a snapshot agent
|
|
|
131
131
|
that returned no tree, and a failure surfaces mid-loop, where "react, never
|
|
132
132
|
block" makes it easy to log and carry on — leaving a PR that *reads* as
|
|
133
133
|
reviewed and is not.
|
|
134
|
+
|
|
135
|
+
## The review's scratch is the scratch root, not its partition
|
|
136
|
+
|
|
137
|
+
**`scratch` is the scratch root itself, the absolute path `scratch-root.mjs` prints, never the review side's `<scratch>/pr<N>` partition:** the review creates `pr<N>/` under it, so a `pr<N>` passed in nests every run root at `pr<N>/pr<N>/`, and the review refuses a `scratch` whose last component is `pr` plus digits before dispatching anything.
|
|
@@ -10,6 +10,8 @@ one it runs in. **Own the CI waits**'s monitor paragraph points here instead of
|
|
|
10
10
|
restating any of it. The merge bot's agent body is the one place this block is
|
|
11
11
|
copied whole (see **The merge bot**); the other deliberate copy is named at the end.
|
|
12
12
|
|
|
13
|
+
A bot already looping cannot be corrected — the loop consumes the turns a correction would land in — so `agents/fleet-merge-bot.agent.md` carries **every entry in `references/shell-traps.md`'s Shell traps**, each written out in full: the rules with the measurements from that file beside them, and the bot has them before its first turn. An edit to `references/shell-traps.md` lands in that body in the same change.
|
|
14
|
+
|
|
13
15
|
**zsh word-splits an unquoted command substitution's result; it does NOT split an unquoted parameter expansion.**
|
|
14
16
|
|
|
15
17
|
**Word the rule against the first row.**
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
The full text of each row `fleet-tick.mjs` prints and what it asks of the controller. SKILL.md's **The tick's rows** carries one line for each.
|
|
4
4
|
|
|
5
5
|
- `PULL #<N> …` — one Pull per named ticket, in the order printed: phase 1's
|
|
6
|
-
read, then
|
|
6
|
+
read, then the dispatch. A ticket that fails the read is relabelled or
|
|
7
7
|
excluded (phase 1), and the next tick names the next head.
|
|
8
8
|
- `REFRESHED shortlist: <n> entries; <k> lifted` — the tick refreshed the
|
|
9
9
|
shortlist itself, and its `PULL` row already reads the result. `REFRESH
|
|
@@ -28,7 +28,7 @@ The full text of each row `fleet-tick.mjs` prints and what it asks of the contro
|
|
|
28
28
|
ahead of reviews on purpose: finishing what is started beats starting more.
|
|
29
29
|
- `DISPATCH review PR#<M> …` — a review per PR, oldest first, off your turn
|
|
30
30
|
(**The reviewer**).
|
|
31
|
-
- `DISPATCH merge-bot` — the next `merge-bot-<n>` (**The merge bot**).
|
|
31
|
+
- `DISPATCH merge-bot` — the next `merge-bot-<n>` (**The merge bot**). The `<scratch>` its brief takes is the absolute `scratch-root.mjs` output, and the bot writes only under `<scratch>/pr<N>/merge-bot-<n>/`.
|
|
32
32
|
- `DISPATCH finisher PR#<M> …` — a finisher settled `labelled`, yet the open
|
|
33
33
|
list shows PR M without `ready-to-merge`, and no `label-off=` (**Run ledger**)
|
|
34
34
|
accounts for the removal. Apply the finisher gate (**The finisher gate**: the
|
|
@@ -107,7 +107,7 @@ The full text of each row `fleet-tick.mjs` prints and what it asks of the contro
|
|
|
107
107
|
the hold stays while the check writes no verdict (its `tier-ok=`, or
|
|
108
108
|
`tier-unverifiable=` for a member settled `killed` or `released` with no
|
|
109
109
|
transcript, clears it); a mismatch is yours to clear, by dispatching the
|
|
110
|
-
replacement at the right tier
|
|
110
|
+
replacement at the right tier. Each prints its clearing step in
|
|
111
111
|
the row's detail. For a mismatch that is the replacement's name —
|
|
112
112
|
`impl-<N>-b` on a first retry, else one letter past the highest the ticket
|
|
113
113
|
has used, or that no retry letter is left. For an unchecked tier, which
|
|
@@ -115,6 +115,24 @@ The full text of each row `fleet-tick.mjs` prints and what it asks of the contro
|
|
|
115
115
|
by hand when the tick ran without `--apply` or the check wrote no verdict,
|
|
116
116
|
with a batch entry per member it names (fill in `<file>`; `<session>` too
|
|
117
117
|
when no receipt of this run records one).
|
|
118
|
+
**The batch file is a JSON array, one entry per dispatched member** — under
|
|
119
|
+
Pull, a batch of one, the member just dispatched: `{member}`.
|
|
120
|
+
`member` is the AgentId the dispatch returns (`impl-<N>`). An entry that
|
|
121
|
+
names neither `session` nor `transcript` takes the session directory phase
|
|
122
|
+
0's receipt `.fleet/phase0.json` of `--ledger`'s workspace (else the cwd's,
|
|
123
|
+
resolved as the default ledger is) records, and is exit 2 naming the receipt
|
|
124
|
+
when it records none; the check reads `<session>/<member>.jsonl`, so a
|
|
125
|
+
member with no assistant turn yet still resolves off its dispatch-time
|
|
126
|
+
record. A `session` the entry gives
|
|
127
|
+
wins over the receipt's; a caller already holding the exact transcript path
|
|
128
|
+
may give `transcript` instead. The agent type an implementer was dispatched
|
|
129
|
+
as lives only in its transcript. `resolvedModel`
|
|
130
|
+
**and** `resolvedThinkingLevel` together — the dispatch's own job record —
|
|
131
|
+
may ride beside it and are preferred for the model and level. An `impl-`
|
|
132
|
+
entry carries no `agentFile`: its definition is the row's, never the
|
|
133
|
+
caller's. `transcript`/`session` resolve relative to `--repo` (defaults to
|
|
134
|
+
the plugin's own root), and the check reads and writes the run's own ledger
|
|
135
|
+
unless `--ledger` names another.
|
|
118
136
|
- `AT CAP`, `IDLE OK` — nothing to do on that row.
|
|
119
137
|
- `MAIN-CHECKOUT-DIRTY <paths> …`, printed above the rows, with every
|
|
120
138
|
dispatching row (implementers, reviewers, merge-bot) reading
|
|
@@ -216,3 +234,14 @@ The full text of each row `fleet-tick.mjs` prints and what it asks of the contro
|
|
|
216
234
|
one that names its own member and fails its family's schema, with the first
|
|
217
235
|
violation. A review runner has no report schema and files none, so none of
|
|
218
236
|
these lines names one.
|
|
237
|
+
**The settle of an implementer's `PR#M` and of a fix-applier's
|
|
238
|
+
`applied:<head>` also checks the Check-step record** beside the report,
|
|
239
|
+
`<scratch>/reports/<member>.check.json`, which the member writes with
|
|
240
|
+
`recipe-check.mjs`: the Recipe's Check step, then the Test entrypoint it was
|
|
241
|
+
handed, run against its staged tree. The settle requires that the record
|
|
242
|
+
exists and parses, that both commands exited 0 in it, and that its tree is
|
|
243
|
+
the reported head's tree — so a message-only amend keeps it valid, and a
|
|
244
|
+
content change or a rebase does not. A head whose tree git cannot read is
|
|
245
|
+
could-not-look (exit 2), never a mismatch. The settle runs neither command,
|
|
246
|
+
and a repository whose Recipe cache is absent or refused has no gate; the
|
|
247
|
+
record is the member's own word, at the trust level of its report.
|