@lannguyensi/harness 0.50.0 → 0.51.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 (55) hide show
  1. package/CHANGELOG.md +108 -0
  2. package/dist/cli/approve/understanding.d.ts +51 -0
  3. package/dist/cli/approve/understanding.js +17 -2
  4. package/dist/cli/approve/understanding.js.map +1 -1
  5. package/dist/cli/doctor/claude-mcp.d.ts +14 -0
  6. package/dist/cli/doctor/claude-mcp.js +7 -1
  7. package/dist/cli/doctor/claude-mcp.js.map +1 -1
  8. package/dist/cli/doctor/format.js +36 -1
  9. package/dist/cli/doctor/format.js.map +1 -1
  10. package/dist/cli/doctor/index.d.ts +20 -0
  11. package/dist/cli/doctor/index.js +40 -1
  12. package/dist/cli/doctor/index.js.map +1 -1
  13. package/dist/cli/doctor/settings-drift.d.ts +19 -0
  14. package/dist/cli/doctor/settings-drift.js +189 -0
  15. package/dist/cli/doctor/settings-drift.js.map +1 -0
  16. package/dist/cli/doctor/types.d.ts +26 -0
  17. package/dist/cli/doctor/types.js.map +1 -1
  18. package/dist/cli/doctor/ug-auto-approvals.d.ts +40 -0
  19. package/dist/cli/doctor/ug-auto-approvals.js +116 -0
  20. package/dist/cli/doctor/ug-auto-approvals.js.map +1 -0
  21. package/dist/cli/doctor/understanding-mode-env.d.ts +10 -0
  22. package/dist/cli/doctor/understanding-mode-env.js +12 -0
  23. package/dist/cli/doctor/understanding-mode-env.js.map +1 -1
  24. package/dist/cli/index.js +11 -0
  25. package/dist/cli/index.js.map +1 -1
  26. package/dist/cli/pack/auto-approve-path.d.ts +118 -0
  27. package/dist/cli/pack/auto-approve-path.js +347 -0
  28. package/dist/cli/pack/auto-approve-path.js.map +1 -0
  29. package/dist/cli/pack/hook-codex-pre-tool-use.d.ts +9 -0
  30. package/dist/cli/pack/hook-codex-pre-tool-use.js +118 -4
  31. package/dist/cli/pack/hook-codex-pre-tool-use.js.map +1 -1
  32. package/dist/cli/pack/hook-pre-tool-use.d.ts +11 -0
  33. package/dist/cli/pack/hook-pre-tool-use.js +67 -1
  34. package/dist/cli/pack/hook-pre-tool-use.js.map +1 -1
  35. package/dist/cli/validate/checks.js +81 -0
  36. package/dist/cli/validate/checks.js.map +1 -1
  37. package/dist/policy-packs/builtin/understanding-before-execution/auto-approve.d.ts +136 -0
  38. package/dist/policy-packs/builtin/understanding-before-execution/auto-approve.js +224 -0
  39. package/dist/policy-packs/builtin/understanding-before-execution/auto-approve.js.map +1 -0
  40. package/dist/policy-packs/builtin/understanding-before-execution/index.d.ts +2 -1
  41. package/dist/policy-packs/builtin/understanding-before-execution/index.js +2 -1
  42. package/dist/policy-packs/builtin/understanding-before-execution/index.js.map +1 -1
  43. package/dist/policy-packs/builtin/understanding-before-execution/measured-permission-modes.d.ts +29 -0
  44. package/dist/policy-packs/builtin/understanding-before-execution/measured-permission-modes.js +82 -0
  45. package/dist/policy-packs/builtin/understanding-before-execution/measured-permission-modes.js.map +1 -0
  46. package/dist/policy-packs/builtin/understanding-before-execution/persisted-reports.d.ts +23 -0
  47. package/dist/policy-packs/builtin/understanding-before-execution/persisted-reports.js +29 -0
  48. package/dist/policy-packs/builtin/understanding-before-execution/persisted-reports.js.map +1 -1
  49. package/dist/policy-packs/builtin/understanding-before-execution.d.ts +23 -0
  50. package/dist/policy-packs/builtin/understanding-before-execution.js +27 -1
  51. package/dist/policy-packs/builtin/understanding-before-execution.js.map +1 -1
  52. package/dist/runtime/approval-signing.d.ts +22 -0
  53. package/dist/runtime/approval-signing.js +55 -1
  54. package/dist/runtime/approval-signing.js.map +1 -1
  55. package/package.json +1 -1
