pi-daddy 0.17.0 → 0.18.0

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.
Files changed (113) hide show
  1. package/CHANGELOG.md +154 -80
  2. package/README.md +54 -25
  3. package/dist/approval-prompt.d.ts +3 -1
  4. package/dist/approval-prompt.d.ts.map +1 -1
  5. package/dist/approval-prompt.js +1 -1
  6. package/dist/approval-prompt.js.map +1 -1
  7. package/dist/approval-store.d.ts.map +1 -1
  8. package/dist/approval-store.js +4 -1
  9. package/dist/approval-store.js.map +1 -1
  10. package/dist/approval.d.ts +20 -2
  11. package/dist/approval.d.ts.map +1 -1
  12. package/dist/approval.js +26 -6
  13. package/dist/approval.js.map +1 -1
  14. package/dist/chain.d.ts +6 -1
  15. package/dist/chain.d.ts.map +1 -1
  16. package/dist/chain.js +1 -1
  17. package/dist/chain.js.map +1 -1
  18. package/dist/check-runner.d.ts +61 -0
  19. package/dist/check-runner.d.ts.map +1 -0
  20. package/dist/check-runner.js +237 -0
  21. package/dist/check-runner.js.map +1 -0
  22. package/dist/correlation.d.ts +90 -0
  23. package/dist/correlation.d.ts.map +1 -0
  24. package/dist/correlation.js +183 -0
  25. package/dist/correlation.js.map +1 -0
  26. package/dist/delegate-types.d.ts +140 -0
  27. package/dist/delegate-types.d.ts.map +1 -0
  28. package/dist/delegate-types.js +8 -0
  29. package/dist/delegate-types.js.map +1 -0
  30. package/dist/delegate.d.ts +4 -128
  31. package/dist/delegate.d.ts.map +1 -1
  32. package/dist/delegate.js +68 -72
  33. package/dist/delegate.js.map +1 -1
  34. package/dist/delegation-approval.d.ts +36 -0
  35. package/dist/delegation-approval.d.ts.map +1 -0
  36. package/dist/delegation-approval.js +67 -0
  37. package/dist/delegation-approval.js.map +1 -0
  38. package/dist/git-identity.d.ts +13 -0
  39. package/dist/git-identity.d.ts.map +1 -0
  40. package/dist/git-identity.js +44 -0
  41. package/dist/git-identity.js.map +1 -0
  42. package/dist/index.d.ts +5 -1
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +5 -1
  45. package/dist/index.js.map +1 -1
  46. package/dist/lease-record.d.ts +78 -0
  47. package/dist/lease-record.d.ts.map +1 -0
  48. package/dist/lease-record.js +52 -0
  49. package/dist/lease-record.js.map +1 -0
  50. package/dist/ledger-events.d.ts +87 -0
  51. package/dist/ledger-events.d.ts.map +1 -0
  52. package/dist/ledger-events.js +45 -0
  53. package/dist/ledger-events.js.map +1 -0
  54. package/dist/ledger-report.d.ts +19 -12
  55. package/dist/ledger-report.d.ts.map +1 -1
  56. package/dist/ledger-report.js +81 -1
  57. package/dist/ledger-report.js.map +1 -1
  58. package/dist/ledger.d.ts +44 -1
  59. package/dist/ledger.d.ts.map +1 -1
  60. package/dist/ledger.js +20 -2
  61. package/dist/ledger.js.map +1 -1
  62. package/dist/refusals.d.ts +16 -0
  63. package/dist/refusals.d.ts.map +1 -0
  64. package/dist/refusals.js +51 -0
  65. package/dist/refusals.js.map +1 -0
  66. package/dist/run-child.d.ts +4 -0
  67. package/dist/run-child.d.ts.map +1 -1
  68. package/dist/run-child.js +21 -1
  69. package/dist/run-child.js.map +1 -1
  70. package/dist/run-herdr.d.ts +7 -0
  71. package/dist/run-herdr.d.ts.map +1 -1
  72. package/dist/run-herdr.js +41 -12
  73. package/dist/run-herdr.js.map +1 -1
  74. package/dist/workspace-lease.d.ts +28 -0
  75. package/dist/workspace-lease.d.ts.map +1 -0
  76. package/dist/workspace-lease.js +276 -0
  77. package/dist/workspace-lease.js.map +1 -0
  78. package/dist/workspace.d.ts +32 -0
  79. package/dist/workspace.d.ts.map +1 -0
  80. package/dist/workspace.js +79 -0
  81. package/dist/workspace.js.map +1 -0
  82. package/extensions/approval-banking.ts +66 -0
  83. package/extensions/approvals.ts +95 -7
  84. package/extensions/chain-approval-facts.ts +51 -0
  85. package/extensions/chain-ledger.ts +48 -0
  86. package/extensions/delegate-chain.ts +115 -81
  87. package/extensions/delegation.ts +81 -23
  88. package/extensions/execute-child.ts +289 -0
  89. package/extensions/fanout-outcome.ts +97 -0
  90. package/extensions/run-delegation.ts +130 -120
  91. package/extensions/session.ts +4 -0
  92. package/extensions/workspace-runtime.ts +165 -0
  93. package/package.json +17 -1
  94. package/src/approval-prompt.ts +4 -2
  95. package/src/approval-store.ts +4 -1
  96. package/src/approval.ts +47 -14
  97. package/src/chain.ts +3 -1
  98. package/src/check-runner.ts +341 -0
  99. package/src/correlation.ts +260 -0
  100. package/src/delegate-types.ts +144 -0
  101. package/src/delegate.ts +80 -179
  102. package/src/delegation-approval.ts +99 -0
  103. package/src/git-identity.ts +52 -0
  104. package/src/index.ts +50 -0
  105. package/src/lease-record.ts +119 -0
  106. package/src/ledger-events.ts +138 -0
  107. package/src/ledger-report.ts +90 -2
  108. package/src/ledger.ts +68 -3
  109. package/src/refusals.ts +66 -0
  110. package/src/run-child.ts +23 -1
  111. package/src/run-herdr.ts +41 -11
  112. package/src/workspace-lease.ts +303 -0
  113. package/src/workspace.ts +135 -0
