@lannguyensi/harness 0.7.0 → 0.8.1

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 (111) hide show
  1. package/CHANGELOG.md +229 -0
  2. package/README.md +56 -17
  3. package/dist/cli/apply/apply.d.ts +13 -0
  4. package/dist/cli/apply/apply.js +59 -3
  5. package/dist/cli/apply/apply.js.map +1 -1
  6. package/dist/cli/apply/generate-codex-config.d.ts +6 -0
  7. package/dist/cli/apply/generate-codex-config.js +149 -0
  8. package/dist/cli/apply/generate-codex-config.js.map +1 -0
  9. package/dist/cli/apply/generate-settings.d.ts +15 -1
  10. package/dist/cli/apply/generate-settings.js +16 -1
  11. package/dist/cli/apply/generate-settings.js.map +1 -1
  12. package/dist/cli/apply/index.d.ts +2 -1
  13. package/dist/cli/apply/index.js +2 -1
  14. package/dist/cli/apply/index.js.map +1 -1
  15. package/dist/cli/approve/understanding.d.ts +39 -0
  16. package/dist/cli/approve/understanding.js +122 -0
  17. package/dist/cli/approve/understanding.js.map +1 -0
  18. package/dist/cli/doctor/codex.d.ts +34 -0
  19. package/dist/cli/doctor/codex.js +331 -0
  20. package/dist/cli/doctor/codex.js.map +1 -0
  21. package/dist/cli/doctor/format.js +11 -0
  22. package/dist/cli/doctor/format.js.map +1 -1
  23. package/dist/cli/doctor/index.d.ts +13 -1
  24. package/dist/cli/doctor/index.js +19 -0
  25. package/dist/cli/doctor/index.js.map +1 -1
  26. package/dist/cli/doctor/types.d.ts +21 -1
  27. package/dist/cli/doctor/types.js +12 -1
  28. package/dist/cli/doctor/types.js.map +1 -1
  29. package/dist/cli/index.js +261 -2
  30. package/dist/cli/index.js.map +1 -1
  31. package/dist/cli/pack/add.d.ts +13 -0
  32. package/dist/cli/pack/add.js +71 -0
  33. package/dist/cli/pack/add.js.map +1 -0
  34. package/dist/cli/pack/hook-codex-pre-tool-use.d.ts +30 -0
  35. package/dist/cli/pack/hook-codex-pre-tool-use.js +149 -0
  36. package/dist/cli/pack/hook-codex-pre-tool-use.js.map +1 -0
  37. package/dist/cli/pack/hook-codex-stop.d.ts +31 -0
  38. package/dist/cli/pack/hook-codex-stop.js +332 -0
  39. package/dist/cli/pack/hook-codex-stop.js.map +1 -0
  40. package/dist/cli/pack/hook-codex-user-prompt-submit.d.ts +18 -0
  41. package/dist/cli/pack/hook-codex-user-prompt-submit.js +92 -0
  42. package/dist/cli/pack/hook-codex-user-prompt-submit.js.map +1 -0
  43. package/dist/cli/pack/hook-pre-tool-use.d.ts +32 -0
  44. package/dist/cli/pack/hook-pre-tool-use.js +181 -0
  45. package/dist/cli/pack/hook-pre-tool-use.js.map +1 -0
  46. package/dist/cli/pack/index.d.ts +4 -0
  47. package/dist/cli/pack/index.js +5 -0
  48. package/dist/cli/pack/index.js.map +1 -0
  49. package/dist/cli/pack/list.d.ts +10 -0
  50. package/dist/cli/pack/list.js +43 -0
  51. package/dist/cli/pack/list.js.map +1 -0
  52. package/dist/cli/pack/mutate.d.ts +14 -0
  53. package/dist/cli/pack/mutate.js +76 -0
  54. package/dist/cli/pack/mutate.js.map +1 -0
  55. package/dist/cli/pack/remove.d.ts +15 -0
  56. package/dist/cli/pack/remove.js +153 -0
  57. package/dist/cli/pack/remove.js.map +1 -0
  58. package/dist/cli/policy/intercept.js +24 -0
  59. package/dist/cli/policy/intercept.js.map +1 -1
  60. package/dist/cli/validate/checks.js +32 -0
  61. package/dist/cli/validate/checks.js.map +1 -1
  62. package/dist/policy-packs/builtin/permission-profiles.d.ts +11 -0
  63. package/dist/policy-packs/builtin/permission-profiles.js +74 -0
  64. package/dist/policy-packs/builtin/permission-profiles.js.map +1 -0
  65. package/dist/policy-packs/builtin/understanding-before-execution-runtime.d.ts +56 -0
  66. package/dist/policy-packs/builtin/understanding-before-execution-runtime.js +186 -0
  67. package/dist/policy-packs/builtin/understanding-before-execution-runtime.js.map +1 -0
  68. package/dist/policy-packs/builtin/understanding-before-execution.d.ts +15 -0
  69. package/dist/policy-packs/builtin/understanding-before-execution.js +254 -0
  70. package/dist/policy-packs/builtin/understanding-before-execution.js.map +1 -0
  71. package/dist/policy-packs/expand.d.ts +4 -0
  72. package/dist/policy-packs/expand.js +90 -0
  73. package/dist/policy-packs/expand.js.map +1 -0
  74. package/dist/policy-packs/index.d.ts +5 -0
  75. package/dist/policy-packs/index.js +5 -0
  76. package/dist/policy-packs/index.js.map +1 -0
  77. package/dist/policy-packs/permission-translator.d.ts +9 -0
  78. package/dist/policy-packs/permission-translator.js +76 -0
  79. package/dist/policy-packs/permission-translator.js.map +1 -0
  80. package/dist/policy-packs/registry.d.ts +11 -0
  81. package/dist/policy-packs/registry.js +20 -0
  82. package/dist/policy-packs/registry.js.map +1 -0
  83. package/dist/policy-packs/runtime.d.ts +8 -0
  84. package/dist/policy-packs/runtime.js +30 -0
  85. package/dist/policy-packs/runtime.js.map +1 -0
  86. package/dist/policy-packs/source.d.ts +6 -0
  87. package/dist/policy-packs/source.js +10 -0
  88. package/dist/policy-packs/source.js.map +1 -0
  89. package/dist/policy-packs/types.d.ts +41 -0
  90. package/dist/policy-packs/types.js +11 -0
  91. package/dist/policy-packs/types.js.map +1 -0
  92. package/dist/runtime/index.d.ts +1 -0
  93. package/dist/runtime/index.js +1 -0
  94. package/dist/runtime/index.js.map +1 -1
  95. package/dist/runtime/intercept.d.ts +20 -1
  96. package/dist/runtime/intercept.js +18 -6
  97. package/dist/runtime/intercept.js.map +1 -1
  98. package/dist/runtime/ledger-add.d.ts +16 -0
  99. package/dist/runtime/ledger-add.js +139 -0
  100. package/dist/runtime/ledger-add.js.map +1 -0
  101. package/dist/schema/index.d.ts +1485 -10
  102. package/dist/schema/index.js +6 -0
  103. package/dist/schema/index.js.map +1 -1
  104. package/dist/schema/permission-profiles.d.ts +2161 -0
  105. package/dist/schema/permission-profiles.js +60 -0
  106. package/dist/schema/permission-profiles.js.map +1 -0
  107. package/dist/schema/policy-packs.d.ts +52 -0
  108. package/dist/schema/policy-packs.js +35 -0
  109. package/dist/schema/policy-packs.js.map +1 -0
  110. package/dist/schema/tools.d.ts +8 -8
  111. package/package.json +1 -1