@@ -0,0 +1,224 @@
1
+ // `auto_approve` pack-config parsing and shared conventions, split out
2
+ // alongside lifecycle.ts (structural sibling of the former monolithic
3
+ // understanding-before-execution-runtime.ts, agent-tasks 348a4d42).
4
+ // Implements slice 1 of docs/decisions/2026-08-27-ug-auto-mode-approval.md
5
+ // (agent-tasks 74b4b17d): the strict pack-config block that lets an
6
+ // operator opt a permission mode into the hook-written signed
7
+ // auto-marker path, plus the shared `approvedBy` / ledger-tag
8
+ // conventions the hook and doctor consume so there is one authority
9
+ // for the string shapes instead of each caller reimplementing them.
10
+ //
11
+ // This module owns no gate decision and no marker write: it only
12
+ // parses the opt-in config (fail-closed: any malformed shape is
13
+ // treated as "not opted in", never as a partial default) and builds /
14
+ // parses the string conventions the ADR's "Audit and doctor" section
15
+ // documents. The PreToolUse hook (auto-path condition checks) and
16
+ // `harness doctor` (auto-approval listing) are the consumers; both
17
+ // land in later slice-1 tasks and import from here.
18
+ /**
19
+ * Prefix every auto-minted marker's `approvedBy` carries, distinguishing
20
+ * it from a human `harness approve understanding` marker (which carries
21
+ * the operator's own identity string, never this prefix).
22
+ */
23
+ export const AUTO_APPROVED_BY_PREFIX = "auto-mode:";
24
+ /** The harness identifier the Claude Code PreToolUse hook mints markers for. */
25
+ export const CLAUDE_CODE_HARNESS = "claude-code";
26
+ /**
27
+ * The harness identifier the Codex PreToolUse hook mints markers for
28
+ * (slice 2 of the ADR: same auto path, same fail-closed conditions, a
29
+ * distinct `approvedBy` segment so an audit can tell the two runtimes
30
+ * apart). Deliberately NOT re-exported through
31
+ * `understanding-before-execution/index.ts`: its only consumer is
32
+ * `src/cli/pack/hook-codex-pre-tool-use.ts`, and widening the runtime
33
+ * shim's pinned public surface (tests/policy-packs/ube-export-surface.test.ts)
34
+ * is a separate, conscious act.
35
+ */
36
+ export const CODEX_HARNESS = "codex";
37
+ /**
38
+ * Build the `approvedBy` value the hook writes into a signed auto-marker:
39
+ * `auto-mode:<harness>:<mode>`, for example `auto-mode:claude-code:bypassPermissions`
40
+ * or `auto-mode:codex:bypassPermissions` ("Audit and doctor" in the ADR).
41
+ * Neither `harness` nor `mode` is validated here; callers pass
42
+ * already-known-good values (one of the fixed harness constants above and
43
+ * a `when`-matched mode string).
44
+ */
45
+ export function autoApprovedByFor(harness, mode) {
46
+ return `${AUTO_APPROVED_BY_PREFIX}${harness}:${mode}`;
47
+ }
48
+ /**
49
+ * Parse an `approvedBy` string back into its harness/mode pair. Returns
50
+ * `null` for anything that is not exactly `auto-mode:<harness>:<mode>`
51
+ * with both segments non-empty, including a human marker's `approvedBy`
52
+ * (which never carries this prefix) and a malformed or truncated auto
53
+ * value. A slice 3 delegation suffix (`;delegated:<parent-sid>`) is
54
+ * tolerated: it is stripped before parsing and otherwise ignored, per
55
+ * the ADR's "Audit and doctor" convention that the delegation binding
56
+ * packs into the same field without changing the harness/mode shape.
57
+ */
58
+ export function parseAutoApprovedBy(approvedBy) {
59
+ if (typeof approvedBy !== "string")
60
+ return null;
61
+ if (!approvedBy.startsWith(AUTO_APPROVED_BY_PREFIX))
62
+ return null;
63
+ const withoutPrefix = approvedBy.slice(AUTO_APPROVED_BY_PREFIX.length);
64
+ const [withoutDelegation] = withoutPrefix.split(";delegated:");
65
+ const segments = (withoutDelegation ?? "").split(":");
66
+ if (segments.length !== 2)
67
+ return null;
68
+ const [harness, mode] = segments;
69
+ if (!harness || !mode)
70
+ return null;
71
+ return { harness, mode };
72
+ }
73
+ /**
74
+ * Build the audit-only ledger fact the ADR's "Audit and doctor" section
75
+ * names: `understanding-auto-approved:<sid>`, distinct from the human
76
+ * `understanding-approved:<sid>` tag (`ledger.ts`), following the same
77
+ * `...:forced:<field>` suffix precedent the ADR cites. Ledger only, never
78
+ * consulted for the gate decision itself.
79
+ */
80
+ export function autoApprovedLedgerTagFor(sessionId) {
81
+ return `understanding-auto-approved:${sessionId}`;
82
+ }
83
+ /**
84
+ * The harness identifiers `auto_approve.harnesses` accepts, in the order
85
+ * the schema and every diagnostic list them. Shared with the pack's zod
86
+ * `configSchema` (`../understanding-before-execution.ts`) so the lint-time
87
+ * enum and this runtime parser cannot drift apart.
88
+ */
89
+ export const AUTO_APPROVE_HARNESS_VALUES = [CLAUDE_CODE_HARNESS, CODEX_HARNESS];
90
+ /**
91
+ * What `auto_approve.harnesses` resolves to when the key is ABSENT.
92
+ * Claude Code only, deliberately: slice 1 shipped `auto_approve` as a
93
+ * Claude-only opt-in, so a repo that opted in before slice 2 must keep
94
+ * exactly the meaning it had — adding the Codex hook to the shared body
95
+ * must not silently extend an existing opt-in to a second runtime
96
+ * (reviewer round-1 finding on slice 2). Opting Codex in is an explicit,
97
+ * visible config edit.
98
+ */
99
+ export const DEFAULT_AUTO_APPROVE_HARNESSES = [CLAUDE_CODE_HARNESS];
100
+ const KNOWN_AUTO_APPROVE_KEYS = new Set(["when", "harnesses", "require_report"]);
101
+ /**
102
+ * Parse the optional `auto_approve` pack-config block
103
+ * (docs/decisions/2026-08-27-ug-auto-mode-approval.md, "Option A").
104
+ *
105
+ * FAIL CLOSED, unlike {@link parseApprovalLifecycle}'s best-effort
106
+ * fallback: this block is an opt-IN to a hook-side signing path
107
+ * (hardening item 3 in the ADR's threat model (b) — `require_report:
108
+ * false` must be a schema error, not a silently-ignored key), so any
109
+ * malformed shape here means "not opted in" (`null`), never a partial
110
+ * or default-filled config that could still enable the auto path. The
111
+ * `configSchema` zod block in `../understanding-before-execution.ts` is
112
+ * the first line of defence (`harness validate` / `harness doctor`
113
+ * reject a malformed manifest at lint time); this parser is the second,
114
+ * defensive line for the runtime hook, which must not trust that every
115
+ * config it sees on disk passed the schema.
116
+ *
117
+ * `undefined` / `null` (the block is simply absent) returns `null`
118
+ * silently — that is the ordinary "not opted in" case, not a warning.
119
+ * Every other malformed shape writes exactly one stderr line and
120
+ * returns `null`.
121
+ *
122
+ * `label` is the stderr prefix of the calling hook, so a Codex-side
123
+ * warning reads `harness pack hook codex: ...` like every other line
124
+ * that hook writes. The default reproduces the Claude Code hook's
125
+ * wording byte-for-byte.
126
+ */
127
+ export function parseAutoApprove(raw, stderr, label = "harness pack hook") {
128
+ if (raw === undefined || raw === null)
129
+ return null;
130
+ if (typeof raw !== "object" || Array.isArray(raw)) {
131
+ stderr?.write(`${label}: config.auto_approve ignored (expected object, got ${typeof raw})\n`);
132
+ return null;
133
+ }
134
+ const obj = raw;
135
+ const unknownKeys = Object.keys(obj).filter((k) => !KNOWN_AUTO_APPROVE_KEYS.has(k));
136
+ if (unknownKeys.length > 0) {
137
+ stderr?.write(`${label}: config.auto_approve ignored (unknown key(s): ${unknownKeys.join(", ")})\n`);
138
+ return null;
139
+ }
140
+ const whenRaw = obj["when"];
141
+ if (!Array.isArray(whenRaw) || whenRaw.length === 0) {
142
+ stderr?.write(`${label}: config.auto_approve.when ignored (expected a non-empty string[], got ${Array.isArray(whenRaw) ? "empty array" : typeof whenRaw})\n`);
143
+ return null;
144
+ }
145
+ const when = [];
146
+ for (const v of whenRaw) {
147
+ if (typeof v !== "string" || v.length === 0) {
148
+ stderr?.write(`${label}: config.auto_approve.when ignored (every entry must be a non-empty string, got ${typeof v})\n`);
149
+ return null;
150
+ }
151
+ when.push(v);
152
+ }
153
+ // `harnesses`: absent means the slice-1 default (Claude Code only).
154
+ // Present means an exact, non-empty, duplicate-free list of the known
155
+ // harness identifiers — anything else fails the whole block closed,
156
+ // like every other malformed shape here, so a typo'd entry can never
157
+ // widen the opt-in to a runtime the operator did not name.
158
+ const harnessesRaw = obj["harnesses"];
159
+ let harnesses = [...DEFAULT_AUTO_APPROVE_HARNESSES];
160
+ if (harnessesRaw !== undefined) {
161
+ if (!Array.isArray(harnessesRaw) || harnessesRaw.length === 0) {
162
+ stderr?.write(`${label}: config.auto_approve.harnesses ignored (expected a non-empty array of ${AUTO_APPROVE_HARNESS_VALUES.join(" | ")}, got ${Array.isArray(harnessesRaw) ? "empty array" : typeof harnessesRaw})\n`);
163
+ return null;
164
+ }
165
+ const seen = [];
166
+ for (const v of harnessesRaw) {
167
+ if (typeof v !== "string" || !AUTO_APPROVE_HARNESS_VALUES.includes(v)) {
168
+ stderr?.write(`${label}: config.auto_approve.harnesses ignored (every entry must be one of ${AUTO_APPROVE_HARNESS_VALUES.join(", ")}, got ${typeof v === "string" ? `"${v}"` : typeof v})\n`);
169
+ return null;
170
+ }
171
+ if (seen.includes(v)) {
172
+ stderr?.write(`${label}: config.auto_approve.harnesses ignored (duplicate entry "${v}")\n`);
173
+ return null;
174
+ }
175
+ seen.push(v);
176
+ }
177
+ harnesses = seen;
178
+ }
179
+ const requireReport = obj["require_report"];
180
+ if (requireReport !== true) {
181
+ stderr?.write(`${label}: config.auto_approve ignored (require_report must be true, got ${requireReport === false ? "false" : typeof requireReport})\n`);
182
+ return null;
183
+ }
184
+ return { when, harnesses };
185
+ }
186
+ /**
187
+ * ADR "Additional hardening to specify" item 2: `when` is an allowlist
188
+ * of payload literals, membership by exact string equality, no case
189
+ * folding, no substring, no wildcards. `mode` absent, empty, or not a
190
+ * string means no auto-approval, and `cfg === null` (block absent or
191
+ * malformed) means no auto-approval regardless of `mode`.
192
+ */
193
+ export function permissionModeAllowed(cfg, mode) {
194
+ if (cfg === null)
195
+ return false;
196
+ if (typeof mode !== "string" || mode.length === 0)
197
+ return false;
198
+ return cfg.when.includes(mode);
199
+ }
200
+ /**
201
+ * Per-harness opt-in membership, the same exact-string-equality
202
+ * discipline {@link permissionModeAllowed} applies to `when`. `cfg ===
203
+ * null` (block absent or malformed) means no auto-approval regardless of
204
+ * the harness, and an unlisted harness means no auto-approval regardless
205
+ * of `when` — the two allowlists are independent AND conditions, not
206
+ * alternatives.
207
+ *
208
+ * Re-exported through `understanding-before-execution/index.ts` (round-2
209
+ * review finding on slice 2): its call site (`src/cli/pack/auto-approve-path.ts`)
210
+ * imports every sibling symbol it needs (`parseAutoApprove`,
211
+ * `permissionModeAllowed`, ...) through the runtime shim already, so this
212
+ * one was pulled onto the pinned shim surface
213
+ * (tests/policy-packs/ube-export-surface.test.ts) to match, unlike
214
+ * {@link CODEX_HARNESS} which still has exactly one consumer and stays a
215
+ * direct import.
216
+ */
217
+ export function harnessAllowed(cfg, harness) {
218
+ if (cfg === null)
219
+ return false;
220
+ if (typeof harness !== "string" || harness.length === 0)
221
+ return false;
222
+ return cfg.harnesses.includes(harness);
223
+ }
224
+ //# sourceMappingURL=auto-approve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-approve.js","sourceRoot":"","sources":["../../../../src/policy-packs/builtin/understanding-before-execution/auto-approve.ts"],"names":[],"mappings":"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"}
@@ -6,8 +6,9 @@ export interface ApprovalCheckResult {
6
6
  }