@@ -0,0 +1,51 @@
1
+ export const REFUSAL_CODES = [
2
+ "CAPABILITY_ESCALATION",
3
+ "DEFINITION_NOT_AUTHORIZED",
4
+ "UNDECLARED_TOOLS",
5
+ "UNKNOWN_TOOL",
6
+ "GATED_UNAPPROVED",
7
+ "APPROVAL_EXPIRED",
8
+ "APPROVAL_SCOPE_MISMATCH",
9
+ "APPROVAL_FLOW_FAILED",
10
+ "DEPTH_EXCEEDED",
11
+ "FANOUT_EXCEEDED",
12
+ "EXECUTOR_UNAVAILABLE",
13
+ // Execution-phase outcomes. Without these, an external controller could distinguish a policy refusal
14
+ // from an internal error but not a lost writer lease from a user pressing stop (R-103).
15
+ "CHILD_TIMED_OUT",
16
+ "CHILD_CANCELLED",
17
+ "CHILD_EXIT_NONZERO",
18
+ // Planner refusals that previously carried a message and no code at all — including the narrowing
19
+ // violation, which is the hardest rule this package enforces (R-109).
20
+ "TASK_MISSING",
21
+ "UNKNOWN_DEFINITION",
22
+ "CEILING_PATTERNS_UNRESOLVED",
23
+ "NARROWING_VIOLATED",
24
+ "DEFINITION_UNREADABLE",
25
+ "CORRELATION_TOO_LARGE",
26
+ "CORRELATION_INVALID",
27
+ "LEDGER_WRITE_FAILED",
28
+ "FANOUT_FAILED",
29
+ "WORKSPACE_NOT_REGISTERED",
30
+ "WORKSPACE_WRITE_CONFLICT",
31
+ "WORKSPACE_LEASE_STALE",
32
+ "CHECK_NOT_CONFIGURED",
33
+ "CHECK_CONFIGURATION_INVALID",
34
+ "CHECK_IDENTITY_UNAVAILABLE",
35
+ "CHECK_IDENTITY_MISMATCH",
36
+ ];
37
+ export function refusal(code, message, details) {
38
+ return { code, message, ...(details && Object.keys(details).length > 0 ? { details: { ...details } } : {}) };
39
+ }
40
+ /** Error shape for API callers. pi-facing tools still throw, as pi requires, while retaining a stable code. */
41
+ export class GovernanceRefusal extends Error {
42
+ code;
43
+ details;
44
+ constructor(value) {
45
+ super(value.message);
46
+ this.name = "GovernanceRefusal";
47
+ this.code = value.code;
48
+ this.details = value.details;
49
+ }
50
+ }
51
+ //# sourceMappingURL=refusals.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refusals.js","sourceRoot":"","sources":["../src/refusals.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,uBAAuB;IACvB,2BAA2B;IAC3B,kBAAkB;IAClB,cAAc;IACd,kBAAkB;IAClB,kBAAkB;IAClB,yBAAyB;IACzB,sBAAsB;IACtB,gBAAgB;IAChB,iBAAiB;IACjB,sBAAsB;IACtB,qGAAqG;IACrG,wFAAwF;IACxF,iBAAiB;IACjB,iBAAiB;IACjB,oBAAoB;IACpB,kGAAkG;IAClG,sEAAsE;IACtE,cAAc;IACd,oBAAoB;IACpB,6BAA6B;IAC7B,oBAAoB;IACpB,uBAAuB;IACvB,uBAAuB;IACvB,qBAAqB;IACrB,qBAAqB;IACrB,eAAe;IACf,0BAA0B;IAC1B,0BAA0B;IAC1B,uBAAuB;IACvB,sBAAsB;IACtB,6BAA6B;IAC7B,4BAA4B;IAC5B,yBAAyB;CACjB,CAAC;AAWX,MAAM,UAAU,OAAO,CACrB,IAAiB,EACjB,OAAe,EACf,OAAsC;IAEtC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AAC/G,CAAC;AAED,+GAA+G;AAC/G,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IACjC,IAAI,CAAc;IAClB,OAAO,CAAgC;IAEhD,YAAY,KAAwB;QAClC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;QACvB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAC/B,CAAC;CACF"}
@@ -56,6 +56,8 @@ export interface ChildRunRequest {
56
56
  * governed child mid-task.
57
57
  */
58
58
  onOutput?: (chunk: string) => void;
59
+ /** Security hook called immediately after spawn, before output handling (for lease attachment). */
60
+ onSpawn?: (pid: number) => void;
59
61
  }
60
62
  export interface ChildRunResult {
61
63
  /** Exit code, or `null` when nothing was spawned or the child was killed by a signal. */
@@ -64,6 +66,8 @@ export interface ChildRunResult {
64
66
  truncated: boolean;
65
67
  timedOut: boolean;
66
68
  aborted: boolean;
69
+ /** Signal that ended the process, separate from the nullable numeric exit code. */
70
+ signal?: NodeJS.Signals | null;
67
71
  /** Set when the process could not be started at all. */
68
72
  spawnError?: string;
69
73
  }
@@ -1 +1 @@
1
- {"version":3,"file":"run-child.d.ts","sourceRoot":"","sources":["../src/run-child.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAY9D;AAED;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,4BAA4B,CAAC;AAE3D,iGAAiG;AACjG,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAK9D;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,yFAAyF;IACzF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC;AAED,MAAM,WAAW,cAAc;IAC7B,yFAAyF;IACzF,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,0FAA0F;AAC1F,eAAO,MAAM,wBAAwB,QAAc,CAAC;AACpD,kGAAkG;AAClG,eAAO,MAAM,kBAAkB,QAAiB,CAAC;AACjD,0GAA0G;AAC1G,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAE1C,wBAAgB,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAsI1E"}
1
+ {"version":3,"file":"run-child.d.ts","sourceRoot":"","sources":["../src/run-child.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAY9D;AAED;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,4BAA4B,CAAC;AAE3D,iGAAiG;AACjG,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAK9D;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,yFAAyF;IACzF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,mGAAmG;IACnG,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,cAAc;IAC7B,yFAAyF;IACzF,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,mFAAmF;IACnF,MAAM,CAAC,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;IAC/B,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,0FAA0F;AAC1F,eAAO,MAAM,wBAAwB,QAAc,CAAC;AACpD,kGAAkG;AAClG,eAAO,MAAM,kBAAkB,QAAiB,CAAC;AACjD,0GAA0G;AAC1G,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAE1C,wBAAgB,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAwJ1E"}
package/dist/run-child.js CHANGED
@@ -83,6 +83,19 @@ export function runChild(request) {
83
83
  settle({ code: null, text: "", truncated: false, timedOut: false, aborted: false, spawnError: String(error) });
84
84
  return;
85
85
  }
86
+ try {
87
+ if (child.pid !== undefined)
88
+ request.onSpawn?.(child.pid);
89
+ }
90
+ catch (error) {
91
+ const failed = { code: null, text: "", truncated: false, timedOut: false, aborted: false, spawnError: String(error) };
92
+ child.stdout?.destroy();
93
+ child.stderr?.destroy();
94
+ child.once("error", () => settle(failed));
95
+ child.once("close", () => settle(failed));
96
+ child.kill("SIGKILL");
97
+ return;
98
+ }
86
99
  // One decoder for BOTH streams is deliberate: they are already interleaved into one `text`, and two
87
100
  // decoders would each hold their own partial character, so a split byte could surface out of order.
88
101
  const decoder = new StringDecoder("utf8");
@@ -177,10 +190,17 @@ export function runChild(request) {
177
190
  done = true;
178
191
  clearTimers();
179
192
  request.signal?.removeEventListener("abort", onAbort);
193
+ child.stdout?.destroy();
194
+ child.stderr?.destroy();
180
195
  settle(result);
181
196
  };
182
197
  child.on("error", (error) => finish({ code: null, text, truncated, timedOut, aborted, spawnError: String(error) }));
183
- child.on("close", (code) => finish({ code, text, truncated, timedOut, aborted }));
198
+ // `close` waits for every inherited pipe, including one retained by a detached grandchild. Once the
199
+ // governed PID exits, allow a short drain and settle anyway so timeout/output bounds remain bounds.
200
+ child.on("exit", (code, signal) => {
201
+ timers.push(setTimeout(() => finish({ code, signal, text, truncated, timedOut, aborted }), 100));
202
+ });
203
+ child.on("close", (code, signal) => finish({ code, signal, text, truncated, timedOut, aborted }));
184
204
  });
185
205
  }
