@feigi/fleet-ctl 3.23.12 → 3.23.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@feigi/fleet-ctl",
3
- "version": "3.23.12",
3
+ "version": "3.23.14",
4
4
  "description": "Agent fleet: run-team controller, merge bot, PR reviewer, and the ticket pipeline they share",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -48,7 +48,7 @@ import { test } from "node:test";
48
48
  import assert from "node:assert/strict";
49
49
  import { readFileSync } from "node:fs";
50
50
  import { join } from "node:path";
51
- import { between, phrase, stripHashGutter } from "./prose-pin.mjs";
51
+ import { between, paragraph, phrase, stripHashGutter } from "./prose-pin.mjs";
52
52
 
53
53
  const REPO = join(import.meta.dirname, "..");
54
54
  const REAPING = readFileSync(
@@ -141,6 +141,58 @@ test("run-team/SKILL.md: the release deletes the branch with update-ref's compar
141
141
  );
142
142
  });
143
143
 
144
+ // The reap paragraph's twin of the release pin above. reap.sh deletes a
145
+ // `[gone]` branch with `git update-ref --no-deref -d refs/heads/<b> <tip>`,
146
+ // never `-D`, and keeps a branch the cherry check cleared whenever a fresh
147
+ // worktree check finds it held — so naming `-D`, or the cherry check as the
148
+ // delete's only authorizer, is false as written.
149
+ const reapParagraph = () =>
150
+ paragraph(RUN_TEAM, "`~/.fleet/bin/fleet-run reap.sh --apply` recomputes every precondition", "run-team/SKILL.md's reap paragraph");
151
+
152
+ test("run-team/SKILL.md: reap's cherry check authorizes the update-ref delete, with the fresh worktree check beside it", () => {
153
+ const p = reapParagraph();
154
+ assert.match(
155
+ p,
156
+ phrase("`git cherry origin/main` to authorize the `git update-ref -d` delete"),
157
+ "SKILL.md's reap paragraph no longer names the cherry check as authorizing the `git update-ref -d` delete",
158
+ );
159
+ assert.match(
160
+ p,
161
+ phrase("a fresh check that no worktree holds the branch"),
162
+ "SKILL.md's reap paragraph no longer names the fresh worktree check — reap.sh keeps a branch the cherry check cleared whenever a worktree holds it",
163
+ );
164
+ assert.doesNotMatch(p, /(?:^|[\s`])(?:git\s+branch\s+)?-D\b/, "SKILL.md's reap paragraph names `-D` — reap.sh deletes with `git update-ref -d`");
165
+ assert.doesNotMatch(
166
+ p,
167
+ /\bonly\s+by\b|\bnothing\s+else\b|\bsolely\b|\balone\b/i,
168
+ "SKILL.md's reap paragraph makes one check the delete's only authorizer — reap.sh's worktree check stops that delete too",
169
+ );
170
+ });
171
+
172
+ test("run-team/SKILL.md: the reap paragraph keeps the preconditions it already named", () => {
173
+ // Input the assertions above must ACCEPT: the corrected clause sits in a
174
+ // list whose other entries stay as they were.
175
+ const p = reapParagraph();
176
+ assert.match(p, phrase("`for-each-ref` for `[gone]`"));
177
+ assert.match(p, phrase("worktree removal without `--force`"));
178
+ });
179
+
180
+ test("reap.sh: the worktree check the reap paragraph names runs before the delete", () => {
181
+ // Live lines only: both names recur in comments, and a comment hit would
182
+ // read as the code.
183
+ const lines = readFileSync(join(REPO, "scripts", "reap.sh"), "utf8")
184
+ .split("\n")
185
+ .filter((l) => !/^\s*(?:#|echo\b)/.test(l));
186
+ const only = (re, what) => {
187
+ const hits = lines.flatMap((l, i) => (re.test(l) ? [i] : []));
188
+ assert.equal(hits.length, 1, `reap.sh: expected exactly one live line that ${what}, found ${hits.length}`);
189
+ return hits[0];
190
+ };
191
+ const check = only(/^\s*if\s+wt_holding\s+"refs\/heads\/\$b"/, "runs wt_holding on the branch");
192
+ const del = only(/\bgit\s+update-ref\s+--no-deref\s+-d\s+"refs\/heads\/\$b"\s+"\$tip"/, "runs `git update-ref -d` on the branch at its tip");
193
+ assert.ok(check < del, "reap.sh runs its worktree check after the delete, not before it");
194
+ });
195
+
144
196
  test("run-team/SKILL.md: the by-hand fallback names worktree-audit.sh's no-argument contract", () => {
145
197
  // #525. The by-hand fallback for a claim `release-ticket.sh` refused sends
146
198
  // the reader to `worktree-audit.sh`, which takes NO argument and audits
@@ -3101,9 +3101,10 @@ included (phase 3, **Merge-bot pass reports done**). See references/reaping.md.
3101
3101
 
3102
3102
  `~/.fleet/bin/fleet-run reap.sh --apply` recomputes every precondition
3103
3103
  inside the same invocation as the delete — `for-each-ref` for `[gone]`, `git
3104
- cherry origin/main` to authorize `-D`, worktree removal without `--force` — and
3105
- reports reaped and kept-with-reason counts. Update the reaped tickets' ledger rows
3106
- in the same step. See references/reaping.md.
3104
+ cherry origin/main` to authorize the `git update-ref -d` delete (plus a fresh
3105
+ check that no worktree holds the branch), worktree removal without `--force` —
3106
+ and reports reaped and kept-with-reason counts. Update the reaped tickets' ledger
3107
+ rows in the same step. See references/reaping.md.
3107
3108
 
3108
3109
  **It sweeps detached worktrees too — the shape a `[gone]` walk structurally
3109
3110
  cannot see.** Bounded to `.worktrees/`, so a checkout of yours outside it is