7
7
  export { APPROVED_LEDGER_TAG_PREFIX, approvedLedgerTagFor, isPolicyDecisionRow, matchLedgerEntries, } from "./ledger.js";
8
8
  export { APPROVAL_MARKER_DIRNAME, approvalMarkerPathFor, type ApprovalMarker, writeApprovalMarker, type MarkerCheck, type CheckApprovalMarkerOptions, checkApprovalMarker, clearApprovalMarker, } from "./markers.js";
9
- export { type PersistedReport, REPORTS_DIR_ENV, defaultReportsDir, reportsDirForManifest, listPersistedReports, TOLERANT_FALLBACK_MAX_AGE_MS, TOLERANT_FALLBACK_FUTURE_SKEW_MS, type FindReportOptions, type FindReportSelection, selectReportForSession, findLatestReportForSession, type PersistedReportEvidence, expirePersistedReport, checkPersistedReport, } from "./persisted-reports.js";
9
+ export { type PersistedReport, REPORTS_DIR_ENV, defaultReportsDir, reportsDirForManifest, listPersistedReports, TOLERANT_FALLBACK_MAX_AGE_MS, TOLERANT_FALLBACK_FUTURE_SKEW_MS, type FindReportOptions, type FindReportSelection, selectReportForSession, selectNewestStrictSessionReport, findLatestReportForSession, type PersistedReportEvidence, expirePersistedReport, checkPersistedReport, } from "./persisted-reports.js";
10
10
  export { type ApprovalLifecycle, parseApprovalLifecycle } from "./lifecycle.js";
