@lannguyensi/harness 0.7.0 → 0.8.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.
- package/CHANGELOG.md +178 -0
- package/README.md +56 -17
- package/dist/cli/apply/apply.d.ts +13 -0
- package/dist/cli/apply/apply.js +59 -3
- package/dist/cli/apply/apply.js.map +1 -1
- package/dist/cli/apply/generate-codex-config.d.ts +6 -0
- package/dist/cli/apply/generate-codex-config.js +149 -0
- package/dist/cli/apply/generate-codex-config.js.map +1 -0
- package/dist/cli/apply/generate-settings.d.ts +15 -1
- package/dist/cli/apply/generate-settings.js +16 -1
- package/dist/cli/apply/generate-settings.js.map +1 -1
- package/dist/cli/apply/index.d.ts +2 -1
- package/dist/cli/apply/index.js +2 -1
- package/dist/cli/apply/index.js.map +1 -1
- package/dist/cli/approve/understanding.d.ts +39 -0
- package/dist/cli/approve/understanding.js +122 -0
- package/dist/cli/approve/understanding.js.map +1 -0
- package/dist/cli/doctor/codex.d.ts +34 -0
- package/dist/cli/doctor/codex.js +331 -0
- package/dist/cli/doctor/codex.js.map +1 -0
- package/dist/cli/doctor/format.js +11 -0
- package/dist/cli/doctor/format.js.map +1 -1
- package/dist/cli/doctor/index.d.ts +13 -1
- package/dist/cli/doctor/index.js +19 -0
- package/dist/cli/doctor/index.js.map +1 -1
- package/dist/cli/doctor/types.d.ts +21 -1
- package/dist/cli/doctor/types.js +12 -1
- package/dist/cli/doctor/types.js.map +1 -1
- package/dist/cli/index.js +257 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/pack/add.d.ts +13 -0
- package/dist/cli/pack/add.js +71 -0
- package/dist/cli/pack/add.js.map +1 -0
- package/dist/cli/pack/hook-codex-pre-tool-use.d.ts +30 -0
- package/dist/cli/pack/hook-codex-pre-tool-use.js +149 -0
- package/dist/cli/pack/hook-codex-pre-tool-use.js.map +1 -0
- package/dist/cli/pack/hook-codex-stop.d.ts +31 -0
- package/dist/cli/pack/hook-codex-stop.js +332 -0
- package/dist/cli/pack/hook-codex-stop.js.map +1 -0
- package/dist/cli/pack/hook-codex-user-prompt-submit.d.ts +18 -0
- package/dist/cli/pack/hook-codex-user-prompt-submit.js +92 -0
- package/dist/cli/pack/hook-codex-user-prompt-submit.js.map +1 -0
- package/dist/cli/pack/hook-pre-tool-use.d.ts +32 -0
- package/dist/cli/pack/hook-pre-tool-use.js +181 -0
- package/dist/cli/pack/hook-pre-tool-use.js.map +1 -0
- package/dist/cli/pack/index.d.ts +4 -0
- package/dist/cli/pack/index.js +5 -0
- package/dist/cli/pack/index.js.map +1 -0
- package/dist/cli/pack/list.d.ts +10 -0
- package/dist/cli/pack/list.js +43 -0
- package/dist/cli/pack/list.js.map +1 -0
- package/dist/cli/pack/mutate.d.ts +14 -0
- package/dist/cli/pack/mutate.js +76 -0
- package/dist/cli/pack/mutate.js.map +1 -0
- package/dist/cli/pack/remove.d.ts +15 -0
- package/dist/cli/pack/remove.js +153 -0
- package/dist/cli/pack/remove.js.map +1 -0
- package/dist/cli/validate/checks.js +32 -0
- package/dist/cli/validate/checks.js.map +1 -1
- package/dist/policy-packs/builtin/permission-profiles.d.ts +11 -0
- package/dist/policy-packs/builtin/permission-profiles.js +74 -0
- package/dist/policy-packs/builtin/permission-profiles.js.map +1 -0
- package/dist/policy-packs/builtin/understanding-before-execution-runtime.d.ts +56 -0
- package/dist/policy-packs/builtin/understanding-before-execution-runtime.js +186 -0
- package/dist/policy-packs/builtin/understanding-before-execution-runtime.js.map +1 -0
- package/dist/policy-packs/builtin/understanding-before-execution.d.ts +15 -0
- package/dist/policy-packs/builtin/understanding-before-execution.js +254 -0
- package/dist/policy-packs/builtin/understanding-before-execution.js.map +1 -0
- package/dist/policy-packs/expand.d.ts +4 -0
- package/dist/policy-packs/expand.js +90 -0
- package/dist/policy-packs/expand.js.map +1 -0
- package/dist/policy-packs/index.d.ts +5 -0
- package/dist/policy-packs/index.js +5 -0
- package/dist/policy-packs/index.js.map +1 -0
- package/dist/policy-packs/permission-translator.d.ts +9 -0
- package/dist/policy-packs/permission-translator.js +76 -0
- package/dist/policy-packs/permission-translator.js.map +1 -0
- package/dist/policy-packs/registry.d.ts +11 -0
- package/dist/policy-packs/registry.js +20 -0
- package/dist/policy-packs/registry.js.map +1 -0
- package/dist/policy-packs/runtime.d.ts +8 -0
- package/dist/policy-packs/runtime.js +30 -0
- package/dist/policy-packs/runtime.js.map +1 -0
- package/dist/policy-packs/source.d.ts +6 -0
- package/dist/policy-packs/source.js +10 -0
- package/dist/policy-packs/source.js.map +1 -0
- package/dist/policy-packs/types.d.ts +41 -0
- package/dist/policy-packs/types.js +11 -0
- package/dist/policy-packs/types.js.map +1 -0
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/index.js +1 -0
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/ledger-add.d.ts +16 -0
- package/dist/runtime/ledger-add.js +139 -0
- package/dist/runtime/ledger-add.js.map +1 -0
- package/dist/schema/index.d.ts +1485 -10
- package/dist/schema/index.js +6 -0
- package/dist/schema/index.js.map +1 -1
- package/dist/schema/permission-profiles.d.ts +2161 -0
- package/dist/schema/permission-profiles.js +60 -0
- package/dist/schema/permission-profiles.js.map +1 -0
- package/dist/schema/policy-packs.d.ts +52 -0
- package/dist/schema/policy-packs.js +35 -0
- package/dist/schema/policy-packs.js.map +1 -0
- package/dist/schema/tools.d.ts +8 -8
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checks.js","sourceRoot":"","sources":["../../../src/cli/validate/checks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"checks.js","sourceRoot":"","sources":["../../../src/cli/validate/checks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { PermissionProfile } from "../../schema/permission-profiles.js";
|
|
2
|
+
export declare const PROFILE_SAFE_START = "safe-start";
|
|
3
|
+
export declare const PROFILE_IMPLEMENTATION_AFTER_APPROVAL = "implementation-after-approval";
|
|
4
|
+
export declare const PROFILE_HIGH_RISK_GRILL_ME = "high-risk-grill-me";
|
|
5
|
+
export declare const KNOWN_PROFILE_NAMES: readonly ["safe-start", "implementation-after-approval", "high-risk-grill-me"];
|
|
6
|
+
export type KnownProfileName = (typeof KNOWN_PROFILE_NAMES)[number];
|
|
7
|
+
export declare function isKnownProfileName(name: string): name is KnownProfileName;
|
|
8
|
+
export declare const SAFE_START: PermissionProfile;
|
|
9
|
+
export declare const IMPLEMENTATION_AFTER_APPROVAL: PermissionProfile;
|
|
10
|
+
export declare const HIGH_RISK_GRILL_ME: PermissionProfile;
|
|
11
|
+
export declare function resolveProfile(name: string): PermissionProfile | null;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// Phase 6 #5 — built-in permission profiles bundled with the
|
|
2
|
+
// `understanding-before-execution` pack.
|
|
3
|
+
//
|
|
4
|
+
// Three profiles, each documented in
|
|
5
|
+
// `docs/policy-packs/understanding-before-execution.md`. The pack's
|
|
6
|
+
// `config.permission_profile` selects which profile is active; the
|
|
7
|
+
// pack contributes the resolved profile's permission entries to the
|
|
8
|
+
// generated `settings.json` at apply time.
|
|
9
|
+
//
|
|
10
|
+
// Profile actions translate to Claude Code's permissions block via
|
|
11
|
+
// `profileToSettingsPermissions()` below. The mapping is intentionally
|
|
12
|
+
// conservative: `limited` and `ask_or_deny` collapse to `ask` for v1
|
|
13
|
+
// (Claude Code does not distinguish these natively); fine-grained
|
|
14
|
+
// shaping is a Phase 6 #5 follow-up.
|
|
15
|
+
export const PROFILE_SAFE_START = "safe-start";
|
|
16
|
+
export const PROFILE_IMPLEMENTATION_AFTER_APPROVAL = "implementation-after-approval";
|
|
17
|
+
export const PROFILE_HIGH_RISK_GRILL_ME = "high-risk-grill-me";
|
|
18
|
+
export const KNOWN_PROFILE_NAMES = [
|
|
19
|
+
PROFILE_SAFE_START,
|
|
20
|
+
PROFILE_IMPLEMENTATION_AFTER_APPROVAL,
|
|
21
|
+
PROFILE_HIGH_RISK_GRILL_ME,
|
|
22
|
+
];
|
|
23
|
+
export function isKnownProfileName(name) {
|
|
24
|
+
return KNOWN_PROFILE_NAMES.includes(name);
|
|
25
|
+
}
|
|
26
|
+
export const SAFE_START = {
|
|
27
|
+
description: "Pre-approval default. Read-only path is open; everything write-capable is denied (commit/push/pr/deploy) or asks (edit/bash). Pair with `harness pack hook pre-tool-use` for the conditional unlock.",
|
|
28
|
+
actions: {
|
|
29
|
+
read: { allow: "true" },
|
|
30
|
+
edit: { allow: "ask" },
|
|
31
|
+
bash: { allow: "ask" },
|
|
32
|
+
commit: { allow: "false" },
|
|
33
|
+
push: { allow: "false" },
|
|
34
|
+
pr: { allow: "false" },
|
|
35
|
+
deploy: { allow: "false" },
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
export const IMPLEMENTATION_AFTER_APPROVAL = {
|
|
39
|
+
description: "Post-approval working profile. Edit/Bash flow without prompts; commit/push/pr ask. Activate after the operator has approved the Understanding Report (run `harness apply` again with this profile selected).",
|
|
40
|
+
actions: {
|
|
41
|
+
read: { allow: "true" },
|
|
42
|
+
edit: { allow: "true" },
|
|
43
|
+
bash: { allow: "ask" },
|
|
44
|
+
commit: { allow: "ask" },
|
|
45
|
+
push: { allow: "ask" },
|
|
46
|
+
pr: { allow: "ask" },
|
|
47
|
+
deploy: { allow: "false" },
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
export const HIGH_RISK_GRILL_ME = {
|
|
51
|
+
description: "High-friction profile for risky surfaces. Asks per-Edit and per-Bash even after approval; refuses commit/deploy outright. Use when the task touches security, infrastructure, or destructive writes.",
|
|
52
|
+
actions: {
|
|
53
|
+
read: { allow: "true" },
|
|
54
|
+
edit: { allow: "ask" },
|
|
55
|
+
bash: { allow: "ask" },
|
|
56
|
+
commit: { allow: "false" },
|
|
57
|
+
push: { allow: "false" },
|
|
58
|
+
pr: { allow: "ask" },
|
|
59
|
+
deploy: { allow: "false" },
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
export function resolveProfile(name) {
|
|
63
|
+
if (!isKnownProfileName(name))
|
|
64
|
+
return null;
|
|
65
|
+
switch (name) {
|
|
66
|
+
case PROFILE_SAFE_START:
|
|
67
|
+
return SAFE_START;
|
|
68
|
+
case PROFILE_IMPLEMENTATION_AFTER_APPROVAL:
|
|
69
|
+
return IMPLEMENTATION_AFTER_APPROVAL;
|
|
70
|
+
case PROFILE_HIGH_RISK_GRILL_ME:
|
|
71
|
+
return HIGH_RISK_GRILL_ME;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=permission-profiles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permission-profiles.js","sourceRoot":"","sources":["../../../src/policy-packs/builtin/permission-profiles.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,yCAAyC;AACzC,EAAE;AACF,qCAAqC;AACrC,oEAAoE;AACpE,mEAAmE;AACnE,oEAAoE;AACpE,2CAA2C;AAC3C,EAAE;AACF,mEAAmE;AACnE,uEAAuE;AACvE,qEAAqE;AACrE,kEAAkE;AAClE,qCAAqC;AAIrC,MAAM,CAAC,MAAM,kBAAkB,GAAG,YAAY,CAAC;AAC/C,MAAM,CAAC,MAAM,qCAAqC,GAAG,+BAA+B,CAAC;AACrF,MAAM,CAAC,MAAM,0BAA0B,GAAG,oBAAoB,CAAC;AAE/D,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,kBAAkB;IAClB,qCAAqC;IACrC,0BAA0B;CAClB,CAAC;AAGX,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,OAAQ,mBAAyC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAsB;IAC3C,WAAW,EACT,sMAAsM;IACxM,OAAO,EAAE;QACP,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE;QACvB,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE;QACtB,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE;QACtB,MAAM,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE;QAC1B,IAAI,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE;QACxB,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE;QACtB,MAAM,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE;KAC3B;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,6BAA6B,GAAsB;IAC9D,WAAW,EACT,8MAA8M;IAChN,OAAO,EAAE;QACP,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE;QACvB,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE;QACvB,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE;QACtB,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE;QACxB,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE;QACtB,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE;QACpB,MAAM,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE;KAC3B;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAsB;IACnD,WAAW,EACT,sMAAsM;IACxM,OAAO,EAAE;QACP,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE;QACvB,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE;QACtB,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE;QACtB,MAAM,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE;QAC1B,IAAI,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE;QACxB,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE;QACpB,MAAM,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE;KAC3B;CACF,CAAC;AAEF,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3C,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,kBAAkB;YACrB,OAAO,UAAU,CAAC;QACpB,KAAK,qCAAqC;YACxC,OAAO,6BAA6B,CAAC;QACvC,KAAK,0BAA0B;YAC7B,OAAO,kBAAkB,CAAC;IAC9B,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type LedgerEntry } from "../../policies/index.js";
|
|
2
|
+
export declare const APPROVED_LEDGER_TAG_PREFIX = "understanding-approved:";
|
|
3
|
+
export type ApprovalSource = "ledger" | "persisted-report" | "none";
|
|
4
|
+
export interface ApprovalCheckResult {
|
|
5
|
+
approved: boolean;
|
|
6
|
+
source: ApprovalSource;
|
|
7
|
+
detail: string;
|
|
8
|
+
}
|
|
9
|
+
export interface PersistedReport {
|
|
10
|
+
filePath: string;
|
|
11
|
+
sessionId: string | null;
|
|
12
|
+
approvalStatus: string | null;
|
|
13
|
+
approvedAt: string | null;
|
|
14
|
+
}
|
|
15
|
+
export declare function defaultReportsDir(cwd?: string): string;
|
|
16
|
+
/** Build the per-session ledger tag the pack searches for. */
|
|
17
|
+
export declare function approvedLedgerTagFor(sessionId: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* List persisted reports under `dir`, newest-first by mtime. Missing
|
|
20
|
+
* directory returns []. Any I/O error on a single file is silently
|
|
21
|
+
* skipped; the caller falls through to the ledger result. The package
|
|
22
|
+
* writes filenames as `<iso>-<slug>-<hash>.json` so the alphabetical
|
|
23
|
+
* sort would also work for ISO prefixes, but mtime is robust against
|
|
24
|
+
* the package changing its naming convention later.
|
|
25
|
+
*/
|
|
26
|
+
export declare function listPersistedReports(dir: string): PersistedReport[];
|
|
27
|
+
/**
|
|
28
|
+
* Return the freshest report for a given session_id, or the freshest
|
|
29
|
+
* report overall when the persisted file lacks a sessionId field
|
|
30
|
+
* (older package versions). null when nothing matches.
|
|
31
|
+
*/
|
|
32
|
+
export declare function findLatestReportForSession(reports: PersistedReport[], sessionId: string): PersistedReport | null;
|
|
33
|
+
export interface PersistedReportApprovalCheck {
|
|
34
|
+
approved: boolean;
|
|
35
|
+
detail: string;
|
|
36
|
+
report: PersistedReport | null;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Phase 6 #6 — substring-pollution defence shared by every PreToolUse
|
|
40
|
+
* blocker (Claude Code + Codex). Drops policy_decision rows so a
|
|
41
|
+
* `understanding-approved:<sess>` substring inside an audit row's
|
|
42
|
+
* JSON-encoded `reason` cannot accidentally satisfy the gate.
|
|
43
|
+
*/
|
|
44
|
+
export declare function isPolicyDecisionRow(e: LedgerEntry): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Match a ledger fetch against the per-session approval tag. Returns
|
|
47
|
+
* `{matched: true, detail}` on the first non-policy_decision row whose
|
|
48
|
+
* content includes the wanted tag; otherwise `{matched: false, detail}`
|
|
49
|
+
* naming how many rows were scanned. Stable across Claude Code and
|
|
50
|
+
* Codex blockers so their diagnostic strings stay identical.
|
|
51
|
+
*/
|
|
52
|
+
export declare function matchLedgerEntries(entries: LedgerEntry[], sessionId: string): {
|
|
53
|
+
matched: boolean;
|
|
54
|
+
detail: string;
|
|
55
|
+
};
|
|
56
|
+
export declare function checkPersistedReport(reportsDir: string, sessionId: string): PersistedReportApprovalCheck;
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
// Phase 6 #4 — runtime helpers for the understanding-before-execution pack.
|
|
2
|
+
//
|
|
3
|
+
// Two-source approval check that the harness-side PreToolUse blocker
|
|
4
|
+
// consults:
|
|
5
|
+
//
|
|
6
|
+
// 1. Evidence ledger via `grounding-mcp` (canonical for harnessed
|
|
7
|
+
// sessions). Tags shaped like `understanding-approved:${SESSION_ID}`.
|
|
8
|
+
// 2. Persisted JSON report under `.understanding-gate/reports/`
|
|
9
|
+
// (canonical for solo `@lannguyensi/understanding-gate` users).
|
|
10
|
+
// The package writes one file per session; the latest with
|
|
11
|
+
// `approvalStatus: "approved"` matching the session_id wins.
|
|
12
|
+
//
|
|
13
|
+
// Either source approves. The persisted-report fallback is what makes a
|
|
14
|
+
// 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
|
|
16
|
+
// the approval immediately on the next tool call.
|
|
17
|
+
import * as fs from "node:fs";
|
|
18
|
+
import * as path from "node:path";
|
|
19
|
+
import { POLICY_DECISION_TYPE } from "../../runtime/ledger-record.js";
|
|
20
|
+
export const APPROVED_LEDGER_TAG_PREFIX = "understanding-approved:";
|
|
21
|
+
const DEFAULT_REPORTS_DIRNAME = ".understanding-gate";
|
|
22
|
+
const REPORTS_SUBDIR = "reports";
|
|
23
|
+
export function defaultReportsDir(cwd = process.cwd()) {
|
|
24
|
+
return path.join(cwd, DEFAULT_REPORTS_DIRNAME, REPORTS_SUBDIR);
|
|
25
|
+
}
|
|
26
|
+
/** Build the per-session ledger tag the pack searches for. */
|
|
27
|
+
export function approvedLedgerTagFor(sessionId) {
|
|
28
|
+
return `${APPROVED_LEDGER_TAG_PREFIX}${sessionId}`;
|
|
29
|
+
}
|
|
30
|
+
function safeJsonParse(text) {
|
|
31
|
+
try {
|
|
32
|
+
return JSON.parse(text);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function readPersistedReport(filePath) {
|
|
39
|
+
let raw;
|
|
40
|
+
try {
|
|
41
|
+
raw = fs.readFileSync(filePath, "utf8");
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
const parsed = safeJsonParse(raw);
|
|
47
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
48
|
+
return null;
|
|
49
|
+
const obj = parsed;
|
|
50
|
+
return {
|
|
51
|
+
filePath,
|
|
52
|
+
sessionId: typeof obj["sessionId"] === "string" ? obj["sessionId"] : null,
|
|
53
|
+
approvalStatus: typeof obj["approvalStatus"] === "string" ? obj["approvalStatus"] : null,
|
|
54
|
+
approvedAt: typeof obj["approvedAt"] === "string" ? obj["approvedAt"] : null,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* List persisted reports under `dir`, newest-first by mtime. Missing
|
|
59
|
+
* directory returns []. Any I/O error on a single file is silently
|
|
60
|
+
* skipped; the caller falls through to the ledger result. The package
|
|
61
|
+
* writes filenames as `<iso>-<slug>-<hash>.json` so the alphabetical
|
|
62
|
+
* sort would also work for ISO prefixes, but mtime is robust against
|
|
63
|
+
* the package changing its naming convention later.
|
|
64
|
+
*/
|
|
65
|
+
export function listPersistedReports(dir) {
|
|
66
|
+
let names;
|
|
67
|
+
try {
|
|
68
|
+
names = fs.readdirSync(dir);
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return [];
|
|
72
|
+
}
|
|
73
|
+
const reports = [];
|
|
74
|
+
for (const name of names) {
|
|
75
|
+
if (!name.endsWith(".json"))
|
|
76
|
+
continue;
|
|
77
|
+
const full = path.join(dir, name);
|
|
78
|
+
let stat;
|
|
79
|
+
try {
|
|
80
|
+
stat = fs.statSync(full);
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
if (!stat.isFile())
|
|
86
|
+
continue;
|
|
87
|
+
const report = readPersistedReport(full);
|
|
88
|
+
if (!report)
|
|
89
|
+
continue;
|
|
90
|
+
reports.push({ report, mtimeMs: stat.mtimeMs });
|
|
91
|
+
}
|
|
92
|
+
reports.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
93
|
+
return reports.map((r) => r.report);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Return the freshest report for a given session_id, or the freshest
|
|
97
|
+
* report overall when the persisted file lacks a sessionId field
|
|
98
|
+
* (older package versions). null when nothing matches.
|
|
99
|
+
*/
|
|
100
|
+
export function findLatestReportForSession(reports, sessionId) {
|
|
101
|
+
// Strict match first.
|
|
102
|
+
for (const r of reports) {
|
|
103
|
+
if (r.sessionId === sessionId)
|
|
104
|
+
return r;
|
|
105
|
+
}
|
|
106
|
+
// Tolerant fallback: a report without sessionId is treated as
|
|
107
|
+
// applicable to whichever session is asking. Only kicks in when no
|
|
108
|
+
// sessionId-tagged report exists, so harnessed sessions with proper
|
|
109
|
+
// tagging never hit this path.
|
|
110
|
+
for (const r of reports) {
|
|
111
|
+
if (r.sessionId === null)
|
|
112
|
+
return r;
|
|
113
|
+
}
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Phase 6 #6 — substring-pollution defence shared by every PreToolUse
|
|
118
|
+
* blocker (Claude Code + Codex). Drops policy_decision rows so a
|
|
119
|
+
* `understanding-approved:<sess>` substring inside an audit row's
|
|
120
|
+
* JSON-encoded `reason` cannot accidentally satisfy the gate.
|
|
121
|
+
*/
|
|
122
|
+
export function isPolicyDecisionRow(e) {
|
|
123
|
+
if (e.type === POLICY_DECISION_TYPE)
|
|
124
|
+
return true;
|
|
125
|
+
if (typeof e.content === "string" && e.content.startsWith(`${POLICY_DECISION_TYPE}:`)) {
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Match a ledger fetch against the per-session approval tag. Returns
|
|
132
|
+
* `{matched: true, detail}` on the first non-policy_decision row whose
|
|
133
|
+
* content includes the wanted tag; otherwise `{matched: false, detail}`
|
|
134
|
+
* naming how many rows were scanned. Stable across Claude Code and
|
|
135
|
+
* Codex blockers so their diagnostic strings stay identical.
|
|
136
|
+
*/
|
|
137
|
+
export function matchLedgerEntries(entries, sessionId) {
|
|
138
|
+
const wanted = approvedLedgerTagFor(sessionId);
|
|
139
|
+
let scanned = 0;
|
|
140
|
+
for (const e of entries) {
|
|
141
|
+
if (isPolicyDecisionRow(e))
|
|
142
|
+
continue;
|
|
143
|
+
scanned += 1;
|
|
144
|
+
if (typeof e.content === "string" && e.content.includes(wanted)) {
|
|
145
|
+
return {
|
|
146
|
+
matched: true,
|
|
147
|
+
detail: `approved via ledger tag ${wanted} at ${e.createdAt}`,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return {
|
|
152
|
+
matched: false,
|
|
153
|
+
detail: `no ledger entry matched ${wanted} (scanned ${scanned} non-policy_decision row(s))`,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
export function checkPersistedReport(reportsDir, sessionId) {
|
|
157
|
+
const reports = listPersistedReports(reportsDir);
|
|
158
|
+
if (reports.length === 0) {
|
|
159
|
+
return {
|
|
160
|
+
approved: false,
|
|
161
|
+
detail: `no reports found at ${reportsDir}`,
|
|
162
|
+
report: null,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
const latest = findLatestReportForSession(reports, sessionId);
|
|
166
|
+
if (!latest) {
|
|
167
|
+
return {
|
|
168
|
+
approved: false,
|
|
169
|
+
detail: `no report matched session_id=${sessionId} (${reports.length} report(s) for other sessions)`,
|
|
170
|
+
report: null,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
if (latest.approvalStatus !== "approved") {
|
|
174
|
+
return {
|
|
175
|
+
approved: false,
|
|
176
|
+
detail: `latest report ${path.basename(latest.filePath)} has approvalStatus=${latest.approvalStatus ?? "<missing>"}`,
|
|
177
|
+
report: latest,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
return {
|
|
181
|
+
approved: true,
|
|
182
|
+
detail: `approved via persisted report ${path.basename(latest.filePath)}${latest.approvedAt ? ` (approved at ${latest.approvedAt})` : ""}`,
|
|
183
|
+
report: latest,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=understanding-before-execution-runtime.js.map
|
|
@@ -0,0 +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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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { PolicyPack } from "../../schema/index.js";
|
|
2
|
+
import { type Runtime } from "../runtime.js";
|
|
3
|
+
import type { PackContribution } from "../types.js";
|
|
4
|
+
export declare const PACK_NAME = "understanding-before-execution";
|
|
5
|
+
export type Mode = "fast_confirm" | "grill_me" | "strict";
|
|
6
|
+
export declare const DEFAULT_MODE: Mode;
|
|
7
|
+
export declare function isMode(value: unknown): value is Mode;
|
|
8
|
+
export declare function resolveMode(pack: PolicyPack): {
|
|
9
|
+
mode: Mode;
|
|
10
|
+
warning: string | null;
|
|
11
|
+
};
|
|
12
|
+
export declare function resolve(pack: PolicyPack, runtime?: Runtime): {
|
|
13
|
+
contribution: PackContribution;
|
|
14
|
+
warnings: string[];
|
|
15
|
+
};
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
// Builtin Policy Pack: `understanding-before-execution`.
|
|
2
|
+
//
|
|
3
|
+
// Bundles three hook contributions for Claude Code (UserPromptSubmit,
|
|
4
|
+
// Stop, PreToolUse), plus a per-mode instructions.md that documents what
|
|
5
|
+
// the pack is doing for human auditors. The actual prompt that the agent
|
|
6
|
+
// sees at UserPromptSubmit time is owned by `@lannguyensi/understanding-gate`
|
|
7
|
+
// (specifically `src/prompts/{full,fast-confirm,grill-me}.ts`); harness's
|
|
8
|
+
// instructions.md is the operator-facing summary, not the agent-injected
|
|
9
|
+
// text. Drift on instructions.md is therefore meaningful (someone edited
|
|
10
|
+
// the audit copy), distinct from drift on the package's own templates
|
|
11
|
+
// (which the package's own drift detection would handle on a future
|
|
12
|
+
// `understanding-gate init` reinstall).
|
|
13
|
+
import { profileToSettingsPermissions } from "../permission-translator.js";
|
|
14
|
+
import { DEFAULT_RUNTIME } from "../runtime.js";
|
|
15
|
+
import { isKnownProfileName, resolveProfile, KNOWN_PROFILE_NAMES, } from "./permission-profiles.js";
|
|
16
|
+
export const PACK_NAME = "understanding-before-execution";
|
|
17
|
+
const MODES = ["fast_confirm", "grill_me", "strict"];
|
|
18
|
+
export const DEFAULT_MODE = "grill_me";
|
|
19
|
+
const HOOK_NAME_PREFIX = `policy-pack:${PACK_NAME}`;
|
|
20
|
+
// Per-runtime hook surface. Claude Code keys on tool name (Edit|Write|Bash);
|
|
21
|
+
// Codex's write surface is `apply_patch` + `Bash`/`shell` (the task's
|
|
22
|
+
// in-scope list). The hook contract Codex feeds to the adapter is the
|
|
23
|
+
// same generic envelope harness publishes: `{ session_id, tool_name,
|
|
24
|
+
// raw_input, event }` on stdin, `{ decision }` on stdout, exit 2 on
|
|
25
|
+
// block. See dogfood/phase6-6/README.md for the wire format.
|
|
26
|
+
const PRE_TOOL_USE_MATCH_CLAUDE = "Edit|Write|Bash";
|
|
27
|
+
const PRE_TOOL_USE_MATCH_CODEX = "apply_patch|Bash|shell";
|
|
28
|
+
// UserPromptSubmit + Stop hooks point at `@lannguyensi/understanding-gate`
|
|
29
|
+
// bare bin names (npm i -g). The harness validator's checkHooks skips
|
|
30
|
+
// PATH lookup for non-rooted commands by design, so missing-bin shows
|
|
31
|
+
// up at runtime, not at lint. `harness doctor` (Phase 6 #4 follow-up)
|
|
32
|
+
// will add the presence check.
|
|
33
|
+
const BIN_USER_PROMPT_SUBMIT_CLAUDE = "understanding-gate-claude-hook";
|
|
34
|
+
const BIN_STOP_CLAUDE = "understanding-gate-claude-stop";
|
|
35
|
+
// PreToolUse blocker is the harness CLI itself (Phase 6 #4): it consults
|
|
36
|
+
// BOTH the evidence-ledger tag (canonical for harnessed sessions) AND
|
|
37
|
+
// the persisted JSON report under `.understanding-gate/reports/`
|
|
38
|
+
// (fallback for sessions without grounding-mcp wired). The npm package's
|
|
39
|
+
// own bin remains available for solo users; the harness blocker is
|
|
40
|
+
// strictly more powerful.
|
|
41
|
+
const PRE_TOOL_USE_COMMAND_CLAUDE = "harness pack hook pre-tool-use";
|
|
42
|
+
// Codex variants. The package `@lannguyensi/understanding-gate` does
|
|
43
|
+
// not yet ship Codex bins, so harness owns the adapter:
|
|
44
|
+
//
|
|
45
|
+
// - UserPromptSubmit-equivalent injector (Phase 6 #6).
|
|
46
|
+
// - Stop-equivalent capture into `.understanding-gate/reports/`
|
|
47
|
+
// (Phase 6 #6 follow-up).
|
|
48
|
+
// - PreToolUse blocker on apply_patch/Bash/shell (Phase 6 #6).
|
|
49
|
+
//
|
|
50
|
+
// Cross-runtime sessions can still approve from a Claude Code report:
|
|
51
|
+
// the ledger tag is the canonical source for harnessed sessions,
|
|
52
|
+
// independent of which runtime captured the report. The persisted-
|
|
53
|
+
// report directory is shared between runtimes, so a Codex stop that
|
|
54
|
+
// writes a report is approvable via `harness approve understanding`
|
|
55
|
+
// regardless of which runtime invokes the next tool call.
|
|
56
|
+
const COMMAND_USER_PROMPT_SUBMIT_CODEX = "harness pack hook codex-user-prompt-submit";
|
|
57
|
+
const COMMAND_STOP_CODEX = "harness pack hook codex-stop";
|
|
58
|
+
const COMMAND_PRE_TOOL_USE_CODEX = "harness pack hook codex-pre-tool-use";
|
|
59
|
+
export function isMode(value) {
|
|
60
|
+
return typeof value === "string" && MODES.includes(value);
|
|
61
|
+
}
|
|
62
|
+
export function resolveMode(pack) {
|
|
63
|
+
const raw = pack.config["mode"];
|
|
64
|
+
if (raw === undefined)
|
|
65
|
+
return { mode: DEFAULT_MODE, warning: null };
|
|
66
|
+
if (isMode(raw))
|
|
67
|
+
return { mode: raw, warning: null };
|
|
68
|
+
const warning = `policy_packs[${pack.name}].config.mode: unrecognised value ${JSON.stringify(raw)}, falling back to "${DEFAULT_MODE}". Allowed: ${MODES.join(", ")}.`;
|
|
69
|
+
return { mode: DEFAULT_MODE, warning };
|
|
70
|
+
}
|
|
71
|
+
function buildHooks(runtime) {
|
|
72
|
+
// Per-mode hook commands are identical (the mode is passed via the
|
|
73
|
+
// package's UNDERSTANDING_GATE_MODE env var, set elsewhere — out of
|
|
74
|
+
// scope for Phase 6 #2). What changes per mode is the instructions.md
|
|
75
|
+
// content + the actual injected prompt (owned by the npm package).
|
|
76
|
+
if (runtime === "codex") {
|
|
77
|
+
return [
|
|
78
|
+
{
|
|
79
|
+
name: `${HOOK_NAME_PREFIX}:codex:user-prompt-submit`,
|
|
80
|
+
event: "UserPromptSubmit",
|
|
81
|
+
command: COMMAND_USER_PROMPT_SUBMIT_CODEX,
|
|
82
|
+
blocking: false,
|
|
83
|
+
budget_ms: 5000,
|
|
84
|
+
description: "Codex adapter: inject the Understanding-Gate instruction template before the agent acts. Phase 6 #6.",
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
name: `${HOOK_NAME_PREFIX}:codex:stop`,
|
|
88
|
+
event: "Stop",
|
|
89
|
+
command: COMMAND_STOP_CODEX,
|
|
90
|
+
blocking: false,
|
|
91
|
+
budget_ms: 5000,
|
|
92
|
+
description: "Codex adapter: capture the agent's Understanding Report into .understanding-gate/reports/ as approvalStatus:pending. Phase 6 #6 follow-up.",
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
name: `${HOOK_NAME_PREFIX}:codex:pre-tool-use`,
|
|
96
|
+
event: "PreToolUse",
|
|
97
|
+
match: PRE_TOOL_USE_MATCH_CODEX,
|
|
98
|
+
command: COMMAND_PRE_TOOL_USE_CODEX,
|
|
99
|
+
blocking: "hard",
|
|
100
|
+
budget_ms: 5000,
|
|
101
|
+
description: "Codex adapter: block apply_patch/Bash/shell until an approved Understanding Report exists for the session. Consults both the evidence-ledger tag and the persisted JSON report.",
|
|
102
|
+
},
|
|
103
|
+
];
|
|
104
|
+
}
|
|
105
|
+
return [
|
|
106
|
+
{
|
|
107
|
+
name: `${HOOK_NAME_PREFIX}:user-prompt-submit`,
|
|
108
|
+
event: "UserPromptSubmit",
|
|
109
|
+
command: BIN_USER_PROMPT_SUBMIT_CLAUDE,
|
|
110
|
+
blocking: false,
|
|
111
|
+
budget_ms: 5000,
|
|
112
|
+
description: "Inject the Understanding-Gate instruction template before the agent acts. Source: @lannguyensi/understanding-gate.",
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
name: `${HOOK_NAME_PREFIX}:stop`,
|
|
116
|
+
event: "Stop",
|
|
117
|
+
command: BIN_STOP_CLAUDE,
|
|
118
|
+
blocking: false,
|
|
119
|
+
budget_ms: 5000,
|
|
120
|
+
description: "Capture the agent's Understanding Report into .understanding-gate/reports/. Source: @lannguyensi/understanding-gate.",
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
name: `${HOOK_NAME_PREFIX}:pre-tool-use`,
|
|
124
|
+
event: "PreToolUse",
|
|
125
|
+
match: PRE_TOOL_USE_MATCH_CLAUDE,
|
|
126
|
+
command: PRE_TOOL_USE_COMMAND_CLAUDE,
|
|
127
|
+
blocking: "hard",
|
|
128
|
+
budget_ms: 5000,
|
|
129
|
+
description: "Block Edit/Write/Bash until an approved Understanding Report exists for the session. Consults both the evidence-ledger tag (understanding-approved:${SESSION_ID}) and the persisted JSON report.",
|
|
130
|
+
},
|
|
131
|
+
];
|
|
132
|
+
}
|
|
133
|
+
function modeFriction(mode) {
|
|
134
|
+
switch (mode) {
|
|
135
|
+
case "fast_confirm":
|
|
136
|
+
return "low friction. The gate fires on prompts the classifier flags as execution-relevant. Brief Understanding Report; one-line approval.";
|
|
137
|
+
case "grill_me":
|
|
138
|
+
return "medium friction (default). The gate fires on any prompt the agent might respond to with a write. Full Understanding Report (assumptions, openQuestions, outOfScope, risks, verificationPlan). Push-back is encouraged.";
|
|
139
|
+
case "strict":
|
|
140
|
+
return "high friction. The gate fires on every prompt. Report MUST include verificationPlan and outOfScope; requiresHumanApproval is forced to true.";
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
function buildInstructions(pack, mode, runtime) {
|
|
144
|
+
const description = pack.description?.trim() ?? "";
|
|
145
|
+
const isCodex = runtime === "codex";
|
|
146
|
+
const injectorCmd = isCodex ? COMMAND_USER_PROMPT_SUBMIT_CODEX : BIN_USER_PROMPT_SUBMIT_CLAUDE;
|
|
147
|
+
const stopCmd = isCodex ? COMMAND_STOP_CODEX : BIN_STOP_CLAUDE;
|
|
148
|
+
const blockerCmd = isCodex ? COMMAND_PRE_TOOL_USE_CODEX : PRE_TOOL_USE_COMMAND_CLAUDE;
|
|
149
|
+
const blockerMatch = isCodex ? PRE_TOOL_USE_MATCH_CODEX : PRE_TOOL_USE_MATCH_CLAUDE;
|
|
150
|
+
const settingsArtefact = isCodex
|
|
151
|
+
? "`harness.generated/codex/config.toml`"
|
|
152
|
+
: "harness-managed `settings.json`";
|
|
153
|
+
const stopBullet = `2. \`Stop\` capture (\`${stopCmd}\`): persists the emitted Understanding
|
|
154
|
+
Report under \`.understanding-gate/reports/\` for audit and downstream
|
|
155
|
+
approval consumption.
|
|
156
|
+
`;
|
|
157
|
+
const blockerOrdinal = "3";
|
|
158
|
+
return `# Policy Pack: ${PACK_NAME}
|
|
159
|
+
|
|
160
|
+
> Operator audit copy. The agent-facing prompt is injected at runtime by
|
|
161
|
+
> the \`${injectorCmd}\` UserPromptSubmit hook; that text lives
|
|
162
|
+
> in the \`@lannguyensi/understanding-gate\` package, not here. This file
|
|
163
|
+
> records WHAT the pack is doing and HOW it is configured so that
|
|
164
|
+
> \`harness diff --since-apply\` can flag operator-facing drift.
|
|
165
|
+
|
|
166
|
+
## Runtime
|
|
167
|
+
|
|
168
|
+
${runtime}
|
|
169
|
+
|
|
170
|
+
## Mode
|
|
171
|
+
|
|
172
|
+
${mode}
|
|
173
|
+
|
|
174
|
+
${modeFriction(mode)}
|
|
175
|
+
|
|
176
|
+
## Effect
|
|
177
|
+
|
|
178
|
+
While this pack is enabled, hooks are wired into the ${settingsArtefact}:
|
|
179
|
+
|
|
180
|
+
1. \`UserPromptSubmit\` injector (\`${injectorCmd}\`): inserts the
|
|
181
|
+
Understanding-Gate instruction template into the agent's first response.
|
|
182
|
+
${stopBullet}${blockerOrdinal}. \`PreToolUse\` blocker (\`${blockerCmd}\`, blocking: hard)
|
|
183
|
+
on \`${blockerMatch}\`: refuses the tool call until an approved
|
|
184
|
+
report exists for the session. Consults BOTH the evidence-ledger
|
|
185
|
+
tag (\`understanding-approved:\${SESSION_ID}\`, canonical for
|
|
186
|
+
harnessed sessions) AND the persisted JSON report under
|
|
187
|
+
\`.understanding-gate/reports/\` (fallback for sessions without
|
|
188
|
+
grounding-mcp wired). Either source approves.
|
|
189
|
+
|
|
190
|
+
## Approval
|
|
191
|
+
|
|
192
|
+
The standalone blocker shipped in \`@lannguyensi/understanding-gate@>=0.2.0\`
|
|
193
|
+
checks the persisted JSON report's \`approvalStatus\`. Phase 6 #4 will
|
|
194
|
+
add a harness-side blocker that ALSO consults the evidence-ledger tag
|
|
195
|
+
\`understanding-approved:\${SESSION_ID}\` (canonical for harnessed
|
|
196
|
+
sessions), and \`harness approve understanding\` will round-trip both.
|
|
197
|
+
Until then, approval flows through the package's own CLI.
|
|
198
|
+
|
|
199
|
+
## Pack metadata
|
|
200
|
+
${description ? `\n> ${description.replace(/\n/g, "\n> ")}\n` : ""}
|
|
201
|
+
- Source: \`builtin\`
|
|
202
|
+
- Pack: \`${PACK_NAME}\`
|
|
203
|
+
- Mode: \`${mode}\`
|
|
204
|
+
- Runtime: \`${runtime}\`
|
|
205
|
+
|
|
206
|
+
## See also
|
|
207
|
+
|
|
208
|
+
- \`docs/policy-packs/understanding-before-execution.md\` (full reference)
|
|
209
|
+
- \`docs/ROADMAP.md\` Phase 6 sub-task decomposition
|
|
210
|
+
`;
|
|
211
|
+
}
|
|
212
|
+
function resolvePermissionProfile(pack) {
|
|
213
|
+
const raw = pack.config["permission_profile"];
|
|
214
|
+
if (raw === undefined)
|
|
215
|
+
return { permissions: null, warning: null };
|
|
216
|
+
if (typeof raw !== "string") {
|
|
217
|
+
return {
|
|
218
|
+
permissions: null,
|
|
219
|
+
warning: `policy_packs[${pack.name}].config.permission_profile: expected a string, got ${typeof raw}; skipping permission contribution.`,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
if (!isKnownProfileName(raw)) {
|
|
223
|
+
return {
|
|
224
|
+
permissions: null,
|
|
225
|
+
warning: `policy_packs[${pack.name}].config.permission_profile: unrecognised profile ${JSON.stringify(raw)}. Allowed: ${KNOWN_PROFILE_NAMES.join(", ")}. Skipping permission contribution.`,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
const profile = resolveProfile(raw);
|
|
229
|
+
if (!profile)
|
|
230
|
+
return { permissions: null, warning: null };
|
|
231
|
+
return { permissions: profileToSettingsPermissions(profile), warning: null };
|
|
232
|
+
}
|
|
233
|
+
export function resolve(pack, runtime = DEFAULT_RUNTIME) {
|
|
234
|
+
const { mode, warning } = resolveMode(pack);
|
|
235
|
+
const hooks = buildHooks(runtime);
|
|
236
|
+
const instructionsContent = buildInstructions(pack, mode, runtime);
|
|
237
|
+
const files = [
|
|
238
|
+
{
|
|
239
|
+
relativePath: `policy-packs/${PACK_NAME}/instructions.md`,
|
|
240
|
+
content: instructionsContent,
|
|
241
|
+
},
|
|
242
|
+
];
|
|
243
|
+
const warnings = [];
|
|
244
|
+
if (warning)
|
|
245
|
+
warnings.push(warning);
|
|
246
|
+
const profileResult = resolvePermissionProfile(pack);
|
|
247
|
+
if (profileResult.warning)
|
|
248
|
+
warnings.push(profileResult.warning);
|
|
249
|
+
const contribution = { hooks, files };
|
|
250
|
+
if (profileResult.permissions)
|
|
251
|
+
contribution.permissions = profileResult.permissions;
|
|
252
|
+
return { contribution, warnings };
|
|
253
|
+
}
|
|
254
|
+
//# sourceMappingURL=understanding-before-execution.js.map
|