@feigi/fleet-ctl 3.77.0 → 3.77.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@feigi/fleet-ctl",
3
- "version": "3.77.0",
3
+ "version": "3.77.1",
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": {
@@ -16,6 +16,11 @@
16
16
  // rows the next drain finds already there, so a second run changes nothing.
17
17
  // A pending file that is empty, or blank lines only, is removed with its own
18
18
  // line: an append created it and never wrote.
19
+ // The drain takes no lock by design: it assumes only the run's controller
20
+ // appends to the pending file and drains it, serially, so nothing appends
21
+ // between the read and either unlink. One controller per checkout is the
22
+ // rule, but phase 0 refuses a second one at its ledger rotation, which runs
23
+ // after its drain step, so a second controller's drain is not guarded.
19
24
  //
20
25
  // COST GUARD. `pr-cost.mjs --guard` rewrites `.fleet/cost-guard.json`, which
21
26
  // the router reads and fails closed without. It needs all three metrics TSVs;
@@ -601,6 +601,10 @@ function main() {
601
601
  issue: readJson(issuePath), sizing: readJson(F.arg("sizing")), guard: readGuard(readJson(guardPath)), table,
602
602
  });
603
603
  const pending = F.arg("pending") ?? join(dirname(guardPath), "ticket-features.pending.tsv");
604
+ // The header decision and the append are not atomic and take no lock. That is
605
+ // safe only while the run's controller is the only process that routes or
606
+ // drains on a checkout, doing both serially: one controller per checkout is
607
+ // the rule, and neither this append nor the drain checks it.
604
608
  try {
605
609
  mkdirSync(dirname(pending), { recursive: true });
606
610
  const header = statSync(pending, { throwIfNoEntry: false })?.size > 0 ? "" : `${COLUMNS.join("\t")}\n`;