@feigi/fleet-ctl 3.81.2 → 3.81.4

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.81.2",
3
+ "version": "3.81.4",
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": {
@@ -446,10 +446,17 @@ export function describe(check, live = null) {
446
446
  switch (check.state) {
447
447
  case "clean":
448
448
  return null;
449
- case "dirty":
450
- // The HEAD entry is text, not a path: quoting it would blur it.
449
+ case "dirty": {
450
+ // The HEAD entry is text, not a path: quoting it would blur it, and
451
+ // ignoring cannot clear it, so only a path entry names the ignore remedy.
452
+ // An exclude hides untracked paths alone, and changedPaths reads a
453
+ // baseline entry that vanishes as changed, so the remedy is limited to
454
+ // untracked paths new since the baseline.
455
+ const hasPath = check.changed.some((p) => p !== check.headMove);
451
456
  return `MAIN-CHECKOUT-DIRTY ${check.changed.map((p) => (p === check.headMove ? p : shown(p))).join(" ")} — changed since the run's baseline${members}`
452
- + ` — dispatch held: resolve the stray paths FIRST, then re-baseline with ${RECORD_COMMAND} (it overwrites, it does not compare)`;
457
+ + ` — dispatch held: resolve the stray paths FIRST, then re-baseline with ${RECORD_COMMAND} (it overwrites, it does not compare)`
458
+ + (hasPath ? " — or, for an untracked path new since the baseline, the maintainer may instead ignore it in .git/info/exclude or the global excludes file: it clears on the next check with no re-baseline, so long as the pattern matches no path the baseline holds; ignoring never clears a tracked or staged file's change" : "");
459
+ }
453
460
  case "absent":
454
461
  return `MAIN-CHECKOUT-NO-BASELINE no baseline at ${check.baseline} — dispatch held: record it at run start with ${RECORD_COMMAND}`;
455
462
  default:
@@ -47,14 +47,25 @@ bill a second one that `rate_limit` does not report; the boundary is per route,
47
47
  so `actions/runs/<id>/jobs` is on the reported counter. Every response says
48
48
  `X-Ratelimit-Resource: core`, so only the reset epoch and the used sequence tell
49
49
  the two apart, and the unreported bucket's remaining count is readable only from
50
- the `X-Ratelimit-Remaining` header of a call that bills it. **A second pass gate
51
- therefore probes it too**: one `gh api -i` read of
50
+ the `X-Ratelimit-Remaining` header of a call that bills it. GitHub's REST
51
+ rate-limit documentation does not describe this bucket (it says `core` covers
52
+ "all non-search-related resources in the REST API"), so the gate rests on
53
+ measurement (2026-10-13 and 2026-10-19), not on documentation. **A second pass
54
+ gate therefore probes it too**: one `gh api -i` read of
52
55
  `actions/workflows?per_page=1` per tick, 1 unit of that bucket (measured
53
56
  2026-10-13: its remaining count fell by 1 per call while `rate_limit` stood
54
57
  still, and its reset epoch differed from `rate_limit`'s). A `ci-state` call
55
58
  spends 4 units of it on the common path — one `gh run list` and one `gh run view`
56
59
  cost 2 each (measured the same day) — so it is held to the same `200 + 4 × count`
57
- reserve. It has its own global latch (`hidden_out`) and its DEGRADED and
60
+ reserve. 4 is the most one call spends on this bucket for a repo with at most 100
61
+ workflows: 0 with no CI, 2 with no run on the PR's head, 4 otherwise. The
62
+ dropped-required-jobs path adds only reported-bucket calls, and the workflow-name
63
+ lookup pages 100 workflows per page, so a repo with more pays more per call. The
64
+ bucket is account-wide, not per repository: probes on three unrelated
65
+ repositories drew one countdown and one reset epoch (measured 2026-10-19), so
66
+ another run on the same token, or any `gh run` use, spends it, and its
67
+ DEGRADED line can fire with few open PRs on this repository. It has its own
68
+ global latch (`hidden_out`) and its DEGRADED and
58
69
  RECOVERED lines name it, so a pause on this bucket is not misread as the
59
70
  reported budget running low. An unreadable header is an outage here exactly as a
60
71
  non-numeric `rate_limit` read is. The probe runs only when the reported-bucket
@@ -75,6 +75,7 @@ older-version baseline and a baseline whose commit is missing from the
75
75
  repository; Phase 3's tick lines say how each is cleared.
76
76
  `main-checkout.mjs --check` prints the same answer
77
77
  without a tick.
78
+ On `MAIN-CHECKOUT-DIRTY` the maintainer may instead ignore a stray path that is untracked and new since the baseline: an entry in `.git/info/exclude` or in the global excludes file hides it from the check, and the hold clears on the next tick with no re-record. Ignoring never clears a tracked or staged file's change, which `git status` reports whatever the excludes say, nor a pattern that also matches a path the baseline holds, which then reads as changed. Ignoring is the maintainer's decision, never the controller's: the controller never writes an exclude or a `.gitignore` entry. Keep the pattern narrow, because an ignored path is invisible to this check, so a later member write that matches it is never seen.
78
79
 
79
80
  ## Run the pre-flight
80
81
 
@@ -129,6 +129,7 @@ The full text of each row `fleet-tick.mjs` prints and what it asks of the contro
129
129
  checkout and the close-out commit's round trip through a branch; **Fix the
130
130
  tooling mid-run** and the commit section of references/close-out.md say how
131
131
  each is cleared.
132
+ The maintainer may instead ignore a stray path that is untracked and new since the baseline: an entry in `.git/info/exclude` or in the global excludes file hides it from the check, and the hold clears on the next tick with no re-baseline. Ignoring never clears a tracked or staged file's change, which `git status` reports whatever the excludes say, nor a pattern that also matches a path the baseline holds, which then reads as changed. Ignoring is the maintainer's decision; the controller never writes an exclude or a `.gitignore` entry. Keep the pattern narrow, because an ignored path is invisible to this check, so a member write that matches it is never seen.
132
133
  - `MAIN-CHECKOUT-UNKNOWN …` with `HOLD (main checkout unknown)` — the tick
133
134
  could not look: a git or hash read failed (`could not look:`), or the
134
135
  baseline exists but cannot be read (`baseline unreadable:`). Never clean,