@lannguyensi/harness 0.51.0 → 0.53.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 (95) hide show
  1. package/CHANGELOG.md +182 -0
  2. package/dist/cli/approve/understanding.d.ts +46 -0
  3. package/dist/cli/approve/understanding.js +50 -22
  4. package/dist/cli/approve/understanding.js.map +1 -1
  5. package/dist/cli/audit.d.ts +29 -0
  6. package/dist/cli/audit.js +130 -17
  7. package/dist/cli/audit.js.map +1 -1
  8. package/dist/cli/delegate/index.d.ts +63 -0
  9. package/dist/cli/delegate/index.js +313 -0
  10. package/dist/cli/delegate/index.js.map +1 -0
  11. package/dist/cli/doctor/auto-approve-mode.d.ts +37 -0
  12. package/dist/cli/doctor/auto-approve-mode.js +80 -0
  13. package/dist/cli/doctor/auto-approve-mode.js.map +1 -0
  14. package/dist/cli/doctor/bypass-without-auto-approve.d.ts +38 -0
  15. package/dist/cli/doctor/bypass-without-auto-approve.js +89 -0
  16. package/dist/cli/doctor/bypass-without-auto-approve.js.map +1 -0
  17. package/dist/cli/doctor/codex-config-drift.d.ts +28 -0
  18. package/dist/cli/doctor/codex-config-drift.js +240 -0
  19. package/dist/cli/doctor/codex-config-drift.js.map +1 -0
  20. package/dist/cli/doctor/format.js +39 -1
  21. package/dist/cli/doctor/format.js.map +1 -1
  22. package/dist/cli/doctor/index.js +68 -7
  23. package/dist/cli/doctor/index.js.map +1 -1
  24. package/dist/cli/doctor/settings-drift.d.ts +6 -0
  25. package/dist/cli/doctor/settings-drift.js +20 -6
  26. package/dist/cli/doctor/settings-drift.js.map +1 -1
  27. package/dist/cli/doctor/types.d.ts +54 -0
  28. package/dist/cli/doctor/types.js.map +1 -1
  29. package/dist/cli/doctor/ug-auto-approvals.js +18 -43
  30. package/dist/cli/doctor/ug-auto-approvals.js.map +1 -1
  31. package/dist/cli/doctor/ug-delegations.d.ts +26 -0
  32. package/dist/cli/doctor/ug-delegations.js +112 -0
  33. package/dist/cli/doctor/ug-delegations.js.map +1 -0
  34. package/dist/cli/doctor/understanding-mode-env.d.ts +2 -0
  35. package/dist/cli/doctor/understanding-mode-env.js +5 -2
  36. package/dist/cli/doctor/understanding-mode-env.js.map +1 -1
  37. package/dist/cli/gc/index.d.ts +13 -2
  38. package/dist/cli/gc/index.js +203 -1
  39. package/dist/cli/gc/index.js.map +1 -1
  40. package/dist/cli/index.js +133 -7
  41. package/dist/cli/index.js.map +1 -1
  42. package/dist/cli/init/composer.js +9 -0
  43. package/dist/cli/init/composer.js.map +1 -1
  44. package/dist/cli/init/profiles.d.ts +2 -2
  45. package/dist/cli/init/profiles.js +11 -0
  46. package/dist/cli/init/profiles.js.map +1 -1
  47. package/dist/cli/init/templates.d.ts +1 -1
  48. package/dist/cli/init/templates.js +11 -0
  49. package/dist/cli/init/templates.js.map +1 -1
  50. package/dist/cli/pack/approve-escape.js +16 -7
  51. package/dist/cli/pack/approve-escape.js.map +1 -1
  52. package/dist/cli/pack/auto-approve-path.d.ts +17 -0
  53. package/dist/cli/pack/auto-approve-path.js +56 -3
  54. package/dist/cli/pack/auto-approve-path.js.map +1 -1
  55. package/dist/cli/pack/hook-pre-tool-use.d.ts +25 -0
  56. package/dist/cli/pack/hook-pre-tool-use.js +335 -3
  57. package/dist/cli/pack/hook-pre-tool-use.js.map +1 -1
  58. package/dist/cli/pack/index.d.ts +1 -0
  59. package/dist/cli/pack/index.js +1 -0
  60. package/dist/cli/pack/index.js.map +1 -1
  61. package/dist/cli/pack/transcript-report-scan.d.ts +71 -0
  62. package/dist/cli/pack/transcript-report-scan.js +359 -0
  63. package/dist/cli/pack/transcript-report-scan.js.map +1 -0
  64. package/dist/cli/pack/upgrade.d.ts +32 -0
  65. package/dist/cli/pack/upgrade.js +273 -0
  66. package/dist/cli/pack/upgrade.js.map +1 -0
  67. package/dist/cli/smoke/index.d.ts +18 -1
  68. package/dist/cli/smoke/index.js +54 -0
  69. package/dist/cli/smoke/index.js.map +1 -1
  70. package/dist/io/read-json-dir-entries.d.ts +36 -0
  71. package/dist/io/read-json-dir-entries.js +38 -0
  72. package/dist/io/read-json-dir-entries.js.map +1 -0
  73. package/dist/policy-packs/builtin/understanding-before-execution/auto-approve-default.d.ts +35 -0
  74. package/dist/policy-packs/builtin/understanding-before-execution/auto-approve-default.js +86 -0
  75. package/dist/policy-packs/builtin/understanding-before-execution/auto-approve-default.js.map +1 -0
  76. package/dist/policy-packs/builtin/understanding-before-execution/auto-approve.d.ts +76 -2
  77. package/dist/policy-packs/builtin/understanding-before-execution/auto-approve.js +139 -2
  78. package/dist/policy-packs/builtin/understanding-before-execution/auto-approve.js.map +1 -1
  79. package/dist/policy-packs/builtin/understanding-before-execution/delegation-markers.d.ts +237 -0
  80. package/dist/policy-packs/builtin/understanding-before-execution/delegation-markers.js +647 -0
  81. package/dist/policy-packs/builtin/understanding-before-execution/delegation-markers.js.map +1 -0
  82. package/dist/policy-packs/builtin/understanding-before-execution/index.d.ts +4 -1
  83. package/dist/policy-packs/builtin/understanding-before-execution/index.js +26 -1
  84. package/dist/policy-packs/builtin/understanding-before-execution/index.js.map +1 -1
  85. package/dist/policy-packs/builtin/understanding-before-execution/permission-mode-observations.d.ts +71 -0
  86. package/dist/policy-packs/builtin/understanding-before-execution/permission-mode-observations.js +169 -0
  87. package/dist/policy-packs/builtin/understanding-before-execution/permission-mode-observations.js.map +1 -0
  88. package/dist/policy-packs/builtin/understanding-before-execution.d.ts +19 -0
  89. package/dist/policy-packs/builtin/understanding-before-execution.js +29 -0
  90. package/dist/policy-packs/builtin/understanding-before-execution.js.map +1 -1
  91. package/dist/runtime/approval-signing.js +28 -0
  92. package/dist/runtime/approval-signing.js.map +1 -1
  93. package/dist/runtime/git-context.js +7 -1
  94. package/dist/runtime/git-context.js.map +1 -1
  95. package/package.json +1 -1
