@lannguyensi/harness 0.51.0 → 0.52.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 (62) hide show
  1. package/CHANGELOG.md +139 -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/codex-config-drift.d.ts +28 -0
  15. package/dist/cli/doctor/codex-config-drift.js +240 -0
  16. package/dist/cli/doctor/codex-config-drift.js.map +1 -0
  17. package/dist/cli/doctor/format.js +32 -1
  18. package/dist/cli/doctor/format.js.map +1 -1
  19. package/dist/cli/doctor/index.js +51 -7
  20. package/dist/cli/doctor/index.js.map +1 -1
  21. package/dist/cli/doctor/settings-drift.d.ts +6 -0
  22. package/dist/cli/doctor/settings-drift.js +20 -6
  23. package/dist/cli/doctor/settings-drift.js.map +1 -1
  24. package/dist/cli/doctor/types.d.ts +43 -0
  25. package/dist/cli/doctor/types.js.map +1 -1
  26. package/dist/cli/doctor/ug-delegations.d.ts +26 -0
  27. package/dist/cli/doctor/ug-delegations.js +112 -0
  28. package/dist/cli/doctor/ug-delegations.js.map +1 -0
  29. package/dist/cli/doctor/understanding-mode-env.d.ts +2 -0
  30. package/dist/cli/doctor/understanding-mode-env.js +5 -2
  31. package/dist/cli/doctor/understanding-mode-env.js.map +1 -1
  32. package/dist/cli/index.js +89 -1
  33. package/dist/cli/index.js.map +1 -1
  34. package/dist/cli/pack/approve-escape.js +16 -7
  35. package/dist/cli/pack/approve-escape.js.map +1 -1
  36. package/dist/cli/pack/auto-approve-path.d.ts +17 -0
  37. package/dist/cli/pack/auto-approve-path.js +56 -3
  38. package/dist/cli/pack/auto-approve-path.js.map +1 -1
  39. package/dist/cli/pack/hook-pre-tool-use.d.ts +25 -0
  40. package/dist/cli/pack/hook-pre-tool-use.js +336 -3
  41. package/dist/cli/pack/hook-pre-tool-use.js.map +1 -1
  42. package/dist/cli/pack/transcript-report-scan.d.ts +71 -0
  43. package/dist/cli/pack/transcript-report-scan.js +359 -0
  44. package/dist/cli/pack/transcript-report-scan.js.map +1 -0
  45. package/dist/cli/smoke/index.d.ts +18 -1
  46. package/dist/cli/smoke/index.js +54 -0
  47. package/dist/cli/smoke/index.js.map +1 -1
  48. package/dist/policy-packs/builtin/understanding-before-execution/auto-approve.d.ts +76 -2
  49. package/dist/policy-packs/builtin/understanding-before-execution/auto-approve.js +139 -2
  50. package/dist/policy-packs/builtin/understanding-before-execution/auto-approve.js.map +1 -1
  51. package/dist/policy-packs/builtin/understanding-before-execution/delegation-markers.d.ts +223 -0
  52. package/dist/policy-packs/builtin/understanding-before-execution/delegation-markers.js +633 -0
  53. package/dist/policy-packs/builtin/understanding-before-execution/delegation-markers.js.map +1 -0
  54. package/dist/policy-packs/builtin/understanding-before-execution/index.d.ts +2 -1
  55. package/dist/policy-packs/builtin/understanding-before-execution/index.js +9 -1
  56. package/dist/policy-packs/builtin/understanding-before-execution/index.js.map +1 -1
  57. package/dist/policy-packs/builtin/understanding-before-execution.d.ts +19 -0
  58. package/dist/policy-packs/builtin/understanding-before-execution.js +29 -0
  59. package/dist/policy-packs/builtin/understanding-before-execution.js.map +1 -1
  60. package/dist/runtime/approval-signing.js +28 -0
  61. package/dist/runtime/approval-signing.js.map +1 -1
  62. package/package.json +1 -1