11
+ export { AUTO_APPROVED_BY_PREFIX, CLAUDE_CODE_HARNESS, autoApprovedByFor, type ParsedAutoApprovedBy, parseAutoApprovedBy, autoApprovedLedgerTagFor, type AutoApproveConfig, parseAutoApprove, permissionModeAllowed, harnessAllowed, AUTO_APPROVE_HARNESS_VALUES, DEFAULT_AUTO_APPROVE_HARNESSES, } from "./auto-approve.js";
11
12
  export { APPROVAL_MARKER_TASK_PREFIX, taskApprovalMarkerPathFor, writeTaskApprovalMarker, checkActiveClaimApprovalMarker, type OperatorMarkerApproval, checkOperatorApprovalMarkers, clearTaskApprovalMarker, } from "./task-markers.js";
12
13
  export { DEFAULT_BASH_TOOL_NAMES, toolNameMatchesAny, bashCommandMatchesAny, extractBashCommandFromToolInput, extractTaskIdFromToolInput, extractTasksTransitionStatusFromToolInput, type PostToolUseBoundaryMatch, matchPostToolUseBoundary, type ApplyPostToolUseExpiryResult, applyPostToolUseExpiry, describePostToolUseExpiry, } from "./post-tool-use-boundary.js";
13
14
  export { ACTIVE_CLAIM_FILENAME, activeClaimPathFor, writeActiveClaim, readActiveClaim, clearActiveClaim, } from "./active-claim.js";
@@ -37,8 +37,9 @@
37
37
  // harness gate; `harness approve understanding` is the approval path.
38
38
  export { APPROVED_LEDGER_TAG_PREFIX, approvedLedgerTagFor, isPolicyDecisionRow, matchLedgerEntries, } from "./ledger.js";
39
39
  export { APPROVAL_MARKER_DIRNAME, approvalMarkerPathFor, writeApprovalMarker, checkApprovalMarker, clearApprovalMarker, } from "./markers.js";
40
- export { REPORTS_DIR_ENV, defaultReportsDir, reportsDirForManifest, listPersistedReports, TOLERANT_FALLBACK_MAX_AGE_MS, TOLERANT_FALLBACK_FUTURE_SKEW_MS, selectReportForSession, findLatestReportForSession, expirePersistedReport, checkPersistedReport, } from "./persisted-reports.js";
40
+ export { REPORTS_DIR_ENV, defaultReportsDir, reportsDirForManifest, listPersistedReports, TOLERANT_FALLBACK_MAX_AGE_MS, TOLERANT_FALLBACK_FUTURE_SKEW_MS, selectReportForSession, selectNewestStrictSessionReport, findLatestReportForSession, expirePersistedReport, checkPersistedReport, } from "./persisted-reports.js";
41
41
  export { parseApprovalLifecycle } from "./lifecycle.js";
42
+ export { AUTO_APPROVED_BY_PREFIX, CLAUDE_CODE_HARNESS, autoApprovedByFor, parseAutoApprovedBy, autoApprovedLedgerTagFor, parseAutoApprove, permissionModeAllowed, harnessAllowed, AUTO_APPROVE_HARNESS_VALUES, DEFAULT_AUTO_APPROVE_HARNESSES, } from "./auto-approve.js";
42
43
  export { APPROVAL_MARKER_TASK_PREFIX, taskApprovalMarkerPathFor, writeTaskApprovalMarker, checkActiveClaimApprovalMarker, checkOperatorApprovalMarkers, clearTaskApprovalMarker, } from "./task-markers.js";
