@lannguyensi/harness 0.13.0 → 0.14.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.
@@ -21,7 +21,7 @@
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
23
  import { queryLedgerByTag, } from "../../policies/index.js";
24
- import { checkPersistedReport, defaultReportsDir, matchLedgerEntries, } from "../../policy-packs/builtin/understanding-before-execution-runtime.js";
24
+ import { checkApprovalMarker, checkPersistedReport, defaultReportsDir, matchLedgerEntries, } from "../../policy-packs/builtin/understanding-before-execution-runtime.js";
25
25
  import { resolveGeneratedDir, writePendingApproval, } from "../../runtime/pending-approval.js";
26
26
  import { loadManifest } from "../loader.js";
27
27
  const PACK_NAME = "understanding-before-execution";
@@ -202,19 +202,39 @@ export async function runPackHookPreToolUseCli(opts = {}) {
202
202
  diagnostic,
203
203
  };
204
204
  }
205
- // Source 1: ledger.
206
- const ledger = await checkLedger(manifest, sessionId, opts);
207
- if (ledger.matched) {
208
- const diagnostic = `harness pack hook: ${ledger.detail}, allowing.`;
209
- stderr.write(`${diagnostic}\n`);
210
- return {
211
- exitCode: 0,
212
- blocked: false,
213
- approvalCheck: { approved: true, source: "ledger", detail: ledger.detail },
214
- diagnostic,
215
- };
205
+ // Resolve generatedDir up-front: marker check and pending-approval
206
+ // staging both depend on it.
207
+ const generatedDir = opts.generatedDir ??
208
+ (manifestPath !== undefined
209
+ ? resolveGeneratedDir({
210
+ ...(opts.homeDir !== undefined ? { homeDir: opts.homeDir } : {}),
211
+ manifestPath,
212
+ })
213
+ : undefined);
214
+ // Source 1: filesystem marker (agent-tasks/88ca4bb3). Canonical for
215
+ // harnessed sessions. The ledger check is no longer authoritative
216
+ // because the agent has direct MCP access to the same ledger and
217
+ // could self-approve; the marker file lives in harness.generated/
218
+ // which Edit / Write / Bash are all gated from writing to. Bail to
219
+ // ledger-as-audit only when generatedDir is unresolvable (injected
220
+ // manifest without a resolved path: only happens in tests).
221
+ if (generatedDir !== undefined) {
222
+ const marker = checkApprovalMarker(generatedDir, sessionId);
223
+ if (marker.matched) {
224
+ const diagnostic = `harness pack hook: ${marker.detail}, allowing.`;
225
+ stderr.write(`${diagnostic}\n`);
226
+ return {
227
+ exitCode: 0,
228
+ blocked: false,
229
+ approvalCheck: { approved: true, source: "marker", detail: marker.detail },
230
+ diagnostic,
231
+ };
232
+ }
216
233
  }
217
- // Source 2: persisted report.
234
+ // Source 2: persisted report. Operator-authored (the agent's Stop
235
+ // hook only writes `pending`; flipping to `approved` requires the
236
+ // operator-side rewrite path in `harness approve understanding`),
237
+ // and the agent has no Edit / Write / Bash path to forge it.
218
238
  const reportsDir = opts.reportsDir ?? defaultReportsDir();
219
239
  const report = checkPersistedReport(reportsDir, sessionId);
220
240
  if (report.approved) {
@@ -227,20 +247,21 @@ export async function runPackHookPreToolUseCli(opts = {}) {
227
247
  diagnostic,
228
248
  };
229
249
  }
230
- // Neither source approved.
231
- const reason = `${ledger.detail}; ${report.detail}`;
250
+ // Audit-only ledger probe: the ledger row is still recorded by
251
+ // `harness approve understanding`, and we surface its presence in
252
+ // the diagnostic so an operator chasing a flapping gate can see the
253
+ // historic trail. The result intentionally does NOT influence the
254
+ // allow/block decision.
255
+ const ledger = await checkLedger(manifest, sessionId, opts);
256
+ // Neither operator source approved.
257
+ const reason = generatedDir !== undefined
258
+ ? `no approval marker for session ${sessionId}; ${report.detail}; ${ledger.detail}`
259
+ : `generatedDir not resolvable (test/injection path); ${report.detail}; ${ledger.detail}`;
232
260
  // Stage the session id so `harness approve`, run from the operator's
233
261
  // shell where $CLAUDE_SESSION_ID is unset, can resolve it without
234
262
  // guessing from transcript filenames. Covers both the ask and the
235
263
  // block branches below. Best-effort: a staging-write failure must not
236
264
  // escalate a gate block into a hook error.
237
- const generatedDir = opts.generatedDir ??
238
- (manifestPath !== undefined
239
- ? resolveGeneratedDir({
240
- ...(opts.homeDir !== undefined ? { homeDir: opts.homeDir } : {}),
241
- manifestPath,
242
- })
243
- : undefined);
244
265
  if (generatedDir !== undefined) {
245
266
  try {
246
267
  writePendingApproval(generatedDir, sessionId);
@@ -1 +1 @@
1
- {"version":3,"file":"hook-pre-tool-use.js","sourceRoot":"","sources":["../../../src/cli/pack/hook-pre-tool-use.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hook-pre-tool-use.js","sourceRoot":"","sources":["../../../src/cli/pack/hook-pre-tool-use.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- export { evaluateRequires, RequiresEvaluationError, type EvaluateRequiresOptions, type LedgerEntry, type RequiresEvaluation, type RequiresTrace, } from "./requires.js";
1
+ export { buildRecordHint, evaluateRequires, RequiresEvaluationError, type EvaluateRequiresOptions, type LedgerEntry, type RequiresEvaluation, type RequiresTrace, } from "./requires.js";
2
2
  export { parseDurationSeconds, InvalidDurationError } from "./duration.js";
3
3
  export { parseLedgerTimestamp } from "./timestamp.js";
4
4
  export { queryLedgerByTag, type LedgerClientOptions, type LedgerQueryResult, type QueryLedgerOptions, } from "./ledger-client.js";
@@ -1,4 +1,4 @@
1
- export { evaluateRequires, RequiresEvaluationError, } from "./requires.js";
1
+ export { buildRecordHint, evaluateRequires, RequiresEvaluationError, } from "./requires.js";
2
2
  export { parseDurationSeconds, InvalidDurationError } from "./duration.js";
3
3
  export { parseLedgerTimestamp } from "./timestamp.js";
4
4
  export { queryLedgerByTag, } from "./ledger-client.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/policies/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,uBAAuB,GAKxB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EACL,gBAAgB,GAIjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,eAAe,EACf,kBAAkB,EAClB,mBAAmB,GASpB,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/policies/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,uBAAuB,GAKxB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EACL,gBAAgB,GAIjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,eAAe,EACf,kBAAkB,EAClB,mBAAmB,GASpB,MAAM,cAAc,CAAC"}
@@ -21,6 +21,20 @@ export interface RequiresEvaluation {
21
21
  reason: string;
22
22
  matchedCount: number;
23
23
  traceData: RequiresTrace;
24
+ /**
25
+ * One-line "to satisfy" hint describing what evidence-ledger entry
26
+ * would unblock the gate, derived from the policy's `requires` spec
27
+ * with no runtime context. Names the content to log and (if a
28
+ * `within` window is declared) the freshness bound. Always omits the
29
+ * "how": the policy gate accepts ledger entries from any producer,
30
+ * and naming a specific recording verb in the deny path would
31
+ * advertise a self-service path to an agent that the operator may
32
+ * not want it to take (see agent-tasks/88ca4bb3). Set on both allow
33
+ * and deny so consumers can show the same satisfaction contract
34
+ * uniformly (e.g. `harness explain <policy>` displaying it on a
35
+ * green-path policy).
36
+ */
37
+ recordHint: string;
24
38
  }
25
39
  export interface RequiresTrace {
26
40
  ledgerTag: string;
@@ -41,4 +55,13 @@ export interface EvaluateRequiresOptions {
41
55
  export declare class RequiresEvaluationError extends Error {
42
56
  constructor(message: string);
43
57
  }
58
+ /**
59
+ * Build a one-line "to satisfy" hint from a `requires` spec. Exported so
60
+ * `harness explain <policy>` can show the same hint that `evaluateRequires`
61
+ * surfaces in its deny path, without having to fire an actual evaluation.
62
+ * `tag` is normally `requires.ledger_tag` after `${VAR}` substitution; the
63
+ * caller may also pass the un-substituted template (explain non-trace path)
64
+ * so the hint reads as a contract instead of a per-event message.
65
+ */
66
+ export declare function buildRecordHint(requires: Requires, tag: string): string;
44
67
  export declare function evaluateRequires(requires: Requires, ledgerEntries: LedgerEntry[], options?: EvaluateRequiresOptions): RequiresEvaluation;
@@ -51,6 +51,39 @@ function describeBound(c) {
51
51
  return `≤${c.max}`;
52
52
  return "?";
53
53
  }
54
+ /**
55
+ * Build a one-line "to satisfy" hint from a `requires` spec. Exported so
56
+ * `harness explain <policy>` can show the same hint that `evaluateRequires`
57
+ * surfaces in its deny path, without having to fire an actual evaluation.
58
+ * `tag` is normally `requires.ledger_tag` after `${VAR}` substitution; the
59
+ * caller may also pass the un-substituted template (explain non-trace path)
60
+ * so the hint reads as a contract instead of a per-event message.
61
+ */
62
+ export function buildRecordHint(requires, tag) {
63
+ const count = requires.count;
64
+ // count.max-only is a "too many" shape: the satisfying action is not
65
+ // recording but keeping the count at or below the bound. Recording
66
+ // more entries would deny harder, so the "record N entries..."
67
+ // phrasing the other shapes use is exactly wrong here. Branch to a
68
+ // bound-phrased hint (agent-tasks/aee9c085).
69
+ const onlyMax = count?.max !== undefined && count.min === undefined && count.exact === undefined;
70
+ if (onlyMax) {
71
+ const windowPhrase = requires.within !== undefined ? ` within ${requires.within}` : "";
72
+ return `keep evidence-ledger entries containing \`${tag}\` at or below ${count.max}${windowPhrase}`;
73
+ }
74
+ let countPhrase;
75
+ if (count?.exact !== undefined) {
76
+ countPhrase = `${count.exact} evidence-ledger entr${count.exact === 1 ? "y" : "ies"}`;
77
+ }
78
+ else if (count?.min !== undefined) {
79
+ countPhrase = `${count.min} evidence-ledger entr${count.min === 1 ? "y" : "ies"}`;
80
+ }
81
+ else {
82
+ countPhrase = "an evidence-ledger entry";
83
+ }
84
+ const windowPhrase = requires.within !== undefined ? ` within ${requires.within}` : "";
85
+ return `record ${countPhrase} containing \`${tag}\`${windowPhrase}`;
86
+ }
54
87
  export function evaluateRequires(requires, ledgerEntries, options = {}) {
55
88
  const now = options.now ?? new Date();
56
89
  const evaluatedAt = now.toISOString();
@@ -93,6 +126,7 @@ export function evaluateRequires(requires, ledgerEntries, options = {}) {
93
126
  countBound,
94
127
  evaluatedAt,
95
128
  };
129
+ const recordHint = buildRecordHint(requires, tag);
96
130
  if (requires.count !== undefined) {
97
131
  const c = requires.count;
98
132
  const failsMin = c.min !== undefined && matchedCount < c.min;
@@ -112,6 +146,7 @@ export function evaluateRequires(requires, ledgerEntries, options = {}) {
112
146
  reason,
113
147
  matchedCount,
114
148
  traceData: trace,
149
+ recordHint,
115
150
  };
116
151
  }
117
152
  return {
@@ -119,6 +154,7 @@ export function evaluateRequires(requires, ledgerEntries, options = {}) {
119
154
  reason: `${matchedCount} entries matched (count bound: ${describeBound(c)})`,
120
155
  matchedCount,
121
156
  traceData: trace,
157
+ recordHint,
122
158
  };
123
159
  }
124
160
  if (matchedCount === 0) {
@@ -128,6 +164,7 @@ export function evaluateRequires(requires, ledgerEntries, options = {}) {
128
164
  reason: `no matching entry within ${requires.within}`,
129
165
  matchedCount,
130
166
  traceData: trace,
167
+ recordHint,
131
168
  };
132
169
  }
133
170
  return {
@@ -135,6 +172,7 @@ export function evaluateRequires(requires, ledgerEntries, options = {}) {
135
172
  reason: `no matching ledger entry for tag \`${tag}\``,
136
173
  matchedCount,
137
174
  traceData: trace,
175
+ recordHint,
138
176
  };
139
177
  }
140
178
  return {
@@ -142,6 +180,7 @@ export function evaluateRequires(requires, ledgerEntries, options = {}) {
142
180
  reason: `${matchedCount} matching ledger entr${matchedCount === 1 ? "y" : "ies"} for tag \`${tag}\``,
143
181
  matchedCount,
144
182
  traceData: trace,
183
+ recordHint,
145
184
  };
146
185
  }
147
186
  //# sourceMappingURL=requires.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"requires.js","sourceRoot":"","sources":["../../src/policies/requires.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"requires.js","sourceRoot":"","sources":["../../src/policies/requires.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { type LedgerEntry } from "../../policies/index.js";
2
2
  export declare const APPROVED_LEDGER_TAG_PREFIX = "understanding-approved:";
3
- export type ApprovalSource = "ledger" | "persisted-report" | "none";
3
+ export declare const APPROVAL_MARKER_DIRNAME = ".approvals";
4
+ export type ApprovalSource = "marker" | "ledger" | "persisted-report" | "none";
4
5
  export interface ApprovalCheckResult {
5
6
  approved: boolean;
6
7
  source: ApprovalSource;
@@ -70,14 +71,51 @@ export interface PersistedReportApprovalCheck {
70
71
  */
71
72
  export declare function isPolicyDecisionRow(e: LedgerEntry): boolean;
72
73
  /**
73
- * Match a ledger fetch against the per-session approval tag. Returns
74
- * `{matched: true, detail}` on the first non-policy_decision row whose
75
- * content includes the wanted tag; otherwise `{matched: false, detail}`
76
- * naming how many rows were scanned. Stable across Claude Code and
77
- * Codex blockers so their diagnostic strings stay identical.
74
+ * Match a ledger fetch against the per-session approval tag. Kept for
75
+ * the audit / forensics path only: a ledger entry tagged
76
+ * `understanding-approved:<sid>` is no longer a sufficient signal to
77
+ * unblock the gate (agent-tasks/88ca4bb3: the agent has the same MCP
78
+ * surface and could self-write the row). Use `checkApprovalMarker`
79
+ * for the gate decision; this helper now serves `harness audit` /
80
+ * `harness explain --trace` style read paths that surface the
81
+ * historic ledger trail without granting approval power.
78
82
  */
79
83
  export declare function matchLedgerEntries(entries: LedgerEntry[], sessionId: string): {
80
84
  matched: boolean;
81
85
  detail: string;
82
86
  };
87
+ /** Filesystem path of the per-session approval marker. */
88
+ export declare function approvalMarkerPathFor(generatedDir: string, sessionId: string): string;
89
+ export interface ApprovalMarker {
90
+ approvedAt: string;
91
+ approvedBy: string;
92
+ }
93
+ /**
94
+ * Operator-side: write the marker file the gate consults. Atomic so a
95
+ * crash mid-write cannot leave a half-empty file the gate would accept
96
+ * as approved. Caller is `harness approve understanding`, which the
97
+ * operator runs from their un-hooked shell; if the agent could call
98
+ * this path the gate's value would collapse, so it lives behind the
99
+ * approve CLI rather than as a generally importable verb.
100
+ */
101
+ export declare function writeApprovalMarker(generatedDir: string, sessionId: string, marker: ApprovalMarker): string;
102
+ export interface MarkerCheck {
103
+ matched: boolean;
104
+ detail: string;
105
+ marker: ApprovalMarker | null;
106
+ }
107
+ /**
108
+ * Gate-side: is the per-session marker file present and readable?
109
+ * Returns `matched: true` even if the marker JSON is malformed: the
110
+ * file's *existence* is the operator's intent. Corrupted contents
111
+ * surface as `marker: null` in the diagnostic but do not invalidate the
112
+ * approval, since invalidating on a parse error would hand a denial-
113
+ * of-service vector to anyone (including the agent) who could append a
114
+ * stray byte to the file. Edit / Write / Bash are gated, so writing
115
+ * stray bytes from inside Claude is not possible today, but the
116
+ * existence-only contract is the defensible boundary regardless.
117
+ */
118
+ export declare function checkApprovalMarker(generatedDir: string, sessionId: string): MarkerCheck;
119
+ /** Clear the per-session marker (used by `harness approve --revoke` and tests). */
120
+ export declare function clearApprovalMarker(generatedDir: string, sessionId: string): void;
83
121
  export declare function checkPersistedReport(reportsDir: string, sessionId: string): PersistedReportApprovalCheck;
@@ -3,21 +3,38 @@
3
3
  // Two-source approval check that the harness-side PreToolUse blocker
4
4
  // consults:
5
5
  //
6
- // 1. Evidence ledger via `grounding-mcp` (canonical for harnessed
7
- // sessions). Tags shaped like `understanding-approved:${SESSION_ID}`.
6
+ // 1. Filesystem marker `<generatedDir>/.approvals/<sessionId>` written
7
+ // by `harness approve understanding` from the operator's shell.
8
+ // Canonical for harnessed sessions. Replaces the ledger-substring
9
+ // check that shipped through v0.13.0 (agent-tasks/88ca4bb3): the
10
+ // agent has direct MCP access to the same ledger that gate path
11
+ // consulted, so any agent could write `understanding-approved:<sid>`
12
+ // itself and self-approve. Edit / Write / Bash are all gated by
13
+ // this same PreToolUse hook, and the configured MCP servers do not
14
+ // expose filesystem writes, so the marker file is reachable only
15
+ // from a process the operator launched (their `!`-shell or any
16
+ // other un-hooked terminal). Operator-side: writeApprovalMarker
17
+ // below. Forensics: the ledger row is still written by
18
+ // `harness approve understanding`, for audit only.
8
19
  // 2. Persisted JSON report under `.understanding-gate/reports/`
9
20
  // (canonical for solo `@lannguyensi/understanding-gate` users).
10
21
  // The package writes one file per session; the latest with
11
- // `approvalStatus: "approved"` matching the session_id wins.
22
+ // `approvalStatus: "approved"` matching the session_id wins. The
23
+ // report is flipped to "approved" by `harness approve`; the
24
+ // agent's Stop hook only writes `pending` reports and cannot flip
25
+ // them (Edit/Write/Bash gated), so this source is also operator-
26
+ // authored.
12
27
  //
13
28
  // Either source approves. The persisted-report fallback is what makes a
14
29
  // solo user without grounding-mcp wired still able to approve via the
15
- // package's CLI; the ledger path is what makes a harnessed session see
30
+ // package's CLI; the marker path is what makes a harnessed session see
16
31
  // the approval immediately on the next tool call.
17
32
  import * as fs from "node:fs";
18
33
  import * as path from "node:path";
34
+ import { atomicWriteFile } from "../../io/atomic-write.js";
19
35
  import { POLICY_DECISION_TYPE } from "../../runtime/ledger-record.js";
20
36
  export const APPROVED_LEDGER_TAG_PREFIX = "understanding-approved:";
37
+ export const APPROVAL_MARKER_DIRNAME = ".approvals";
21
38
  const DEFAULT_REPORTS_DIRNAME = ".understanding-gate";
22
39
  const REPORTS_SUBDIR = "reports";
23
40
  /**
@@ -160,11 +177,14 @@ export function isPolicyDecisionRow(e) {
160
177
  return false;
161
178
  }
162
179
  /**
163
- * Match a ledger fetch against the per-session approval tag. Returns
164
- * `{matched: true, detail}` on the first non-policy_decision row whose
165
- * content includes the wanted tag; otherwise `{matched: false, detail}`
166
- * naming how many rows were scanned. Stable across Claude Code and
167
- * Codex blockers so their diagnostic strings stay identical.
180
+ * Match a ledger fetch against the per-session approval tag. Kept for
181
+ * the audit / forensics path only: a ledger entry tagged
182
+ * `understanding-approved:<sid>` is no longer a sufficient signal to
183
+ * unblock the gate (agent-tasks/88ca4bb3: the agent has the same MCP
184
+ * surface and could self-write the row). Use `checkApprovalMarker`
185
+ * for the gate decision; this helper now serves `harness audit` /
186
+ * `harness explain --trace` style read paths that surface the
187
+ * historic ledger trail without granting approval power.
168
188
  */
169
189
  export function matchLedgerEntries(entries, sessionId) {
170
190
  const wanted = approvedLedgerTagFor(sessionId);
@@ -176,7 +196,7 @@ export function matchLedgerEntries(entries, sessionId) {
176
196
  if (typeof e.content === "string" && e.content.includes(wanted)) {
177
197
  return {
178
198
  matched: true,
179
- detail: `approved via ledger tag ${wanted} at ${e.createdAt}`,
199
+ detail: `audit: ledger tag ${wanted} present at ${e.createdAt} (no longer satisfies the gate; see harness.generated/${APPROVAL_MARKER_DIRNAME}/${sessionId})`,
180
200
  };
181
201
  }
182
202
  }
@@ -185,6 +205,102 @@ export function matchLedgerEntries(entries, sessionId) {
185
205
  detail: `no ledger entry matched ${wanted} (scanned ${scanned} non-policy_decision row(s))`,
186
206
  };
187
207
  }
208
+ /** Filesystem path of the per-session approval marker. */
209
+ export function approvalMarkerPathFor(generatedDir, sessionId) {
210
+ return path.join(generatedDir, APPROVAL_MARKER_DIRNAME, sessionId);
211
+ }
212
+ /**
213
+ * Operator-side: write the marker file the gate consults. Atomic so a
214
+ * crash mid-write cannot leave a half-empty file the gate would accept
215
+ * as approved. Caller is `harness approve understanding`, which the
216
+ * operator runs from their un-hooked shell; if the agent could call
217
+ * this path the gate's value would collapse, so it lives behind the
218
+ * approve CLI rather than as a generally importable verb.
219
+ */
220
+ export function writeApprovalMarker(generatedDir, sessionId, marker) {
221
+ const filePath = approvalMarkerPathFor(generatedDir, sessionId);
222
+ atomicWriteFile(filePath, `${JSON.stringify(marker, null, 2)}\n`);
223
+ return filePath;
224
+ }
225
+ /**
226
+ * Gate-side: is the per-session marker file present and readable?
227
+ * Returns `matched: true` even if the marker JSON is malformed: the
228
+ * file's *existence* is the operator's intent. Corrupted contents
229
+ * surface as `marker: null` in the diagnostic but do not invalidate the
230
+ * approval, since invalidating on a parse error would hand a denial-
231
+ * of-service vector to anyone (including the agent) who could append a
232
+ * stray byte to the file. Edit / Write / Bash are gated, so writing
233
+ * stray bytes from inside Claude is not possible today, but the
234
+ * existence-only contract is the defensible boundary regardless.
235
+ */
236
+ export function checkApprovalMarker(generatedDir, sessionId) {
237
+ const filePath = approvalMarkerPathFor(generatedDir, sessionId);
238
+ let stat;
239
+ try {
240
+ // lstatSync (NOT statSync): defense-in-depth against a symlink at
241
+ // the marker path pointing at an arbitrary target the agent
242
+ // controls. In today's threat model the agent has no Edit / Write
243
+ // / Bash path to plant such a symlink (the same PreToolUse hook
244
+ // gates all three), but the gate's contract is to assume the
245
+ // agent is hostile, so the lstat reject is cheap insurance
246
+ // (agent-tasks/d39f160e).
247
+ stat = fs.lstatSync(filePath);
248
+ }
249
+ catch {
250
+ return {
251
+ matched: false,
252
+ detail: `no approval marker at ${filePath}`,
253
+ marker: null,
254
+ };
255
+ }
256
+ if (stat.isSymbolicLink()) {
257
+ return {
258
+ matched: false,
259
+ detail: `approval marker is a symlink, refusing for safety: ${filePath}`,
260
+ marker: null,
261
+ };
262
+ }
263
+ if (!stat.isFile()) {
264
+ return {
265
+ matched: false,
266
+ detail: `approval marker path is not a regular file: ${filePath}`,
267
+ marker: null,
268
+ };
269
+ }
270
+ let marker = null;
271
+ try {
272
+ const raw = fs.readFileSync(filePath, "utf8");
273
+ const parsed = safeJsonParse(raw);
274
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
275
+ const obj = parsed;
276
+ const approvedAt = typeof obj["approvedAt"] === "string" ? obj["approvedAt"] : "";
277
+ const approvedBy = typeof obj["approvedBy"] === "string" ? obj["approvedBy"] : "";
278
+ if (approvedAt.length > 0 && approvedBy.length > 0) {
279
+ marker = { approvedAt, approvedBy };
280
+ }
281
+ }
282
+ }
283
+ catch {
284
+ /* keep marker:null; existence already satisfied the gate */
285
+ }
286
+ const provenance = marker
287
+ ? `approved at ${marker.approvedAt} by ${marker.approvedBy}`
288
+ : "marker present, body unreadable (existence still satisfies the gate)";
289
+ return {
290
+ matched: true,
291
+ detail: `approved via marker ${path.basename(filePath)}: ${provenance}`,
292
+ marker,
293
+ };
294
+ }
295
+ /** Clear the per-session marker (used by `harness approve --revoke` and tests). */
296
+ export function clearApprovalMarker(generatedDir, sessionId) {
297
+ try {
298
+ fs.rmSync(approvalMarkerPathFor(generatedDir, sessionId));
299
+ }
300
+ catch {
301
+ /* already gone */
302
+ }
303
+ }
188
304
  export function checkPersistedReport(reportsDir, sessionId) {
189
305
  const reports = listPersistedReports(reportsDir);
190
306
  if (reports.length === 0) {
@@ -1 +1 @@
1
- {"version":3,"file":"understanding-before-execution-runtime.js","sourceRoot":"","sources":["../../../src/policy-packs/builtin/understanding-before-execution-runtime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"understanding-before-execution-runtime.js","sourceRoot":"","sources":["../../../src/policy-packs/builtin/understanding-before-execution-runtime.ts"],"names":[],"mappings":"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"}
@@ -20,6 +20,14 @@ export interface PolicyDecision {
20
20
  matchedCount: number;
21
21
  reason: string;
22
22
  };
23
+ /**
24
+ * One-line "to satisfy" hint synthesised from the policy's `requires`
25
+ * spec. Carried on the live decision so the deny-envelope formatter
26
+ * can append it to the user-facing reason text together with the
27
+ * session id. Optional because the warn-degraded path (requires eval
28
+ * threw) skips the requires evaluator and has no hint to forward.
29
+ */
30
+ recordHint?: string;
23
31
  evaluatedAt: string;
24
32
  }
25
33
  /**
@@ -131,6 +131,7 @@ async function evaluateOnePolicy(policy, options) {
131
131
  matchedCount: evaluation.matchedCount,
132
132
  reason: evaluation.reason,
133
133
  },
134
+ recordHint: evaluation.recordHint,
134
135
  evaluatedAt,
135
136
  };
136
137
  }
@@ -169,7 +170,18 @@ export async function intercept(options) {
169
170
  }
170
171
  const blocking = decisions.find((d) => d.enforcement === "block" && d.outcome === "deny");
171
172
  if (blocking) {
172
- const reasonText = `${blocking.policyName}: ${blocking.reason}`;
173
+ const sessionId = resolveSessionId(options.event.session_id);
174
+ // Append the "to satisfy" hint so Claude Code's deny message tells
175
+ // the operator (or the agent reading the same surface) what evidence
176
+ // would unblock the gate, instead of just naming the missing tag.
177
+ // The hint is content + window only; it does not prescribe a
178
+ // recording verb so the deny path stays neutral on producer (see
179
+ // agent-tasks/88ca4bb3 for why "use mcp__..." would be the wrong
180
+ // suggestion).
181
+ const hintSuffix = blocking.recordHint
182
+ ? ` To satisfy: ${blocking.recordHint} (session \`${sessionId}\`).`
183
+ : "";
184
+ const reasonText = `${blocking.policyName}: ${blocking.reason}.${hintSuffix}`;
173
185
  const block = {
174
186
  decision: "block",
175
187
  reason: reasonText,