@feigi/fleet-ctl 3.94.0 → 3.94.1
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 +5 -1
- package/agents/fleet-implementer-slow-medium.agent.md +5 -1
- package/agents/fleet-implementer-smol-high.agent.md +5 -1
- package/agents/fleet-implementer-task-high.agent.md +5 -1
- package/agents/fleet-implementer-task-max.agent.md +5 -1
- package/package.json +1 -1
- package/scripts/fleet-event.mjs +1 -0
- package/scripts/ledger.mjs +5 -0
- package/scripts/member-outcomes.mjs +2 -0
- package/scripts/pull-attribution.mjs +3 -3
- package/scripts/report-files.mjs +1 -1
- package/scripts/report-schema.mjs +28 -10
- package/skills/run-team/SKILL.md +2 -4
- package/skills/run-team/references/failure-handling.md +7 -0
|
@@ -240,6 +240,10 @@ including if the `Sizing:` line was written before the run and corrected after;
|
|
|
240
240
|
`sizing.verdict` and `sizing.signal` are that line's verdict and signal.
|
|
241
241
|
Nothing in the PR body separates a measured verdict from one typed in early;
|
|
242
242
|
that field is the only thing that does, and an unreported ordering costs the
|
|
243
|
-
covariate. A bail is `outcome` `bailed`, its cause in `bailCause
|
|
243
|
+
covariate. A bail is `outcome` `bailed`, its cause in `bailCause`: the
|
|
244
|
+
pre-code outcome, before you touch code. A block or ambiguity you find after
|
|
245
|
+
implementation began — the work cannot finish without a ruling or human hands
|
|
246
|
+
you do not have — is `outcome` `blocked` instead, with `pr`, `head` and `bailCause` `null` and
|
|
247
|
+
the reason in `bailDetail`; report it rather than ending with no report. Then send
|
|
244
248
|
the one line your brief gives, `<your name>: <outcome> <path>`, and exit. Never
|
|
245
249
|
apply `ready-to-merge`, never merge.
|
|
@@ -240,6 +240,10 @@ including if the `Sizing:` line was written before the run and corrected after;
|
|
|
240
240
|
`sizing.verdict` and `sizing.signal` are that line's verdict and signal.
|
|
241
241
|
Nothing in the PR body separates a measured verdict from one typed in early;
|
|
242
242
|
that field is the only thing that does, and an unreported ordering costs the
|
|
243
|
-
covariate. A bail is `outcome` `bailed`, its cause in `bailCause
|
|
243
|
+
covariate. A bail is `outcome` `bailed`, its cause in `bailCause`: the
|
|
244
|
+
pre-code outcome, before you touch code. A block or ambiguity you find after
|
|
245
|
+
implementation began — the work cannot finish without a ruling or human hands
|
|
246
|
+
you do not have — is `outcome` `blocked` instead, with `pr`, `head` and `bailCause` `null` and
|
|
247
|
+
the reason in `bailDetail`; report it rather than ending with no report. Then send
|
|
244
248
|
the one line your brief gives, `<your name>: <outcome> <path>`, and exit. Never
|
|
245
249
|
apply `ready-to-merge`, never merge.
|
|
@@ -240,6 +240,10 @@ including if the `Sizing:` line was written before the run and corrected after;
|
|
|
240
240
|
`sizing.verdict` and `sizing.signal` are that line's verdict and signal.
|
|
241
241
|
Nothing in the PR body separates a measured verdict from one typed in early;
|
|
242
242
|
that field is the only thing that does, and an unreported ordering costs the
|
|
243
|
-
covariate. A bail is `outcome` `bailed`, its cause in `bailCause
|
|
243
|
+
covariate. A bail is `outcome` `bailed`, its cause in `bailCause`: the
|
|
244
|
+
pre-code outcome, before you touch code. A block or ambiguity you find after
|
|
245
|
+
implementation began — the work cannot finish without a ruling or human hands
|
|
246
|
+
you do not have — is `outcome` `blocked` instead, with `pr`, `head` and `bailCause` `null` and
|
|
247
|
+
the reason in `bailDetail`; report it rather than ending with no report. Then send
|
|
244
248
|
the one line your brief gives, `<your name>: <outcome> <path>`, and exit. Never
|
|
245
249
|
apply `ready-to-merge`, never merge.
|
|
@@ -240,6 +240,10 @@ including if the `Sizing:` line was written before the run and corrected after;
|
|
|
240
240
|
`sizing.verdict` and `sizing.signal` are that line's verdict and signal.
|
|
241
241
|
Nothing in the PR body separates a measured verdict from one typed in early;
|
|
242
242
|
that field is the only thing that does, and an unreported ordering costs the
|
|
243
|
-
covariate. A bail is `outcome` `bailed`, its cause in `bailCause
|
|
243
|
+
covariate. A bail is `outcome` `bailed`, its cause in `bailCause`: the
|
|
244
|
+
pre-code outcome, before you touch code. A block or ambiguity you find after
|
|
245
|
+
implementation began — the work cannot finish without a ruling or human hands
|
|
246
|
+
you do not have — is `outcome` `blocked` instead, with `pr`, `head` and `bailCause` `null` and
|
|
247
|
+
the reason in `bailDetail`; report it rather than ending with no report. Then send
|
|
244
248
|
the one line your brief gives, `<your name>: <outcome> <path>`, and exit. Never
|
|
245
249
|
apply `ready-to-merge`, never merge.
|
|
@@ -240,6 +240,10 @@ including if the `Sizing:` line was written before the run and corrected after;
|
|
|
240
240
|
`sizing.verdict` and `sizing.signal` are that line's verdict and signal.
|
|
241
241
|
Nothing in the PR body separates a measured verdict from one typed in early;
|
|
242
242
|
that field is the only thing that does, and an unreported ordering costs the
|
|
243
|
-
covariate. A bail is `outcome` `bailed`, its cause in `bailCause
|
|
243
|
+
covariate. A bail is `outcome` `bailed`, its cause in `bailCause`: the
|
|
244
|
+
pre-code outcome, before you touch code. A block or ambiguity you find after
|
|
245
|
+
implementation began — the work cannot finish without a ruling or human hands
|
|
246
|
+
you do not have — is `outcome` `blocked` instead, with `pr`, `head` and `bailCause` `null` and
|
|
247
|
+
the reason in `bailDetail`; report it rather than ending with no report. Then send
|
|
244
248
|
the one line your brief gives, `<your name>: <outcome> <path>`, and exit. Never
|
|
245
249
|
apply `ready-to-merge`, never merge.
|
package/package.json
CHANGED
package/scripts/fleet-event.mjs
CHANGED
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
// opens with no sha, is a NEED and N is left untouched, claim and all.
|
|
51
51
|
// The PR a `covered` detail names is never written to.
|
|
52
52
|
// A `PR#M` outcome also sets the claim branch's upstream when it has none: `reap.sh` keeps a branch with no upstream, and only an upstream's `[gone]` state makes it reapable. It writes `branch.<b>.remote` and `branch.<b>.merge` only while the merge key is unset, and prints `NEED upstream <b> — <why>` when a write fails.
|
|
53
|
+
// A `blocked` outcome takes no action beyond the settle: no label, comment, release or upstream, so the ticket keeps `in-progress`.
|
|
53
54
|
// fix-report <fix-pr-M[-x]>
|
|
54
55
|
// `settle --from-report`, which records the filings and rulings the
|
|
55
56
|
// report carries. Settled `applied:`/`no-op`, on a PR whose rows carry
|
package/scripts/ledger.mjs
CHANGED
|
@@ -2508,6 +2508,9 @@ function recordFiled(id, subject) {
|
|
|
2508
2508
|
// own repository name N;
|
|
2509
2509
|
// the Check-step record (below) holds for <head>
|
|
2510
2510
|
// impl-N=bailed bailCause is not null; the receipt names it
|
|
2511
|
+
// impl-N=blocked nothing to check: report-schema.mjs already
|
|
2512
|
+
// refuses a block that names a bailCause, a pr or
|
|
2513
|
+
// a head, or gives no reason in bailDetail
|
|
2511
2514
|
// fix-pr-M=applied:<head> origin's refs/heads/<branch> is <head>, fetched
|
|
2512
2515
|
// by verify-sha.sh; the Check-step record (below)
|
|
2513
2516
|
// holds for <head>
|
|
@@ -2670,6 +2673,8 @@ async function runSettleFromReport() {
|
|
|
2670
2673
|
const { view: pr, numbers } = prViewClosing(report.pr, "state,closingIssuesReferences,url");
|
|
2671
2674
|
check(`PR #${report.pr} reads OPEN`, pr.state === "OPEN");
|
|
2672
2675
|
check(`PR #${report.pr} closes #${live.number}`, numbers.includes(live.number));
|
|
2676
|
+
} else if (report.outcome === "blocked") {
|
|
2677
|
+
outcome = "blocked";
|
|
2673
2678
|
} else {
|
|
2674
2679
|
outcome = "bailed";
|
|
2675
2680
|
check(`bailCause: ${report.bailCause}`, report.bailCause !== null);
|
|
@@ -146,6 +146,7 @@ export function withReports(rows, scratch) {
|
|
|
146
146
|
// opened one (more than one leaves the pr column blank), or
|
|
147
147
|
// the last report claims a PR an earlier same-ticket
|
|
148
148
|
// implementer opened in this session;
|
|
149
|
+
// blocked the last report blocks mid-implementation;
|
|
149
150
|
// bail:<cause> the last report bails (`fixed` is checked against main);
|
|
150
151
|
// provider a model fell back, or the last turn errored;
|
|
151
152
|
// budget a budget notice reached the member;
|
|
@@ -162,6 +163,7 @@ export function endingOf({ member, pr, signals = null, earlierPrs = new Set(), v
|
|
|
162
163
|
if (signals.openedPrs.length > 0) return "pr";
|
|
163
164
|
const last = lastReport(signals.reportWrites, member.split("/").pop());
|
|
164
165
|
if (last?.outcome === "pr" && earlierPrs.has(String(last.pr))) return "pr";
|
|
166
|
+
if (last?.outcome === "blocked") return "blocked";
|
|
165
167
|
// lastReport passed the impl schema, whose bailCause is a BAILS key or null.
|
|
166
168
|
if (last?.bailCause) return bailEnding(last, verifyMain);
|
|
167
169
|
if (signals.providerFallback || signals.lastStopReason === "error") return "provider";
|
|
@@ -38,8 +38,8 @@
|
|
|
38
38
|
// counted every other Pull: the only ones in a cell's figures.
|
|
39
39
|
//
|
|
40
40
|
// ENDINGS come from member-outcomes' `ending` column. The cell's: `hollow`,
|
|
41
|
-
// `budget`, `bail:fixed-refuted`, `unknown`. The ticket's: every
|
|
42
|
-
// `bail:<cause>`. Neither's: `provider`, `crash`, `abort`.
|
|
41
|
+
// `budget`, `bail:fixed-refuted`, `unknown`. The ticket's: `blocked` and every
|
|
42
|
+
// other `bail:<cause>`. Neither's: `provider`, `crash`, `abort`.
|
|
43
43
|
//
|
|
44
44
|
// CLAIMS. A merged Pull is one claim, false when its Ruling fails the floor
|
|
45
45
|
// (`minted_false_claim=yes` or `closed_own_ticket=no`). Each `bail:fixed` or
|
|
@@ -125,7 +125,7 @@ function datedRows(features) {
|
|
|
125
125
|
|
|
126
126
|
const CELL_ENDINGS = new Set(["hollow", "budget", "bail:fixed-refuted", "unknown"]);
|
|
127
127
|
const NEITHER_ENDINGS = new Set(["provider", "crash", "abort"]);
|
|
128
|
-
const ticketsEnding = (e) => e.startsWith("bail:") && !CELL_ENDINGS.has(e);
|
|
128
|
+
const ticketsEnding = (e) => e === "blocked" || (e.startsWith("bail:") && !CELL_ENDINGS.has(e));
|
|
129
129
|
const failsFloor = (ruling) => ruling.minted_false_claim === "yes" || ruling.closed_own_ticket === "no";
|
|
130
130
|
// An omp session id opens with its ISO start time, so two of them sort in time order.
|
|
131
131
|
const STARTED = /^\d{4}-\d{2}-\d{2}T/;
|
package/scripts/report-files.mjs
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// (flat: no per-run directory), `<member>` being its ledger name (`impl-412`,
|
|
7
7
|
// `impl-412-b`, `fix-pr-88`, `finisher-pr-88`, `merge-bot-3`). The file is
|
|
8
8
|
// checked against the schema of the member's family, report-schema.mjs's
|
|
9
|
-
// SCHEMAS, and the
|
|
9
|
+
// SCHEMAS, and the rules reportViolation() adds to them. The review runner and
|
|
10
10
|
// every member outside those four families have no schema, so no file to
|
|
11
11
|
// look up.
|
|
12
12
|
//
|
|
@@ -18,9 +18,14 @@
|
|
|
18
18
|
// 0 print: the schema is on stdout. validate: `valid` on stdout
|
|
19
19
|
// 1 validate: `invalid: <violation>` on stdout, naming the FIRST violation;
|
|
20
20
|
// a file that is not JSON is invalid too, as `$: not JSON (...)`, and so
|
|
21
|
-
// is one that repeats a key, as `$.merged: duplicate key "merged"`,
|
|
22
|
-
//
|
|
23
|
-
// `$.refused[0].pr: PR #<pr> already has a verdict at $.merged[0].pr
|
|
21
|
+
// is one that repeats a key, as `$.merged: duplicate key "merged"`, a
|
|
22
|
+
// merge-bot report giving one PR two verdicts, as
|
|
23
|
+
// `$.refused[0].pr: PR #<pr> already has a verdict at $.merged[0].pr`,
|
|
24
|
+
// and an impl report whose `blocked` outcome names a `bailCause`, as
|
|
25
|
+
// `$.bailCause: "<cause>" is not null, with outcome "blocked" — a block
|
|
26
|
+
// is no bail`, gives no reason in `bailDetail`, or names a `pr` or a
|
|
27
|
+
// `head`, as `$.pr: <pr> is not null, with outcome "blocked" — a block
|
|
28
|
+
// reports no PR`
|
|
24
29
|
// 2 usage: no or unknown subcommand, a wrong argument count, an unknown
|
|
25
30
|
// family, any flag; or <file> could not be read; or print could not
|
|
26
31
|
// write the schema to stdout. Refused on stderr, nothing on stdout
|
|
@@ -112,7 +117,9 @@ const issues = listOf({ issue: id, subject: str });
|
|
|
112
117
|
export const SCHEMAS = {
|
|
113
118
|
impl: report({
|
|
114
119
|
member: str,
|
|
115
|
-
outcome
|
|
120
|
+
// `bailed` is the pre-code outcome; `blocked` a block or ambiguity found
|
|
121
|
+
// after implementation began, its reason in `bailDetail`.
|
|
122
|
+
outcome: { type: "string", enum: ["pr", "bailed", "blocked"] },
|
|
116
123
|
pr: { ...id, type: ["integer", "null"] },
|
|
117
124
|
head: { type: ["string", "null"], pattern: HEX },
|
|
118
125
|
branch: str,
|
|
@@ -174,14 +181,25 @@ export function mergeBotVerdicts(report) {
|
|
|
174
181
|
];
|
|
175
182
|
}
|
|
176
183
|
|
|
177
|
-
// The first violation of `family`'s schema by `value`, or null;
|
|
178
|
-
//
|
|
179
|
-
//
|
|
180
|
-
//
|
|
181
|
-
//
|
|
184
|
+
// The first violation of `family`'s schema by `value`, or null; then the rules
|
|
185
|
+
// no schema keyword states. For an impl report: a `blocked` outcome names no
|
|
186
|
+
// `bailCause`, since a block is no bail, gives its reason in `bailDetail`,
|
|
187
|
+
// text that is not only whitespace, and names no `pr` or `head`, since a block
|
|
188
|
+
// reports no PR — a PR it opened is outcome `pr`, which settle checks. For a
|
|
189
|
+
// merge-bot report: each PR gets one verdict — merged, held, conflict-held or
|
|
190
|
+
// refused — the last it reached in the pass, so a PR named twice, in one list
|
|
191
|
+
// or in two, is a violation at its second entry.
|
|
182
192
|
export function reportViolation(family, value) {
|
|
183
193
|
const found = validate(SCHEMAS[family], value);
|
|
184
|
-
if (found !== null
|
|
194
|
+
if (found !== null) return found;
|
|
195
|
+
if (family === "impl" && value.outcome === "blocked") {
|
|
196
|
+
if (value.bailCause !== null) return `$.bailCause: ${show(value.bailCause)} is not null, with outcome "blocked" — a block is no bail`;
|
|
197
|
+
if (!/\S/.test(value.bailDetail ?? "")) return `$.bailDetail: ${show(value.bailDetail)} is not a reason, with outcome "blocked"`;
|
|
198
|
+
for (const field of ["pr", "head"]) {
|
|
199
|
+
if (value[field] !== null) return `$.${field}: ${show(value[field])} is not null, with outcome "blocked" — a block reports no PR`;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
if (family !== "merge-bot") return null;
|
|
185
203
|
const first = new Map();
|
|
186
204
|
for (const { pr, path } of mergeBotVerdicts(value)) {
|
|
187
205
|
if (first.has(pr)) return `${path}: PR #${pr} already has a verdict at ${first.get(pr)}`;
|
package/skills/run-team/SKILL.md
CHANGED
|
@@ -792,7 +792,7 @@ Match the failure to its row in the table below and run that response; where the
|
|
|
792
792
|
|---|---|
|
|
793
793
|
| SHA not on expected branch | Flag, do not enqueue, report |
|
|
794
794
|
| Implementer bails before implementing | Act by the report's `bailCause` as the **Relabel causes** table says, then refill (**What a wake owes beyond its call**) |
|
|
795
|
-
| Implementer blocked or ambiguous *mid-implementation* | Free the slot, `ledger.mjs settle impl-<N> blocked`,
|
|
795
|
+
| Implementer blocked or ambiguous *mid-implementation* | Free the slot. A `blocked` report settles on the **Implementer report** wake, no label moved; with no report, `ledger.mjs settle impl-<N> blocked`, its Ending still `hollow`. Leave `in-progress`, report — the ticket is not In flight and waits for a human; the row above is the pre-code bail |
|
|
796
796
|
| `review-pr` workflow throws or returns no tree | Retry once under the next letter (`review-pr-<pr#>-b`); still failing, report and leave the PR at review-due. Never enqueue the PR as reviewed — the workflow is not a member, so no other row here covers it |
|
|
797
797
|
| Reviewer, fix-applier or red-check fixer cannot reach green | Report, leave the PR unlabeled, free the slot — a fix-applier or red-check fixer settles `failed` |
|
|
798
798
|
| Merge bot hits the hold rule | Report `held-behind-#<lower>`, PR stays queued |
|
|
@@ -841,9 +841,7 @@ enqueue, do not return the ticket to the shortlist until the maintainer rules.
|
|
|
841
841
|
escalate if it repeats, and never read it as `not reachable` or record it as a
|
|
842
842
|
stray commit. See references/failure-handling.md.
|
|
843
843
|
|
|
844
|
-
**Never `--delete-branch` — the merge bot deletes the head branch itself.**
|
|
845
|
-
`gh pr merge <n> --merge` alone: the flag's local cleanup errors on a `main`
|
|
846
|
-
held by another worktree, or strands the feature worktree on `main`.
|
|
844
|
+
**Never `--delete-branch` — the merge bot deletes the head branch itself.** See references/failure-handling.md.
|
|
847
845
|
|
|
848
846
|
**Never force a rebase to start.** No `git clean`, `git checkout .`,
|
|
849
847
|
`git reset --hard`, `git stash`. Non-empty `git status --porcelain -unormal` →
|
|
@@ -66,6 +66,13 @@ escalate if it repeats. Never read exit 2 as `not reachable`, and never record i
|
|
|
66
66
|
as a stray commit — the flag and the maintainer's ruling above are what exit 1
|
|
67
67
|
earns, and spending them on a probe that never answered costs a member its
|
|
68
68
|
ticket over a failure a re-run would have cleared.
|
|
69
|
+
|
|
70
|
+
## Never `--delete-branch`
|
|
71
|
+
|
|
72
|
+
**Never `--delete-branch` — the merge bot deletes the head branch itself.**
|
|
73
|
+
`gh pr merge <n> --merge` alone: the flag's local cleanup errors on a `main`
|
|
74
|
+
held by another worktree, or strands the feature worktree on `main`.
|
|
75
|
+
|
|
69
76
|
## Never force a rebase to start
|
|
70
77
|
|
|
71
78
|
**Never force a rebase to start.** No `git clean`, `git checkout .`,
|