43
44
  export { DEFAULT_BASH_TOOL_NAMES, toolNameMatchesAny, bashCommandMatchesAny, extractBashCommandFromToolInput, extractTaskIdFromToolInput, extractTasksTransitionStatusFromToolInput, matchPostToolUseBoundary, applyPostToolUseExpiry, describePostToolUseExpiry, } from "./post-tool-use-boundary.js";
44
45
  export { ACTIVE_CLAIM_FILENAME, activeClaimPathFor, writeActiveClaim, readActiveClaim, clearActiveClaim, } from "./active-claim.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/policy-packs/builtin/understanding-before-execution/index.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,EAAE;AACF,mEAAmE;AACnE,sEAAsE;AACtE,EAAE;AACF,yEAAyE;AACzE,wEAAwE;AACxE,uEAAuE;AACvE,oEAAoE;AACpE,qEAAqE;AACrE,yEAAyE;AACzE,uEAAuE;AACvE,oEAAoE;AACpE,qEAAqE;AACrE,sEAAsE;AACtE,uEAAuE;AACvE,sEAAsE;AACtE,oEAAoE;AACpE,yEAAyE;AACzE,gEAAgE;AAChE,0EAA0E;AAC1E,yEAAyE;AACzE,uEAAuE;AACvE,yEAAyE;AACzE,uEAAuE;AACvE,sEAAsE;AACtE,kEAAkE;AAClE,wEAAwE;AACxE,yDAAyD;AACzD,qEAAqE;AACrE,sEAAsE;AACtE,uEAAuE;AACvE,EAAE;AACF,uEAAuE;AACvE,sEAAsE;AACtE,oEAAoE;AACpE,sEAAsE;AActE,OAAO,EACL,0BAA0B,EAC1B,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EAErB,mBAAmB,EAGnB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAEL,eAAe,EACf,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,4BAA4B,EAC5B,gCAAgC,EAGhC,sBAAsB,EACtB,0BAA0B,EAE1B,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAA0B,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAEhF,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,EACzB,uBAAuB,EACvB,8BAA8B,EAE9B,4BAA4B,EAC5B,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,uBAAuB,EACvB,kBAAkB,EAClB,qBAAqB,EACrB,+BAA+B,EAC/B,0BAA0B,EAC1B,yCAAyC,EAEzC,wBAAwB,EAExB,sBAAsB,EACtB,yBAAyB,GAC1B,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,GACjB,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/policy-packs/builtin/understanding-before-execution/index.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,EAAE;AACF,mEAAmE;AACnE,sEAAsE;AACtE,EAAE;AACF,yEAAyE;AACzE,wEAAwE;AACxE,uEAAuE;AACvE,oEAAoE;AACpE,qEAAqE;AACrE,yEAAyE;AACzE,uEAAuE;AACvE,oEAAoE;AACpE,qEAAqE;AACrE,sEAAsE;AACtE,uEAAuE;AACvE,sEAAsE;AACtE,oEAAoE;AACpE,yEAAyE;AACzE,gEAAgE;AAChE,0EAA0E;AAC1E,yEAAyE;AACzE,uEAAuE;AACvE,yEAAyE;AACzE,uEAAuE;AACvE,sEAAsE;AACtE,kEAAkE;AAClE,wEAAwE;AACxE,yDAAyD;AACzD,qEAAqE;AACrE,sEAAsE;AACtE,uEAAuE;AACvE,EAAE;AACF,uEAAuE;AACvE,sEAAsE;AACtE,oEAAoE;AACpE,sEAAsE;AActE,OAAO,EACL,0BAA0B,EAC1B,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EAErB,mBAAmB,EAGnB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAEL,eAAe,EACf,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,4BAA4B,EAC5B,gCAAgC,EAGhC,sBAAsB,EACtB,+BAA+B,EAC/B,0BAA0B,EAE1B,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAA0B,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAEhF,OAAO,EACL,uBAAuB,EACvB,mBAAmB,EACnB,iBAAiB,EAEjB,mBAAmB,EACnB,wBAAwB,EAExB,gBAAgB,EAChB,qBAAqB,EACrB,cAAc,EACd,2BAA2B,EAC3B,8BAA8B,GAC/B,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,EACzB,uBAAuB,EACvB,8BAA8B,EAE9B,4BAA4B,EAC5B,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,uBAAuB,EACvB,kBAAkB,EAClB,qBAAqB,EACrB,+BAA+B,EAC/B,0BAA0B,EAC1B,yCAAyC,EAEzC,wBAAwB,EAExB,sBAAsB,EACtB,yBAAyB,GAC1B,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,GACjB,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,29 @@