@@ -76,6 +76,23 @@ export interface AutoApproveAttemptArgs {
76
76
  reportsDir: string;
77
77
  /** Step 3's verdict: a marker FILE existed and failed signature verification. */
78
78
  markerForged: boolean;
79
+ /**
80
+ * Slice 3 (agent-tasks 37ad0b05, ADR "Decision: two-key design"): a
81
+ * VALID, unexpired, cwd/task-matching delegation the calling hook has
82
+ * already verified for this child session. Present means key one is
83
+ * satisfied by the delegation instead of by a `when`-listed
84
+ * `permission_mode`, so a `-p` child whose payload carries `default`
85
+ * (or no mode at all) can still reach the report check.
86
+ *
87
+ * It is a PRE-AUTHORIZATION, not an approval: every other condition in
88
+ * this function stays exactly as it was, key two (the child's own
89
+ * `pending` report) very much included. The caller is responsible for
90
+ * the verification; this function never reads a delegation file
91
+ * itself, so there is no second, weaker verifier to keep in sync.
92
+ */
93
+ delegation?: {
94
+ parentSessionId: string;
95
+ };
79
96
  stderr: {
80
97
  write(s: string): void;
81
98
  };
@@ -44,6 +44,16 @@
44
44
  // but does name a per-session `transcript_path` that exists on disk at
45
45
  // PreToolUse time.
46
46
  //
47
+ // TWO ALTERNATIVE KEY-ONE SIGNALS (slice 3, agent-tasks 37ad0b05). The
48
+ // ADR's "Decision: two-key design" makes the trusted signal a
49
+ // disjunction: a `when`-listed `permission_mode`, OR a valid delegation
50
+ // for this child session that the CALLING HOOK has already verified and
51
+ // passes in as `delegation`. Both are only key ONE. Key two, the child's
52
+ // own strict-session `pending` report, is condition (6) below and is
53
+ // identical on both paths; nothing about a delegation relaxes it, and no
54
+ // branch here reads a delegation file, so the one verifier stays in
55
+ // `understanding-before-execution/delegation-markers.ts`.
56
+ //
47
57
  // ONE BODY IS NOT ONE OPT-IN. Sharing the body would otherwise mean an
48
58
  // `auto_approve` block written for Claude Code opts every Codex session
49
59
  // in too; `auto_approve.harnesses` is the explicit per-harness
@@ -71,6 +81,15 @@ export const AUTO_APPROVE_LEDGER_SOURCE = "harness-pack-hook-pre-tool-use";
71
81
  export const AUTO_APPROVE_LEDGER_SOURCE_CODEX = "harness-pack-hook-codex-pre-tool-use";
72
82
  /** Default stderr prefix: the Claude Code hook's, byte-for-byte. */
73
83
  const DEFAULT_LABEL = "harness pack hook";
84
+ /**
85
+ * The `<mode>` segment an auto-marker carries whenever key one came from
86
+ * the DELEGATION rather than from a `when`-listed `permission_mode`.
87
+ * `auto-mode:claude-code:delegated;delegated:<parent-sid>` reads as what
88
+ * it is: a child whose trusted signal was the parent's pre-authorization,
89
+ * not a permission mode. Used unconditionally on that path, whatever the
90
+ * payload's own mode says, since that mode played no part in the decision.
91
+ */
92
+ const DELEGATED_MODE_LABEL = "delegated";
74
93
  function decline(reason) {
75
94
  return { approved: false, reason };
76
95
  }
@@ -119,10 +138,35 @@ export async function attemptAutoApproval(args) {
119
138
  // the configured `auto_approve.when` allowlist to stderr on every
120
139
  // ordinary prompting-mode call (reviewer round-1 finding).
121
140
  const mode = args.permissionMode;
122
- if (!permissionModeAllowed(cfg, mode)) {
141
+ const modeAllowed = permissionModeAllowed(cfg, mode);
142
+ if (!modeAllowed && args.delegation === undefined) {
123
143
  return decline("permission_mode not in auto_approve.when");
124
144
  }
125
- const modeStr = mode;
145
+ // Which of the ADR's two alternative key-one signals actually applied.
146
+ // Logged only on the delegation path: the `when` hit is the ordinary
147
+ // slice-1 case and stays as silent as it was, so slice 1's stderr trail
148
+ // is byte-identical to what it was before this argument existed.
149
+ if (args.delegation !== undefined) {
150
+ note(modeAllowed
151
+ ? `auto-approval key one: permission_mode ${JSON.stringify(mode)} in auto_approve.when (a valid delegation from parent session ${args.delegation.parentSessionId} is also present)`
152
+ : `auto-approval key one: valid delegation from parent session ${args.delegation.parentSessionId}`);
153
+ }
154
+ // The `<mode>` segment of `approvedBy` records WHICH key one applied,
155
+ // so it carries a payload literal in exactly one case: the mode itself
156
+ // was `when`-listed, i.e. the operator wrote that exact string in the
157
+ // config and this call matched it.
158
+ //
159
+ // On the delegation path the payload's mode is UNCONSTRAINED (that is
160
+ // the whole point: a `-p` child may carry `default`, or nothing) and it
161
+ // played no part in the decision, so it is replaced by the neutral
162
+ // `delegated` literal wholesale rather than filtered. Filtering only the
163
+ // encoding-breaking characters was not enough: `approvedBy` is a signed
164
+ // AUDIT record, and a payload-composed mode carrying a newline or a tab
165
+ // survives a `;`/`:` check, lands verbatim in the signed field, and then
166
+ // shows up in the doctor listing as a permission mode that never
167
+ // existed (reviewer finding L2). Nothing is lost: the payload's mode is
168
+ // not evidence of anything on this path.
169
+ const modeStr = modeAllowed ? mode : DELEGATED_MODE_LABEL;
126
170
  // Resolve the audit-only ledger writer NOW, not earlier: this is the
127
171
  // first point past both the opt-in check (1) and the `when` allowlist
128
172
  // check (2), so `args.resolveLedger` runs only on a call that has an
@@ -267,7 +311,16 @@ export async function attemptAutoApproval(args) {
267
311
  // BEFORE the approval rewrite, exactly as the approve CLI computes it.
268
312
  const reportContentHash = sha256Hex(raw);
269
313
  const approvedAt = new Date().toISOString();
270
- const approvedBy = autoApprovedByFor(args.harness, modeStr);
314
+ // The parent linkage rides in the same signed `approvedBy` field the
315
+ // source already travels in (ADR "Audit and doctor"): no new signed
316
+ // field, therefore no `SIGNING_ALG` bump. `parseAutoApprovedBy` strips
317
+ // the suffix, so the doctor listing still buckets the marker by
318
+ // harness/mode. The parent id needs no escaping here: it comes out of a
319
+ // verified delegation whose own writer already refused a `;` or `=` in
320
+ // it (`buildDelegationApprovedBy`'s `rejectUnsafeSegmentValue`).
321
+ const approvedBy = args.delegation === undefined
322
+ ? autoApprovedByFor(args.harness, modeStr)
323
+ : `${autoApprovedByFor(args.harness, modeStr)};delegated:${args.delegation.parentSessionId}`;
271
324
  // CONSUME FIRST, then sign. If the marker write fails after this, the
272
325
  // report is spent and no marker exists: the call blocks and the same
273
326
  // report can never mint again. The reverse order would leave a
@@ -1 +1 @@
1
- {"version":3,"file":"auto-approve-path.js","sourceRoot":"","sources":["../../../src/cli/pack/auto-approve-path.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auto-approve-path.js","sourceRoot":"","sources":["../../../src/cli/pack/auto-approve-path.ts"],"names":[],"mappings":"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"}
@@ -42,6 +42,17 @@ export interface PackHookPreToolUseOptions extends LoaderOptions {
42
42
  * real-time sleep.
43
43
  */
44
44
  now?: Date;
45
+ /**
46
+ * Clock / sleep / interval injection for the slice-3 transcript scan
47
+ * (test). The scan is a bounded POLL, so without this a suite covering
48
+ * its timeout would have to sleep for real time. Production leaves it
49
+ * unset and the scan uses `Date.now` and a real `setTimeout`.
50
+ */
51
+ reportScanClock?: {
52
+ now?: () => number;
53
+ sleep?: (ms: number) => Promise<void>;
54
+ pollMs?: number;
55
+ };
45
56
  }
46
57
  export interface PackHookPreToolUseResult {
47
58
  exitCode: number;
@@ -57,4 +68,18 @@ export interface PackHookPreToolUseResult {
57
68
  /** Diagnostic line emitted to stderr (always; even on allow). */
58
69
  diagnostic: string;
59
70
  }
71
+ /**
72
+ * The sentence appended to the standard block reason when a valid
73
+ * delegation was present but the child's own report had not reached the
74
+ * transcript within `auto_approve.report_scan.max_wait` (ADR "Report
75
+ * capture under `-p`": past the bound the hook blocks with an instruction
76
+ * that asks for REPEATED retries, because a text asking for a single
77
+ * retry was measured to leave the outcome to run-to-run variation).
78
+ *
79
+ * Deliberately does NOT pin a heading level. The same block envelope
80
+ * already carries `renderReportSchemaHint`'s "any heading level (#, ##,
81
+ * ###)" rule, and naming one level here would give the agent two
82
+ * different heading rules in one deny text.
83
+ */
84
+ export declare const DELEGATION_REPORT_RETRY_INSTRUCTION = "Emit or re-emit your Understanding Report as an `Understanding Report` section (any heading level), then retry this command; if it is denied again, retry again.";
60
85
  export declare function runPackHookPreToolUseCli(opts?: PackHookPreToolUseOptions): Promise<PackHookPreToolUseResult>;
@@ -20,12 +20,34 @@
20
20
  // hostile. The npm package's own standalone blocker still runs as a
21
21
  // secondary safety net for solo users, and `harness explain --trace`
22
22
  // (Phase 4 #6) surfaces the runtime audit trail when configured.
23
+ //
24
+ // SLICE 3 (agent-tasks 37ad0b05) adds the delegation-path capture of the
25
+ // child's own report from its session transcript. Two rules of that path
26
+ // live here rather than in the modules it calls:
27
+ //
28
+ // - ONE TRANSCRIPT ENTRY IS ADOPTED AT MOST ONCE PER SESSION. Every
29
+ // adopted entry's id is appended to
30
+ // `<generatedDir>/.delegation-adoptions/<sid>` BEFORE the capture is
31
+ // persisted, and the scan is given that set. Without it the same
32
+ // report would be re-captured and re-minted every time the auto-marker
33
+ // expired (or a task boundary cleared it), so the delegation's TTL
34
+ // would silently replace the marker's.
35
+ // - A CAPTURE THAT DOES NOT PARSE writes a parse-error log, once per
36
+ // failed capture, through the same `persistStdinReport` the operator
37
+ // path uses. That log is what the block envelope's malformed-sections
38
+ // notice is rendered from, so the per-capture write is deliberate.
39
+ import { appendFileSync, existsSync, lstatSync, mkdirSync } from "node:fs";
23
40
  import * as path from "node:path";
41
+ import { readRegularFileRejectingSymlink } from "../../io/read-regular-file.js";
24
42
  import { queryLedgerByTag, } from "../../policies/index.js";
25
43
  import { renderProducers } from "../../policies/producers.js";
26
- import { CLAUDE_CODE_HARNESS, checkOperatorApprovalMarkers, checkPersistedReport, defaultReportsDir, matchLedgerEntries, } from "../../policy-packs/builtin/understanding-before-execution-runtime.js";
44
+ import { CLAUDE_CODE_HARNESS, checkOperatorApprovalMarkers, checkPersistedReport, defaultReportsDir, delegationMarkerPathFor, harnessAllowed, listPersistedReports, matchLedgerEntries, parseAutoApprove, readActiveClaim, selectNewestStrictSessionReport, verifyDelegation, } from "../../policy-packs/builtin/understanding-before-execution-runtime.js";
45
+ import { resolveMode, toPackageMode, } from "../../policy-packs/builtin/understanding-before-execution.js";
46
+ import { signingKeyExists } from "../../runtime/approval-signing.js";
27
47
  import { findLatestParseError, renderMalformedSectionsNotice } from "../approve/understanding.js";
48
+ import { persistStdinReport } from "../approve/stdin-report.js";
28
49
  import { attemptAutoApproval, AUTO_APPROVE_LEDGER_SOURCE } from "./auto-approve-path.js";
50
+ import { scanTranscriptForReport } from "./transcript-report-scan.js";
29
51
  import { resolveGeneratedDir, writePendingApproval, } from "../../runtime/pending-approval.js";
30
52
  import { resolveManifestLedgerWriter } from "../../runtime/ledger-writer.js";
31
53
  import { isReadOnlyBashPipeline } from "../../runtime/read-only-bash.js";
@@ -37,9 +59,114 @@ import { isEscapeCommand } from "./approve-escape.js";
37
59
  import { checkHookPause, loadManifestOrInjected, parseConfigUx, readStdin, } from "./hook-bootstrap.js";
38
60
  import { renderReportSchemaHint } from "./understanding-report-schema-hint.js";
39
61
  const PACK_NAME = "understanding-before-execution";
62
+ /**
63
+ * The sentence appended to the standard block reason when a valid
64
+ * delegation was present but the child's own report had not reached the
65
+ * transcript within `auto_approve.report_scan.max_wait` (ADR "Report
66
+ * capture under `-p`": past the bound the hook blocks with an instruction
67
+ * that asks for REPEATED retries, because a text asking for a single
68
+ * retry was measured to leave the outcome to run-to-run variation).
69
+ *
70
+ * Deliberately does NOT pin a heading level. The same block envelope
71
+ * already carries `renderReportSchemaHint`'s "any heading level (#, ##,
72
+ * ###)" rule, and naming one level here would give the agent two
73
+ * different heading rules in one deny text.
74
+ */
75
+ export const DELEGATION_REPORT_RETRY_INSTRUCTION = "Emit or re-emit your Understanding Report as an `Understanding Report` section (any heading level), then retry this command; if it is denied again, retry again.";
40
76
  function findGroundingMcp(manifest) {
41
77
  return manifest.tools.mcp.find((m) => m.name === "grounding-mcp") ?? null;
42
78
  }
79
+ /**
80
+ * Directory holding the per-child ADOPTED-ENTRY ledgers, a SIBLING of
81
+ * `.delegations/` itself rather than a subdirectory of it:
82
+ * `<generatedDir>/.delegation-adoptions/<sid>`.
83
+ *
84
+ * Never inside `.delegations/`, and never in `.approvals/`: these files
85
+ * record what was SPENT, they are not approvals and must never land where
86
+ * a marker scan or the doctor's `approvedBy` listing would read them as
87
+ * one. Kept OUT of `.delegations/` for two reasons: `harness doctor`'s
88
+ * delegations metric counts every regular file directly under
89
+ * `.delegations/` (a ledger file nested in there, flat or not, would be
90
+ * reported as an extra, unreadable delegation), and no reserved
91
+ * subdirectory NAME sits under `.delegations/` for a child session id to
92
+ * collide with, since the ledger lives at its own sibling path instead of
93
+ * inside `.delegations/` at all.
94
+ *
95
+ * One id per line. Ids come from the scan (`entryId`), which guarantees
96
+ * they carry no line break.
97
+ */
98
+ const ADOPTION_LEDGER_DIRNAME = ".delegation-adoptions";
99
+ function adoptedEntriesPathFor(generatedDir, childSessionId) {
100
+ return path.join(generatedDir, ADOPTION_LEDGER_DIRNAME, childSessionId);
101
+ }
102
+ /**
103
+ * The entry ids this session has already spent. An absent file is the
104
+ * ordinary first-call case and reads as the empty set; every OTHER read
105
+ * failure fails closed with a result the caller declines on, because a
106
+ * ledger we cannot read cannot prove that the next transcript hit has not
107
+ * already been adopted. Goes through the same symlink-rejecting reader
108
+ * every other gate marker uses (`readRegularFileRejectingSymlink`):
109
+ * without it a symlink planted at this path would have the ledger read
110
+ * follow it to an arbitrary target the agent controls, and an empty or
111
+ * missing target there would read as "nothing adopted yet", the same
112
+ * open the delegation and approval marker reads already close.
113
+ */
114
+ function readAdoptedEntries(filePath) {
115
+ const read = readRegularFileRejectingSymlink(filePath);
116
+ if (read.kind === "missing")
117
+ return { ok: true, ids: new Set() };
118
+ if (read.kind === "symlink") {
119
+ return { ok: false, detail: `${filePath} is a symlink, refusing for safety` };
120
+ }
121
+ if (read.kind === "not-regular") {
122
+ return { ok: false, detail: `${filePath} is not a regular file` };
123
+ }
124
+ if (read.kind !== "ok") {
125
+ return { ok: false, detail: `${filePath} exists but could not be read (I/O error)` };
126
+ }
127
+ const ids = new Set();
128
+ for (const line of read.content.split("\n")) {
129
+ const id = line.trim();
130
+ if (id.length > 0)
131
+ ids.add(id);
132
+ }
133
+ return { ok: true, ids };
134
+ }
135
+ /**
136
+ * Append one adopted entry id, creating `.delegation-adoptions/` on first
137
+ * use with the same default directory mode `atomicWriteFile` gives
138
+ * `.delegations/` itself (the ledger FILE is 0600, like every marker).
139
+ * `appendFileSync` opens with `O_APPEND`, so a single short write lands
140
+ * whole even if two hooks race on the same session; no read-modify-write,
141
+ * therefore nothing to lose. `lstatSync` (NOT `existsSync`/`statSync`)
142
+ * gates the append the same way `readRegularFileRejectingSymlink` gates
143
+ * the read: a symlink planted at this path would otherwise have
144
+ * `appendFileSync` follow it and write the adoption record through to an
145
+ * arbitrary target, same class of defense as the read side above.
146
+ */
147
+ function recordAdoptedEntry(filePath, entryId) {
148
+ try {
149
+ let priorStat;
150
+ try {
151
+ priorStat = lstatSync(filePath);
152
+ }
153
+ catch {
154
+ priorStat = undefined;
155
+ }
156
+ if (priorStat !== undefined && !priorStat.isFile()) {
157
+ return {
158
+ ok: false,
159
+ detail: `${filePath} exists and is not a regular file, refusing to append through it`,
160
+ };
161
+ }
162
+ mkdirSync(path.dirname(filePath), { recursive: true });
163
+ appendFileSync(filePath, `${entryId}\n`, { mode: 0o600 });
164
+ return { ok: true };
165
+ }
166
+ catch (err) {
167
+ return { ok: false, detail: err.message };
168
+ }
169
+ }
43
170
  // The Claude Code "block" envelope. Mirrors the runtime/intercept.ts
44
171
  // shape (PR #81): `decision: "block"` keeps legacy 2.0.x CLIs blocking,
45
172
  // `hookSpecificOutput.permissionDecision: "deny"` is the Claude Code
@@ -76,7 +203,7 @@ function parseConfigProducers(raw, stderr) {
76
203
  // the deny envelope the agent sees becomes the plain-language
77
204
  // `{ cannot, required, run }` shape and the legacy "Understanding Gate:
78
205
  // no approved..." + schemaHint + producers vocabulary is suppressed.
79
- function blockJson(toolName, reason, producers, ux, sessionId, escapeHint, malformedSections) {
206
+ function blockJson(toolName, reason, producers, ux, sessionId, escapeHint, malformedSections, retryInstruction) {
80
207
  // When the pack config declares `ux:`, the agent-facing surface
81
208
  // becomes the plain-language `{ cannot, required, run }` shape, and
82
209
  // the legacy schemaHint + producers block is suppressed (the ux
@@ -125,6 +252,15 @@ function blockJson(toolName, reason, producers, ux, sessionId, escapeHint, malfo
125
252
  if (escapeHint) {
126
253
  reasonText = `${reasonText}\n\n${escapeHint}`;
127
254
  }
255
+ // Slice 3's repeated-retry instruction, appended only when a valid
256
+ // delegation was present and the child's report simply had not landed
257
+ // yet. It is the most immediate remediation for that specific case (and
258
+ // the only one the child can act on alone), so it reads last. The
259
+ // standard reason above is kept intact rather than replaced: an
260
+ // operator reading the audit trail still sees the same block cause.
261
+ if (retryInstruction) {
262
+ reasonText = `${reasonText}\n\n${retryInstruction}`;
263
+ }
128
264
  return JSON.stringify({
129
265
  decision: "block",
130
266
  reason: reasonText,
@@ -543,6 +679,198 @@ export async function runPackHookPreToolUseCli(opts = {}) {
543
679
  // up `grounding-mcp` in the manifest on demand. Stays audit-only
544
680
  // either way: a missing `grounding-mcp` entry costs one stderr line
545
681
  // inside the auto path, never an approval.
682
+ // Step 9's key-one-by-delegation branch (slice 3, agent-tasks/37ad0b05,
683
+ // ADR "Decision: two-key design"). Placed immediately before the
684
+ // `attemptAutoApproval` call and therefore, like it, only on a call
685
+ // every branch above has already declined. What happens here is
686
+ // narrow: verify the delegation, and if it holds, obtain the child's
687
+ // OWN report through the bounded transcript poll and persist it
688
+ // `pending`. It writes no marker and returns no allow of its own; the
689
+ // auto path below still applies every condition it applies to a
690
+ // `when`-matched call, the `pending`-only report rule included, and the
691
+ // marker re-check inside it is still the only thing that allows.
692
+ //
693
+ // Fail-closed at every step, each with its own stderr line: no opt-in,
694
+ // an unlisted harness, no payload `session_id`, no delegation file, an
695
+ // absent signing key, any refusal from `verifyDelegation`, an
696
+ // unparseable or absent transcript report. Each one falls through with
697
+ // `delegation` unset, and the block below is what the call then
698
+ // reaches.
699
+ let delegation;
700
+ // Set only by the bound elapsing with no report in the transcript: the
701
+ // measured case where the child DID what it was asked and the write is
702
+ // simply still in flight. That is the one case where the deny text asks
703
+ // for a retry, so it is the one case that sets this flag.
704
+ let reportScanTimedOut = false;
705
+ if (generatedDir !== undefined && !markerForged) {
706
+ // `null` stderr on purpose: `attemptAutoApproval` parses the same
707
+ // block a few lines below and writes the malformed-config line
708
+ // itself, so passing this hook's stderr here would double it.
709
+ const autoCfg = parseAutoApprove(declared.config["auto_approve"], null);
710
+ const payloadSid = typeof event.session_id === "string" && event.session_id.length > 0
711
+ ? event.session_id
712
+ : null;
713
+ let delegationPath = null;
714
+ if (autoCfg !== null && harnessAllowed(autoCfg, CLAUDE_CODE_HARNESS) && payloadSid !== null) {
715
+ try {
716
+ delegationPath = delegationMarkerPathFor(generatedDir, payloadSid);
717
+ }
718
+ catch {
719
+ // A session id that cannot name a file has no delegation, by
720
+ // construction (`verifyDelegation` draws the same conclusion).
721
+ delegationPath = null;
722
+ }
723
+ }
724
+ if (autoCfg !== null && delegationPath !== null && existsSync(delegationPath)) {
725
+ const childSessionId = payloadSid;
726
+ if (!signingKeyExists(generatedDir)) {
727
+ // Never verify through a path that would MINT the key
728
+ // (`verifyMarkerSignature` -> `getOrCreateSigningKey`). The
729
+ // verifier prechecks this too; this line names the condition at
730
+ // the hook, where the operator is reading.
731
+ stderr.write("harness pack hook: delegation present but signing key absent; not verified\n");
732
+ }
733
+ else {
734
+ const verified = verifyDelegation({
735
+ generatedDir,
736
+ childSessionId,
737
+ // The payload's own cwd, held against the hashed binding the
738
+ // parent signed. Absent means the delegation's cwd binding
739
+ // cannot be satisfied, which the verifier reports as a
740
+ // `cwd_mismatch` rather than waving through.
741
+ cwd: typeof event.cwd === "string" && event.cwd.length > 0 ? event.cwd : null,
742
+ // The same active-claim id the task-scoped marker check resolves
743
+ // above, so a delegation issued for one task cannot authorize a
744
+ // child that has claimed another. Read a SECOND time here on
745
+ // purpose: `checkOperatorApprovalMarkers` resolves the claim
746
+ // inside itself and returns only a detail string, never the id,
747
+ // so there is no resolved value to reuse without widening that
748
+ // shared runtime's return shape for one caller.
749
+ taskId: readActiveClaim(generatedDir),
750
+ });
751
+ if (!verified.ok) {
752
+ if (verified.reason === "report_path_mismatch") {
753
+ // This hook never passes `launcherReportPath` to
754
+ // `verifyDelegation`, so a delegation that binds one (the
755
+ // `--report` fallback shape) is refused here every time,
756
+ // not merely on a path/content mismatch. Name the actual
757
+ // limitation instead of the generic `report_path_mismatch`
758
+ // wording `verified.detail` carries: the fallback shape is
759
+ // issued and signature-verifiable by `harness delegate`, it
760
+ // is just not yet consumed by THIS hook (a named
761
+ // follow-up); the transcript scan below is the only report
762
+ // channel this hook acts on today.
763
+ stderr.write(`harness pack hook: delegation for ${childSessionId} refused: it binds a launcher-supplied report file (the --report fallback shape), which is issued and verifiable but not yet consumed by the child hook (a named follow-up); the transcript scan is the only report channel this hook acts on\n`);
764
+ }
765
+ else {
766
+ stderr.write(`harness pack hook: delegation for ${childSessionId} refused: ${verified.reason}: ${verified.detail}\n`);
767
+ }
768
+ }
769
+ else {
770
+ delegation = { parentSessionId: verified.parentSessionId };
771
+ // Key two: the child's own report. Already on disk and pending
772
+ // (the child was denied once and its report has since been
773
+ // captured) means there is nothing to scan for, so the
774
+ // transcript is not read at all.
775
+ // `childSessionId`, not the outer `sessionId`: this whole block
776
+ // decides the PAYLOAD's session, and the two only coincide
777
+ // because the env fallback never wins on a path that carries a
778
+ // payload session_id. Spelling it out keeps the report this
779
+ // branch looks for bound to the same session the delegation,
780
+ // the scan and the adoption ledger are all keyed by.
781
+ const existing = selectNewestStrictSessionReport(listPersistedReports(reportsDir), childSessionId);
782
+ if (existing === null || existing.approvalStatus !== "pending") {
783
+ const transcriptPath = typeof event.transcript_path === "string" && event.transcript_path.length > 0
784
+ ? event.transcript_path
785
+ : null;
786
+ // The once-per-session adoption ledger, read only on the path
787
+ // that can actually capture something.
788
+ const adoptedPath = adoptedEntriesPathFor(generatedDir, childSessionId);
789
+ const adopted = transcriptPath === null
790
+ ? { ok: true, ids: new Set() }
791
+ : readAdoptedEntries(adoptedPath);
792
+ if (transcriptPath === null) {
793
+ stderr.write(`harness pack hook: delegation for ${childSessionId} is valid but the payload carries no transcript_path; the child's report cannot be captured\n`);
794
+ }
795
+ else if (!adopted.ok) {
796
+ // Fail closed: without the ledger we cannot tell a fresh
797
+ // report from one this session already spent.
798
+ stderr.write(`harness pack hook: the adopted-entry ledger at ${adoptedPath} could not be read (${adopted.detail}); refusing to capture a transcript entry that may already have been adopted for session ${childSessionId}\n`);
799
+ }
800
+ else {
801
+ const scan = await scanTranscriptForReport({
802
+ transcriptPath,
803
+ sessionId: childSessionId,
804
+ maxWaitMs: autoCfg.reportScan.maxWaitMs,
805
+ adopted: adopted.ids,
806
+ ...(opts.reportScanClock?.now !== undefined
807
+ ? { now: opts.reportScanClock.now }
808
+ : {}),
809
+ ...(opts.reportScanClock?.sleep !== undefined
810
+ ? { sleep: opts.reportScanClock.sleep }
811
+ : {}),
812
+ ...(opts.reportScanClock?.pollMs !== undefined
813
+ ? { pollMs: opts.reportScanClock.pollMs }
814
+ : {}),
815
+ });
816
+ if (scan.found) {
817
+ // RECORD THE ADOPTION FIRST, then persist. In this order a
818
+ // failed ledger write costs one blocked call and leaves the
819
+ // entry re-scannable, while the reverse order would leave a
820
+ // persisted, mintable report behind an unrecorded adoption:
821
+ // exactly the replay this ledger exists to stop.
822
+ const recorded = recordAdoptedEntry(adoptedPath, scan.entryId);
823
+ if (!recorded.ok) {
824
+ stderr.write(`harness pack hook: could not record transcript entry ${scan.entryId} as adopted for session ${childSessionId} (${recorded.detail}); nothing was persisted\n`);
825
+ }
826
+ else {
827
+ // Reuses the SAME persister `harness approve
828
+ // understanding` uses for a heredoc-attached report, so
829
+ // the capture is session-bound, `pending`, and validated
830
+ // by one parser rather than a second one written here.
831
+ // A real `new Date()` on purpose: the persisted report
832
+ // must sort as the newest strict-session report against
833
+ // whatever is already on disk, which a caller-injected
834
+ // clock could not guarantee.
835
+ const persisted = persistStdinReport({
836
+ markdown: scan.markdown,
837
+ reportsDir,
838
+ sessionId: childSessionId,
839
+ now: new Date(),
840
+ mode: toPackageMode(resolveMode(declared).mode),
841
+ });
842
+ if (persisted.ok) {
843
+ stderr.write(`harness pack hook: captured the Understanding Report for session ${childSessionId} from its own transcript (line ${scan.lineIndex}, after ${scan.waitedMs}ms) and persisted it pending at ${persisted.filePath}\n`);
844
+ }
845
+ else {
846
+ // The entry stays adopted: re-reading a report that
847
+ // does not parse would fail identically forever, so
848
+ // the child needs a NEW one, which is what the block's
849
+ // retry instruction asks for. Set the same flag the
850
+ // timeout branch sets, for that reason: the retry
851
+ // sentence reads correctly for this case too, and
852
+ // without it the block below would ask for a retry
853
+ // implicitly while never saying so.
854
+ reportScanTimedOut = true;
855
+ stderr.write(`harness pack hook: the transcript report for session ${childSessionId} did not parse (${persisted.reason}); nothing was persisted\n`);
856
+ }
857
+ }
858
+ }
859
+ else if (scan.reason === "timeout") {
860
+ reportScanTimedOut = true;
861
+ stderr.write(scan.adoptedOnly === true
862
+ ? `harness pack hook: the newest Understanding Report entry in the transcript for session ${childSessionId} was already adopted; emit a fresh report\n`
863
+ : `harness pack hook: no Understanding Report for session ${childSessionId} reached its transcript within ${autoCfg.reportScan.maxWaitMs}ms (waited ${scan.waitedMs}ms); blocking and asking the child to re-emit and retry\n`);
864
+ }
865
+ else {
866
+ stderr.write(`harness pack hook: the transcript at ${transcriptPath} exists but could not be read; the report for session ${childSessionId} cannot be captured\n`);
867
+ }
868
+ }
869
+ }
870
+ }
871
+ }
872
+ }
873
+ }
546
874
  const resolveAutoLedger = () => {
547
875
  if (opts.writeLedger)
548
876
  return { write: opts.writeLedger };
@@ -572,6 +900,11 @@ export async function runPackHookPreToolUseCli(opts = {}) {
572
900
  packConfig: declared.config,
573
901
  reportsDir,
574
902
  markerForged,
903
+ // Slice 3: present only when the branch above verified a delegation
904
+ // for this child session. It supplies key ONE in place of a
905
+ // `when`-listed `permission_mode`; every other condition, key two
906
+ // included, is unchanged.
907
+ ...(delegation !== undefined ? { delegation } : {}),
575
908
  stderr,
576
909
  resolveLedger: resolveAutoLedger,
577
910
  });
@@ -609,7 +942,7 @@ export async function runPackHookPreToolUseCli(opts = {}) {
609
942
  const latestParseError = report.report === null
610
943
  ? findLatestParseError(path.join(path.dirname(reportsDir), "parse-errors"), sessionId)
611
944
  : null;
612
- stdout.write(`${blockJson(toolName, "no approved Understanding Report for this session", configProducers, configUx, sessionId, escapeHint, latestParseError?.malformedSections)}\n`);
945
+ stdout.write(`${blockJson(toolName, "no approved Understanding Report for this session", configProducers, configUx, sessionId, escapeHint, latestParseError?.malformedSections, reportScanTimedOut ? DELEGATION_REPORT_RETRY_INSTRUCTION : null)}\n`);
613
946
  return {
614
947
  exitCode: 0,
615
948
  blocked: true,