186
206
  //# sourceMappingURL=run-child.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"run-child.js","sourceRoot":"","sources":["../src/run-child.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run-child.js","sourceRoot":"","sources":["../src/run-child.ts"],"names":[],"mappings":"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"}
@@ -89,9 +89,16 @@ export interface HerdrRunRequest {
89
89
  * name a human can switch to **while the child is alive**, which is the whole point of the pane surviving.
90
90
  */
91
91
  onPane?: (paneId: string, agentName: string) => void;
92
+ /** Security hook for attaching a writer lease to the tab. Unlike display callbacks, errors fail the run. */
93
+ onTab?: (tabId: string) => void;
94
+ /** Close even a settled pane before releasing a writer lease; no post-lease prompt may remain live. */
95
+ closeOnSettle?: boolean;
92
96
  /** Poll cadence override. Exists so tests do not wait `POLL_INTERVAL_MS` per state transition. */
93
97
  pollIntervalMs?: number;
94
98
  }
99
+ export declare class HerdrWriterCloseError extends Error {
100
+ constructor(tabId: string);
101
+ }
95
102
  /** How often to retry `agent start` while a freshly created pane is still reaching its shell prompt. */
96
103
  export declare const PANE_READY_POLL_MS = 300;
97
104
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"run-herdr.d.ts","sourceRoot":"","sources":["../src/run-herdr.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGrD,OAAO,EAA2B,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAKzE;;;;;GAKG;AACH,OAAO,EAAE,KAAK,SAAS,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5D,gHAAgH;AAChH,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACxE,wGAAwG;AACxG,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD;;;;;GAKG;AACH,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,QAAQ,EAAE,SAAS,EAAE,cAAc,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEjI,MAAM,WAAW,eAAe;IAC9B,8DAA8D;IAC9D,IAAI,EAAE,MAAM,EAAE,CAAC;IACf;;;;;;OAMG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,uFAAuF;IACvF,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;;;;;;;OASG;IACH,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACvC,oFAAoF;IACpF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACrD,kGAAkG;IAClG,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAGD,wGAAwG;AACxG,eAAO,MAAM,kBAAkB,MAAM,CAAC;AAGtC;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CA2MpF"}
1
+ {"version":3,"file":"run-herdr.d.ts","sourceRoot":"","sources":["../src/run-herdr.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGrD,OAAO,EAA2B,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAKzE;;;;;GAKG;AACH,OAAO,EAAE,KAAK,SAAS,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5D,gHAAgH;AAChH,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACxE,wGAAwG;AACxG,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD;;;;;GAKG;AACH,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,QAAQ,EAAE,SAAS,EAAE,cAAc,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEjI,MAAM,WAAW,eAAe;IAC9B,8DAA8D;IAC9D,IAAI,EAAE,MAAM,EAAE,CAAC;IACf;;;;;;OAMG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,uFAAuF;IACvF,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;;;;;;;OASG;IACH,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACvC,oFAAoF;IACpF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACrD,4GAA4G;IAC5G,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,uGAAuG;IACvG,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kGAAkG;IAClG,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAGD,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,KAAK,EAAE,MAAM;CAI1B;AAED,wGAAwG;AACxG,eAAO,MAAM,kBAAkB,MAAM,CAAC;AAGtC;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CA8NpF"}
package/dist/run-herdr.js CHANGED
@@ -45,6 +45,12 @@ export { uniqueAgentName } from "./herdr-name.js";
45
45
  * of this module's surface and moving a file should not move an export.
46
46
  */
47
47
  export { DEFAULT_SNAPSHOT_LINES, POLL_INTERVAL_MS, readPane, tailLines, waitForSettled } from "./herdr-poll.js";
48
+ export class HerdrWriterCloseError extends Error {
49
+ constructor(tabId) {
50
+ super(`herdr writer tab ${tabId} could not be closed; retaining its workspace lease`);
51
+ this.name = "HerdrWriterCloseError";
52
+ }
53
+ }
48
54
  /** How often to retry `agent start` while a freshly created pane is still reaching its shell prompt. */
49
55
  export const PANE_READY_POLL_MS = 300;
50
56
  /**
@@ -114,14 +120,29 @@ export async function runHerdrPane(request) {
114
120
  // path leaked a `/tmp/grants-herdr-*` that neither sweep could reach.
115
121
  trackPane({ tab: tabId, name: agentName, promptDir, settled: true, keepTab: true });
116
122
  }
117
- if (tabId && !request.keepPane) {
123
+ if (tabId && !request.keepPane)
118
124
  trackPane({ tab: tabId, name: agentName, promptDir });
125
+ // Attach before the first post-create await. If the parent dies after this point, the independent lock
126
+ // helper closes the tab before releasing the writer lease.
127
+ if (request.onTab) {
128
+ try {
129
+ if (!tabId)
130
+ throw new Error("herdr returned no tab id for writer-lease attachment");
131
+ request.onTab(tabId);
132
+ }
133
+ catch (error) {
134
+ if (tabId && !request.keepPane) {
135
+ const closed = await exec(["tab", "close", tabId]).catch(() => undefined);
136
+ if (closed === undefined || parseReply(closed).error)
137
+ throw new HerdrWriterCloseError(tabId);
138
+ }
139
+ return { ...empty, spawnError: `workspace writer lease could not attach to herdr tab (${String(error)})` };
140
+ }
141
+ }
142
+ if (tabId && !request.keepPane) {
119
143
  // ADR-0032: panes now live until `agent_settled`, so they accumulate across one agent run — and a plain
120
144
  // blocking `delegate` spends nothing from the fan-out budget, so the count is otherwise unbounded. Trimmed
121
145
  // here rather than at settle time so the bound holds DURING a long run, not only after it.
122
- //
123
- // Whatever is closed is reported through `onOutput` rather than dropped: an operator whose pane vanished
124
- // while they were reading it deserves to know why (R-48's rule, applied to a display).
125
146
  const dropped = await trimOpenPanes(exec);
126
147
  if (dropped.length > 0 && request.onSnapshot) {
127
148
  try {
@@ -142,8 +163,13 @@ export async function runHerdrPane(request) {
142
163
  const reply = await exec(["tab", "close", tabId]).catch(() => undefined);
143
164
  // Same rule as `cleanup`: untrack only what is provably gone, so a close herdr refused stays the
144
165
  // reaper's problem rather than being dropped on the assumption that it worked.
145
- if (reply !== undefined && !parseReply(reply).error)
166
+ if (reply === undefined || parseReply(reply).error) {
167
+ if (request.closeOnSettle)
168
+ throw new HerdrWriterCloseError(tabId);
169
+ }
170
+ else {
146
171
  untrackPane(tabId);
172
+ }
147
173
  }
148
174
  // There is no agent in this pane to ask, so the staged prompt has no reader — remove it. Kept only under
149
175
  // `keepPane`, where the operator asked to inspect whatever exists.
@@ -175,18 +201,21 @@ export async function runHerdrPane(request) {
175
201
  const cleanup = async (settledCleanly) => {
176
202
  if (request.keepPane)
177
203
  return;
178
- if (settledCleanly)
204
+ if (settledCleanly && !request.closeOnSettle)
179
205
  return;
180
206
  if (!tabId)
181
207
  return;
182
208
  const reply = await exec(["tab", "close", tabId]).catch(() => undefined);
183
- // Untracked only if provably closed — R-62's rule. A close herdr refused stays the reaper's problem rather
184
- // than being dropped on the assumption that it worked.
185
- if (reply !== undefined && !parseReply(reply).error) {
186
- untrackPane(tabId);
187
- if (promptDir)
188
- await rm(promptDir, { recursive: true, force: true }).catch(() => undefined);
209
+ // Untracked only if provably closed — R-62's rule. A writer close failure must retain the lease;
210
+ // otherwise a still-promptable pane can overlap the successor admitted by a clean release.
211
+ if (reply === undefined || parseReply(reply).error) {
212
+ if (request.closeOnSettle)
213
+ throw new HerdrWriterCloseError(tabId);
214
+ return;
189
215
  }
216
+ untrackPane(tabId);
217
+ if (promptDir)
218
+ await rm(promptDir, { recursive: true, force: true }).catch(() => undefined);
190
219
  };
191
220
  // ADR-0032: the pane exists and has a name, so tell the caller NOW. A pane id that arrives with the result is
192
221
  // useless — the point is switching to a child while it is still working. Guarded because a renderer must not
@@ -1 +1 @@
1
- {"version":3,"file":"run-herdr.js","sourceRoot":"","sources":["../src/run-herdr.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAEtC,OAAO,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,SAAS,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC1G,OAAO,EAAE,WAAW,EAAE,UAAU,EAAkB,MAAM,gBAAgB,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD;;;;;GAKG;AACH,OAAO,EAAkB,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5D,gHAAgH;AAChH,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACxE,wGAAwG;AACxG,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD;;;;;GAKG;AACH,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,QAAQ,EAAE,SAAS,EAAE,cAAc,EAAmB,MAAM,iBAAiB,CAAC;AAwDjI,wGAAwG;AACxG,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAGtC;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAwB;IACzD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,WAAW,CAAC;IACzC,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,kBAAkB,CAAC;IAC1D,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,wBAAwB,CAAC;IAC1E,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;IACxC,MAAM,KAAK,GAAmB,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAE1G,oGAAoG;IACpG,sGAAsG;IACtG,2DAA2D;IAC3D,IAAI,OAAO,CAAC,MAAM,EAAE,OAAO;QAAE,OAAO,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAEhE,qGAAqG;IACrG,yGAAyG;IACzG,iGAAiG;IACjG,qFAAqF;IACrF,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACpE,OAAO;YACL,GAAG,KAAK;YACR,UAAU,EACR,mGAAmG;gBACnG,8EAA8E;SACjF,CAAC;IACJ,CAAC;IAED,0GAA0G;IAC1G,qFAAqF;IACrF,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,IAAI,MAAM,CAAC,KAAK;QAAE,OAAO,EAAE,GAAG,KAAK,EAAE,UAAU,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;IAChE,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;IACnC,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC;IAElC,MAAM,MAAM,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IAChF,IAAI,OAAO,CAAC,SAAS;QAAE,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IACrE,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC;QAAE,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC,CAAC;IAEhG,0GAA0G;IAC1G,8CAA8C;IAC9C,MAAM,SAAS,GAAG,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/C,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,6GAA6G;QAC7G,6GAA6G;QAC7G,6GAA6G;QAC7G,yEAAyE;QACzE,IAAI,SAAS;YAAE,MAAM,EAAE,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC5F,OAAO,EAAE,GAAG,KAAK,EAAE,UAAU,EAAE,4BAA4B,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;IAC/E,CAAC;IAED,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,SAAS,IAAI,EAAE,CAA0C,CAAC;IAC5F,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC;IAChC,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC;IAC9B,yGAAyG;IACzG,yGAAyG;IACzG,yGAAyG;IACzG,4FAA4F;IAC5F,IAAI,KAAK,IAAI,OAAO,CAAC,QAAQ,IAAI,SAAS,EAAE,CAAC;QAC3C,yGAAyG;QACzG,4GAA4G;QAC5G,yGAAyG;QACzG,sEAAsE;QACtE,SAAS,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IACtF,CAAC;IACD,IAAI,KAAK,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;QAC/B,SAAS,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;QACtD,wGAAwG;QACxG,2GAA2G;QAC3G,2FAA2F;QAC3F,EAAE;QACF,yGAAyG;QACzG,uFAAuF;QACvF,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;YAC7C,IAAI,CAAC;gBACH,OAAO,CAAC,UAAU,CAAC;oBACjB,mBAAmB,OAAO,CAAC,MAAM,qCAAqC,cAAc,eAAe;wBACjG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;iBACrB,CAAC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACP,kBAAkB;YACpB,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,gGAAgG;QAChG,oGAAoG;QACpG,IAAI,KAAK,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;YAC/B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;YACzE,iGAAiG;YACjG,+EAA+E;YAC/E,IAAI,KAAK,KAAK,SAAS,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,KAAK;gBAAE,WAAW,CAAC,KAAK,CAAC,CAAC;QAC1E,CAAC;QACD,yGAAyG;QACzG,mEAAmE;QACnE,IAAI,SAAS,IAAI,CAAC,OAAO,CAAC,QAAQ;YAAE,MAAM,EAAE,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QACjH,OAAO,EAAE,GAAG,KAAK,EAAE,UAAU,EAAE,sCAAsC,EAAE,CAAC;IAC1E,CAAC;IAED;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,MAAM,OAAO,GAAG,KAAK,EAAE,cAAuB,EAAE,EAAE;QAChD,IAAI,OAAO,CAAC,QAAQ;YAAE,OAAO;QAC7B,IAAI,cAAc;YAAE,OAAO;QAC3B,IAAI,CAAC,KAAK;YAAE,OAAO;QACnB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QACzE,2GAA2G;QAC3G,uDAAuD;QACvD,IAAI,KAAK,KAAK,SAAS,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;YACpD,WAAW,CAAC,KAAK,CAAC,CAAC;YACnB,IAAI,SAAS;gBAAE,MAAM,EAAE,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC9F,CAAC;IACH,CAAC,CAAC;IAEF,8GAA8G;IAC9G,6GAA6G;IAC7G,oDAAoD;IACpD,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,IAAI,CAAC;YACH,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QACpC,CAAC;QAAC,MAAM,CAAC;YACP,kBAAkB;QACpB,CAAC;IACH,CAAC;IAED,wGAAwG;IACxG,+FAA+F;IAC/F,IAAI,cAAc,GAAG,KAAK,CAAC;IAE3B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;QACnF,IAAI,OAAO,CAAC,KAAK;YAAE,OAAO,EAAE,GAAG,KAAK,EAAE,UAAU,EAAE,6BAA6B,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;QAEjG,+FAA+F;QAC/F,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAErC,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACxF,IAAI,QAAQ,CAAC,KAAK;YAAE,OAAO,EAAE,GAAG,KAAK,EAAE,UAAU,EAAE,8BAA8B,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC;QAEpG,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,IAAI,EAAE,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAC;QAC9G,IAAI,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACxC,qGAAqG;YACrG,2FAA2F;YAC3F,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC;YAChE,OAAO,EAAE,GAAG,KAAK,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC;QAC9G,CAAC;QACD,IAAI,OAAO,CAAC,UAAU;YAAE,OAAO,EAAE,GAAG,KAAK,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC;QAE5E,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC;QAC5D,wGAAwG;QACxG,oEAAoE;QACpE,0GAA0G;QAC1G,0FAA0F;QAC1F,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;YACnB,OAAO;gBACL,GAAG,KAAK;gBACR,UAAU,EACR,qDAAqD,GAAG,CAAC,UAAU,+BAA+B;oBAClG,4CAA4C,MAAM,uBAAuB;aAC5E,CAAC;QACJ,CAAC;QACD,cAAc,GAAG,IAAI,CAAC;QACtB,2GAA2G;QAC3G,oDAAoD;QACpD,IAAI,KAAK;YAAE,eAAe,CAAC,KAAK,CAAC,CAAC;QAClC,OAAO;YACL,IAAI,EAAE,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1C,uGAAuG;YACvG,uGAAuG;YACvG,qGAAqG;YACrG,IAAI,EAAE;gBACJ,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,qFAAqF,CAAC,CAAC,CAAC,EAAE;gBAC1G,GAAG,CAAC,IAAI;gBACR,OAAO,CAAC,MAAM,KAAK,SAAS;oBAC1B,CAAC,CAAC,kEAAkE,MAAM,GAAG;oBAC7E,CAAC,CAAC,EAAE;aACP,CAAC,IAAI,CAAC,EAAE,CAAC;YACV,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,QAAQ,EAAE,KAAK;YACf,OAAO,EAAE,KAAK;SACf,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,cAAc,CAAC,CAAC;IAChC,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,KAAK,UAAU,UAAU,CACvB,IAAe,EACf,IAAY,EACZ,MAAc,EACd,IAAc,EACd,QAAgB;IAEhB,SAAS,CAAC;QACR,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,IAAI,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAChH,IAAI,CAAC,KAAK,CAAC,KAAK;YAAE,OAAO,KAAK,CAAC;QAC/B,MAAM,IAAI,GAAG,wCAAwC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACxE,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,QAAQ;YAAE,OAAO,KAAK,CAAC;QAClD,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,kBAAkB,CAAC,CAAC,CAAC;IAC9D,CAAC;AACH,CAAC;AAED,SAAS,KAAK,CAAC,MAA2C;IACxD,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE,CAAkC,CAAC;IACrE,OAAO,OAAO,KAAK,CAAC,gBAAgB,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAClF,CAAC"}
1
+ {"version":3,"file":"run-herdr.js","sourceRoot":"","sources":["../src/run-herdr.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { type LeaseReleaseOutcome, type WorkspaceLease } from "./lease-record.ts";
2
+ export type { LeaseReleaseOutcome, WorkspaceLease } from "./lease-record.ts";
3
+ import type { ValidatedWorkspace, WorkspaceAccess } from "./workspace.ts";
4
+ export declare const ENV_WORKSPACE_LEASE_DIR = "PI_GRANTS_WORKSPACE_LEASE_DIR";
5
+ export declare function defaultWorkspaceLeaseDir(env?: NodeJS.ProcessEnv): string;
6
+ /**
7
+ * The ledger outcome for a release. ONE definition, exported, because two call sites had their own copies
8
+ * and the check runner's copy asserted `released` unconditionally — reproducing in the evidence path the
9
+ * exact defect this union was added to expose (R-100/R-103).
10
+ */
11
+ export declare function leaseReleaseLedgerOutcome(outcome: LeaseReleaseOutcome | "retained", reason: string): "timeout" | "released" | "released-unrecorded" | "lost" | "retained" | "uncontended";
12
+ /**
13
+ * `acquired` must mean the kernel actually excluded somebody. A read lease takes no lock (R-105), and an
14
+ * unreadable predecessor record is not proof of a crash (R-100) — so neither may be reported as one.
15
+ */
16
+ export declare function leaseAcquisitionOutcome(access: "read" | "write", recovered: boolean | "unknown"): "acquired" | "uncontended" | "recovered";
17
+ export declare function acquireWorkspaceLease(input: {
18
+ workspace: ValidatedWorkspace;
19
+ access: WorkspaceAccess;
20
+ leaseDir: string;
21
+ ownerId: string;
22
+ signal?: AbortSignal;
23
+ flockCommand?: string;
24
+ acquisitionTimeoutMs?: number;
25
+ /** Bound on the helper's `herdr tab close` retries before it releases the lock anyway (R-102). */
26
+ herdrCloseAttempts?: number;
27
+ }): Promise<WorkspaceLease>;
28
+ //# sourceMappingURL=workspace-lease.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-lease.d.ts","sourceRoot":"","sources":["../src/workspace-lease.ts"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAM7E,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAE1E,eAAO,MAAM,uBAAuB,kCAAkC,CAAC;AAEvE,wBAAgB,wBAAwB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAGrF;AAoBD;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,mBAAmB,GAAG,UAAU,EACzC,MAAM,EAAE,MAAM,GACb,SAAS,GAAG,UAAU,GAAG,qBAAqB,GAAG,MAAM,GAAG,UAAU,GAAG,aAAa,CAQtF;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,GAAG,OAAO,EACxB,SAAS,EAAE,OAAO,GAAG,SAAS,GAC7B,UAAU,GAAG,aAAa,GAAG,WAAW,CAG1C;AAED,wBAAsB,qBAAqB,CAAC,KAAK,EAAE;IACjD,SAAS,EAAE,kBAAkB,CAAC;IAC9B,MAAM,EAAE,eAAe,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,kGAAkG;IAClG,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B,GAAG,OAAO,CAAC,cAAc,CAAC,CA4N1B"}
@@ -0,0 +1,276 @@
1
+ import { createHash, randomUUID } from "node:crypto";
2
+ import { atomicMetadata, leasePaths, readMetadata, } from "./lease-record.js";
3
+ import { once } from "node:events";
4
+ import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
5
+ import { homedir } from "node:os";
6
+ import { join } from "node:path";
7
+ import { GovernanceRefusal, refusal } from "./refusals.js";
8
+ export const ENV_WORKSPACE_LEASE_DIR = "PI_GRANTS_WORKSPACE_LEASE_DIR";
9
+ export function defaultWorkspaceLeaseDir(env = process.env) {
10
+ const agentDir = env.PI_CODING_AGENT_DIR ?? join(homedir(), ".pi", "agent");
11
+ return env[ENV_WORKSPACE_LEASE_DIR] ?? join(agentDir, "pi-daddy", "workspace-leases");
12
+ }
13
+ const LEASE_READY = "PI_DADDY_LEASE_READY";
14
+ // The lock holder also owns crash cleanup for the governed child. If the parent dies, stdin closes;
15
+ // the helper signals the attached process, or closes the herdr tab, before releasing flock. A raw
16
+ // descendant deliberately detached by bash remains ADR-0012's OS-containment boundary, not a lease
17
+ // guarantee. The process branch SIGTERMs, escalates to SIGKILL at +500ms, and releases at +750ms
18
+ // WITHOUT confirming death (R-101). The herdr branch retries `tab close` a BOUNDED number of times
19
+ // and then releases anyway, leaving a marker file: an unreleasable lock strands a worktree forever
20
+ // with no in-product recovery, which is strictly worse than a recorded failure to close (R-102).
21
+ const HELPER_SOURCE = `
22
+ import { execFile } from "node:child_process";
23
+ import { writeFileSync } from "node:fs";
24
+ let clean=false, target=null, buffered="";
25
+ process.stdout.write(${JSON.stringify(`${LEASE_READY}:`)}+process.pid+"\\n");
26
+ process.stdin.setEncoding("utf8");
27
+ process.stdin.on("data",chunk=>{buffered+=chunk;for(;;){const i=buffered.indexOf("\\n");if(i<0)break;const line=buffered.slice(0,i);buffered=buffered.slice(i+1);try{const value=JSON.parse(line);if(value.release)clean=true;else if(value.process_pid)target={process_pid:value.process_pid};else if(value.herdr_tab)target={herdr_tab:value.herdr_tab};}catch{}}});
28
+ process.stdin.on("end",()=>{if(clean||!target)return process.exit(0);if(target.process_pid){try{process.kill(target.process_pid,"SIGTERM")}catch{return process.exit(0)}setTimeout(()=>{try{process.kill(target.process_pid,"SIGKILL")}catch{}},500);return setTimeout(()=>process.exit(0),750);}let left=Number(process.env.PI_DADDY_LEASE_CLOSE_ATTEMPTS||10);const giveUp=()=>{try{if(process.env.PI_DADDY_LEASE_MARKER)writeFileSync(process.env.PI_DADDY_LEASE_MARKER,JSON.stringify({reason:"herdr-close-failed",herdr_tab:target.herdr_tab})+"\\n")}catch{}process.exit(0)};const close=()=>execFile("herdr",["tab","close",target.herdr_tab],error=>{if(!error)return process.exit(0);if(--left<=0)return giveUp();setTimeout(close,1000)});close();});
29
+ process.stdin.resume();`;
30
+ /**
31
+ * The ledger outcome for a release. ONE definition, exported, because two call sites had their own copies
32
+ * and the check runner's copy asserted `released` unconditionally — reproducing in the evidence path the
33
+ * exact defect this union was added to expose (R-100/R-103).
34
+ */
35
+ export function leaseReleaseLedgerOutcome(outcome, reason) {
36
+ if (outcome === "retained")
37
+ return "retained";
38
+ if (outcome === "lost")
39
+ return "lost";
40
+ if (outcome === "released-unrecorded")
41
+ return "released-unrecorded";
42
+ if (outcome === "not-held")
43
+ return "uncontended";
44
+ // `released-superseded` is a clean handover as far as the ledger is concerned: the lock went back and the
45
+ // record is correct — it just belongs to somebody else now.
46
+ return reason === "timeout" ? "timeout" : "released";
47
+ }
48
+ /**
49
+ * `acquired` must mean the kernel actually excluded somebody. A read lease takes no lock (R-105), and an
50
+ * unreadable predecessor record is not proof of a crash (R-100) — so neither may be reported as one.
51
+ */
52
+ export function leaseAcquisitionOutcome(access, recovered) {
53
+ if (access === "read")
54
+ return "uncontended";
55
+ return recovered === true ? "recovered" : "acquired";
56
+ }
57
+ export async function acquireWorkspaceLease(input) {
58
+ if (input.access === "read") {
59
+ return {
60
+ workspace: input.workspace,
61
+ access: "read",
62
+ ownerId: input.ownerId,
63
+ recovered: false,
64
+ attachProcess: () => { },
65
+ attachHerdrTab: () => { },
66
+ markRetained: async () => { },
67
+ readCloseFailure: async () => null,
68
+ lost: new Promise(() => { }),
69
+ // No kernel lock was ever taken, so there is no handover to claim (R-105, release side).
70
+ release: async () => "not-held",
71
+ };
72
+ }
73
+ if (input.signal?.aborted) {
74
+ throw new GovernanceRefusal(refusal("WORKSPACE_WRITE_CONFLICT", `writer lease for ${input.workspace.workspaceId} was cancelled before acquisition`));
75
+ }
76
+ await mkdir(input.leaseDir, { recursive: true, mode: 0o700 });
77
+ const paths = leasePaths(input.leaseDir, input.workspace.root);
78
+ const { spawn } = await import("node:child_process");
79
+ const holder = spawn(input.flockCommand ?? "flock", [
80
+ "--exclusive", "--nonblock", "--conflict-exit-code", "73", paths.lock,
81
+ process.execPath, "--input-type=module", "-e", HELPER_SOURCE,
82
+ ], {
83
+ stdio: ["pipe", "pipe", "pipe"],
84
+ env: { ...process.env, PI_DADDY_LEASE_MARKER: paths.marker, PI_DADDY_LEASE_CLOSE_ATTEMPTS: String(input.herdrCloseAttempts ?? 10) },
85
+ // Own process group, for two reasons. It lets teardown kill `flock` AND the helper holding the lock
86
+ // file descriptor as one unit even before the helper has reported its pid (R-99), and it stops a
87
+ // stray group signal — a terminal Ctrl-C, a closed window — from releasing a live writer's lock as
88
+ // a side effect.
89
+ detached: true,
90
+ });
91
+ const timeoutMs = input.acquisitionTimeoutMs ?? 2000;
92
+ let ready = false;
93
+ let helperPid;
94
+ let stderr = "";
95
+ /**
96
+ * Kill the whole holder GROUP — one signal, no ordering. (The pid-by-pid fallback below is the
97
+ * only path that kills in sequence, and only when the group is already reaped.) `flock` does not pass `--close`, so the helper inherits
98
+ * the lock file descriptor and holds the lock in its own right — killing only `flock` leaves the
99
+ * lock HELD by an orphan, and every later acquisition then reports WORKSPACE_WRITE_CONFLICT, which
100
+ * is the one message an operator would use to conclude another agent is writing. Measured in
101
+ * `docs/probes/g35-flock-fd-inheritance` (R-99).
102
+ */
103
+ const hardKill = () => {
104
+ // The GROUP, so this works on the readiness-timeout path too — there `helperPid` is usually still
105
+ // unknown, and killing only the wrapper leaves a half-booted helper free to inherit the lock file
106
+ // descriptor and hold it forever. Fall back to individual pids if the group is already reaped.
107
+ if (holder.pid !== undefined) {
108
+ try {
109
+ process.kill(-holder.pid, "SIGKILL");
110
+ return;
111
+ }
112
+ catch { /* group gone */ }
113
+ }
114
+ if (Number.isInteger(helperPid)) {
115
+ try {
116
+ process.kill(helperPid, "SIGKILL");
117
+ }
118
+ catch { /* already gone */ }
119
+ }
120
+ holder.kill("SIGKILL");
121
+ };
122
+ holder.stderr?.on("data", (chunk) => { stderr += String(chunk); });
123
+ try {
124
+ await new Promise((resolveReady, rejectReady) => {
125
+ const timer = setTimeout(() => rejectReady(new GovernanceRefusal(refusal("WORKSPACE_LEASE_STALE", `writer lease helper did not become ready within ${timeoutMs}ms`))), timeoutMs);
126
+ const cleanup = () => {
127
+ clearTimeout(timer);
128
+ input.signal?.removeEventListener("abort", onAbort);
129
+ };
130
+ const onAbort = () => rejectReady(new GovernanceRefusal(refusal("WORKSPACE_WRITE_CONFLICT", `writer lease for ${input.workspace.workspaceId} was cancelled before acquisition`)));
131
+ input.signal?.addEventListener("abort", onAbort, { once: true });
132
+ holder.once("error", (error) => {
133
+ cleanup();
134
+ rejectReady(new GovernanceRefusal(refusal("WORKSPACE_LEASE_STALE", `workspace writer leases require a working flock command (${String(error)})`)));
135
+ });
136
+ holder.once("close", (code) => {
137
+ if (ready)
138
+ return;
139
+ cleanup();
140
+ const codeName = code === 73 ? "WORKSPACE_WRITE_CONFLICT" : "WORKSPACE_LEASE_STALE";
141
+ rejectReady(new GovernanceRefusal(refusal(codeName, code === 73
142
+ ? `workspace ${input.workspace.workspaceId} already has an active pi-daddy-governed writer`
143
+ : `workspace lease helper exited before acquisition${stderr ? ` (${stderr.trim()})` : ""}`, { workspace_id: input.workspace.workspaceId, root: input.workspace.root })));
144
+ });
145
+ holder.stdout?.on("data", (chunk) => {
146
+ const output = String(chunk);
147
+ if (!output.includes(LEASE_READY) || ready)
148
+ return;
149
+ helperPid = Number(output.match(new RegExp(`${LEASE_READY}:(\\d+)`))?.[1]);
150
+ ready = true;
151
+ cleanup();
152
+ resolveReady();
153
+ });
154
+ });
155
+ }
156
+ catch (error) {
157
+ hardKill();
158
+ throw error;
159
+ }
160
+ const previous = await readMetadata(paths.metadata);
161
+ // "malformed" is not "no prior owner": an unreadable record cannot prove a clean handover (R-100).
162
+ const recovered = previous === "malformed" ? "unknown" : previous?.state === "active";
163
+ const token = randomUUID();
164
+ const metadata = {
165
+ version: 1,
166
+ state: "active",
167
+ token,
168
+ owner_id: input.ownerId,
169
+ workspace_id: input.workspace.workspaceId,
170
+ root: input.workspace.root,
171
+ pid: Number.isInteger(helperPid) ? helperPid : (holder.pid ?? process.pid),
172
+ acquired_at: new Date().toISOString(),
173
+ };
174
+ try {
175
+ await atomicMetadata(paths.metadata, metadata);
176
+ }
177
+ catch (error) {
178
+ holder.stdin?.end();
179
+ throw new GovernanceRefusal(refusal("WORKSPACE_LEASE_STALE", `acquired the kernel writer lock but could not record its owner (${String(error)})`, { workspace_id: input.workspace.workspaceId, root: input.workspace.root }));
180
+ }
181
+ // TWO variables, deliberately. `releasing` goes up the instant release begins, because the handshake
182
+ // below closes the helper on purpose — and if `lost` could still fire during it, an intentional release
183
+ // would report itself as a lost lease. `settled` memoizes the ANSWER, so a second call cannot invent a
184
+ // clean handover. Collapsing these into one flag set at the end broke every check-runner test.
185
+ let releasing = false;
186
+ let settled;
187
+ let lose;
188
+ const lost = new Promise((resolveLost) => { lose = resolveLost; });
189
+ const lostError = () => new Error(`workspace writer lease helper exited for ${input.workspace.workspaceId}`);
190
+ holder.once("close", () => { if (!releasing)
191
+ lose(lostError()); });
192
+ if (holder.exitCode !== null || holder.signalCode !== null)
193
+ queueMicrotask(() => lose(lostError()));
194
+ const attach = (value) => {
195
+ if (releasing || holder.exitCode !== null || holder.signalCode !== null || !holder.stdin?.writable) {
196
+ throw new GovernanceRefusal(refusal("WORKSPACE_LEASE_STALE", `writer lease for ${input.workspace.workspaceId} was lost before child attachment`));
197
+ }
198
+ holder.stdin.write(`${JSON.stringify(value)}\n`);
199
+ };
200
+ return {
201
+ workspace: input.workspace,
202
+ access: "write",
203
+ ownerId: input.ownerId,
204
+ recovered,
205
+ attachProcess(pid) { attach({ process_pid: pid }); },
206
+ attachHerdrTab(tabId) { attach({ herdr_tab: tabId }); },
207
+ lost,
208
+ async markRetained(reason = "retained") {
209
+ // Deliberately does NOT touch the kernel lock or the helper: the pane may still be live. It only
210
+ // stops the record from looking like a crash.
211
+ const current = await readMetadata(paths.metadata);
212
+ if (current !== "malformed" && current?.token === token) {
213
+ await atomicMetadata(paths.metadata, {
214
+ ...metadata, state: "released", released_at: new Date().toISOString(), release_reason: `retained:${reason}`,
215
+ }).catch(() => undefined);
216
+ }
217
+ },
218
+ async readCloseFailure() {
219
+ try {
220
+ return JSON.parse(await readFile(paths.marker, "utf8"));
221
+ }
222
+ catch {
223
+ return null;
224
+ }
225
+ },
226
+ async release(reason = "completed") {
227
+ // Memoized, not a boolean. A second call used to answer "released" whatever the first returned, so a
228
+ // retry — or a `finally` after an explicit release — read a clean handover that never happened.
229
+ if (settled)
230
+ return settled;
231
+ releasing = true;
232
+ // Already gone: this owner never released anything, and saying so is the caller's business to
233
+ // record. Throwing here discarded completed work and masked the real error (R-99).
234
+ if (holder.exitCode !== null || holder.signalCode !== null)
235
+ return (settled = "lost");
236
+ // Default FALSE: "recorded" must mean this owner actually wrote its own handover. Anything else —
237
+ // an unreadable record, or a successor's token in place of ours — means the lock goes back but the
238
+ // record does not say so, and the NEXT owner will report a recovery that never happened unless the
239
+ // caller ledgers it (R-100). Only the current token may mark the handover, so a stale lease object
240
+ // can never overwrite a live successor.
241
+ // Three outcomes, because they call for three different responses: we wrote our handover; a
242
+ // successor already owns the record and we correctly left it alone; or the record is unreadable or
243
+ // unwritable and somebody has to be told.
244
+ let how = "released-unrecorded";
245
+ const current = await readMetadata(paths.metadata);
246
+ if (current !== "malformed" && current?.token === token) {
247
+ try {
248
+ await atomicMetadata(paths.metadata, {
249
+ ...metadata,
250
+ state: "released",
251
+ released_at: new Date().toISOString(),
252
+ release_reason: reason,
253
+ });
254
+ how = "released";
255
+ }
256
+ catch {
257
+ how = "released-unrecorded";
258
+ }
259
+ }
260
+ else if (current !== "malformed" && current !== null) {
261
+ // A live successor's record. Declining to overwrite it is the token guard working, not a fault.
262
+ how = "released-superseded";
263
+ }
264
+ holder.stdin?.write(`${JSON.stringify({ release: true })}\n`);
265
+ holder.stdin?.end();
266
+ if (holder.exitCode === null && holder.signalCode === null) {
267
+ await Promise.race([once(holder, "close"), new Promise((resolveWait) => setTimeout(resolveWait, 1000))]);
268
+ }
269
+ // The helper holds the lock fd in its own right, so the wrapper alone is not enough (R-99).
270
+ if (holder.exitCode === null && holder.signalCode === null)
271
+ hardKill();
272
+ return (settled = how);
273
+ },
274
+ };
275
+ }
276
+ //# sourceMappingURL=workspace-lease.js.map