@feigi/fleet-ctl 3.23.25 → 3.23.26

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.25",
3
+ "version": "3.23.26",
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": {
@@ -18,6 +18,9 @@ for (const l of TSV.split("\n")) {
18
18
  headerLines.push(l);
19
19
  }
20
20
  const HEADER = headerLines.join("\n");
21
+ // A comment block as prose: comment markers stripped, whitespace collapsed, so
22
+ // a pinned sentence survives a re-wrap.
23
+ const flat = (s) => s.replace(/^\/\/ ?|^# ?/gm, "").replace(/\s+/g, " ");
21
24
 
22
25
  test("the header's column line matches COLUMNS exactly, in order", () => {
23
26
  // Drift here is silent and total: every awk one-liner in the header indexes
@@ -41,8 +44,9 @@ test("the header states the blank, hand-edit, and superseded-generation rules",
41
44
  // meant a pinned rule that had been moved down among the data rows still
42
45
  // satisfied the pin.
43
46
  assert.match(HEADER, /BLANK MEANS UNKNOWN/);
44
- // …and the one column where it does not. Blank `subagent_type` means the
45
- // dispatch named no agent definition — a closed category, not missing data.
47
+ // …and the one column where it does not. Blank `subagent_type` is a closed
48
+ // category, not missing data: on an omp row the transcript carried no
49
+ // `session_init` agent to read, on a claude row the dispatch was untyped.
46
50
  // Read as "unknown" it turns thousands of pre-2026-08-28 rows into evidence
47
51
  // someone believes a re-scrape could recover, which is how #1066's
48
52
  // over-count got argued for in the first place.
@@ -55,6 +59,23 @@ test("the header states the blank, hand-edit, and superseded-generation rules",
55
59
  assert.match(HEADER, /workflows\/wf_/);
56
60
  });
57
61
 
62
+ test("the blank-subagent_type wording says what blank means per harness: omp in the header and the script, claude in the header", () => {
63
+ // On omp an untyped dispatch records the generic `task`; blank is only a
64
+ // transcript with no `session_init` agent to read. Both places that restate
65
+ // the column must say so, and neither may call an omp blank an untyped
66
+ // dispatch. The claude rows are the other population — there blank IS an
67
+ // untyped dispatch — and only the header describes them, so only it is held
68
+ // to saying so.
69
+ const SRC = readFileSync(join(import.meta.dirname, "member-outcomes.mjs"), "utf8");
70
+ for (const [where, text] of [["header", flat(HEADER)], ["script", flat(SRC)]]) {
71
+ assert.match(text, /no `session_init` agent to read/, `${where}: blank's cause`);
72
+ assert.match(text, /records the generic `task`/, `${where}: untyped dispatch's record`);
73
+ assert.doesNotMatch(text, /named no (agent )?definition/, `${where}: stale wording`);
74
+ assert.doesNotMatch(text, /untyped Task call/, `${where}: stale wording`);
75
+ }
76
+ assert.match(flat(HEADER), /claude row[^.]*blank means the sidecar carried no `customAgentType`/, "header: claude's blank");
77
+ });
78
+
58
79
  test("the header's awk read-out indexes the column it names", () => {
59
80
  // Read the `$n` reference out of the header's own awk line and resolve it
60
81
  // against COLUMNS — a fact about the CODE alone (COLUMNS[4]) stays green when
@@ -88,7 +109,7 @@ test("the header points at cell-readout.mjs for a cell's comparisons and carries
88
109
  );
89
110
 
90
111
  // The definition the header states is the one the script applies.
91
- const block = HEADER.replace(/^#\s?/gm, "").replace(/\s+/g, " ");
112
+ const block = flat(HEADER);
92
113
  assert.match(block, /a comparison is one session holding an ADMISSIBLE row at X and an admissible slow-high row whose resolved \(`model`, `effort`\) differ from the X row's/);
93
114
  assert.match(block, /admissible only when its `subagent_type` is `fleet-implementer-<chosen_cell>` and its `effort` is the cell's level/);
94
115
  assert.match(block, /joined to its row here on `session`\+`agent`/);
@@ -35,8 +35,11 @@ export { normalizeModel, parseMemberName };
35
35
  //
36
36
  // `subagentType` is the record's `subagent_type` unchanged — `""` stays
37
37
  // `""` here, because unlike `effort` it does NOT mean unknown: it means the
38
- // dispatch named no agent definition, which is the reading cell-readout.mjs's
39
- // admissibility test depends on: a blank is never any cell's definition.
38
+ // transcript carried no `session_init` agent to read (no such line, or one
39
+ // without a string `agent`); an untyped dispatch is not that shape, since the
40
+ // omp reader records the generic `task` for it. That closed reading is what
41
+ // cell-readout.mjs's admissibility test depends on: a blank is never any
42
+ // cell's definition.
40
43
  //
41
44
  // A member is never torn in the sense this file historically tracked (no
42
45
  // fold-back to tear mid-turn); `false` says so plainly rather than leaving