@feigi/fleet-ctl 3.22.1 → 3.22.3
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
|
@@ -60,9 +60,12 @@ export function classifyRole(signals) {
|
|
|
60
60
|
// #1505: a dispatch that recorded `memory-housekeeper` books memory whatever
|
|
61
61
|
// it called the member, so the eleven rows that shared one definition across
|
|
62
62
|
// three buckets collapse to one. The NAME stays a signal beside it because a
|
|
63
|
-
//
|
|
64
|
-
//
|
|
65
|
-
// `
|
|
63
|
+
// definition that says nothing about the role is a real category here rather
|
|
64
|
+
// than a hole — an untyped dispatch records the generic `task` (the
|
|
65
|
+
// transcript's `session_init` writes it for the default agent; the field is
|
|
66
|
+
// blank only where that line itself is absent), which names no memory agent
|
|
67
|
+
// and matches none of the definition branches below — and the memory members
|
|
68
|
+
// named `memory-proxy-session-review-2-3` have nothing else to be classified on;
|
|
66
69
|
// drop it and they fall to "other", which is the same defect wearing the
|
|
67
70
|
// other shoe. `desc` is excluded on purpose: every memory-adjacent fleet
|
|
68
71
|
// member's own prompt says "memory-proxy" somewhere, so blending the prose
|
|
@@ -177,13 +177,26 @@ test("the memory exclusion reads the recorded DEFINITION, so any member name boo
|
|
|
177
177
|
assert.equal(classifyRole({ agentDefinition: "memory-proxy", memberName: "review-eval", spawnDepth: 2 }), "memory");
|
|
178
178
|
});
|
|
179
179
|
|
|
180
|
-
test("an untyped dispatch
|
|
181
|
-
// #1505's other half.
|
|
182
|
-
//
|
|
183
|
-
//
|
|
184
|
-
//
|
|
185
|
-
//
|
|
186
|
-
//
|
|
180
|
+
test("an untyped dispatch, recorded as the generic `task` or as no definition, still classifies by its NAME", () => {
|
|
181
|
+
// #1505's other half. The default agent records the literal `task` in
|
|
182
|
+
// `session_init`, and a transcript with no `session_init` line records no
|
|
183
|
+
// definition at all; neither names a memory agent or any fleet definition, so
|
|
184
|
+
// the name is the only memory signal those members have. Re-measured
|
|
185
|
+
// 2026-10-04: over the Claude Code `meta.json` sidecars under
|
|
186
|
+
// ~/.claude/projects (the reader #1505 fixed, since dropped from
|
|
187
|
+
// member-record.mjs) three members booked memory on their name alone, each
|
|
188
|
+
// with no definition recorded and none with `task`; over the omp members on
|
|
189
|
+
// disk none did, under `task` or without a definition. Dropping the name
|
|
190
|
+
// would put `memory-housekeeper` (named for its own definition, at depth 1)
|
|
191
|
+
// in the SPECIALIST bucket, which is the very defect #1505 reports.
|
|
192
|
+
assert.equal(foldOmpTranscript(JSON.stringify({ type: "session_init", agent: "task" }), "/fake/omp.jsonl").agent, "task");
|
|
193
|
+
assert.equal(foldOmpTranscript(JSON.stringify({ type: "session" }), "/fake/omp.jsonl").agent, null);
|
|
194
|
+
assert.equal(classifyRole({ agentDefinition: "task", memberName: "memory-proxy-session-review-2-3" }), "memory");
|
|
195
|
+
assert.equal(classifyRole({ agentDefinition: "task", memberName: "memory-housekeeper", spawnDepth: 1 }), "memory");
|
|
196
|
+
// `task` matches no definition branch, so with a name it is the name that
|
|
197
|
+
// decides and without one nothing does.
|
|
198
|
+
assert.equal(classifyRole({ agentDefinition: "task", memberName: "fix-pr-1380" }), "reviewer");
|
|
199
|
+
assert.equal(classifyRole({ agentDefinition: "task" }), "other");
|
|
187
200
|
assert.equal(classifyRole({ agentDefinition: "", memberName: "memory-proxy-session-review-2-3" }), "memory");
|
|
188
201
|
assert.equal(classifyRole({ agentDefinition: "", memberName: "memory-housekeeper", spawnDepth: 1 }), "memory");
|
|
189
202
|
// ...and it is still not a guess: a name carrying no memory agent falls
|
|
@@ -19,8 +19,9 @@
|
|
|
19
19
|
// alternate-tier pair from two members whose models already happened to
|
|
20
20
|
// differ, and both readers keep it because it is derived rather than
|
|
21
21
|
// authored and survives a regeneration. `""` is NOT the hole use; it means
|
|
22
|
-
// the
|
|
23
|
-
// `task`
|
|
22
|
+
// the transcript carried no `session_init` agent to read (no such line, or
|
|
23
|
+
// one without a string `agent`). An untyped `task` dispatch is not that
|
|
24
|
+
// shape: the omp reader records the generic `task` for it.
|
|
24
25
|
import { readdirSync, readFileSync, realpathSync } from "node:fs";
|
|
25
26
|
import { join, basename, relative, isAbsolute, sep } from "node:path";
|
|
26
27
|
|
package/scripts/reap.test.mjs
CHANGED
|
@@ -13,7 +13,7 @@ import assert from "node:assert/strict";
|
|
|
13
13
|
import { execFileSync, spawnSync } from "node:child_process";
|
|
14
14
|
import { chmodSync, copyFileSync, existsSync, lstatSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, realpathSync, renameSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
|
|
15
15
|
import { tmpdir } from "node:os";
|
|
16
|
-
import { join } from "node:path";
|
|
16
|
+
import { dirname, join } from "node:path";
|
|
17
17
|
import { fileURLToPath } from "node:url";
|
|
18
18
|
import { slowTransport, SSH_URL } from "./slow-transport.mjs";
|
|
19
19
|
import { writeExecStub } from "./exec-stub.mjs";
|
|
@@ -41,8 +41,14 @@ const ENV = {
|
|
|
41
41
|
GIT_CONFIG_SYSTEM: "/dev/null",
|
|
42
42
|
};
|
|
43
43
|
|
|
44
|
+
// `maintenance.auto=false` on every fixture call: fetch, commit and merge start
|
|
45
|
+
// a detached `git maintenance run --auto`, whose `worktree-prune` task can erase
|
|
46
|
+
// a deliberately faulted `gitdir` before the script under test reads the
|
|
47
|
+
// registry, leaving the test to check a consistent registry instead of the
|
|
48
|
+
// fault. Kept out of ENV, which also reaches reap.sh's own git calls and would
|
|
49
|
+
// hide a lapse in net_git's own suppression.
|
|
44
50
|
const git = (cwd, ...args) =>
|
|
45
|
-
execFileSync("git", args, { cwd, env: ENV, encoding: "utf8" }).trim();
|
|
51
|
+
execFileSync("git", ["-c", "maintenance.auto=false", ...args], { cwd, env: ENV, encoding: "utf8" }).trim();
|
|
46
52
|
|
|
47
53
|
/** worktreeNames() of `w`'s listing: never its paths, which carry TMPDIR (#2531). */
|
|
48
54
|
const listedNames = (w) => worktreeNames(git(w, "worktree", "list", "--porcelain"));
|
|
@@ -4398,3 +4404,29 @@ for (const m of SIBLING_MUTATIONS) {
|
|
|
4398
4404
|
assert.equal(branchExists(w, "feature/free"), false);
|
|
4399
4405
|
});
|
|
4400
4406
|
}
|
|
4407
|
+
|
|
4408
|
+
// The `maintenance.auto=false` the `git` helper carries (see the comment above
|
|
4409
|
+
// it) cannot be pinned by the gitdir fault fixtures: the race it prevents is
|
|
4410
|
+
// timing-dependent, so those stay green with the flag gone. What is
|
|
4411
|
+
// deterministic is the spawn itself — a commit or a fetch through the helper
|
|
4412
|
+
// must leave no `git maintenance run` in a GIT_TRACE. The trace is switched on
|
|
4413
|
+
// through ENV, the object the helper hands its child, because the helper takes
|
|
4414
|
+
// no env of its own; node:test runs a file's tests one at a time, so nothing
|
|
4415
|
+
// else spawns git while it is set. The first two assertions are the positive
|
|
4416
|
+
// control: without them a trace the child never wrote would pass the last.
|
|
4417
|
+
test("the fixture git() helper suppresses the detached auto-maintenance run", (t) => {
|
|
4418
|
+
const w = repo(t);
|
|
4419
|
+
const trace = join(dirname(w), "trace.txt");
|
|
4420
|
+
writeFileSync(trace, "");
|
|
4421
|
+
ENV.GIT_TRACE = trace;
|
|
4422
|
+
try {
|
|
4423
|
+
commit(w, "probe");
|
|
4424
|
+
git(w, "fetch", "-q", "--prune", "origin");
|
|
4425
|
+
} finally {
|
|
4426
|
+
delete ENV.GIT_TRACE;
|
|
4427
|
+
}
|
|
4428
|
+
const traced = readFileSync(trace, "utf8");
|
|
4429
|
+
assert.match(traced, /built-in: git commit/, "the trace reached the commit");
|
|
4430
|
+
assert.match(traced, /built-in: git fetch/, "the trace reached the fetch");
|
|
4431
|
+
assert.doesNotMatch(traced, /maintenance run/);
|
|
4432
|
+
});
|