@lannguyensi/harness 0.50.0 → 0.52.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +247 -0
- package/dist/cli/approve/understanding.d.ts +97 -0
- package/dist/cli/approve/understanding.js +67 -24
- package/dist/cli/approve/understanding.js.map +1 -1
- package/dist/cli/audit.d.ts +29 -0
- package/dist/cli/audit.js +130 -17
- package/dist/cli/audit.js.map +1 -1
- package/dist/cli/delegate/index.d.ts +63 -0
- package/dist/cli/delegate/index.js +313 -0
- package/dist/cli/delegate/index.js.map +1 -0
- package/dist/cli/doctor/auto-approve-mode.d.ts +37 -0
- package/dist/cli/doctor/auto-approve-mode.js +80 -0
- package/dist/cli/doctor/auto-approve-mode.js.map +1 -0
- package/dist/cli/doctor/claude-mcp.d.ts +14 -0
- package/dist/cli/doctor/claude-mcp.js +7 -1
- package/dist/cli/doctor/claude-mcp.js.map +1 -1
- package/dist/cli/doctor/codex-config-drift.d.ts +28 -0
- package/dist/cli/doctor/codex-config-drift.js +240 -0
- package/dist/cli/doctor/codex-config-drift.js.map +1 -0
- package/dist/cli/doctor/format.js +67 -1
- package/dist/cli/doctor/format.js.map +1 -1
- package/dist/cli/doctor/index.d.ts +20 -0
- package/dist/cli/doctor/index.js +84 -1
- package/dist/cli/doctor/index.js.map +1 -1
- package/dist/cli/doctor/settings-drift.d.ts +25 -0
- package/dist/cli/doctor/settings-drift.js +203 -0
- package/dist/cli/doctor/settings-drift.js.map +1 -0
- package/dist/cli/doctor/types.d.ts +69 -0
- package/dist/cli/doctor/types.js.map +1 -1
- package/dist/cli/doctor/ug-auto-approvals.d.ts +40 -0
- package/dist/cli/doctor/ug-auto-approvals.js +116 -0
- package/dist/cli/doctor/ug-auto-approvals.js.map +1 -0
- package/dist/cli/doctor/ug-delegations.d.ts +26 -0
- package/dist/cli/doctor/ug-delegations.js +112 -0
- package/dist/cli/doctor/ug-delegations.js.map +1 -0
- package/dist/cli/doctor/understanding-mode-env.d.ts +12 -0
- package/dist/cli/doctor/understanding-mode-env.js +16 -1
- package/dist/cli/doctor/understanding-mode-env.js.map +1 -1
- package/dist/cli/index.js +100 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/pack/approve-escape.js +16 -7
- package/dist/cli/pack/approve-escape.js.map +1 -1
- package/dist/cli/pack/auto-approve-path.d.ts +135 -0
- package/dist/cli/pack/auto-approve-path.js +400 -0
- package/dist/cli/pack/auto-approve-path.js.map +1 -0
- package/dist/cli/pack/hook-codex-pre-tool-use.d.ts +9 -0
- package/dist/cli/pack/hook-codex-pre-tool-use.js +118 -4
- package/dist/cli/pack/hook-codex-pre-tool-use.js.map +1 -1
- package/dist/cli/pack/hook-pre-tool-use.d.ts +36 -0
- package/dist/cli/pack/hook-pre-tool-use.js +402 -3
- package/dist/cli/pack/hook-pre-tool-use.js.map +1 -1
- package/dist/cli/pack/transcript-report-scan.d.ts +71 -0
- package/dist/cli/pack/transcript-report-scan.js +359 -0
- package/dist/cli/pack/transcript-report-scan.js.map +1 -0
- package/dist/cli/smoke/index.d.ts +18 -1
- package/dist/cli/smoke/index.js +54 -0
- package/dist/cli/smoke/index.js.map +1 -1
- package/dist/cli/validate/checks.js +81 -0
- package/dist/cli/validate/checks.js.map +1 -1
- package/dist/policy-packs/builtin/understanding-before-execution/auto-approve.d.ts +210 -0
- package/dist/policy-packs/builtin/understanding-before-execution/auto-approve.js +361 -0
- package/dist/policy-packs/builtin/understanding-before-execution/auto-approve.js.map +1 -0
- package/dist/policy-packs/builtin/understanding-before-execution/delegation-markers.d.ts +223 -0
- package/dist/policy-packs/builtin/understanding-before-execution/delegation-markers.js +633 -0
- package/dist/policy-packs/builtin/understanding-before-execution/delegation-markers.js.map +1 -0
- package/dist/policy-packs/builtin/understanding-before-execution/index.d.ts +3 -1
- package/dist/policy-packs/builtin/understanding-before-execution/index.js +10 -1
- package/dist/policy-packs/builtin/understanding-before-execution/index.js.map +1 -1
- package/dist/policy-packs/builtin/understanding-before-execution/measured-permission-modes.d.ts +29 -0
- package/dist/policy-packs/builtin/understanding-before-execution/measured-permission-modes.js +82 -0
- package/dist/policy-packs/builtin/understanding-before-execution/measured-permission-modes.js.map +1 -0
- package/dist/policy-packs/builtin/understanding-before-execution/persisted-reports.d.ts +23 -0
- package/dist/policy-packs/builtin/understanding-before-execution/persisted-reports.js +29 -0
- package/dist/policy-packs/builtin/understanding-before-execution/persisted-reports.js.map +1 -1
- package/dist/policy-packs/builtin/understanding-before-execution.d.ts +42 -0
- package/dist/policy-packs/builtin/understanding-before-execution.js +56 -1
- package/dist/policy-packs/builtin/understanding-before-execution.js.map +1 -1
- package/dist/runtime/approval-signing.d.ts +22 -0
- package/dist/runtime/approval-signing.js +83 -1
- package/dist/runtime/approval-signing.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/audit.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { parseDurationSeconds, parseLedgerTimestamp, queryLedgerByTag, } from "../policies/index.js";
|
|
2
2
|
import { decisionSortKey, decodeLedgerContent, } from "../io/ledger-record.js";
|
|
3
3
|
import { POLICY_DECISION_TYPE } from "../io/ledger-record.js";
|
|
4
|
+
import { approvedLedgerTagFor, autoApprovedLedgerTagFor, } from "../policy-packs/builtin/understanding-before-execution/index.js";
|
|
4
5
|
import { resolveReadSessionId, } from "../runtime/session-id.js";
|
|
5
6
|
import { EX_UNAVAILABLE, EX_USAGE, HarnessExitError } from "./exit-codes.js";
|
|
6
7
|
import { loadManifest } from "./loader.js";
|
|
@@ -66,6 +67,64 @@ function rowsFromEntries(entries) {
|
|
|
66
67
|
}),
|
|
67
68
|
}));
|
|
68
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* agent-tasks 5ad63b01: build the raw understanding-gate approval-fact
|
|
72
|
+
* rows for the audit window. Reuses the two writers' own tag builders
|
|
73
|
+
* (`approvedLedgerTagFor` / `autoApprovedLedgerTagFor`, keyed on the
|
|
74
|
+
* SAME resolved `sessionId` the ledger fetch itself is scoped to)
|
|
75
|
+
* instead of re-deriving the tag shape with a parser, so a change to
|
|
76
|
+
* either prefix or to the `:forced:<field>` suffix convention cannot
|
|
77
|
+
* drift out of sync with this read path. Matching is exact-or-forced-
|
|
78
|
+
* prefix, never substring, so `review:42:approved` (or any future tag
|
|
79
|
+
* that merely CONTAINS one of these strings) cannot slip in, the same
|
|
80
|
+
* substring-pollution concern `isPolicyDecisionRow` guards on the
|
|
81
|
+
* gate-check side (`ledger.ts`).
|
|
82
|
+
*/
|
|
83
|
+
function rowsFromApprovalEntries(entries, sessionId) {
|
|
84
|
+
const humanTag = approvedLedgerTagFor(sessionId);
|
|
85
|
+
const humanForcedPrefix = `${humanTag}:forced:`;
|
|
86
|
+
const autoTag = autoApprovedLedgerTagFor(sessionId);
|
|
87
|
+
const rows = [];
|
|
88
|
+
for (const entry of entries) {
|
|
89
|
+
const content = entry.content;
|
|
90
|
+
if (content !== humanTag && content !== autoTag && !content.startsWith(humanForcedPrefix)) {
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
rows.push({
|
|
94
|
+
timestamp: typeof entry.createdAt === "string"
|
|
95
|
+
? entry.createdAt
|
|
96
|
+
: entry.createdAt.toISOString(),
|
|
97
|
+
tag: content,
|
|
98
|
+
source: entry.source ?? "",
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
rows.sort((a, b) => parseLedgerTimestamp(a.timestamp) - parseLedgerTimestamp(b.timestamp));
|
|
102
|
+
return rows;
|
|
103
|
+
}
|
|
104
|
+
function renderTable(header, data) {
|
|
105
|
+
if (data.length === 0)
|
|
106
|
+
return "";
|
|
107
|
+
const widths = header.map((h, i) => Math.max(h.length, ...data.map((row) => row[i].length)));
|
|
108
|
+
const fmt = (cells) => cells.map((c, i) => c.padEnd(widths[i])).join(" ").trimEnd();
|
|
109
|
+
const lines = [];
|
|
110
|
+
lines.push(fmt(header));
|
|
111
|
+
lines.push(widths.map((w) => "-".repeat(w)).join(" ").trimEnd());
|
|
112
|
+
for (const row of data)
|
|
113
|
+
lines.push(fmt(row));
|
|
114
|
+
return `${lines.join("\n")}\n`;
|
|
115
|
+
}
|
|
116
|
+
// Single-line-ify a cell so a newline buried in untrusted content (a policy
|
|
117
|
+
// reason, or a ledger `tag`/`source` value the approvals section reads
|
|
118
|
+
// verbatim) can't split one logical row into two rendered table rows.
|
|
119
|
+
const flatten = (s) => s.replace(/\s+/g, " ").trim();
|
|
120
|
+
// M3: cap after flattening so a very long tag/source can't blow out the
|
|
121
|
+
// table width; the ellipsis marker makes the truncation visible rather than
|
|
122
|
+
// silently swallowing content.
|
|
123
|
+
const MAX_CELL_LEN = 200;
|
|
124
|
+
const flattenAndCap = (s) => {
|
|
125
|
+
const flat = flatten(s);
|
|
126
|
+
return flat.length > MAX_CELL_LEN ? `${flat.slice(0, MAX_CELL_LEN)}…` : flat;
|
|
127
|
+
};
|
|
69
128
|
function formatTable(rows) {
|
|
70
129
|
if (rows.length === 0)
|
|
71
130
|
return "";
|
|
@@ -74,19 +133,29 @@ function formatTable(rows) {
|
|
|
74
133
|
// alignment doesn't break on a newline buried in a future policy's reason.
|
|
75
134
|
// M7: annotate with [unclassified-fallback] when the fail-closed flag is
|
|
76
135
|
// set, so the human table reflects the same information the JSON field does.
|
|
77
|
-
const flatten = (s) => s.replace(/\s+/g, " ").trim();
|
|
78
136
|
const data = rows.map((r) => {
|
|
79
137
|
const reasonCell = flatten(r.reason) + (r.whenUnclassifiedFallback ? " [unclassified-fallback]" : "");
|
|
80
138
|
return [r.timestamp, r.name, r.outcome, reasonCell];
|
|
81
139
|
});
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
140
|
+
return renderTable(header, data);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Table rendering for the approvals section. Empty is `""` (never a
|
|
144
|
+
* header-only table), so the caller can decide whether to omit the whole
|
|
145
|
+
* section without inspecting row counts twice.
|
|
146
|
+
*
|
|
147
|
+
* M3: `tag` and `source` are untrusted ledger content (a forged or
|
|
148
|
+
* malformed entry could carry a newline), so both cells are flattened and
|
|
149
|
+
* length-capped the same way `formatTable` treats `reason`, otherwise an
|
|
150
|
+
* embedded newline renders as an extra table row that looks like a second,
|
|
151
|
+
* forged approval fact.
|
|
152
|
+
*/
|
|
153
|
+
function formatApprovals(rows) {
|
|
154
|
+
if (rows.length === 0)
|
|
155
|
+
return "";
|
|
156
|
+
const header = ["timestamp", "tag", "source"];
|
|
157
|
+
const data = rows.map((r) => [r.timestamp, flattenAndCap(r.tag), flattenAndCap(r.source)]);
|
|
158
|
+
return renderTable(header, data);
|
|
90
159
|
}
|
|
91
160
|
export async function audit(opts = {}) {
|
|
92
161
|
const since = opts.since ?? DEFAULT_SINCE;
|
|
@@ -125,15 +194,59 @@ export async function audit(opts = {}) {
|
|
|
125
194
|
if (opts.outcome) {
|
|
126
195
|
filtered = filtered.filter((r) => r.outcome === opts.outcome);
|
|
127
196
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
197
|
+
// Second, independent ledger fetch for the raw understanding-gate
|
|
198
|
+
// approval facts (docs/decisions/2026-08-27-ug-auto-mode-approval.md,
|
|
199
|
+
// "Audit and doctor"). Same server-side-narrowing / client-side-filter-
|
|
200
|
+
// stays-correct contract as the policy_decision fetch above:
|
|
201
|
+
// `contentPrefix: "understanding-"` is pushed server-side when
|
|
202
|
+
// supported, and rowsFromApprovalEntries + the `--since` filter below
|
|
203
|
+
// are applied regardless, so an old server that ignores the hint and
|
|
204
|
+
// returns the whole session still renders correctly. Filtered by
|
|
205
|
+
// `--since` and `--session` only (never `--policy` / `--outcome`,
|
|
206
|
+
// which are policy-decision-only filters); the `--session` filtering
|
|
207
|
+
// falls out of `rowsFromApprovalEntries` matching tags built from this
|
|
208
|
+
// SAME resolved `sessionId`.
|
|
209
|
+
const approvalResult = await fetch(sessionId, {
|
|
210
|
+
sinceIso,
|
|
211
|
+
contentPrefix: "understanding-",
|
|
212
|
+
});
|
|
213
|
+
const stderrSink = opts.stderr ?? ((s) => process.stderr.write(s));
|
|
214
|
+
let approvals = [];
|
|
215
|
+
let approvalsUnavailable;
|
|
216
|
+
if (approvalResult.kind === "degraded") {
|
|
217
|
+
// M4: a degraded approvals fetch degrades softly, it must not discard
|
|
218
|
+
// the decisions table that already fetched successfully. Exit code is
|
|
219
|
+
// unchanged (tied to the policy-decision fetch only, above); the
|
|
220
|
+
// audit-only posture gets one stderr line, matching
|
|
221
|
+
// `src/cli/pack/auto-approve-path.ts`'s own audit-only-write failures.
|
|
222
|
+
approvalsUnavailable = approvalResult.reason;
|
|
223
|
+
stderrSink(`approvals unavailable: ${approvalResult.reason}\n`);
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
approvals = rowsFromApprovalEntries(approvalResult.entries, sessionId).filter((r) => parseLedgerTimestamp(r.timestamp) >= cutoffMs);
|
|
133
227
|
}
|
|
228
|
+
const decisionsText = filtered.length === 0 ? `no policy decisions in the last ${since}\n` : formatTable(filtered);
|
|
229
|
+
// Omitted entirely when empty and available (acceptance criterion 1), so
|
|
230
|
+
// the documented empty-window message above stays byte-identical when
|
|
231
|
+
// there is also nothing to approve.
|
|
232
|
+
const approvalsText = approvalsUnavailable !== undefined
|
|
233
|
+
? `\napprovals unavailable: ${approvalsUnavailable}\n`
|
|
234
|
+
: approvals.length === 0
|
|
235
|
+
? ""
|
|
236
|
+
: `\napprovals\n${formatApprovals(approvals)}`;
|
|
134
237
|
const output = opts.json
|
|
135
|
-
? `${JSON.stringify({
|
|
136
|
-
|
|
137
|
-
|
|
238
|
+
? `${JSON.stringify({
|
|
239
|
+
sessionId,
|
|
240
|
+
decisions: filtered,
|
|
241
|
+
approvals,
|
|
242
|
+
...(approvalsUnavailable !== undefined && { approvalsUnavailable }),
|
|
243
|
+
}, null, 2)}\n`
|
|
244
|
+
: `${decisionsText}${approvalsText}`;
|
|
245
|
+
return {
|
|
246
|
+
output,
|
|
247
|
+
decisions: filtered,
|
|
248
|
+
approvals,
|
|
249
|
+
...(approvalsUnavailable !== undefined && { approvalsUnavailable }),
|
|
250
|
+
};
|
|
138
251
|
}
|
|
139
252
|
//# sourceMappingURL=audit.js.map
|
package/dist/cli/audit.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/cli/audit.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,gBAAgB,GAGjB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,eAAe,EACf,mBAAmB,GAEpB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EACL,oBAAoB,GAErB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAsB,MAAM,aAAa,CAAC;AAE/D,MAAM,aAAa,GAAG,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/cli/audit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { Manifest } from "../../schema/index.js";
|
|
2
|
+
import { type LoaderOptions } from "../loader.js";
|
|
3
|
+
/** Default delegation lifetime when neither `--ttl` nor the pack's `approval_lifecycle.max_age` is set (ADR "TTL, cwd, and subagents"). */
|
|
4
|
+
export declare const DEFAULT_DELEGATION_TTL_SECONDS = 3600;
|
|
5
|
+
/** Default ledger `source` tag for the audit-only fact this verb writes (ADR "Audit and doctor"). */
|
|
6
|
+
export declare const DEFAULT_DELEGATE_LEDGER_SOURCE = "harness-delegate-cli";
|
|
7
|
+
/** Ceiling for an explicit `--ttl` when the applied pack sets no `approval_lifecycle.max_age` (L4 fix, agent-tasks 37ad0b05: an unbounded `--ttl` would otherwise let a caller mint a delegation that outlives any lifetime the pack's own policy intends). */
|
|
8
|
+
export declare const MAX_DELEGATION_TTL_SECONDS: number;
|
|
9
|
+
/** The exact usage message the ADR pins for a delegation with no binding (AC 1). Shared so the CLI's early usage check and this function's own refusal read identically. */
|
|
10
|
+
export declare const NO_BINDING_MESSAGE = "a delegation must bind a cwd or a task";
|
|
11
|
+
export interface IssueDelegationOptions extends LoaderOptions {
|
|
12
|
+
/** Session id of the `claude -p` child this delegation authorizes. Must be a UUID (case-insensitive). */
|
|
13
|
+
childSessionId: string;
|
|
14
|
+
/** Bind the delegation to this working directory. At least one of `cwd` / `taskId` is required. */
|
|
15
|
+
cwd?: string;
|
|
16
|
+
/** Bind the delegation to this agent-tasks task id. At least one of `cwd` / `taskId` is required. */
|
|
17
|
+
taskId?: string;
|
|
18
|
+
/** Delegation lifetime in seconds (already parsed, e.g. via `parseDurationSeconds`). Default: the applied pack's `approval_lifecycle.max_age` when set, else {@link DEFAULT_DELEGATION_TTL_SECONDS}. */
|
|
19
|
+
ttlSeconds?: number;
|
|
20
|
+
/** Fallback shape: path to the launcher-supplied Understanding Report file, bound by content AND path hash. */
|
|
21
|
+
reportPath?: string;
|
|
22
|
+
/** Explicit parent session id. Resolved exactly like `harness approve understanding` (flag > env > `.pending-approval`; no newest-report fallback) when omitted. */
|
|
23
|
+
parentSessionId?: string;
|
|
24
|
+
/** Override `harness.generated/` (test injection). */
|
|
25
|
+
generatedDir?: string;
|
|
26
|
+
/** Override "now" for deterministic tests. */
|
|
27
|
+
now?: Date;
|
|
28
|
+
/** Inject a manifest (test). */
|
|
29
|
+
manifest?: Manifest;
|
|
30
|
+
/** Override the ledger writer (test). */
|
|
31
|
+
ledgerAdd?: (sessionId: string, content: string) => Promise<{
|
|
32
|
+
ok: true;
|
|
33
|
+
} | {
|
|
34
|
+
ok: false;
|
|
35
|
+
reason: string;
|
|
36
|
+
}>;
|
|
37
|
+
}
|
|
38
|
+
export type IssueDelegationRefusalReason = "invalid-child-session" | "no-binding" | "invalid-cwd" | "invalid-task" | "invalid-ttl" | "ttl-above-max-age" | "parent-session-unresolved" | "parent-marker-missing" | "parent-marker-forged" | "parent-marker-expired" | "signing-key-absent" | "report-unreadable" | "invalid-input" | "write-failed";
|
|
39
|
+
export type IssueDelegationResult = {
|
|
40
|
+
ok: true;
|
|
41
|
+
filePath: string;
|
|
42
|
+
parentSessionId: string;
|
|
43
|
+
childSessionId: string;
|
|
44
|
+
expiresAt: string;
|
|
45
|
+
/** `written: false` is audit-only degradation (ADR: "failure to write the fact is one stderr line, never a refusal"); the delegation itself is still minted. */
|
|
46
|
+
ledgerFact: {
|
|
47
|
+
written: boolean;
|
|
48
|
+
reason?: string;
|
|
49
|
+
};
|
|
50
|
+
} | {
|
|
51
|
+
ok: false;
|
|
52
|
+
reason: IssueDelegationRefusalReason;
|
|
53
|
+
detail: string;
|
|
54
|
+
};
|
|
55
|
+
/** The `understanding-delegated:<child-sid>:<parent-sid>` ledger fact content (ADR "Audit and doctor"). */
|
|
56
|
+
export declare function delegationLedgerFactFor(childSessionId: string, parentSessionId: string): string;
|
|
57
|
+
/**
|
|
58
|
+
* Issue a signed delegation marker for a `claude -p` child session. Never
|
|
59
|
+
* calls `process.exit`; every failure mode is a `{ ok: false }` result
|
|
60
|
+
* with a distinct `reason` (ADR slice plan format rule: every refusal is
|
|
61
|
+
* a block with a distinct diagnostic, never a fall-through to allow).
|
|
62
|
+
*/
|
|
63
|
+
export declare function issueDelegation(opts: IssueDelegationOptions): Promise<IssueDelegationResult>;
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
// `harness delegate`: slice 3 of docs/decisions/2026-08-27-ug-auto-mode-approval.md
|
|
2
|
+
// ("`claude -p` child processes", "Delegation marker shape", "TTL, cwd,
|
|
3
|
+
// and subagents"), acceptance criterion 1.
|
|
4
|
+
//
|
|
5
|
+
// Issues a signed delegation for a headless `claude -p` child session,
|
|
6
|
+
// bound to an already-approved PARENT session. The delegation is a
|
|
7
|
+
// PRE-AUTHORIZATION, not an approval (key one of the ADR's two-key
|
|
8
|
+
// design): it supplies the trusted signal and the parent linkage; the
|
|
9
|
+
// child's own Understanding Report (key two) is still checked, and its
|
|
10
|
+
// auto-marker still minted, by the child's own PreToolUse hook: nothing
|
|
11
|
+
// here opens a gate.
|
|
12
|
+
//
|
|
13
|
+
// `issueDelegation` is an in-process function, never calling
|
|
14
|
+
// `process.exit`, so the smoke runner (a future consumer, ADR "TTL, cwd,
|
|
15
|
+
// and subagents": "The harness smoke runner ... is the natural first
|
|
16
|
+
// consumer") and tests can call it directly. The CLI wiring in
|
|
17
|
+
// `src/cli/index.ts` is a thin wrapper: flag parsing, one CLI-level
|
|
18
|
+
// usage check with the exact ADR-specified message, and printing the
|
|
19
|
+
// result in the approve CLI's line style.
|
|
20
|
+
//
|
|
21
|
+
// PARENT SESSION RESOLUTION mirrors `harness approve understanding`
|
|
22
|
+
// exactly (flag > $CLAUDE_CODE_SESSION_ID > $CLAUDE_SESSION_ID >
|
|
23
|
+
// $CODEX_SESSION_ID > staged .pending-approval), via the same
|
|
24
|
+
// `resolveApprovalSessionId` helper, with NO newest-report fallback
|
|
25
|
+
// (delegation has no report of its own to guess a session from).
|
|
26
|
+
//
|
|
27
|
+
// LEDGER SOURCE: the ledger fact this verb writes uses its own fixed
|
|
28
|
+
// source tag `harness-delegate-cli` (ADR "Audit and doctor"), distinct
|
|
29
|
+
// from `harness approve understanding`'s `harness-approve-understanding`.
|
|
30
|
+
// Reused directly: the approve CLI's `writeLedgerTag` now takes `source`
|
|
31
|
+
// as an additive parameter (default unchanged, so `approveUnderstanding`'s
|
|
32
|
+
// own call is unaffected) so this verb does not re-implement the same
|
|
33
|
+
// findGroundingMcp + addLedgerFact shape `branch-protection.ts` already
|
|
34
|
+
// carries its own independent copy of. There is no actor field to stamp
|
|
35
|
+
// on a delegation and no `--approved-by` flag to override the source:
|
|
36
|
+
// the delegation's signed `approvedBy` string is the packed
|
|
37
|
+
// `delegated:<parent>;cwd=...;task=...;expires=...` tuple
|
|
38
|
+
// (delegation-markers.ts), which has no room for one, and the ADR rules
|
|
39
|
+
// out adding a new signed field (a `SIGNING_ALG` bump).
|
|
40
|
+
//
|
|
41
|
+
// REPORT FALLBACK (`--report <path>`): binds the launcher-supplied
|
|
42
|
+
// report by BOTH its content (`reportContentHash`) and its path
|
|
43
|
+
// (`reportPathHash`, via the same `hashDelegationCwd` the cwd binding
|
|
44
|
+
// uses, so both sides of the delegation hash paths the same way).
|
|
45
|
+
import { sha256Hex, signingKeyExists, signingKeyPathFor } from "../../runtime/approval-signing.js";
|
|
46
|
+
import { resolveGeneratedDir } from "../../runtime/pending-approval.js";
|
|
47
|
+
import { resolveApprovalSessionId } from "../../runtime/session-id.js";
|
|
48
|
+
import { checkApprovalMarker, hashDelegationCwd, parseApprovalLifecycle, writeDelegationMarker, } from "../../policy-packs/builtin/understanding-before-execution-runtime.js";
|
|
49
|
+
import { readRegularFileRejectingSymlink } from "../../io/read-regular-file.js";
|
|
50
|
+
import { loadDeclaredUnderstandingPack, writeLedgerTag } from "../approve/understanding.js";
|
|
51
|
+
import { resolvePaths } from "../loader.js";
|
|
52
|
+
/** Default delegation lifetime when neither `--ttl` nor the pack's `approval_lifecycle.max_age` is set (ADR "TTL, cwd, and subagents"). */
|
|
53
|
+
export const DEFAULT_DELEGATION_TTL_SECONDS = 3600;
|
|
54
|
+
/** Default ledger `source` tag for the audit-only fact this verb writes (ADR "Audit and doctor"). */
|
|
55
|
+
export const DEFAULT_DELEGATE_LEDGER_SOURCE = "harness-delegate-cli";
|
|
56
|
+
/** Ceiling for an explicit `--ttl` when the applied pack sets no `approval_lifecycle.max_age` (L4 fix, agent-tasks 37ad0b05: an unbounded `--ttl` would otherwise let a caller mint a delegation that outlives any lifetime the pack's own policy intends). */
|
|
57
|
+
export const MAX_DELEGATION_TTL_SECONDS = 24 * 60 * 60;
|
|
58
|
+
/** Same 8-4-4-4-12 hex shape the session-id helpers already validate a Claude Code session id against (`session-id.ts`'s `SESSION_TRANSCRIPT_RE`), case-insensitive. */
|
|
59
|
+
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
60
|
+
/** The exact usage message the ADR pins for a delegation with no binding (AC 1). Shared so the CLI's early usage check and this function's own refusal read identically. */
|
|
61
|
+
export const NO_BINDING_MESSAGE = "a delegation must bind a cwd or a task";
|
|
62
|
+
/** The `understanding-delegated:<child-sid>:<parent-sid>` ledger fact content (ADR "Audit and doctor"). */
|
|
63
|
+
export function delegationLedgerFactFor(childSessionId, parentSessionId) {
|
|
64
|
+
return `understanding-delegated:${childSessionId}:${parentSessionId}`;
|
|
65
|
+
}
|
|
66
|
+
/** Control characters rejected from a raw `--task` value, mirroring the `CONTROL_CHARS` check `delegation-markers.ts` already runs on `parentSessionId` (not exported, so mirrored rather than imported). */
|
|
67
|
+
const TASK_ID_CONTROL_CHARS = /[\x00-\x1f\x7f]/;
|
|
68
|
+
/**
|
|
69
|
+
* Validate a raw `--task` value before it ever reaches
|
|
70
|
+
* `writeDelegationMarker` (L1 fix, agent-tasks 37ad0b05: an unvalidated
|
|
71
|
+
* `--task` used to surface downstream as an opaque `write-failed`, or
|
|
72
|
+
* silently rebind, depending on the value). Mirrors
|
|
73
|
+
* `delegation-markers.ts`'s own (unexported) `rejectUnsafeSegmentValue`:
|
|
74
|
+
* empty, or carrying a `;`/`=` segment delimiter, both corrupt the
|
|
75
|
+
* packed `approvedBy` encoding, plus the reserved unbound literal
|
|
76
|
+
* `"-"` (would silently round-trip as "no task bound") and a control
|
|
77
|
+
* character. Returns a detail string on a rejected value, `null` on a
|
|
78
|
+
* safe one.
|
|
79
|
+
*/
|
|
80
|
+
function validateTaskId(taskId) {
|
|
81
|
+
if (taskId.length === 0) {
|
|
82
|
+
return "--task must not be empty";
|
|
83
|
+
}
|
|
84
|
+
if (taskId === "-") {
|
|
85
|
+
return '--task must not be the reserved unbound literal "-"';
|
|
86
|
+
}
|
|
87
|
+
if (taskId.includes(";") || taskId.includes("=")) {
|
|
88
|
+
return `--task must not contain a delegation-segment delimiter (";" or "="): ${JSON.stringify(taskId)}`;
|
|
89
|
+
}
|
|
90
|
+
if (TASK_ID_CONTROL_CHARS.test(taskId)) {
|
|
91
|
+
return `--task must not contain a control character: ${JSON.stringify(taskId)}`;
|
|
92
|
+
}
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Issue a signed delegation marker for a `claude -p` child session. Never
|
|
97
|
+
* calls `process.exit`; every failure mode is a `{ ok: false }` result
|
|
98
|
+
* with a distinct `reason` (ADR slice plan format rule: every refusal is
|
|
99
|
+
* a block with a distinct diagnostic, never a fall-through to allow).
|
|
100
|
+
*/
|
|
101
|
+
export async function issueDelegation(opts) {
|
|
102
|
+
if (!UUID_RE.test(opts.childSessionId)) {
|
|
103
|
+
return {
|
|
104
|
+
ok: false,
|
|
105
|
+
reason: "invalid-child-session",
|
|
106
|
+
detail: `--child-session must be a UUID (8-4-4-4-12 hex, case-insensitive): got ${JSON.stringify(opts.childSessionId)}`,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
if (opts.cwd === undefined && opts.taskId === undefined) {
|
|
110
|
+
return { ok: false, reason: "no-binding", detail: NO_BINDING_MESSAGE };
|
|
111
|
+
}
|
|
112
|
+
// L3 fix (agent-tasks 37ad0b05): an empty `--cwd` used to fall through
|
|
113
|
+
// uncaught, and `hashDelegationCwd("")` -> `path.resolve("")` silently
|
|
114
|
+
// rebinds it to the issuer's OWN cwd rather than refusing. Caught here,
|
|
115
|
+
// alongside the no-binding check, before either value reaches a hash.
|
|
116
|
+
if (opts.cwd !== undefined && opts.cwd.length === 0) {
|
|
117
|
+
return {
|
|
118
|
+
ok: false,
|
|
119
|
+
reason: "invalid-cwd",
|
|
120
|
+
detail: "--cwd must not be empty (an empty value would silently rebind to the issuer's own cwd via path.resolve)",
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
if (opts.taskId !== undefined) {
|
|
124
|
+
const taskError = validateTaskId(opts.taskId);
|
|
125
|
+
if (taskError !== null) {
|
|
126
|
+
return { ok: false, reason: "invalid-task", detail: taskError };
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
const generatedDir = opts.generatedDir ??
|
|
130
|
+
resolveGeneratedDir({
|
|
131
|
+
...(opts.homeDir !== undefined ? { homeDir: opts.homeDir } : {}),
|
|
132
|
+
manifestPath: resolvePaths(opts).base,
|
|
133
|
+
});
|
|
134
|
+
// Signing-key precheck FIRST, before resolving or checking the parent
|
|
135
|
+
// marker at all. `checkApprovalMarker`'s own read path (via
|
|
136
|
+
// `verifyMarkerSignature` -> `getOrCreateSigningKey`) self-heals a
|
|
137
|
+
// missing key by CREATING one as a side effect of verification, that
|
|
138
|
+
// is correct for the gate's read side (delegation-markers.ts's own
|
|
139
|
+
// doc comment on `verifyDelegation` explains why), but it would mean
|
|
140
|
+
// this precheck could never observe a genuinely absent key if it ran
|
|
141
|
+
// after the parent-marker check: by the time that check returns, a
|
|
142
|
+
// key would already exist again. Checking here, before either
|
|
143
|
+
// resolveApprovalSessionId or checkApprovalMarker touches the
|
|
144
|
+
// filesystem, is what keeps "no operator signing key" a real,
|
|
145
|
+
// independently reachable refusal rather than one only writeDelegationMarker's
|
|
146
|
+
// own (necessarily later) precheck could ever see.
|
|
147
|
+
if (!signingKeyExists(generatedDir)) {
|
|
148
|
+
return {
|
|
149
|
+
ok: false,
|
|
150
|
+
reason: "signing-key-absent",
|
|
151
|
+
detail: `no operator signing key at ${signingKeyPathFor(generatedDir)}; refusing to delegate (key creation is an operator-side act, never a side effect of delegating)`,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
// Parent session resolution: exactly the `harness approve
|
|
155
|
+
// understanding` precedence chain (flag > $CLAUDE_CODE_SESSION_ID >
|
|
156
|
+
// $CLAUDE_SESSION_ID > $CODEX_SESSION_ID > staged .pending-approval),
|
|
157
|
+
// with NO 6th-tier newest-report fallback: a delegation has no report
|
|
158
|
+
// of its own to guess a parent session from, and guessing the PARENT
|
|
159
|
+
// wrong here would mint a pre-authorization under the wrong identity.
|
|
160
|
+
const resolvedParent = resolveApprovalSessionId({
|
|
161
|
+
session: opts.parentSessionId,
|
|
162
|
+
generatedDir,
|
|
163
|
+
});
|
|
164
|
+
const parentSessionId = resolvedParent.sessionId;
|
|
165
|
+
if (parentSessionId === "") {
|
|
166
|
+
return {
|
|
167
|
+
ok: false,
|
|
168
|
+
reason: "parent-session-unresolved",
|
|
169
|
+
detail: "no parent session id available. Pass --session-id <id>, or set one of " +
|
|
170
|
+
"$CLAUDE_CODE_SESSION_ID / $CLAUDE_SESSION_ID / $CODEX_SESSION_ID, or run " +
|
|
171
|
+
"`harness preflight` (or trip the gate once) so harness.generated/.pending-approval is staged.",
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
// Manifest: best-effort, exactly like the approve CLI (shared via
|
|
175
|
+
// `loadDeclaredUnderstandingPack`, agent-tasks 37ad0b05). A load
|
|
176
|
+
// failure here degrades the TTL default (falls back to the hardcoded
|
|
177
|
+
// default below) and the ledger write (audit-only, never a refusal)
|
|
178
|
+
// but never blocks issuing the delegation itself.
|
|
179
|
+
const { manifest, manifestLoadError, declaredPack } = loadDeclaredUnderstandingPack(opts);
|
|
180
|
+
const lifecycle = parseApprovalLifecycle(declaredPack.config["approval_lifecycle"]);
|
|
181
|
+
// Key one of the ADR's two-key design: the parent must already carry a
|
|
182
|
+
// valid, unexpired, signed approval marker. Same check the gate itself
|
|
183
|
+
// runs (`checkApprovalMarker`), same `max_age` bound.
|
|
184
|
+
const parentCheck = checkApprovalMarker(generatedDir, parentSessionId, {
|
|
185
|
+
...(lifecycle.maxAgeMs !== undefined ? { maxAgeMs: lifecycle.maxAgeMs } : {}),
|
|
186
|
+
...(opts.now !== undefined ? { now: opts.now } : {}),
|
|
187
|
+
});
|
|
188
|
+
if (!parentCheck.matched) {
|
|
189
|
+
const reason = parentCheck.forged
|
|
190
|
+
? "parent-marker-forged"
|
|
191
|
+
: parentCheck.expired
|
|
192
|
+
? "parent-marker-expired"
|
|
193
|
+
: "parent-marker-missing";
|
|
194
|
+
return { ok: false, reason, detail: parentCheck.detail };
|
|
195
|
+
}
|
|
196
|
+
const now = opts.now ?? new Date();
|
|
197
|
+
// L2/L4 fix (agent-tasks 37ad0b05): an explicit `--ttl` is validated
|
|
198
|
+
// and clamped BEFORE it can reach `expiresAt`. `ttlSeconds <= 0` (or
|
|
199
|
+
// non-finite) used to mint a delegation that is already expired
|
|
200
|
+
// (L2); an unbounded `--ttl` used to let a caller mint one that
|
|
201
|
+
// outlives the applied pack's own `approval_lifecycle.max_age` (L4,
|
|
202
|
+
// or the 24h default ceiling when the pack sets none). Only an
|
|
203
|
+
// EXPLICIT `--ttl` is checked here: the computed default below (from
|
|
204
|
+
// `max_age` or the hardcoded default) is by construction already
|
|
205
|
+
// within whichever ceiling would apply to it.
|
|
206
|
+
let ttlSeconds;
|
|
207
|
+
if (opts.ttlSeconds !== undefined) {
|
|
208
|
+
if (!Number.isFinite(opts.ttlSeconds) || opts.ttlSeconds <= 0) {
|
|
209
|
+
return {
|
|
210
|
+
ok: false,
|
|
211
|
+
reason: "invalid-ttl",
|
|
212
|
+
detail: `--ttl must resolve to a positive, finite number of seconds; got ${opts.ttlSeconds}`,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
const ceilingSeconds = lifecycle.maxAgeMs !== undefined
|
|
216
|
+
? Math.round(lifecycle.maxAgeMs / 1_000)
|
|
217
|
+
: MAX_DELEGATION_TTL_SECONDS;
|
|
218
|
+
if (opts.ttlSeconds > ceilingSeconds) {
|
|
219
|
+
return {
|
|
220
|
+
ok: false,
|
|
221
|
+
reason: "ttl-above-max-age",
|
|
222
|
+
detail: lifecycle.maxAgeMs !== undefined
|
|
223
|
+
? `--ttl (${opts.ttlSeconds}s) exceeds the applied pack's approval_lifecycle.max_age (${ceilingSeconds}s)`
|
|
224
|
+
: `--ttl (${opts.ttlSeconds}s) exceeds the default ${ceilingSeconds}s (24h) ceiling; set approval_lifecycle.max_age to raise it`,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
ttlSeconds = opts.ttlSeconds;
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
ttlSeconds =
|
|
231
|
+
lifecycle.maxAgeMs !== undefined
|
|
232
|
+
? Math.round(lifecycle.maxAgeMs / 1_000)
|
|
233
|
+
: DEFAULT_DELEGATION_TTL_SECONDS;
|
|
234
|
+
}
|
|
235
|
+
const expiresAt = new Date(now.getTime() + ttlSeconds * 1_000).toISOString();
|
|
236
|
+
// Fallback shape: bind the launcher-supplied report by BOTH its
|
|
237
|
+
// content and its path (delegation-markers.ts, "Delegation marker
|
|
238
|
+
// shape" table: half a binding is worse than none).
|
|
239
|
+
let reportPathHash;
|
|
240
|
+
let reportContentHash;
|
|
241
|
+
if (opts.reportPath !== undefined) {
|
|
242
|
+
const read = readRegularFileRejectingSymlink(opts.reportPath);
|
|
243
|
+
if (read.kind !== "ok") {
|
|
244
|
+
return {
|
|
245
|
+
ok: false,
|
|
246
|
+
reason: "report-unreadable",
|
|
247
|
+
detail: `--report ${opts.reportPath} could not be read (${read.kind})`,
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
reportContentHash = sha256Hex(read.content);
|
|
251
|
+
reportPathHash = hashDelegationCwd(opts.reportPath);
|
|
252
|
+
}
|
|
253
|
+
const cwdHash = opts.cwd !== undefined ? hashDelegationCwd(opts.cwd) : null;
|
|
254
|
+
const taskId = opts.taskId !== undefined ? opts.taskId : null;
|
|
255
|
+
const writeResult = writeDelegationMarker({
|
|
256
|
+
generatedDir,
|
|
257
|
+
childSessionId: opts.childSessionId,
|
|
258
|
+
parentSessionId,
|
|
259
|
+
cwdHash,
|
|
260
|
+
taskId,
|
|
261
|
+
expiresAt,
|
|
262
|
+
...(reportPathHash !== undefined ? { reportPathHash } : {}),
|
|
263
|
+
...(reportContentHash !== undefined ? { reportContentHash } : {}),
|
|
264
|
+
now,
|
|
265
|
+
});
|
|
266
|
+
if (!writeResult.ok) {
|
|
267
|
+
if (writeResult.reason === "signing-key-absent") {
|
|
268
|
+
return { ok: false, reason: "signing-key-absent", detail: writeResult.detail };
|
|
269
|
+
}
|
|
270
|
+
if (writeResult.reason === "invalid-input") {
|
|
271
|
+
// Reachable: a malformed raw parent session id (`--session-id`, or
|
|
272
|
+
// a value read from $CLAUDE_CODE_SESSION_ID / $CLAUDE_SESSION_ID /
|
|
273
|
+
// $CODEX_SESSION_ID / a staged .pending-approval) still reaches
|
|
274
|
+
// `buildDelegationApprovedBy`'s `rejectMalformedSessionId` /
|
|
275
|
+
// `rejectUnsafeSegmentValue` checks on `parentSessionId`
|
|
276
|
+
// unvalidated by this function. `--task` no longer reaches this
|
|
277
|
+
// branch: its own value is now validated (the `invalid-task`
|
|
278
|
+
// refusal above) before `writeDelegationMarker` is ever called.
|
|
279
|
+
// Mapped to its own reason rather than folded into "write-failed",
|
|
280
|
+
// so a malformed parent session id fails closed with a diagnostic
|
|
281
|
+
// distinct from a genuine I/O write failure.
|
|
282
|
+
return { ok: false, reason: "invalid-input", detail: writeResult.detail };
|
|
283
|
+
}
|
|
284
|
+
return { ok: false, reason: "write-failed", detail: writeResult.detail };
|
|
285
|
+
}
|
|
286
|
+
const ledgerContent = delegationLedgerFactFor(opts.childSessionId, parentSessionId);
|
|
287
|
+
let ledgerResult;
|
|
288
|
+
if (opts.ledgerAdd) {
|
|
289
|
+
ledgerResult = await opts.ledgerAdd(opts.childSessionId, ledgerContent);
|
|
290
|
+
}
|
|
291
|
+
else if (manifest) {
|
|
292
|
+
ledgerResult = await writeLedgerTag(manifest, opts.childSessionId, ledgerContent, {}, DEFAULT_DELEGATE_LEDGER_SOURCE);
|
|
293
|
+
}
|
|
294
|
+
else {
|
|
295
|
+
ledgerResult = {
|
|
296
|
+
ok: false,
|
|
297
|
+
reason: manifestLoadError
|
|
298
|
+
? `manifest unreadable (${manifestLoadError}); skipped ledger write`
|
|
299
|
+
: "manifest unreadable; skipped ledger write",
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
return {
|
|
303
|
+
ok: true,
|
|
304
|
+
filePath: writeResult.filePath,
|
|
305
|
+
parentSessionId,
|
|
306
|
+
childSessionId: opts.childSessionId,
|
|
307
|
+
expiresAt,
|
|
308
|
+
ledgerFact: ledgerResult.ok
|
|
309
|
+
? { written: true }
|
|
310
|
+
: { written: false, reason: ledgerResult.reason },
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/delegate/index.ts"],"names":[],"mappings":"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"}
|