@@ -0,0 +1,647 @@
1
+ // Signed DELEGATION markers for `claude -p` child sessions: slice 3 of
2
+ // docs/decisions/2026-08-27-ug-auto-mode-approval.md ("Delegation marker
3
+ // shape", "TTL, cwd, and subagents", "Audit and doctor").
4
+ //
5
+ // A delegation is a PRE-AUTHORIZATION, not an approval. It is key one of
6
+ // the ADR's two-key design: the parent, already approved, hands the child
7
+ // session a signed artifact that supplies the trusted signal and the
8
+ // parent linkage. Key two (the child's own Understanding Report) is
9
+ // checked elsewhere; nothing in this module ever opens a gate on its own.
10
+ //
11
+ // WHY ITS OWN DIRECTORY AND ITS OWN VERIFIER. The file lives at
12
+ // `<generatedDir>/.delegations/<child-sid>`, never in `.approvals/`:
13
+ // keeping pre-authorizations out of the approvals directory keeps every
14
+ // existing marker scan and the doctor `approvedBy`-prefix listing free of
15
+ // artifacts that never opened a gate. `checkApprovalMarker` cannot consume
16
+ // a delegation anyway: the signature is computed over the markerId
17
+ // `delegation-<child-sid>`, so a delegation copied onto `.approvals/<sid>`
18
+ // fails that reader's signature check exactly like a forgery, and an
19
+ // approval marker copied into `.delegations/` fails this module's check
20
+ // for the mirror-image reason. Both directions are pinned by
21
+ // tests/policy-packs/understanding-before-execution-delegation.test.ts.
22
+ //
23
+ // WHY EVERY BINDING TRAVELS INSIDE `approvedBy`. The signing primitive
24
+ // signs exactly the tuple (markerId, approvedAt, approvedBy,
25
+ // reportContentHash) (src/runtime/approval-signing.ts), and adding a
26
+ // signed field would change `canonicalPayload`, which under that module's
27
+ // strict no-migration precedent means a `SIGNING_ALG` bump and forced
28
+ // re-approval on every install. So the delegation packs parent, cwd, task
29
+ // and expiry into `approvedBy`, the one free-text field inside the signed
30
+ // tuple:
31
+ //
32
+ // delegated:<parent-sid>;cwd=<sha256|->;task=<id|->;expires=<iso>[;report=<sha256>]
33
+ //
34
+ // All of it is therefore tamper-evident with no schema change. The cwd is
35
+ // hashed rather than written literally so the file carries no machine
36
+ // path. `approvedAt` records ISSUE time only, never the expiry:
37
+ // `verifyMarkerSignature` rejects a marker with a missing/empty
38
+ // `approvedAt` before it computes any HMAC, so the field must be there,
39
+ // and the marker readers keep no `expiresAt` field for anything to
40
+ // enforce, which is exactly why the lifetime rides in the `expires`
41
+ // segment above and why this module ships its own verifier.
42
+ //
43
+ // FAIL CLOSED THROUGHOUT. Every refusal in `verifyDelegation` carries a
44
+ // distinct reason; no branch turns a missing, malformed, unparseable or
45
+ // unbound delegation into an `ok` result. `parseDelegationApprovedBy`
46
+ // never fills in a default for an absent segment: a delegation whose
47
+ // bindings cannot be read in full is not a delegation.
48
+ import * as fs from "node:fs";
49
+ import * as path from "node:path";
50
+ import { atomicWriteFile } from "../../../io/atomic-write.js";
51
+ import { readRegularFileRejectingSymlink } from "../../../io/read-regular-file.js";
52
+ import { safeJsonParse } from "../../../io/safe-json-parse.js";
53
+ import { sha256Hex, signMarker, signingKeyExists, signingKeyPathFor, verifyMarkerSignature, } from "../../../runtime/approval-signing.js";
54
+ import { rejectMalformedSessionId } from "../../../runtime/reject-malformed-session-id.js";
55
+ /** Directory holding delegation markers, a sibling of `.approvals/` under `generatedDir`. */
56
+ export const DELEGATION_MARKER_DIRNAME = ".delegations";
57
+ /**
58
+ * Directory holding the per-child ADOPTED-ENTRY ledgers (once-per-session
59
+ * transcript-capture bookkeeping written by the PreToolUse hook,
60
+ * `hook-pre-tool-use.ts`), a SIBLING of `.delegations/` itself rather than
61
+ * a subdirectory of it: `<generatedDir>/.delegation-adoptions/<sid>`.
62
+ *
63
+ * Defined here (not in `hook-pre-tool-use.ts`, the only writer) so that a
64
+ * reader that never writes a ledger, such as `harness gc`'s delegation
65
+ * sweep, can name the directory without importing a `cli/` module: this
66
+ * file already owns `DELEGATION_MARKER_DIRNAME`, the sibling constant an
67
+ * adoption-ledger reader also needs, and both dirnames traveling together
68
+ * keeps `.delegations/` and its ledger sibling from drifting apart.
69
+ */
70
+ export const ADOPTION_LEDGER_DIRNAME = ".delegation-adoptions";
71
+ /** Prefix of the signed markerId, mirroring `task-<id>` for task markers. */
72
+ const DELEGATION_MARKER_ID_PREFIX = "delegation-";
73
+ /** The `approvedBy` segment carrying the parent linkage. Colon-separated, unlike the `key=value` segments after it. */
74
+ const DELEGATED_SEGMENT_PREFIX = "delegated:";
75
+ /** Literal written for a binding the delegation deliberately leaves open (`cwd=-`, `task=-`). */
76
+ const UNBOUND = "-";
77
+ const SHA256_HEX = /^[0-9a-f]{64}$/;
78
+ // Control characters (including NUL and DEL) are rejected from the parent
79
+ // linkage in both directions: the writer refuses to encode one and the
80
+ // reader refuses to accept one it finds, mirroring `;`/`=`.
81
+ const CONTROL_CHARS = /[\x00-\x1f\x7f]/;
82
+ // Deliberately narrower than `Date.parse`, which accepts plenty of
83
+ // non-ISO input ("March 3 2026") and, worse, timezone-less strings whose
84
+ // meaning depends on the reader's local zone. An expiry must mean the
85
+ // same instant in the parent's process and in the child's.
86
+ const ISO_INSTANT = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,9})?(?:Z|[+-]\d{2}:\d{2})$/;
87
+ /**
88
+ * The signed markerId for a child session: `delegation-<child-sid>`.
89
+ * Binding it into the signed payload is what stops a validly signed
90
+ * delegation from being copied onto another child id, or onto a session
91
+ * marker's id, and still verifying (`task-markers.ts` precedent).
92
+ */
93
+ export function delegationMarkerIdFor(childSessionId) {
94
+ return `${DELEGATION_MARKER_ID_PREFIX}${childSessionId}`;
95
+ }
96
+ /**
97
+ * Filesystem path of a child session's delegation marker. Rejects a
98
+ * malformed session id the same way `approvalMarkerPathFor` does (the
99
+ * value lands in a `path.join` verbatim).
100
+ */
101
+ export function delegationMarkerPathFor(generatedDir, childSessionId) {
102
+ rejectMalformedSessionId(childSessionId);
103
+ return path.join(generatedDir, DELEGATION_MARKER_DIRNAME, childSessionId);
104
+ }
105
+ /**
106
+ * sha256 hex of a filesystem path, canonicalized through `realpathSync`
107
+ * when the path exists and through `path.resolve` when it does not.
108
+ *
109
+ * The canonicalization is the point, not an optimization: the parent
110
+ * writing the delegation and the child reporting its cwd routinely spell
111
+ * the same directory differently (on macOS `os.tmpdir()` hands out
112
+ * `/var/folders/...` while the process reports `/private/var/folders/...`,
113
+ * because `/var` is a symlink), and an uncanonicalized comparison would
114
+ * refuse a perfectly legitimate delegation. Falling back to `resolve` for
115
+ * a non-existent path keeps the function total: a path that cannot be
116
+ * canonicalized still hashes deterministically, and a delegation bound to
117
+ * it simply will not match a cwd that resolves elsewhere.
118
+ *
119
+ * Named for its primary use; the fallback shape hashes the launcher-
120
+ * supplied report file's PATH with the same function, so that WHERE the
121
+ * parent put the report is part of what was signed.
122
+ */
123
+ export function hashDelegationCwd(targetPath) {
124
+ let canonical;
125
+ try {
126
+ canonical = fs.realpathSync(targetPath);
127
+ }
128
+ catch {
129
+ canonical = path.resolve(targetPath);
130
+ }
131
+ return sha256Hex(canonical);
132
+ }
133
+ function rejectUnsafeSegmentValue(field, value) {
134
+ if (value.length === 0) {
135
+ throw new Error(`${field} is empty`);
136
+ }
137
+ if (value.includes(";") || value.includes("=")) {
138
+ throw new Error(`${field} contains a delegation-segment delimiter (";" or "="): ${JSON.stringify(value)}`);
139
+ }
140
+ }
141
+ function rejectNonSha256(field, value) {
142
+ if (!SHA256_HEX.test(value)) {
143
+ throw new Error(`${field} is not a sha256 hex digest: ${JSON.stringify(value)}`);
144
+ }
145
+ }
146
+ function rejectNonIsoInstant(field, value) {
147
+ if (!ISO_INSTANT.test(value) || !Number.isFinite(Date.parse(value))) {
148
+ throw new Error(`${field} is not an ISO-8601 instant: ${JSON.stringify(value)}`);
149
+ }
150
+ }
151
+ /**
152
+ * Build the `approvedBy` string a delegation signs:
153
+ * `delegated:<parent>;cwd=<sha256|->;task=<id|->;expires=<iso>` plus
154
+ * `;report=<sha256>` in the fallback shape.
155
+ *
156
+ * Throws on any input that would corrupt the encoding (an empty value, a
157
+ * value carrying a `;` or `=` delimiter or a control character, a
158
+ * malformed parent session id (`rejectMalformedSessionId`), a cwd/report
159
+ * hash that is not a sha256 digest, a non-ISO expiry, or the literal `-`
160
+ * as a task id, which would round-trip as "no task bound"). A silently
161
+ * mis-encoded delegation would be signed and then read back with
162
+ * different bindings than the caller intended, so this fails loudly at
163
+ * the only place that can still tell the difference.
164
+ */
165
+ export function buildDelegationApprovedBy(fields) {
166
+ const { parentSessionId, cwdHash, taskId, expiresAt, reportPathHash } = fields;
167
+ // Same shape check the CHILD session id already gets in
168
+ // `delegationMarkerPathFor`: the parent id never reaches a `path.join`
169
+ // here, but it is still a session id, and a value carrying `/`, `\`, or
170
+ // `..` has no business inside a signed audit field either.
171
+ rejectMalformedSessionId(parentSessionId);
172
+ rejectUnsafeSegmentValue("parentSessionId", parentSessionId);
173
+ if (CONTROL_CHARS.test(parentSessionId)) {
174
+ throw new Error(`parentSessionId contains a control character: ${JSON.stringify(parentSessionId)}`);
175
+ }
176
+ if (cwdHash !== null)
177
+ rejectNonSha256("cwdHash", cwdHash);
178
+ if (taskId !== null) {
179
+ rejectUnsafeSegmentValue("taskId", taskId);
180
+ if (taskId === UNBOUND) {
181
+ throw new Error(`taskId is the reserved unbound literal ${JSON.stringify(UNBOUND)}`);
182
+ }
183
+ }
184
+ rejectNonIsoInstant("expiresAt", expiresAt);
185
+ if (reportPathHash !== undefined)
186
+ rejectNonSha256("reportPathHash", reportPathHash);
187
+ const segments = [
188
+ `${DELEGATED_SEGMENT_PREFIX}${parentSessionId}`,
189
+ `cwd=${cwdHash ?? UNBOUND}`,
190
+ `task=${taskId ?? UNBOUND}`,
191
+ `expires=${expiresAt}`,
192
+ ];
193
+ if (reportPathHash !== undefined) {
194
+ segments.push(`report=${reportPathHash}`);
195
+ }
196
+ return segments.join(";");
197
+ }
198
+ /**
199
+ * Strict inverse of {@link buildDelegationApprovedBy}. All four of
200
+ * `delegated`, `cwd`, `task` and `expires` are required and `report` is
201
+ * optional; a missing, duplicated, unknown, empty or malformed segment is
202
+ * an error RESULT, never a default. Segment order is not enforced (the
203
+ * signature already pins the exact bytes), but every other deviation is
204
+ * refused: this string is the only place a delegation's bindings live, so
205
+ * "read it partially and assume the rest" is the one failure mode that
206
+ * would quietly widen a delegation past what the parent signed.
207
+ */
208
+ export function parseDelegationApprovedBy(approvedBy) {
209
+ if (typeof approvedBy !== "string" || approvedBy.length === 0) {
210
+ return {
211
+ ok: false,
212
+ reason: `approvedBy is not a non-empty string (got ${typeof approvedBy})`,
213
+ };
214
+ }
215
+ let parentSessionId;
216
+ let cwdRaw;
217
+ let taskRaw;
218
+ let expiresRaw;
219
+ let reportRaw;
220
+ for (const segment of approvedBy.split(";")) {
221
+ if (segment.startsWith(DELEGATED_SEGMENT_PREFIX)) {
222
+ if (parentSessionId !== undefined) {
223
+ return { ok: false, reason: `duplicate "delegated" segment` };
224
+ }
225
+ const value = segment.slice(DELEGATED_SEGMENT_PREFIX.length);
226
+ if (value.length === 0) {
227
+ return { ok: false, reason: `empty value for segment "delegated"` };
228
+ }
229
+ // Mirror of the writer's checks (`buildDelegationApprovedBy`): the
230
+ // reader must never accept a parent linkage the writer could not
231
+ // have produced. `;` cannot survive the `split(";")` above without
232
+ // becoming a second, unrecognized segment, but `=` and control
233
+ // characters can, so they are checked explicitly here.
234
+ if (value.includes("=") || CONTROL_CHARS.test(value)) {
235
+ return {
236
+ ok: false,
237
+ reason: `"delegated" value contains "=" or a control character: ${JSON.stringify(value)}`,
238
+ };
239
+ }
240
+ try {
241
+ rejectMalformedSessionId(value);
242
+ }
243
+ catch (err) {
244
+ return {
245
+ ok: false,
246
+ reason: `"delegated" value is not a well-formed session id: ${err instanceof Error ? err.message : String(err)}`,
247
+ };
248
+ }
249
+ parentSessionId = value;
250
+ continue;
251
+ }
252
+ const eq = segment.indexOf("=");
253
+ if (eq <= 0) {
254
+ return { ok: false, reason: `unrecognized delegation segment ${JSON.stringify(segment)}` };
255
+ }
256
+ const key = segment.slice(0, eq);
257
+ const value = segment.slice(eq + 1);
258
+ if (value.length === 0) {
259
+ return { ok: false, reason: `empty value for segment ${JSON.stringify(key)}` };
260
+ }
261
+ switch (key) {
262
+ case "cwd":
263
+ if (cwdRaw !== undefined)
264
+ return { ok: false, reason: `duplicate "cwd" segment` };
265
+ cwdRaw = value;
266
+ break;
267
+ case "task":
268
+ if (taskRaw !== undefined)
269
+ return { ok: false, reason: `duplicate "task" segment` };
270
+ taskRaw = value;
271
+ break;
272
+ case "expires":
273
+ if (expiresRaw !== undefined)
274
+ return { ok: false, reason: `duplicate "expires" segment` };
275
+ expiresRaw = value;
276
+ break;
277
+ case "report":
278
+ if (reportRaw !== undefined)
279
+ return { ok: false, reason: `duplicate "report" segment` };
280
+ reportRaw = value;
281
+ break;
282
+ default:
283
+ return { ok: false, reason: `unknown delegation segment key ${JSON.stringify(key)}` };
284
+ }
285
+ }
286
+ if (parentSessionId === undefined)
287
+ return { ok: false, reason: `missing "delegated" segment` };
288
+ if (cwdRaw === undefined)
289
+ return { ok: false, reason: `missing "cwd" segment` };
290
+ if (taskRaw === undefined)
291
+ return { ok: false, reason: `missing "task" segment` };
292
+ if (expiresRaw === undefined)
293
+ return { ok: false, reason: `missing "expires" segment` };
294
+ let cwdHash = null;
295
+ if (cwdRaw !== UNBOUND) {
296
+ if (!SHA256_HEX.test(cwdRaw)) {
297
+ return { ok: false, reason: `"cwd" is not a sha256 hex digest: ${JSON.stringify(cwdRaw)}` };
298
+ }
299
+ cwdHash = cwdRaw;
300
+ }
301
+ let taskId = null;
302
+ if (taskRaw !== UNBOUND) {
303
+ if (taskRaw.includes("=")) {
304
+ return { ok: false, reason: `"task" contains a segment delimiter: ${JSON.stringify(taskRaw)}` };
305
+ }
306
+ taskId = taskRaw;
307
+ }
308
+ if (!ISO_INSTANT.test(expiresRaw) || !Number.isFinite(Date.parse(expiresRaw))) {
309
+ return {
310
+ ok: false,
311
+ reason: `"expires" is not an ISO-8601 instant: ${JSON.stringify(expiresRaw)}`,
312
+ };
313
+ }
314
+ if (reportRaw !== undefined && !SHA256_HEX.test(reportRaw)) {
315
+ return { ok: false, reason: `"report" is not a sha256 hex digest: ${JSON.stringify(reportRaw)}` };
316
+ }
317
+ const value = {
318
+ parentSessionId,
319
+ cwdHash,
320
+ taskId,
321
+ expiresAt: expiresRaw,
322
+ ...(reportRaw !== undefined ? { reportPathHash: reportRaw } : {}),
323
+ };
324
+ return { ok: true, value };
325
+ }
326
+ /**
327
+ * Write a signed delegation marker through the shared `signMarker` path,
328
+ * under markerId `delegation-<child-sid>`, at
329
+ * `<generatedDir>/.delegations/<child-sid>`. Atomic and mode 0600, like
330
+ * every other marker write.
331
+ *
332
+ * NEVER CREATES THE SIGNING KEY. `signMarker` -> `getOrCreateSigningKey`
333
+ * treats a missing key as a case to REPAIR, generating one and signing
334
+ * with it; key creation is an operator-side act (`harness init`,
335
+ * `harness approve`), and a delegation minted on a machine that never had
336
+ * a key would be a marker signed by whoever asked for it. So this
337
+ * prechecks `signingKeyExists` and returns `signing-key-absent` without
338
+ * reaching the write path at all (ADR threat model (b) item 5, the same
339
+ * rule slice 1's auto path follows).
340
+ *
341
+ * Returns a result rather than throwing, for every failure mode: the
342
+ * callers are a CLI verb and, later, a hook, and both must fail closed
343
+ * with a diagnostic instead of unwinding.
344
+ *
345
+ * Deliberately does NOT refuse a delegation that binds neither cwd nor
346
+ * task. That refusal belongs to the issuing verb (ADR slice 3 acceptance
347
+ * criterion 1) and to `verifyDelegation`, which reports `no_binding`;
348
+ * keeping the writer able to produce one is what lets the test suite
349
+ * exercise that verifier branch against a genuinely signed artifact
350
+ * rather than a hand-rolled fake.
351
+ */
352
+ export function writeDelegationMarker(opts) {
353
+ const reportPathHash = opts.reportPathHash;
354
+ const reportContentHash = opts.reportContentHash ?? null;
355
+ if ((reportPathHash === undefined) !== (reportContentHash === null)) {
356
+ // The fallback shape binds the launcher-supplied report by BOTH its
357
+ // path and its content. Half a binding is worse than none: a `report=`
358
+ // segment with no content hash, or a content hash with no `report=`
359
+ // segment, reads as "bound" to a human and enforces only one half.
360
+ return {
361
+ ok: false,
362
+ reason: "invalid-input",
363
+ detail: "the fallback shape requires reportPathHash AND reportContentHash together (one without the other would leave half the report binding unenforced)",
364
+ };
365
+ }
366
+ if (reportContentHash !== null) {
367
+ try {
368
+ rejectNonSha256("reportContentHash", reportContentHash);
369
+ }
370
+ catch (err) {
371
+ return {
372
+ ok: false,
373
+ reason: "invalid-input",
374
+ detail: err instanceof Error ? err.message : String(err),
375
+ };
376
+ }
377
+ }
378
+ let filePath;
379
+ let approvedBy;
380
+ try {
381
+ filePath = delegationMarkerPathFor(opts.generatedDir, opts.childSessionId);
382
+ approvedBy = buildDelegationApprovedBy({
383
+ parentSessionId: opts.parentSessionId,
384
+ cwdHash: opts.cwdHash,
385
+ taskId: opts.taskId,
386
+ expiresAt: opts.expiresAt,
387
+ reportPathHash,
388
+ });
389
+ }
390
+ catch (err) {
391
+ return {
392
+ ok: false,
393
+ reason: "invalid-input",
394
+ detail: err instanceof Error ? err.message : String(err),
395
+ };
396
+ }
397
+ if (!signingKeyExists(opts.generatedDir)) {
398
+ return {
399
+ ok: false,
400
+ reason: "signing-key-absent",
401
+ detail: `no operator signing key at ${signingKeyPathFor(opts.generatedDir)}; refusing to mint a delegation (key creation is an operator-side act, never a side effect of delegating)`,
402
+ };
403
+ }
404
+ const approvedAt = (opts.now ?? new Date()).toISOString();
405
+ const markerId = delegationMarkerIdFor(opts.childSessionId);
406
+ const signed = signMarker(opts.generatedDir, markerId, {
407
+ approvedAt,
408
+ approvedBy,
409
+ reportContentHash,
410
+ });
411
+ try {
412
+ atomicWriteFile(filePath, `${JSON.stringify(signed, null, 2)}\n`, { mode: 0o600 });
413
+ }
414
+ catch (err) {
415
+ return {
416
+ ok: false,
417
+ reason: "write-failed",
418
+ detail: err instanceof Error ? err.message : String(err),
419
+ };
420
+ }
421
+ return { ok: true, filePath, markerId, approvedAt, approvedBy };
422
+ }
423
+ /**
424
+ * Gate-side: is there a valid, unexpired, matching delegation for this
425
+ * child session? Checks, in order (ADR slice 3 acceptance criterion 2):
426
+ *
427
+ * 1. the file is present and JSON-readable,
428
+ * 2. its signature verifies against markerId `delegation-<child-sid>`,
429
+ * 3. its `approvedBy` segments parse in full,
430
+ * 4. it binds at least one of cwd / task,
431
+ * 5. it has not expired,
432
+ * 6. the bound cwd hash-matches the caller's cwd,
433
+ * 7. the bound task equals the caller's task,
434
+ * 8. in the fallback shape, the launcher report sits at the bound path
435
+ * AND hashes to the bound content.
436
+ *
437
+ * Reads only `.delegations/`; an artifact in `.approvals/` is `missing`
438
+ * here, whatever it contains.
439
+ *
440
+ * NEVER CREATES THE SIGNING KEY, on the READ path either.
441
+ * `verifyMarkerSignature` obtains the key through
442
+ * `getOrCreateSigningKey`, which treats a missing key as a case to
443
+ * REPAIR and generates one; on a machine the operator never initialized
444
+ * that would make a mere gate-time read perform the operator-side act of
445
+ * minting the key. It cannot make a foreign-signed delegation verify, but
446
+ * it does leave a key behind that every LATER write path would then
447
+ * happily sign with, so the never-create rule applies here exactly as it
448
+ * does to `writeDelegationMarker` and to slice 1's auto path. An absent
449
+ * key is reported as `unreadable` (we could not check, not "we checked
450
+ * and it is a forgery"), the same class `verifyMarkerSignature`'s own
451
+ * `key-unavailable` lands in below.
452
+ */
453
+ export function verifyDelegation(opts) {
454
+ const { generatedDir, childSessionId } = opts;
455
+ let filePath;
456
+ try {
457
+ filePath = delegationMarkerPathFor(generatedDir, childSessionId);
458
+ }
459
+ catch (err) {
460
+ // A session id that cannot name a file has no delegation, by
461
+ // construction. Fail closed here rather than throwing out of a hook.
462
+ return {
463
+ ok: false,
464
+ reason: "missing",
465
+ detail: `invalid childSessionId for delegation marker: ${err instanceof Error ? err.message : String(err)}`,
466
+ };
467
+ }
468
+ const read = readRegularFileRejectingSymlink(filePath);
469
+ if (read.kind === "missing") {
470
+ return { ok: false, reason: "missing", detail: `no delegation marker at ${filePath}` };
471
+ }
472
+ if (read.kind === "symlink") {
473
+ return {
474
+ ok: false,
475
+ reason: "unreadable",
476
+ detail: `delegation marker is a symlink, refusing for safety: ${filePath}`,
477
+ };
478
+ }
479
+ if (read.kind === "not-regular") {
480
+ return {
481
+ ok: false,
482
+ reason: "unreadable",
483
+ detail: `delegation marker path is not a regular file: ${filePath}`,
484
+ };
485
+ }
486
+ if (read.kind === "unreadable") {
487
+ return {
488
+ ok: false,
489
+ reason: "unreadable",
490
+ detail: `delegation marker at ${filePath} exists but could not be read (I/O error); treating as no delegation since its signature cannot be verified`,
491
+ };
492
+ }
493
+ const parsed = safeJsonParse(read.content);
494
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
495
+ return {
496
+ ok: false,
497
+ reason: "forged",
498
+ detail: `forged/unsigned delegation rejected: body at ${filePath} is not a JSON object`,
499
+ };
500
+ }
501
+ const body = parsed;
502
+ // Key precheck BEFORE `verifyMarkerSignature`, which would otherwise
503
+ // mint the key it is supposed to require (see the doc comment above).
504
+ // Placed after the file read so a session with no delegation at all
505
+ // still reports `missing` rather than this stronger, misleading reason.
506
+ if (!signingKeyExists(generatedDir)) {
507
+ return {
508
+ ok: false,
509
+ reason: "unreadable",
510
+ detail: `signing key absent at ${signingKeyPathFor(generatedDir)}; the delegation at ${filePath} cannot be verified and no key is created to verify it (key creation is an operator-side act)`,
511
+ };
512
+ }
513
+ const markerId = delegationMarkerIdFor(childSessionId);
514
+ const verification = verifyMarkerSignature(generatedDir, markerId, body);
515
+ if (!verification.ok) {
516
+ if (verification.kind === "key-unavailable") {
517
+ // Fail-closed I/O problem, not evidence of tampering (the same
518
+ // distinction `checkApprovalMarker` draws).
519
+ return {
520
+ ok: false,
521
+ reason: "unreadable",
522
+ detail: `delegation at ${filePath} could not be verified: ${verification.reason}`,
523
+ };
524
+ }
525
+ return {
526
+ ok: false,
527
+ reason: "forged",
528
+ detail: `forged/unsigned delegation rejected: ${verification.reason} (${filePath})`,
529
+ };
530
+ }
531
+ const segments = parseDelegationApprovedBy(body["approvedBy"]);
532
+ if (!segments.ok) {
533
+ return {
534
+ ok: false,
535
+ reason: "unparseable",
536
+ detail: `delegation at ${filePath} has an unparseable approvedBy: ${segments.reason}`,
537
+ };
538
+ }
539
+ const { parentSessionId, cwdHash, taskId, expiresAt, reportPathHash } = segments.value;
540
+ if (cwdHash === null && taskId === null) {
541
+ return {
542
+ ok: false,
543
+ reason: "no_binding",
544
+ detail: `delegation at ${filePath} binds neither a cwd nor a task; refusing an unbound pre-authorization`,
545
+ };
546
+ }
547
+ const nowMs = (opts.now ?? new Date()).getTime();
548
+ const expiresMs = Date.parse(expiresAt);
549
+ // `nowMs` is caller-supplied (`opts.now`, a test-only override); an
550
+ // invalid Date's `.getTime()` is NaN, and NaN fails every `<=`
551
+ // comparison, which would otherwise fail this check OPEN (a clock that
552
+ // cannot report the time would silently pass every delegation as
553
+ // unexpired). Fail closed instead: an unusable clock is treated the same
554
+ // as an already-expired one.
555
+ if (!Number.isFinite(nowMs) || expiresMs <= nowMs) {
556
+ return {
557
+ ok: false,
558
+ reason: "expired",
559
+ detail: Number.isFinite(nowMs)
560
+ ? `delegation at ${filePath} expired at ${expiresAt} (now ${new Date(nowMs).toISOString()})`
561
+ : `delegation at ${filePath} cannot be checked for expiry: the supplied clock is unusable (now getTime() => ${nowMs})`,
562
+ };
563
+ }
564
+ if (cwdHash !== null) {
565
+ if (opts.cwd === null) {
566
+ return {
567
+ ok: false,
568
+ reason: "cwd_mismatch",
569
+ detail: `delegation at ${filePath} is bound to a cwd but the caller supplied none`,
570
+ };
571
+ }
572
+ const actual = hashDelegationCwd(opts.cwd);
573
+ if (actual !== cwdHash) {
574
+ return {
575
+ ok: false,
576
+ reason: "cwd_mismatch",
577
+ detail: `delegation at ${filePath} is bound to a different cwd (bound ${cwdHash}, got ${actual} for ${opts.cwd})`,
578
+ };
579
+ }
580
+ }
581
+ if (taskId !== null) {
582
+ if (opts.taskId === null) {
583
+ return {
584
+ ok: false,
585
+ reason: "task_mismatch",
586
+ detail: `delegation at ${filePath} is bound to task ${taskId} but the caller supplied none`,
587
+ };
588
+ }
589
+ if (opts.taskId !== taskId) {
590
+ return {
591
+ ok: false,
592
+ reason: "task_mismatch",
593
+ detail: `delegation at ${filePath} is bound to task ${taskId}, not ${opts.taskId}`,
594
+ };
595
+ }
596
+ }
597
+ if (reportPathHash !== undefined) {
598
+ if (opts.launcherReportPath === undefined) {
599
+ return {
600
+ ok: false,
601
+ reason: "report_path_mismatch",
602
+ detail: `delegation at ${filePath} binds a launcher-supplied report but no report path was offered`,
603
+ };
604
+ }
605
+ const actualPathHash = hashDelegationCwd(opts.launcherReportPath);
606
+ if (actualPathHash !== reportPathHash) {
607
+ return {
608
+ ok: false,
609
+ reason: "report_path_mismatch",
610
+ detail: `delegation at ${filePath} binds a report at a different path (bound ${reportPathHash}, got ${actualPathHash} for ${opts.launcherReportPath})`,
611
+ };
612
+ }
613
+ const boundContentHash = typeof body["reportContentHash"] === "string" ? body["reportContentHash"] : null;
614
+ if (boundContentHash === null) {
615
+ return {
616
+ ok: false,
617
+ reason: "report_content_mismatch",
618
+ detail: `delegation at ${filePath} carries a report path binding but no reportContentHash to check the file against`,
619
+ };
620
+ }
621
+ const reportRead = readRegularFileRejectingSymlink(opts.launcherReportPath);
622
+ if (reportRead.kind !== "ok") {
623
+ return {
624
+ ok: false,
625
+ reason: "report_content_mismatch",
626
+ detail: `launcher-supplied report at ${opts.launcherReportPath} could not be read (${reportRead.kind}); its content cannot be checked against the bound hash`,
627
+ };
628
+ }
629
+ const actualContentHash = sha256Hex(reportRead.content);
630
+ if (actualContentHash !== boundContentHash) {
631
+ return {
632
+ ok: false,
633
+ reason: "report_content_mismatch",
634
+ detail: `launcher-supplied report at ${opts.launcherReportPath} does not match the bound content hash (bound ${boundContentHash}, got ${actualContentHash})`,
635
+ };
636
+ }
637
+ }
638
+ return {
639
+ ok: true,
640
+ parentSessionId,
641
+ expiresAt,
642
+ boundCwdHash: cwdHash,
643
+ boundTaskId: taskId,
644
+ ...(reportPathHash !== undefined ? { reportPathHash } : {}),
645
+ };
646
+ }
647
+ //# sourceMappingURL=delegation-markers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delegation-markers.js","sourceRoot":"","sources":["../../../../src/policy-packs/builtin/understanding-before-execution/delegation-markers.ts"],"names":[],"mappings":"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"}