1
+ export type MeasuredHarness = "claude-code" | "codex";
2
+ export interface MeasuredPermissionMode {
3
+ readonly harness: MeasuredHarness;
4
+ readonly permissionMode: string;
5
+ /** Repo-relative path under dogfood/ug-auto-mode-signals/payloads/. */
6
+ readonly fixture: string;
7
+ }
8
+ /** Repo-relative directory every registry fixture must live in. */
9
+ export declare const MEASURED_FIXTURES_DIR = "dogfood/ug-auto-mode-signals/payloads";
10
+ /**
11
+ * Which harness a fixture file under {@link MEASURED_FIXTURES_DIR} was
12
+ * captured from, by file-name convention: `codex-*` is Codex, anything
13
+ * else is Claude Code. Shared with the sync test so the convention has
14
+ * one definition.
15
+ */
16
+ export declare function harnessForFixtureFile(basename: string): MeasuredHarness;
17
+ export declare const MEASURED_PERMISSION_MODES: ReadonlyArray<MeasuredPermissionMode>;
18
+ /**
19
+ * True when the given HARNESS has a measured fixture for this exact
20
+ * literal. `auto_approve.harnesses` (docs/decisions/2026-08-27-ug-auto-mode-approval.md,
21
+ * Slice 2) scopes which harnesses' PreToolUse hooks may take the auto
22
+ * path at all, so "measured" is checked per listed harness, not across
23
+ * the whole registry: a literal measured only for Claude Code is not
24
+ * evidence that Codex ever emits it. Exact string equality: no case
25
+ * folding, no wildcards.
26
+ */
27
+ export declare function isMeasuredPermissionModeFor(literal: string, harness: MeasuredHarness): boolean;
28
+ /** Sorted, de-duplicated list of every literal measured for HARNESS. */
29
+ export declare function measuredPermissionModeLiteralsFor(harness: MeasuredHarness): string[];
@@ -0,0 +1,82 @@
1
+ // Registry of measured `permission_mode` literals for the
2
+ // `auto_approve.when` allowlist (docs/decisions/2026-08-27-ug-auto-mode-approval.md,
3
+ // Slice 2 AC 3, "Option A").
4
+ //
5
+ // RULE: an entry is added here ONLY together with a checked-in dogfood
6
+ // fixture (under `dogfood/ug-auto-mode-signals/payloads/`) that shows the
7
+ // named harness actually emitting that exact `permission_mode` string on a
8
+ // `PreToolUse` hook payload. `tests/policy-packs/measured-permission-modes-sync.test.ts`
9
+ // enforces both directions: every entry here must be backed by a fixture
10
+ // that carries the claimed value, and every `permission_mode` value found
11
+ // in any `*.PreToolUse.json` fixture must be registered for its harness.
12
+ // Do not add a literal "because it seems plausible": capture a fixture
13
+ // first, then register it.
14
+ //
15
+ // A fixture's harness is bound by its file name: `codex-*` fixtures are
16
+ // Codex captures, every other `*.PreToolUse.json` under the payloads
17
+ // directory is a Claude Code capture (`harnessForFixtureFile`). The sync
18
+ // test checks each entry's fixture name against the entry's `harness`, so
19
+ // a Claude Code fixture cannot back a Codex claim or vice versa.
20
+ //
21
+ // `harness validate` runs in the OPERATOR's repo, which has no `dogfood/`
22
+ // directory, so this registry ships inside the package as a constant
23
+ // (`checkUnderstandingBeforeExecutionAutoApproveMeasured` in
24
+ // `src/cli/validate/checks.ts` consults it without touching the
25
+ // filesystem); the sync test above is what keeps it honest against the
26
+ // fixtures in THIS repo.
27
+ /** Repo-relative directory every registry fixture must live in. */
28
+ export const MEASURED_FIXTURES_DIR = "dogfood/ug-auto-mode-signals/payloads";
29
+ const PAYLOADS_DIR = MEASURED_FIXTURES_DIR;
30
+ /**
31
+ * Which harness a fixture file under {@link MEASURED_FIXTURES_DIR} was
32
+ * captured from, by file-name convention: `codex-*` is Codex, anything
33
+ * else is Claude Code. Shared with the sync test so the convention has
34
+ * one definition.
35
+ */
36
+ export function harnessForFixtureFile(basename) {
37
+ return basename.startsWith("codex-") ? "codex" : "claude-code";
38
+ }
39
+ export const MEASURED_PERMISSION_MODES = [
40
+ {
41
+ harness: "claude-code",
42
+ permissionMode: "default",
43
+ fixture: `${PAYLOADS_DIR}/claude-p-default.PreToolUse.json`,
44
+ },
45
+ {
46
+ harness: "claude-code",
47
+ permissionMode: "acceptEdits",
48
+ fixture: `${PAYLOADS_DIR}/claude-p-acceptedits.PreToolUse.json`,
49
+ },
50
+ {
51
+ harness: "claude-code",
52
+ permissionMode: "bypassPermissions",
53
+ fixture: `${PAYLOADS_DIR}/claude-p-bypass.PreToolUse.json`,
54
+ },
55
+ {
56
+ harness: "codex",
57
+ permissionMode: "bypassPermissions",
58
+ fixture: `${PAYLOADS_DIR}/codex-exec-default.PreToolUse.json`,
59
+ },
60
+ {
61
+ harness: "codex",
62
+ permissionMode: "default",
63
+ fixture: `${PAYLOADS_DIR}/codex-tui-default.PreToolUse.json`,
64
+ },
65
+ ];
66
+ /**
67
+ * True when the given HARNESS has a measured fixture for this exact
68
+ * literal. `auto_approve.harnesses` (docs/decisions/2026-08-27-ug-auto-mode-approval.md,
69
+ * Slice 2) scopes which harnesses' PreToolUse hooks may take the auto
70
+ * path at all, so "measured" is checked per listed harness, not across
71
+ * the whole registry: a literal measured only for Claude Code is not
72
+ * evidence that Codex ever emits it. Exact string equality: no case
73
+ * folding, no wildcards.
74
+ */
75
+ export function isMeasuredPermissionModeFor(literal, harness) {
76
+ return MEASURED_PERMISSION_MODES.some((entry) => entry.harness === harness && entry.permissionMode === literal);
77
+ }
78
+ /** Sorted, de-duplicated list of every literal measured for HARNESS. */
79
+ export function measuredPermissionModeLiteralsFor(harness) {
80
+ return Array.from(new Set(MEASURED_PERMISSION_MODES.filter((entry) => entry.harness === harness).map((entry) => entry.permissionMode))).sort();
81
+ }
82
+ //# sourceMappingURL=measured-permission-modes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"measured-permission-modes.js","sourceRoot":"","sources":["../../../../src/policy-packs/builtin/understanding-before-execution/measured-permission-modes.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAC1D,qFAAqF;AACrF,6BAA6B;AAC7B,EAAE;AACF,uEAAuE;AACvE,0EAA0E;AAC1E,2EAA2E;AAC3E,yFAAyF;AACzF,yEAAyE;AACzE,0EAA0E;AAC1E,yEAAyE;AACzE,uEAAuE;AACvE,2BAA2B;AAC3B,EAAE;AACF,wEAAwE;AACxE,qEAAqE;AACrE,yEAAyE;AACzE,0EAA0E;AAC1E,iEAAiE;AACjE,EAAE;AACF,0EAA0E;AAC1E,qEAAqE;AACrE,6DAA6D;AAC7D,gEAAgE;AAChE,uEAAuE;AACvE,yBAAyB;AAWzB,mEAAmE;AACnE,MAAM,CAAC,MAAM,qBAAqB,GAAG,uCAAuC,CAAC;AAC7E,MAAM,YAAY,GAAG,qBAAqB,CAAC;AAE3C;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAgB;IACpD,OAAO,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC;AACjE,CAAC;AAED,MAAM,CAAC,MAAM,yBAAyB,GAA0C;IAC9E;QACE,OAAO,EAAE,aAAa;QACtB,cAAc,EAAE,SAAS;QACzB,OAAO,EAAE,GAAG,YAAY,mCAAmC;KAC5D;IACD;QACE,OAAO,EAAE,aAAa;QACtB,cAAc,EAAE,aAAa;QAC7B,OAAO,EAAE,GAAG,YAAY,uCAAuC;KAChE;IACD;QACE,OAAO,EAAE,aAAa;QACtB,cAAc,EAAE,mBAAmB;QACnC,OAAO,EAAE,GAAG,YAAY,kCAAkC;KAC3D;IACD;QACE,OAAO,EAAE,OAAO;QAChB,cAAc,EAAE,mBAAmB;QACnC,OAAO,EAAE,GAAG,YAAY,qCAAqC;KAC9D;IACD;QACE,OAAO,EAAE,OAAO;QAChB,cAAc,EAAE,SAAS;QACzB,OAAO,EAAE,GAAG,YAAY,oCAAoC;KAC7D;CACF,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,UAAU,2BAA2B,CAAC,OAAe,EAAE,OAAwB;IACnF,OAAO,yBAAyB,CAAC,IAAI,CACnC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,KAAK,OAAO,IAAI,KAAK,CAAC,cAAc,KAAK,OAAO,CACzE,CAAC;AACJ,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,iCAAiC,CAAC,OAAwB;IACxE,OAAO,KAAK,CAAC,IAAI,CACf,IAAI,GAAG,CACL,yBAAyB,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC,GAAG,CACxE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,cAAc,CAChC,CACF,CACF,CAAC,IAAI,EAAE,CAAC;AACX,CAAC"}
@@ -137,6 +137,29 @@ export interface FindReportSelection {
137
137
  * for the caller to be loud about non-strict adoptions.
138
138
  */
139
139
  export declare function selectReportForSession(reports: PersistedReport[], sessionId: string, opts?: FindReportOptions): FindReportSelection;
140
+ /**
141
+ * The NEWEST report whose `sessionId` strictly equals `sessionId`, or
142
+ * `null` when the newest-first list has none. Deliberately NOT a thin
143
+ * wrapper over {@link selectReportForSession}: it stops at the first
144
+ * strict match and never consults the sessionId-null tolerant fallback.
145
+ *
146
+ * Written for the PreToolUse hook's auto-approval path
147
+ * (agent-tasks/74b4b17d, ADR
148
+ * docs/decisions/2026-08-27-ug-auto-mode-approval.md, Option A condition
149
+ * 3), where both of the fallback's properties are unacceptable:
150
+ *
151
+ * - A sessionId-null report is adopted by whichever session asks, so
152
+ * the fallback would let a report bound to no session at all mint a
153
+ * marker for THIS one. The auto path has no operator to confirm that
154
+ * adoption the way `harness approve understanding` does.
155
+ * - Eligibility is evaluated on the newest report ONLY. The caller
156
+ * checks `approvalStatus === "pending"` on whatever this returns; if
157
+ * the newest strict-session report was already consumed, the session
158
+ * is ineligible even when an older `pending` report is still on disk.
159
+ * Scanning further down the list for some other pending report is
160
+ * exactly the re-mint this design forbids.
161
+ */
162
+ export declare function selectNewestStrictSessionReport(reports: PersistedReport[], sessionId: string): PersistedReport | null;
140
163
  /**
141
164
  * Back-compat wrapper around `selectReportForSession` for callers that
142
165
  * only need the report (the gate read and expiry paths).
@@ -201,6 +201,35 @@ export function selectReportForSession(reports, sessionId, opts = {}) {
201
201
  }
202
202
  return { report: null, fallbackAdopted: false, staleRejected };
203
203
  }
204
+ /**
205
+ * The NEWEST report whose `sessionId` strictly equals `sessionId`, or
206
+ * `null` when the newest-first list has none. Deliberately NOT a thin
207
+ * wrapper over {@link selectReportForSession}: it stops at the first
208
+ * strict match and never consults the sessionId-null tolerant fallback.
209
+ *
210
+ * Written for the PreToolUse hook's auto-approval path
211
+ * (agent-tasks/74b4b17d, ADR
212
+ * docs/decisions/2026-08-27-ug-auto-mode-approval.md, Option A condition
213
+ * 3), where both of the fallback's properties are unacceptable:
214
+ *
215
+ * - A sessionId-null report is adopted by whichever session asks, so
216
+ * the fallback would let a report bound to no session at all mint a
217
+ * marker for THIS one. The auto path has no operator to confirm that
218
+ * adoption the way `harness approve understanding` does.
219
+ * - Eligibility is evaluated on the newest report ONLY. The caller
220
+ * checks `approvalStatus === "pending"` on whatever this returns; if
221
+ * the newest strict-session report was already consumed, the session
222
+ * is ineligible even when an older `pending` report is still on disk.
223
+ * Scanning further down the list for some other pending report is
224
+ * exactly the re-mint this design forbids.
225
+ */
226
+ export function selectNewestStrictSessionReport(reports, sessionId) {
227
+ for (const r of reports) {
228
+ if (r.sessionId === sessionId)
229
+ return r;
230
+ }
231
+ return null;
232
+ }
204
233
  /**
205
234
  * Back-compat wrapper around `selectReportForSession` for callers that
206
235
  * only need the report (the gate read and expiry paths).
@@ -1 +1 @@
1
- {"version":3,"file":"persisted-reports.js","sourceRoot":"","sources":["../../../../src/policy-packs/builtin/understanding-before-execution/persisted-reports.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"persisted-reports.js","sourceRoot":"","sources":["../../../../src/policy-packs/builtin/understanding-before-execution/persisted-reports.ts"],"names":[],"mappings":"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"}
@@ -123,6 +123,19 @@ export declare const configSchema: z.ZodObject<{
123
123
  expire_on_bash_match?: string[] | undefined;
124
124
  max_age?: string | undefined;
125
125
  }>>;
126
+ auto_approve: z.ZodOptional<z.ZodObject<{
127
+ when: z.ZodArray<z.ZodString, "many">;
128
+ harnesses: z.ZodOptional<z.ZodEffects<z.ZodArray<z.ZodEnum<["claude-code", "codex"]>, "many">, ("claude-code" | "codex")[], ("claude-code" | "codex")[]>>;
129
+ require_report: z.ZodLiteral<true>;
130
+ }, "strict", z.ZodTypeAny, {
131
+ when: string[];
132
+ require_report: true;
133
+ harnesses?: ("claude-code" | "codex")[] | undefined;
134
+ }, {
135
+ when: string[];
136
+ require_report: true;
137
+ harnesses?: ("claude-code" | "codex")[] | undefined;
138
+ }>>;
126
139
  ux: z.ZodOptional<z.ZodObject<{
127
140
  cannot: z.ZodString;
128
141
  required: z.ZodArray<z.ZodString, "many">;
@@ -204,6 +217,11 @@ export declare const configSchema: z.ZodObject<{
204
217
  max_age?: string | undefined;
205
218
  } | undefined;
206
219
  permission_profile?: string | undefined;
220
+ auto_approve?: {
221
+ when: string[];
222
+ require_report: true;
223
+ harnesses?: ("claude-code" | "codex")[] | undefined;
224
+ } | undefined;
207
225
  }, {
208
226
  producers?: ({
209
227
  command: string;
@@ -232,6 +250,11 @@ export declare const configSchema: z.ZodObject<{
232
250
  max_age?: string | undefined;
233
251
  } | undefined;
234
252
  permission_profile?: string | undefined;
253
+ auto_approve?: {
254
+ when: string[];
255
+ require_report: true;
256
+ harnesses?: ("claude-code" | "codex")[] | undefined;
257
+ } | undefined;
235
258
  }>;
236
259
  export interface ResolvePackOptions {
237
260
  /**
@@ -15,7 +15,7 @@ import { PolicyUxSchema, ProducerSchema } from "../../schema/policies.js";
15
15
  import { profileToSettingsPermissions } from "../permission-translator.js";
16
16
  import { DEFAULT_RUNTIME } from "../runtime.js";
17
17
  import { isKnownProfileName, resolveProfile, KNOWN_PROFILE_NAMES, } from "./permission-profiles.js";
18
- import { REPORTS_DIR_ENV } from "./understanding-before-execution-runtime.js";
18
+ import { AUTO_APPROVE_HARNESS_VALUES, REPORTS_DIR_ENV, } from "./understanding-before-execution-runtime.js";
19
19
  import { SHELL_ALIASES } from "../../runtime/tool-name-aliases.js";
20
20
  // Env var the npm-backed `understanding-gate-claude-hook` bin reads to find
21
21
  // the harness pause sentinel (`src/runtime/pause-sentinel.ts`,
@@ -238,6 +238,32 @@ export const configSchema = z
238
238
  })
239
239
  .strict()
240
240
  .optional(),
241
+ // Operator opt-in to the hook-written signed auto-marker path for
242
+ // an allowlisted `permission_mode` (docs/decisions/2026-08-27-ug-auto-mode-approval.md,
243
+ // "Option A"). `when` names the exact permission-mode literals the
244
+ // hook may auto-approve; `harnesses` names which runtimes' PreToolUse
245
+ // hooks may take the auto path at all (absent means Claude Code only,
246
+ // the meaning the key had before the Codex hook joined the shared
247
+ // path, so an existing opt-in is never silently widened);
248
+ // `require_report` is required and must be literal `true` in v1 (ADR
249
+ // threat model (b) item 3: rejecting `false` here makes a future
250
+ // relaxation a visible schema change instead of a silent default).
251
+ // Runtime parsing/validation lives in
252
+ // `./understanding-before-execution/auto-approve.ts`.
253
+ auto_approve: z
254
+ .object({
255
+ when: z.array(z.string().min(1)).min(1),
256
+ harnesses: z
257
+ .array(z.enum(AUTO_APPROVE_HARNESS_VALUES))
258
+ .min(1)
259
+ .refine((values) => new Set(values).size === values.length, {
260
+ message: "harnesses must not contain duplicate entries",
261
+ })
262
+ .optional(),
263
+ require_report: z.literal(true),
264
+ })
265
+ .strict()
266
+ .optional(),
241
267
  // `ux` + `producers` are consumed by the PreToolUse blocker
242
268
  // (`src/cli/pack/hook-pre-tool-use.ts`) to render an agent-facing
243
269
  // remediation block when the gate trips. Same shape as the