@@ -0,0 +1,149 @@
1
+ // Phase 6 #6 — `harness pack hook codex-pre-tool-use` runtime verb.
2
+ //
3
+ // Codex variant of the Claude Code blocker (`hook-pre-tool-use.ts`).
4
+ // Same approval logic (ledger + persisted-report, either approves), but
5
+ // a different I/O contract:
6
+ //
7
+ // stdin : JSON envelope shaped as `{ session_id, tool_name,
8
+ // raw_input, event }` — harness's published wire format that
9
+ // the Codex CLI integration is wrapped to emit. The
10
+ // integration is documented in
11
+ // `docs/policy-packs/understanding-before-execution.md`
12
+ // "Adapter notes / Codex".
13
+ // stdout : block reason on stderr; allow path is silent on stdout.
14
+ // exit : 0 on allow, 2 on block. Codex's blocking convention is
15
+ // non-zero exit (the JSON-decision shape Claude Code reads
16
+ // is not part of Codex's hook contract today).
17
+ //
18
+ // Failure mode mirrors the Claude blocker: any error in load / parse /
19
+ // ledger / report scan resolves to ALLOW (exit 0, silent diagnostic on
20
+ // stderr). The package's optional standalone blocker remains a safety
21
+ // net for solo users; the harness blocker is strictly more powerful.
22
+ import { queryLedgerByTag } from "../../policies/index.js";
23
+ import { checkPersistedReport, defaultReportsDir, matchLedgerEntries, } from "../../policy-packs/builtin/understanding-before-execution-runtime.js";
24
+ import { loadManifest } from "../loader.js";
25
+ const PACK_NAME = "understanding-before-execution";
26
+ const EXIT_BLOCK = 2;
27
+ async function readStdin(stream) {
28
+ return new Promise((resolve, reject) => {
29
+ let data = "";
30
+ stream.setEncoding("utf8");
31
+ stream.on("data", (chunk) => {
32
+ data += chunk;
33
+ });
34
+ stream.on("end", () => resolve(data));
35
+ stream.on("error", (err) => reject(err));
36
+ });
37
+ }
38
+ function pickString(...candidates) {
39
+ for (const c of candidates) {
40
+ if (typeof c === "string" && c.length > 0)
41
+ return c;
42
+ }
43
+ return undefined;
44
+ }
45
+ function findGroundingMcp(manifest) {
46
+ return manifest.tools.mcp.find((m) => m.name === "grounding-mcp") ?? null;
47
+ }
48
+ async function checkLedger(manifest, sessionId, opts) {
49
+ if (opts.ledgerQuery) {
50
+ const result = await opts.ledgerQuery(sessionId);
51
+ if ("degraded" in result) {
52
+ return { matched: false, detail: `ledger degraded (${result.degraded})` };
53
+ }
54
+ return matchLedgerEntries(result, sessionId);
55
+ }
56
+ const server = findGroundingMcp(manifest);
57
+ if (!server) {
58
+ return { matched: false, detail: "grounding-mcp not declared in manifest" };
59
+ }
60
+ const command = Array.isArray(server.command)
61
+ ? server.command
62
+ : server.command.trim().split(/\s+/);
63
+ const env = server.env ?? undefined;
64
+ const timeoutMs = opts.ledgerTimeoutMs ?? server.health?.timeout_ms ?? 5_000;
65
+ const result = await queryLedgerByTag({
66
+ mcpCommand: command,
67
+ ...(env && { mcpEnv: env }),
68
+ sessionId,
69
+ timeoutMs,
70
+ });
71
+ if (result.kind === "degraded") {
72
+ return { matched: false, detail: `ledger degraded (${result.reason})` };
73
+ }
74
+ return matchLedgerEntries(result.entries, sessionId);
75
+ }
76
+ function allowResult(detail, source, stderr) {
77
+ const diagnostic = `harness pack hook codex: ${detail}, allowing.`;
78
+ stderr.write(`${diagnostic}\n`);
79
+ return {
80
+ exitCode: 0,
81
+ blocked: false,
82
+ approvalCheck: { approved: true, source, detail },
83
+ diagnostic,
84
+ };
85
+ }
86
+ export async function runPackHookCodexPreToolUseCli(opts = {}) {
87
+ const stdin = opts.stdin ?? process.stdin;
88
+ const stderr = opts.stderr ?? process.stderr;
89
+ const packName = opts.pack ?? PACK_NAME;
90
+ // Read stdin defensively. Bad JSON falls through to allow (matches
91
+ // Claude blocker's failure mode).
92
+ const raw = await readStdin(stdin);
93
+ let event = {};
94
+ try {
95
+ event = JSON.parse(raw.trim() || "{}");
96
+ }
97
+ catch {
98
+ /* allow on malformed input */
99
+ }
100
+ const sessionId = pickString(event.session_id) ??
101
+ process.env["CODEX_SESSION_ID"] ??
102
+ process.env["CLAUDE_SESSION_ID"] ??
103
+ "";
104
+ const toolName = pickString(event.tool_name, event.tool) ?? "(unknown)";
105
+ // Load manifest (or use injection). Bail to allow on any failure so a
106
+ // missing harness install never bricks the session.
107
+ let manifest;
108
+ try {
109
+ manifest = opts.manifest ?? loadManifest(opts).manifest;
110
+ }
111
+ catch (err) {
112
+ return allowResult(`manifest load failed (${err.message})`, "none", stderr);
113
+ }
114
+ // Confirm the pack is enabled.
115
+ const declared = manifest.policy_packs.find((p) => p.name === packName);
116
+ if (!declared) {
117
+ return allowResult(`pack "${packName}" not declared in manifest`, "none", stderr);
118
+ }
119
+ if (!declared.enabled) {
120
+ return allowResult(`pack "${packName}" is enabled:false`, "none", stderr);
121
+ }
122
+ if (sessionId === "") {
123
+ return allowResult("no session_id resolvable from input or $CODEX_SESSION_ID/$CLAUDE_SESSION_ID", "none", stderr);
124
+ }
125
+ // Source 1: ledger.
126
+ const ledger = await checkLedger(manifest, sessionId, opts);
127
+ if (ledger.matched) {
128
+ return allowResult(ledger.detail, "ledger", stderr);
129
+ }
130
+ // Source 2: persisted report.
131
+ const reportsDir = opts.reportsDir ?? defaultReportsDir();
132
+ const report = checkPersistedReport(reportsDir, sessionId);
133
+ if (report.approved) {
134
+ return allowResult(report.detail, "persisted-report", stderr);
135
+ }
136
+ // Neither source approved. Codex blocks via non-zero exit + stderr
137
+ // reason; there is no JSON-decision wire to write to stdout.
138
+ const reason = `${ledger.detail}; ${report.detail}`;
139
+ const diagnostic = `harness pack hook codex: BLOCK: ${reason}. Tool: ${toolName}. ` +
140
+ "Run `harness approve understanding` once you have produced and confirmed an Understanding Report.";
141
+ stderr.write(`${diagnostic}\n`);
142
+ return {
143
+ exitCode: EXIT_BLOCK,
144
+ blocked: true,
145
+ approvalCheck: { approved: false, source: "none", detail: reason },
146
+ diagnostic,
147
+ };
148
+ }
149
+ //# sourceMappingURL=hook-codex-pre-tool-use.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook-codex-pre-tool-use.js","sourceRoot":"","sources":["../../../src/cli/pack/hook-codex-pre-tool-use.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import type { Manifest } from "../../schema/index.js";
2
+ import { type LoaderOptions } from "../loader.js";
3
+ export interface PackHookCodexStopOptions extends LoaderOptions {
4
+ pack?: string;
5
+ reportsDir?: string;
6
+ stdin?: NodeJS.ReadableStream;
7
+ stdout?: NodeJS.WritableStream;
8
+ stderr?: NodeJS.WritableStream;
9
+ manifest?: Manifest;
10
+ /** Test-injectable clock; defaults to new Date(). */
11
+ now?: Date;
12
+ }
13
+ export interface ParsedReport {
14
+ interpretation: string;
15
+ assumptions: string[];
16
+ openQuestions: string[];
17
+ outOfScope: string[];
18
+ risks: string[];
19
+ verificationPlan: string;
20
+ }
21
+ export interface PackHookCodexStopResult {
22
+ exitCode: number;
23
+ /** Path of the persisted report; null when no file was written. */
24
+ reportPath: string | null;
25
+ /** True when at least one Understanding Report field was extracted. */
26
+ parsed: boolean;
27
+ diagnostic: string;
28
+ }
29
+ export declare function parseUnderstandingReport(text: string): ParsedReport;
30
+ export declare function reportHasContent(r: ParsedReport): boolean;
31
+ export declare function runPackHookCodexStopCli(opts?: PackHookCodexStopOptions): Promise<PackHookCodexStopResult>;
@@ -0,0 +1,332 @@
1
+ // Phase 6 #6 follow-up — `harness pack hook codex-stop` runtime verb.
2
+ //
3
+ // Codex Stop-equivalent for the `understanding-before-execution` pack.
4
+ // Mirrors the `@lannguyensi/understanding-gate` claude-code stop bin's
5
+ // contract, scoped to v1: read the agent's stop event on stdin,
6
+ // extract the last assistant message, parse Understanding Report
7
+ // fields, persist as JSON under `.understanding-gate/reports/`. The
8
+ // resulting file lands with `approvalStatus: "pending"` so a later
9
+ // `harness approve understanding` flips it to approved.
10
+ //
11
+ // Wire format on stdin (envelope harness publishes; Codex CLI
12
+ // integration wraps its native event into this shape):
13
+ //
14
+ // { session_id?: string, last_assistant_message?: string,
15
+ // messages?: Array<{ role: string, content: string }> }
16
+ //
17
+ // Either `last_assistant_message` is provided directly, OR the last
18
+ // entry in `messages[]` with role === "assistant" is used.
19
+ //
20
+ // Failure mode: any error (malformed input, missing session id,
21
+ // unwritable reports dir, parser yielded zero recognisable fields)
22
+ // falls through to exit 0 + a stderr diagnostic. The Stop event must
23
+ // never block the agent's response path; capture is best-effort.
24
+ //
25
+ // Out of scope for v1 (filed separately when needed):
26
+ // - Backfill of older transcripts.
27
+ // - A schema-validating parser; the v1 parser is heading-driven and
28
+ // intentionally lenient.
29
+ import { createHash } from "node:crypto";
30
+ import * as fs from "node:fs";
31
+ import * as path from "node:path";
32
+ import { atomicWriteFile } from "../../io/atomic-write.js";
33
+ import { defaultReportsDir } from "../../policy-packs/builtin/understanding-before-execution-runtime.js";
34
+ import { loadManifest } from "../loader.js";
35
+ const PACK_NAME = "understanding-before-execution";
36
+ const RUNTIME_TAG = "codex";
37
+ async function readStdin(stream) {
38
+ return new Promise((resolve, reject) => {
39
+ let data = "";
40
+ stream.setEncoding("utf8");
41
+ stream.on("data", (chunk) => {
42
+ data += chunk;
43
+ });
44
+ stream.on("end", () => resolve(data));
45
+ stream.on("error", (err) => reject(err));
46
+ });
47
+ }
48
+ function pickString(...candidates) {
49
+ for (const c of candidates) {
50
+ if (typeof c === "string" && c.length > 0)
51
+ return c;
52
+ }
53
+ return undefined;
54
+ }
55
+ function extractLastAssistantText(env) {
56
+ const direct = pickString(env.last_assistant_message);
57
+ if (direct !== undefined)
58
+ return direct;
59
+ if (!Array.isArray(env.messages))
60
+ return null;
61
+ for (let i = env.messages.length - 1; i >= 0; i--) {
62
+ const row = env.messages[i];
63
+ if (row && typeof row === "object" && row.role === "assistant") {
64
+ const content = pickString(row.content);
65
+ if (content !== undefined)
66
+ return content;
67
+ }
68
+ }
69
+ return null;
70
+ }
71
+ // Field names recognised by the parser. Lower-case canonical forms;
72
+ // the matcher is case-insensitive and accepts CamelCase / snake_case
73
+ // / spaces.
74
+ const FIELDS = [
75
+ "interpretation",
76
+ "assumptions",
77
+ "openquestions",
78
+ "outofscope",
79
+ "risks",
80
+ "verificationplan",
81
+ ];
82
+ const SCALAR_FIELDS = new Set(["interpretation", "verificationplan"]);
83
+ function normalizeFieldKey(raw) {
84
+ // Strip trailing punctuation that operators commonly leave inside
85
+ // bold labels (e.g. `**Interpretation:**` → field name is just
86
+ // "Interpretation"). Then compact whitespace/separators.
87
+ const compact = raw
88
+ .trim()
89
+ .replace(/[:.\s]+$/g, "")
90
+ .toLowerCase()
91
+ .replace(/[\s_-]+/g, "");
92
+ // Accept synonyms / British/American variants.
93
+ switch (compact) {
94
+ case "openquestions":
95
+ case "questions":
96
+ return "openquestions";
97
+ case "outofscope":
98
+ case "scopeexclusions":
99
+ case "exclusions":
100
+ return "outofscope";
101
+ case "verificationplan":
102
+ case "validation":
103
+ case "verification":
104
+ return "verificationplan";
105
+ default:
106
+ if (FIELDS.includes(compact)) {
107
+ return compact;
108
+ }
109
+ return null;
110
+ }
111
+ }
112
+ // A heading/label line opens a section. Recognised:
113
+ // `## Interpretation` markdown heading
114
+ // `**Interpretation:**` bold label
115
+ // `Interpretation:` (line) plain colon-prefixed label
116
+ // Returns the FieldKey on hit, plus any inline content trailing on
117
+ // the same line (e.g. `Interpretation: short paragraph`).
118
+ function matchSectionHeader(line) {
119
+ const trimmed = line.trim();
120
+ if (trimmed === "")
121
+ return null;
122
+ // Markdown heading: `## Interpretation` or `### Open Questions`.
123
+ const heading = trimmed.match(/^#{1,6}\s+(.+?)\s*$/);
124
+ if (heading) {
125
+ const field = normalizeFieldKey(heading[1] ?? "");
126
+ if (field)
127
+ return { field, inlineRest: "" };
128
+ }
129
+ // Bold label: `**Interpretation:**` or `**Interpretation**:`.
130
+ const bold = trimmed.match(/^\*\*([^*]+?)\*\*\s*:?\s*(.*)$/);
131
+ if (bold) {
132
+ const field = normalizeFieldKey(bold[1] ?? "");
133
+ if (field)
134
+ return { field, inlineRest: bold[2]?.trim() ?? "" };
135
+ }
136
+ // Plain label `Interpretation: rest of line` (avoid matching arbitrary
137
+ // sentence colons by requiring the prefix to be a known field name).
138
+ const plain = trimmed.match(/^([A-Za-z][A-Za-z _-]*)\s*:\s*(.*)$/);
139
+ if (plain) {
140
+ const field = normalizeFieldKey(plain[1] ?? "");
141
+ if (field)
142
+ return { field, inlineRest: plain[2]?.trim() ?? "" };
143
+ }
144
+ return null;
145
+ }
146
+ function extractBulletText(line) {
147
+ const trimmed = line.trim();
148
+ if (trimmed === "")
149
+ return null;
150
+ const m = trimmed.match(/^[-*•]\s+(.+)$/);
151
+ return m ? m[1].trim() : null;
152
+ }
153
+ export function parseUnderstandingReport(text) {
154
+ const out = {
155
+ interpretation: "",
156
+ assumptions: [],
157
+ openQuestions: [],
158
+ outOfScope: [],
159
+ risks: [],
160
+ verificationPlan: "",
161
+ };
162
+ if (typeof text !== "string" || text.trim() === "")
163
+ return out;
164
+ const lines = text.split(/\r?\n/);
165
+ let active = null;
166
+ let scalarBuffer = [];
167
+ const flushScalar = () => {
168
+ if (active && SCALAR_FIELDS.has(active) && scalarBuffer.length > 0) {
169
+ const joined = scalarBuffer.join(" ").replace(/\s+/g, " ").trim();
170
+ writeScalar(out, active, joined);
171
+ }
172
+ scalarBuffer = [];
173
+ };
174
+ for (const line of lines) {
175
+ const header = matchSectionHeader(line);
176
+ if (header) {
177
+ flushScalar();
178
+ active = header.field;
179
+ if (header.inlineRest !== "") {
180
+ if (SCALAR_FIELDS.has(active)) {
181
+ scalarBuffer.push(header.inlineRest);
182
+ }
183
+ else {
184
+ // Inline content on a list-field header counts as the first item.
185
+ appendList(out, active, header.inlineRest);
186
+ }
187
+ }
188
+ continue;
189
+ }
190
+ if (!active)
191
+ continue;
192
+ if (SCALAR_FIELDS.has(active)) {
193
+ const trimmed = line.trim();
194
+ if (trimmed === "") {
195
+ // Blank line within a scalar paragraph terminates accumulation.
196
+ if (scalarBuffer.length > 0)
197
+ flushScalar();
198
+ continue;
199
+ }
200
+ scalarBuffer.push(trimmed);
201
+ }
202
+ else {
203
+ const bullet = extractBulletText(line);
204
+ if (bullet !== null) {
205
+ appendList(out, active, bullet);
206
+ }
207
+ // Non-bullet lines under a list field are dropped (the upstream
208
+ // package's contract is "use bullets"; lenient drop avoids
209
+ // accidentally appending the next paragraph).
210
+ }
211
+ }
212
+ flushScalar();
213
+ return out;
214
+ }
215
+ function writeScalar(out, field, value) {
216
+ if (field === "interpretation")
217
+ out.interpretation = value;
218
+ else if (field === "verificationplan")
219
+ out.verificationPlan = value;
220
+ }
221
+ function appendList(out, field, value) {
222
+ if (field === "assumptions")
223
+ out.assumptions.push(value);
224
+ else if (field === "openquestions")
225
+ out.openQuestions.push(value);
226
+ else if (field === "outofscope")
227
+ out.outOfScope.push(value);
228
+ else if (field === "risks")
229
+ out.risks.push(value);
230
+ }
231
+ export function reportHasContent(r) {
232
+ return (r.interpretation !== "" ||
233
+ r.verificationPlan !== "" ||
234
+ r.assumptions.length > 0 ||
235
+ r.openQuestions.length > 0 ||
236
+ r.outOfScope.length > 0 ||
237
+ r.risks.length > 0);
238
+ }
239
+ function sessionShortHash(sessionId) {
240
+ return createHash("sha256").update(sessionId).digest("hex").slice(0, 8);
241
+ }
242
+ function isoFilenameStamp(now) {
243
+ // 2026-05-10T17:25:30.123Z -> 2026-05-10T17-25-30
244
+ const iso = now.toISOString();
245
+ const head = iso.slice(0, iso.indexOf(".") === -1 ? iso.length - 1 : iso.indexOf("."));
246
+ return head.replace(/:/g, "-");
247
+ }
248
+ function buildReportFilename(sessionId, now) {
249
+ const stamp = isoFilenameStamp(now);
250
+ const hash = sessionShortHash(sessionId);
251
+ return `${stamp}-${RUNTIME_TAG}-${hash}.json`;
252
+ }
253
+ function writeReportFile(reportsDir, filename, body) {
254
+ fs.mkdirSync(reportsDir, { recursive: true });
255
+ const target = path.join(reportsDir, filename);
256
+ atomicWriteFile(target, `${JSON.stringify(body, null, 2)}\n`);
257
+ return target;
258
+ }
259
+ function allowResult(diagnostic, stderr) {
260
+ stderr.write(`${diagnostic}\n`);
261
+ return { exitCode: 0, reportPath: null, parsed: false, diagnostic };
262
+ }
263
+ export async function runPackHookCodexStopCli(opts = {}) {
264
+ const stdin = opts.stdin ?? process.stdin;
265
+ const stderr = opts.stderr ?? process.stderr;
266
+ const packName = opts.pack ?? PACK_NAME;
267
+ const now = opts.now ?? new Date();
268
+ // Fail-open on stdin read errors (e.g. EPIPE on a closed pipe). The
269
+ // Stop hook must never crash the agent's response path; a missed
270
+ // capture is acceptable, an uncaught reject is not.
271
+ let raw;
272
+ try {
273
+ raw = await readStdin(stdin);
274
+ }
275
+ catch (err) {
276
+ return allowResult(`harness pack hook codex-stop: stdin read failed (${err.message}), skipping capture.`, stderr);
277
+ }
278
+ let envelope = {};
279
+ try {
280
+ envelope = JSON.parse(raw.trim() || "{}");
281
+ }
282
+ catch {
283
+ return allowResult("harness pack hook codex-stop: malformed JSON on stdin, skipping capture.", stderr);
284
+ }
285
+ let manifest;
286
+ try {
287
+ manifest = opts.manifest ?? loadManifest(opts).manifest;
288
+ }
289
+ catch (err) {
290
+ return allowResult(`harness pack hook codex-stop: manifest load failed (${err.message}), skipping capture.`, stderr);
291
+ }
292
+ const declared = manifest.policy_packs.find((p) => p.name === packName);
293
+ if (!declared || !declared.enabled) {
294
+ return allowResult(`harness pack hook codex-stop: pack "${packName}" not enabled, skipping capture.`, stderr);
295
+ }
296
+ const sessionId = pickString(envelope.session_id) ??
297
+ process.env["CODEX_SESSION_ID"] ??
298
+ process.env["CLAUDE_SESSION_ID"] ??
299
+ "";
300
+ if (sessionId === "") {
301
+ return allowResult("harness pack hook codex-stop: no session_id resolvable, skipping capture.", stderr);
302
+ }
303
+ const lastMessage = extractLastAssistantText(envelope);
304
+ if (lastMessage === null || lastMessage.trim() === "") {
305
+ return allowResult("harness pack hook codex-stop: no assistant message in stop event, skipping capture.", stderr);
306
+ }
307
+ const report = parseUnderstandingReport(lastMessage);
308
+ if (!reportHasContent(report)) {
309
+ return allowResult("harness pack hook codex-stop: assistant message did not contain a recognisable Understanding Report (no labelled fields found), skipping capture.", stderr);
310
+ }
311
+ const reportsDir = opts.reportsDir ?? defaultReportsDir();
312
+ const filename = buildReportFilename(sessionId, now);
313
+ const body = {
314
+ sessionId,
315
+ runtime: RUNTIME_TAG,
316
+ createdAt: now.toISOString(),
317
+ approvalStatus: "pending",
318
+ report,
319
+ rawMessage: lastMessage,
320
+ };
321
+ let target;
322
+ try {
323
+ target = writeReportFile(reportsDir, filename, body);
324
+ }
325
+ catch (err) {
326
+ return allowResult(`harness pack hook codex-stop: failed to write report (${err.message}), skipping capture.`, stderr);
327
+ }
328
+ const diagnostic = `harness pack hook codex-stop: captured Understanding Report at ${target} (approvalStatus: pending).`;
329
+ stderr.write(`${diagnostic}\n`);
330
+ return { exitCode: 0, reportPath: target, parsed: true, diagnostic };
331
+ }
332
+ //# sourceMappingURL=hook-codex-stop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook-codex-stop.js","sourceRoot":"","sources":["../../../src/cli/pack/hook-codex-stop.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { type Mode } from "../../policy-packs/builtin/understanding-before-execution.js";
2
+ import type { Manifest } from "../../schema/index.js";
3
+ import { type LoaderOptions } from "../loader.js";
4
+ export interface PackHookCodexUserPromptSubmitOptions extends LoaderOptions {
5
+ pack?: string;
6
+ stdin?: NodeJS.ReadableStream;
7
+ stdout?: NodeJS.WritableStream;
8
+ stderr?: NodeJS.WritableStream;
9
+ manifest?: Manifest;
10
+ }
11
+ export interface PackHookCodexUserPromptSubmitResult {
12
+ exitCode: number;
13
+ emitted: boolean;
14
+ /** The exact text written to stdout (empty when not emitted). */
15
+ text: string;
16
+ }
17
+ export declare function buildInstructionBlock(mode: Mode): string;
18
+ export declare function runPackHookCodexUserPromptSubmitCli(opts?: PackHookCodexUserPromptSubmitOptions): Promise<PackHookCodexUserPromptSubmitResult>;
@@ -0,0 +1,92 @@
1
+ // Phase 6 #6 — `harness pack hook codex-user-prompt-submit` runtime verb.
2
+ //
3
+ // Codex variant of the Understanding-Gate UserPromptSubmit injector.
4
+ // The Claude Code adapter delegates to `@lannguyensi/understanding-gate`'s
5
+ // `understanding-gate-claude-hook` bin (the npm package owns the
6
+ // instruction template). The Codex adapter mirrors that contract here:
7
+ // reads the upstream prompt JSON on stdin, writes a system-style
8
+ // instruction block on stdout that Codex will prepend to its system
9
+ // prompt before the agent runs.
10
+ //
11
+ // Wire format on stdin (envelope harness publishes; Codex CLI
12
+ // integration wraps its native event into this shape):
13
+ //
14
+ // { session_id?: string, prompt?: string }
15
+ //
16
+ // stdout: a plain-text instruction block (no JSON wrapper) that Codex
17
+ // concatenates into `additional_instructions`. The block is identical
18
+ // across modes for v1; finer-grained per-mode templating is an
19
+ // upstream-package concern.
20
+ //
21
+ // Failure mode: any error → exit 0, no stdout, diagnostic on stderr.
22
+ // A missing injector text must never fail the agent's prompt path.
23
+ import { resolveMode } from "../../policy-packs/builtin/understanding-before-execution.js";
24
+ import { loadManifest } from "../loader.js";
25
+ const PACK_NAME = "understanding-before-execution";
26
+ async function readStdin(stream) {
27
+ return new Promise((resolve, reject) => {
28
+ let data = "";
29
+ stream.setEncoding("utf8");
30
+ stream.on("data", (chunk) => {
31
+ data += chunk;
32
+ });
33
+ stream.on("end", () => resolve(data));
34
+ stream.on("error", (err) => reject(err));
35
+ });
36
+ }
37
+ export function buildInstructionBlock(mode) {
38
+ // Self-contained instruction text. The richer template owned by
39
+ // @lannguyensi/understanding-gate is a Claude-specific surface; the
40
+ // Codex variant ships a sibling block that names the same artefacts
41
+ // (Understanding Report, .understanding-gate/reports/) so the agent's
42
+ // expected output is byte-shaped to land in the persisted-report
43
+ // directory the Codex stop-hook captures into.
44
+ const base = [
45
+ "## Understanding Gate (mode: " + mode + ")",
46
+ "",
47
+ "Before you call any write-capable tool (apply_patch, Bash/shell, file edits),",
48
+ "produce an *Understanding Report* with these fields:",
49
+ "",
50
+ "- **interpretation**: one paragraph explaining what you understand the task to be.",
51
+ "- **assumptions**: bullet list of assumptions you are making about scope, environment, intent.",
52
+ "- **openQuestions**: bullet list of things you still need clarification on.",
53
+ "- **outOfScope**: bullet list of things you will explicitly NOT do.",
54
+ "- **risks**: bullet list of failure modes / things that could go wrong.",
55
+ "- **verificationPlan**: how you will know whether the change worked.",
56
+ "",
57
+ "Wait for explicit human approval before invoking apply_patch, Bash, or shell tools.",
58
+ "Approval is recorded by the operator running `harness approve understanding`.",
59
+ "",
60
+ "If you are unsure whether the gate applies, ask. Do not pre-emptively edit.",
61
+ ].join("\n");
62
+ return base + "\n";
63
+ }
64
+ export async function runPackHookCodexUserPromptSubmitCli(opts = {}) {
65
+ const stdin = opts.stdin ?? process.stdin;
66
+ const stdout = opts.stdout ?? process.stdout;
67
+ const stderr = opts.stderr ?? process.stderr;
68
+ const packName = opts.pack ?? PACK_NAME;
69
+ // Drain stdin so the parent isn't blocked. We don't actually need any
70
+ // field from it for v1 — the instruction block is prompt-independent.
71
+ await readStdin(stdin).catch(() => "");
72
+ let manifest;
73
+ try {
74
+ manifest = opts.manifest ?? loadManifest(opts).manifest;
75
+ }
76
+ catch (err) {
77
+ stderr.write(`harness pack hook codex-user-prompt-submit: manifest load failed (${err.message}), suppressing injection.\n`);
78
+ return { exitCode: 0, emitted: false, text: "" };
79
+ }
80
+ const declared = manifest.policy_packs.find((p) => p.name === packName);
81
+ if (!declared || !declared.enabled) {
82
+ stderr.write(`harness pack hook codex-user-prompt-submit: pack "${packName}" not enabled, suppressing injection.\n`);
83
+ return { exitCode: 0, emitted: false, text: "" };
84
+ }
85
+ const { mode, warning } = resolveMode(declared);
86
+ if (warning)
87
+ stderr.write(`${warning}\n`);
88
+ const text = buildInstructionBlock(mode);
89
+ stdout.write(text);
90
+ return { exitCode: 0, emitted: true, text };
91
+ }
92
+ //# sourceMappingURL=hook-codex-user-prompt-submit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook-codex-user-prompt-submit.js","sourceRoot":"","sources":["../../../src/cli/pack/hook-codex-user-prompt-submit.ts"],"names":[],"mappings":"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"}