@lannguyensi/harness 0.8.0 → 0.9.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 +93 -0
- package/README.md +31 -3
- package/dist/cli/index.js +93 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init/detect.d.ts +38 -0
- package/dist/cli/init/detect.js +111 -0
- package/dist/cli/init/detect.js.map +1 -0
- package/dist/cli/init/index.js +1 -1
- package/dist/cli/init/index.js.map +1 -1
- package/dist/cli/init/interactive.d.ts +30 -0
- package/dist/cli/init/interactive.js +178 -0
- package/dist/cli/init/interactive.js.map +1 -0
- package/dist/cli/init/profiles.d.ts +2 -0
- package/dist/cli/init/profiles.js +163 -0
- package/dist/cli/init/profiles.js.map +1 -0
- package/dist/cli/init/templates.d.ts +1 -1
- package/dist/cli/init/templates.js +11 -1
- package/dist/cli/init/templates.js.map +1 -1
- package/dist/cli/pack/hook-pre-tool-use.js +14 -1
- package/dist/cli/pack/hook-pre-tool-use.js.map +1 -1
- package/dist/cli/policy/intercept.js +24 -0
- package/dist/cli/policy/intercept.js.map +1 -1
- package/dist/cli/smoke/assertions.d.ts +39 -0
- package/dist/cli/smoke/assertions.js +163 -0
- package/dist/cli/smoke/assertions.js.map +1 -0
- package/dist/cli/smoke/index.d.ts +59 -0
- package/dist/cli/smoke/index.js +183 -0
- package/dist/cli/smoke/index.js.map +1 -0
- package/dist/cli/smoke/runner.d.ts +55 -0
- package/dist/cli/smoke/runner.js +134 -0
- package/dist/cli/smoke/runner.js.map +1 -0
- package/dist/cli/smoke/stream-parser.d.ts +65 -0
- package/dist/cli/smoke/stream-parser.js +115 -0
- package/dist/cli/smoke/stream-parser.js.map +1 -0
- package/dist/policies/ledger-client.js +15 -3
- package/dist/policies/ledger-client.js.map +1 -1
- package/dist/runtime/intercept.d.ts +20 -1
- package/dist/runtime/intercept.js +18 -6
- package/dist/runtime/intercept.js.map +1 -1
- package/dist/schema/requires.js +17 -0
- package/dist/schema/requires.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { select, confirm, input } from "@inquirer/prompts";
|
|
2
|
+
import { type InitResult } from "./index.js";
|
|
3
|
+
export type ProfileChoice = "solo" | "team" | "custom";
|
|
4
|
+
export interface InteractivePrompts {
|
|
5
|
+
select: typeof select;
|
|
6
|
+
confirm: typeof confirm;
|
|
7
|
+
input: typeof input;
|
|
8
|
+
}
|
|
9
|
+
export interface RunInteractiveOptions {
|
|
10
|
+
/** Override homedir for detection + write target. */
|
|
11
|
+
homeDir?: string;
|
|
12
|
+
/** Dependency-injection seam for tests. */
|
|
13
|
+
prompts?: InteractivePrompts;
|
|
14
|
+
stdout?: (s: string) => void;
|
|
15
|
+
stderr?: (s: string) => void;
|
|
16
|
+
/** Force-confirm overwrite of existing manifest. Real users go through
|
|
17
|
+
* the prompt; tests can pre-set this. */
|
|
18
|
+
forceOverwrite?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface InteractiveResult {
|
|
21
|
+
/** True if the operator (or a Ctrl-C / decline) bailed out. No write happened. */
|
|
22
|
+
aborted: boolean;
|
|
23
|
+
/** The init result, if a write happened. */
|
|
24
|
+
init?: InitResult;
|
|
25
|
+
/** The profile the operator chose, if not aborted. */
|
|
26
|
+
profile?: ProfileChoice;
|
|
27
|
+
/** Whether `harness validate` reported zero errors after the write. */
|
|
28
|
+
validateClean?: boolean;
|
|
29
|
+
}
|
|
30
|
+
export declare function runInteractive(opts?: RunInteractiveOptions): Promise<InteractiveResult>;
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
// Interactive wizard for `harness init --interactive` (task c5287b80,
|
|
2
|
+
// PR split 3/3). Sequential Q&A via `@inquirer/prompts`. Composes the
|
|
3
|
+
// detection module (PR 1) and the profile templates (PR 2).
|
|
4
|
+
//
|
|
5
|
+
// Design notes:
|
|
6
|
+
//
|
|
7
|
+
// - Prompts are dependency-injected via the InteractivePrompts shape so
|
|
8
|
+
// tests can drive the wizard with synchronous mock answers. The
|
|
9
|
+
// default values come from the @inquirer/prompts package.
|
|
10
|
+
// - Ctrl-C from inquirer surfaces as an `ExitPromptError` with a name
|
|
11
|
+
// matching `/ExitPrompt|aborted/i`. The wizard catches it, prints an
|
|
12
|
+
// abort line to stderr, and returns `aborted:true` WITHOUT calling
|
|
13
|
+
// `init()`. No partial manifest is ever written.
|
|
14
|
+
// - The wizard never invokes `harness apply` itself. It prints the
|
|
15
|
+
// suggested command and lets the operator decide. This is a
|
|
16
|
+
// deliberate scope-cut for v1 (per the task description's
|
|
17
|
+
// out-of-scope list).
|
|
18
|
+
// - Acceptance criterion "fresh ~/.claude/ produces a valid harness.yaml":
|
|
19
|
+
// we delegate writing to the existing `init()` so the same atomic
|
|
20
|
+
// write + file-lock + post-write validate path is reused. The wizard
|
|
21
|
+
// is essentially a UI for picking the `--template` value.
|
|
22
|
+
import { select, confirm, input } from "@inquirer/prompts";
|
|
23
|
+
import * as path from "node:path";
|
|
24
|
+
import { EX_FAIL, HarnessExitError } from "../exit-codes.js";
|
|
25
|
+
import { detect } from "./detect.js";
|
|
26
|
+
import { init } from "./index.js";
|
|
27
|
+
import { validate } from "../validate/index.js";
|
|
28
|
+
const DEFAULT_PROMPTS = { select, confirm, input };
|
|
29
|
+
function isAbortError(err) {
|
|
30
|
+
if (!(err instanceof Error))
|
|
31
|
+
return false;
|
|
32
|
+
return /ExitPrompt|aborted|cancel/i.test(err.name) || /force.?closed/i.test(err.message);
|
|
33
|
+
}
|
|
34
|
+
function summariseDetection(d) {
|
|
35
|
+
const lines = ["Environment probe:"];
|
|
36
|
+
for (const r of d.runtimes) {
|
|
37
|
+
const status = r.homeExists ? (r.settingsExists ? "configured" : "home only") : "not found";
|
|
38
|
+
lines.push(` ${r.name.padEnd(12)} ${status} (${r.home})`);
|
|
39
|
+
}
|
|
40
|
+
lines.push(` manifest ${d.manifest.exists ? "present" : "absent"} (${d.manifest.path})`);
|
|
41
|
+
if (d.mcpServers.length > 0) {
|
|
42
|
+
lines.push(` MCP wired ${d.mcpServers.map((s) => s.name).join(", ")}`);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
lines.push(` MCP wired (none detected in Claude settings.json)`);
|
|
46
|
+
}
|
|
47
|
+
lines.push(` harness v${d.harness.version}`);
|
|
48
|
+
return lines.join("\n");
|
|
49
|
+
}
|
|
50
|
+
function profileNeedsAgentTasks(profile) {
|
|
51
|
+
return profile === "team";
|
|
52
|
+
}
|
|
53
|
+
function detectionHasAgentTasks(d) {
|
|
54
|
+
return d.mcpServers.some((s) => s.name === "agent-tasks");
|
|
55
|
+
}
|
|
56
|
+
export async function runInteractive(opts = {}) {
|
|
57
|
+
const prompts = opts.prompts ?? DEFAULT_PROMPTS;
|
|
58
|
+
const stderr = opts.stderr ?? ((s) => process.stderr.write(s));
|
|
59
|
+
const stdout = opts.stdout ?? ((s) => process.stdout.write(s));
|
|
60
|
+
let detection;
|
|
61
|
+
try {
|
|
62
|
+
detection = await detect({ ...(opts.homeDir !== undefined && { homeDir: opts.homeDir }) });
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
throw new HarnessExitError(`detection failed before wizard could start: ${err.message}`, EX_FAIL);
|
|
66
|
+
}
|
|
67
|
+
stderr(`${summariseDetection(detection)}\n\n`);
|
|
68
|
+
try {
|
|
69
|
+
if (detection.manifest.exists && !opts.forceOverwrite) {
|
|
70
|
+
const overwrite = await prompts.confirm({
|
|
71
|
+
message: `A manifest already exists at ${detection.manifest.path}. Overwrite it?`,
|
|
72
|
+
default: false,
|
|
73
|
+
});
|
|
74
|
+
if (!overwrite) {
|
|
75
|
+
stderr("Aborted: existing manifest left untouched.\n");
|
|
76
|
+
return { aborted: true };
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
const profile = (await prompts.select({
|
|
80
|
+
message: "Pick a setup profile",
|
|
81
|
+
choices: [
|
|
82
|
+
{
|
|
83
|
+
name: "Solo (memory-router + understanding-before-execution)",
|
|
84
|
+
value: "solo",
|
|
85
|
+
description: "Single-operator baseline. No agent-tasks loop, no merge gate.",
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: "Team (Solo + agent-tasks MCP + review-before-merge policy)",
|
|
89
|
+
value: "team",
|
|
90
|
+
description: "Adds the merge gate that blocks PR merges without a review ledger entry.",
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
name: "Custom (advanced, bail out and hand-edit)",
|
|
94
|
+
value: "custom",
|
|
95
|
+
description: "Print the install layout and exit. Run `harness init --template full` to get the full reference manifest and edit it directly.",
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
}));
|
|
99
|
+
if (profile === "custom") {
|
|
100
|
+
stderr([
|
|
101
|
+
"Custom profile selected. The interactive wizard does not yet build",
|
|
102
|
+
"manifests à la carte. Run `harness init --template full` to land",
|
|
103
|
+
"the full Appendix A manifest, then hand-edit it. Detection results",
|
|
104
|
+
"above tell you what the harness already sees in your environment.",
|
|
105
|
+
"",
|
|
106
|
+
].join("\n"));
|
|
107
|
+
return { aborted: true, profile };
|
|
108
|
+
}
|
|
109
|
+
if (profileNeedsAgentTasks(profile) && !detectionHasAgentTasks(detection)) {
|
|
110
|
+
const proceed = await prompts.confirm({
|
|
111
|
+
message: "The Team profile wires the agent-tasks MCP, but no agent-tasks server is wired in Claude's settings.json yet. The hooks will still be written, but you will need to wire agent-tasks (or run `harness apply`) before they fire. Proceed?",
|
|
112
|
+
default: true,
|
|
113
|
+
});
|
|
114
|
+
if (!proceed) {
|
|
115
|
+
stderr("Aborted: Team profile declined because agent-tasks is not yet wired.\n");
|
|
116
|
+
return { aborted: true, profile };
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
const defaultMemoryDir = path.join(detection.runtimes[0]?.home ?? "~/.claude", "projects", "{project}", "memory");
|
|
120
|
+
const memoryDir = await prompts.input({
|
|
121
|
+
message: "Memory directory pattern (use {project} for the per-project slug)",
|
|
122
|
+
default: defaultMemoryDir,
|
|
123
|
+
});
|
|
124
|
+
if (memoryDir.trim() === "") {
|
|
125
|
+
stderr("Aborted: memory directory left empty.\n");
|
|
126
|
+
return { aborted: true, profile };
|
|
127
|
+
}
|
|
128
|
+
const confirmWrite = await prompts.confirm({
|
|
129
|
+
message: `Write harness.yaml to ${detection.manifest.path}?`,
|
|
130
|
+
default: true,
|
|
131
|
+
});
|
|
132
|
+
if (!confirmWrite) {
|
|
133
|
+
stderr("Aborted: declined to write manifest.\n");
|
|
134
|
+
return { aborted: true, profile };
|
|
135
|
+
}
|
|
136
|
+
// `custom` was handled above with an early return, so the remaining
|
|
137
|
+
// value is one of the two real TemplateName entries.
|
|
138
|
+
//
|
|
139
|
+
// Path semantics are deliberately split: detect() treats `homeDir`
|
|
140
|
+
// as the user's $HOME and synthesizes `.claude` from it, while
|
|
141
|
+
// init() treats `homeDir` as the .claude directory itself. Bridge
|
|
142
|
+
// by passing the .claude path explicitly when the caller overrides
|
|
143
|
+
// homeDir (test scenarios). When unset, both fall back to their own
|
|
144
|
+
// defaults from os.homedir().
|
|
145
|
+
const initOpts = {
|
|
146
|
+
template: profile,
|
|
147
|
+
force: detection.manifest.exists,
|
|
148
|
+
};
|
|
149
|
+
if (opts.homeDir !== undefined) {
|
|
150
|
+
initOpts.homeDir = path.join(opts.homeDir, ".claude");
|
|
151
|
+
}
|
|
152
|
+
const initResult = await init(initOpts);
|
|
153
|
+
if (initResult.stderr)
|
|
154
|
+
stderr(initResult.stderr);
|
|
155
|
+
stdout(initResult.stdout);
|
|
156
|
+
const v = validate({ configPath: initResult.path });
|
|
157
|
+
const validateClean = v.errorCount === 0;
|
|
158
|
+
stderr(`\nharness validate: ${v.errorCount} error(s), ${v.warningCount} warning(s)\n`);
|
|
159
|
+
for (const d of v.diagnostics) {
|
|
160
|
+
stderr(` [${d.severity}] ${d.path}: ${d.message}\n`);
|
|
161
|
+
}
|
|
162
|
+
if (validateClean) {
|
|
163
|
+
stderr(`\nNext: \`harness apply --runtime claude\` to wire ~/.claude/settings.json. The wizard does not run apply for you; review the generated manifest first.\n`);
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
stderr(`\nValidate reported errors. Fix the manifest before running \`harness apply\`.\n`);
|
|
167
|
+
}
|
|
168
|
+
return { aborted: false, profile, init: initResult, validateClean };
|
|
169
|
+
}
|
|
170
|
+
catch (err) {
|
|
171
|
+
if (isAbortError(err)) {
|
|
172
|
+
stderr("Aborted: Ctrl-C received during prompt; no manifest written.\n");
|
|
173
|
+
return { aborted: true };
|
|
174
|
+
}
|
|
175
|
+
throw err;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=interactive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive.js","sourceRoot":"","sources":["../../../src/cli/init/interactive.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const SOLO_TEMPLATE = "# ~/.claude/harness.yaml\n#\n# Bootstrapped by `harness init --template solo`.\n#\n# Single-operator profile: memory-router for cross-conversation memory\n# routing + understanding-before-execution policy pack to force an\n# explicit interpretation confirmation before any write-capable tool\n# fires. No agent-tasks loop (use --template team if you want PR\n# review-gating).\n#\n# Adapt the paths under `command:` to your install layout, or move\n# host-specific paths to ~/.claude/machines/<host>.harness.overrides.yaml.\n\nversion: 1\n\ngrounding:\n session:\n auto_start: true\n id_format: \"gs-{repo}-{rand:8}\"\n evidence_ledger:\n path: ~/.evidence-ledger/ledger.db\n retention_days: 90\n\ntools:\n builtin:\n known: [Read, Edit, Write, Bash, Agent, Skill, TaskCreate, Glob, Grep]\n\nmemory:\n directories:\n - path: ~/.claude/projects/{project}/memory\n scope: project\n router:\n command: [node, ~/git/pandora/agent-memory/packages/memory-router/dist/hooks/user-prompt-submit.js]\n enabled: true\n retention:\n staleness_days: 180\n broken_refs: warn\n scopes:\n default: project\n allowed: [project, user]\n\npolicy_packs:\n - name: understanding-before-execution\n source: builtin\n enabled: true\n description: Force agents to expose their task interpretation and wait for explicit human approval before any write-capable tool fires.\n config:\n mode: grill_me\n";
|
|
2
|
+
export declare const TEAM_TEMPLATE = "# ~/.claude/harness.yaml\n#\n# Bootstrapped by `harness init --template team`.\n#\n# Solo profile + agent-tasks MCP + the review-before-merge policy. Block\n# pull_requests_merge MCP calls unless a ledger entry tagged\n# review:<pr-number> exists for the current grounding session, the\n# standard team workflow where every PR gets a review-subagent pass\n# before it can land.\n#\n# Adapt the paths under `command:` to your install layout, or move\n# host-specific paths to ~/.claude/machines/<host>.harness.overrides.yaml.\n\nversion: 1\n\ngrounding:\n session:\n auto_start: true\n id_format: \"gs-{repo}-{rand:8}\"\n evidence_ledger:\n path: ~/.evidence-ledger/ledger.db\n retention_days: 90\n\ntools:\n mcp:\n - name: agent-tasks\n command: [node, ~/git/pandora/agent-tasks/mcp-server/dist/server.js]\n env:\n AGENT_TASKS_URL: https://agent-tasks.opentriologue.ai\n health:\n verb: projects_list\n timeout_ms: 5000\n enabled: true\n - name: grounding-mcp\n command: [node, ~/git/pandora/agent-grounding/packages/grounding-mcp/dist/server.js]\n env:\n EVIDENCE_LEDGER_DB: ~/.evidence-ledger/ledger.db\n health:\n verb: ledger_status\n timeout_ms: 5000\n enabled: true\n builtin:\n known: [Read, Edit, Write, Bash, Agent, Skill, TaskCreate, Glob, Grep]\n\nmemory:\n directories:\n - path: ~/.claude/projects/{project}/memory\n scope: project\n router:\n command: [node, ~/git/pandora/agent-memory/packages/memory-router/dist/hooks/user-prompt-submit.js]\n enabled: true\n retention:\n staleness_days: 180\n broken_refs: warn\n scopes:\n default: project\n allowed: [project, user]\n\nhooks:\n - name: require-review-evidence\n event: PreToolUse\n match: \"mcp__agent-tasks__pull_requests_merge\"\n # The built-in `harness policy intercept` CLI verb is the generic\n # deny-on-missing-evidence hook entrypoint. It reads the tool event\n # JSON on stdin, evaluates all policies whose triggers match, emits\n # Claude Code's deny envelope on block. Using it here removes the\n # need to ship a per-policy shell script under ~/.claude/hooks/ for\n # the team setup; operators with custom logic can swap in their own\n # script path.\n command: harness policy intercept\n blocking: hard\n budget_ms: 2000\n\npolicies:\n - name: review-before-merge\n description: Block PR merges unless a ledger entry tagged review:<pr-number> exists for this session.\n trigger:\n event: PreToolUse\n match: \"mcp__agent-tasks__pull_requests_merge\"\n extract:\n PR_NUMBER: \"toolArgs.prNumber\"\n requires:\n ledger_tag: \"review:${PR_NUMBER}\"\n hook: require-review-evidence\n enforcement: block\n\npolicy_packs:\n - name: understanding-before-execution\n source: builtin\n enabled: true\n description: Force agents to expose their task interpretation and wait for explicit human approval before any write-capable tool fires.\n config:\n mode: grill_me\n";
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
// Profile templates for `harness init` (task c5287b80, PR split 2/3).
|
|
2
|
+
//
|
|
3
|
+
// Two opinionated starting manifests that go beyond the bare `minimal`
|
|
4
|
+
// template but stay smaller than `full`:
|
|
5
|
+
//
|
|
6
|
+
// solo: memory-router + understanding-before-execution policy pack.
|
|
7
|
+
// Single-operator setup that wires the recurring "make me
|
|
8
|
+
// defend my interpretation before I touch anything write-
|
|
9
|
+
// capable" gate without dragging in the agent-tasks loop.
|
|
10
|
+
//
|
|
11
|
+
// team: solo + agent-tasks MCP server + review-before-merge policy.
|
|
12
|
+
// Adds the merge gate that requires a ledger entry tagged
|
|
13
|
+
// review:<pr-number> for the current session before the
|
|
14
|
+
// pull_requests_merge MCP verb fires.
|
|
15
|
+
//
|
|
16
|
+
// Both manifests are validate-clean against the v1 schema. They use the
|
|
17
|
+
// same path layouts as the existing FULL template (`~/git/pandora/...`,
|
|
18
|
+
// `~/.claude/...`); operators on a different layout should override via
|
|
19
|
+
// `~/.claude/machines/<host>.harness.overrides.yaml` (ARCHITECTURE §8).
|
|
20
|
+
export const SOLO_TEMPLATE = `# ~/.claude/harness.yaml
|
|
21
|
+
#
|
|
22
|
+
# Bootstrapped by \`harness init --template solo\`.
|
|
23
|
+
#
|
|
24
|
+
# Single-operator profile: memory-router for cross-conversation memory
|
|
25
|
+
# routing + understanding-before-execution policy pack to force an
|
|
26
|
+
# explicit interpretation confirmation before any write-capable tool
|
|
27
|
+
# fires. No agent-tasks loop (use --template team if you want PR
|
|
28
|
+
# review-gating).
|
|
29
|
+
#
|
|
30
|
+
# Adapt the paths under \`command:\` to your install layout, or move
|
|
31
|
+
# host-specific paths to ~/.claude/machines/<host>.harness.overrides.yaml.
|
|
32
|
+
|
|
33
|
+
version: 1
|
|
34
|
+
|
|
35
|
+
grounding:
|
|
36
|
+
session:
|
|
37
|
+
auto_start: true
|
|
38
|
+
id_format: "gs-{repo}-{rand:8}"
|
|
39
|
+
evidence_ledger:
|
|
40
|
+
path: ~/.evidence-ledger/ledger.db
|
|
41
|
+
retention_days: 90
|
|
42
|
+
|
|
43
|
+
tools:
|
|
44
|
+
builtin:
|
|
45
|
+
known: [Read, Edit, Write, Bash, Agent, Skill, TaskCreate, Glob, Grep]
|
|
46
|
+
|
|
47
|
+
memory:
|
|
48
|
+
directories:
|
|
49
|
+
- path: ~/.claude/projects/{project}/memory
|
|
50
|
+
scope: project
|
|
51
|
+
router:
|
|
52
|
+
command: [node, ~/git/pandora/agent-memory/packages/memory-router/dist/hooks/user-prompt-submit.js]
|
|
53
|
+
enabled: true
|
|
54
|
+
retention:
|
|
55
|
+
staleness_days: 180
|
|
56
|
+
broken_refs: warn
|
|
57
|
+
scopes:
|
|
58
|
+
default: project
|
|
59
|
+
allowed: [project, user]
|
|
60
|
+
|
|
61
|
+
policy_packs:
|
|
62
|
+
- name: understanding-before-execution
|
|
63
|
+
source: builtin
|
|
64
|
+
enabled: true
|
|
65
|
+
description: Force agents to expose their task interpretation and wait for explicit human approval before any write-capable tool fires.
|
|
66
|
+
config:
|
|
67
|
+
mode: grill_me
|
|
68
|
+
`;
|
|
69
|
+
export const TEAM_TEMPLATE = `# ~/.claude/harness.yaml
|
|
70
|
+
#
|
|
71
|
+
# Bootstrapped by \`harness init --template team\`.
|
|
72
|
+
#
|
|
73
|
+
# Solo profile + agent-tasks MCP + the review-before-merge policy. Block
|
|
74
|
+
# pull_requests_merge MCP calls unless a ledger entry tagged
|
|
75
|
+
# review:<pr-number> exists for the current grounding session, the
|
|
76
|
+
# standard team workflow where every PR gets a review-subagent pass
|
|
77
|
+
# before it can land.
|
|
78
|
+
#
|
|
79
|
+
# Adapt the paths under \`command:\` to your install layout, or move
|
|
80
|
+
# host-specific paths to ~/.claude/machines/<host>.harness.overrides.yaml.
|
|
81
|
+
|
|
82
|
+
version: 1
|
|
83
|
+
|
|
84
|
+
grounding:
|
|
85
|
+
session:
|
|
86
|
+
auto_start: true
|
|
87
|
+
id_format: "gs-{repo}-{rand:8}"
|
|
88
|
+
evidence_ledger:
|
|
89
|
+
path: ~/.evidence-ledger/ledger.db
|
|
90
|
+
retention_days: 90
|
|
91
|
+
|
|
92
|
+
tools:
|
|
93
|
+
mcp:
|
|
94
|
+
- name: agent-tasks
|
|
95
|
+
command: [node, ~/git/pandora/agent-tasks/mcp-server/dist/server.js]
|
|
96
|
+
env:
|
|
97
|
+
AGENT_TASKS_URL: https://agent-tasks.opentriologue.ai
|
|
98
|
+
health:
|
|
99
|
+
verb: projects_list
|
|
100
|
+
timeout_ms: 5000
|
|
101
|
+
enabled: true
|
|
102
|
+
- name: grounding-mcp
|
|
103
|
+
command: [node, ~/git/pandora/agent-grounding/packages/grounding-mcp/dist/server.js]
|
|
104
|
+
env:
|
|
105
|
+
EVIDENCE_LEDGER_DB: ~/.evidence-ledger/ledger.db
|
|
106
|
+
health:
|
|
107
|
+
verb: ledger_status
|
|
108
|
+
timeout_ms: 5000
|
|
109
|
+
enabled: true
|
|
110
|
+
builtin:
|
|
111
|
+
known: [Read, Edit, Write, Bash, Agent, Skill, TaskCreate, Glob, Grep]
|
|
112
|
+
|
|
113
|
+
memory:
|
|
114
|
+
directories:
|
|
115
|
+
- path: ~/.claude/projects/{project}/memory
|
|
116
|
+
scope: project
|
|
117
|
+
router:
|
|
118
|
+
command: [node, ~/git/pandora/agent-memory/packages/memory-router/dist/hooks/user-prompt-submit.js]
|
|
119
|
+
enabled: true
|
|
120
|
+
retention:
|
|
121
|
+
staleness_days: 180
|
|
122
|
+
broken_refs: warn
|
|
123
|
+
scopes:
|
|
124
|
+
default: project
|
|
125
|
+
allowed: [project, user]
|
|
126
|
+
|
|
127
|
+
hooks:
|
|
128
|
+
- name: require-review-evidence
|
|
129
|
+
event: PreToolUse
|
|
130
|
+
match: "mcp__agent-tasks__pull_requests_merge"
|
|
131
|
+
# The built-in \`harness policy intercept\` CLI verb is the generic
|
|
132
|
+
# deny-on-missing-evidence hook entrypoint. It reads the tool event
|
|
133
|
+
# JSON on stdin, evaluates all policies whose triggers match, emits
|
|
134
|
+
# Claude Code's deny envelope on block. Using it here removes the
|
|
135
|
+
# need to ship a per-policy shell script under ~/.claude/hooks/ for
|
|
136
|
+
# the team setup; operators with custom logic can swap in their own
|
|
137
|
+
# script path.
|
|
138
|
+
command: harness policy intercept
|
|
139
|
+
blocking: hard
|
|
140
|
+
budget_ms: 2000
|
|
141
|
+
|
|
142
|
+
policies:
|
|
143
|
+
- name: review-before-merge
|
|
144
|
+
description: Block PR merges unless a ledger entry tagged review:<pr-number> exists for this session.
|
|
145
|
+
trigger:
|
|
146
|
+
event: PreToolUse
|
|
147
|
+
match: "mcp__agent-tasks__pull_requests_merge"
|
|
148
|
+
extract:
|
|
149
|
+
PR_NUMBER: "toolArgs.prNumber"
|
|
150
|
+
requires:
|
|
151
|
+
ledger_tag: "review:\${PR_NUMBER}"
|
|
152
|
+
hook: require-review-evidence
|
|
153
|
+
enforcement: block
|
|
154
|
+
|
|
155
|
+
policy_packs:
|
|
156
|
+
- name: understanding-before-execution
|
|
157
|
+
source: builtin
|
|
158
|
+
enabled: true
|
|
159
|
+
description: Force agents to expose their task interpretation and wait for explicit human approval before any write-capable tool fires.
|
|
160
|
+
config:
|
|
161
|
+
mode: grill_me
|
|
162
|
+
`;
|
|
163
|
+
//# sourceMappingURL=profiles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profiles.js","sourceRoot":"","sources":["../../../src/cli/init/profiles.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,EAAE;AACF,uEAAuE;AACvE,yCAAyC;AACzC,EAAE;AACF,sEAAsE;AACtE,kEAAkE;AAClE,kEAAkE;AAClE,kEAAkE;AAClE,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,kEAAkE;AAClE,gDAAgD;AAChD,EAAE;AACF,wEAAwE;AACxE,wEAAwE;AACxE,wEAAwE;AACxE,wEAAwE;AAExE,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgD5B,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6F5B,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export declare const MINIMAL_TEMPLATE = "# ~/.claude/harness.yaml\n#\n# Bootstrapped by `harness init --template minimal`.\n#\n# This is the empty-but-valid manifest. Run `harness validate` to confirm it\n# parses, then add entries under the five top-level keys:\n#\n# grounding: evidence-ledger + claim-gate config (see docs/ARCHITECTURE.md \u00A72)\n# tools: mcp / cli / skills / builtin inventory (\u00A73)\n# memory: directories, retention, scopes (\u00A74)\n# hooks: event-bound shell commands (\u00A75)\n# policies: named rules that bind hooks to triggers (\u00A76)\n#\n# Phase 2 verbs to add entries safely: `harness add mcp <name> ...`,\n# `harness add cli`, `harness add hook`, `harness add skill`.\n# Per-machine overrides live at ~/.claude/machines/<discriminator>.harness.overrides.yaml\n# (ARCHITECTURE.md \u00A78) for paths that vary per host.\n#\n# Docs: https://github.com/LanNguyenSi/harness\n\nversion: 1\n";
|
|
2
2
|
export declare const FULL_TEMPLATE = "# ~/.claude/harness.yaml\n#\n# Bootstrapped by `harness init --template full`. Mirrors the example manifest\n# from docs/ARCHITECTURE.md Appendix A. Paths under `command:` reference the\n# developer machine that authored Appendix A \u2014 adapt them to your host (or\n# move host-specific paths to ~/.claude/machines/<hostname>.harness.overrides.yaml\n# per ARCHITECTURE.md \u00A78) before running `harness validate`.\n\nversion: 1\n\ngrounding:\n session:\n auto_start: true\n id_format: \"gs-{repo}-{rand:8}\"\n evidence_ledger:\n path: ~/.evidence-ledger/ledger.db\n retention_days: 90\n policies_source: ~/.claude/harness.d/policies/claim-gate.yaml\n\ntools:\n mcp:\n - name: codebase-oracle\n command: [npx, tsx, ~/git/pandora/codebase-oracle/src/mcp-server.ts]\n health:\n verb: oracle_list_repos\n timeout_ms: 5000\n enabled: true\n - name: agent-tasks\n command: [node, ~/git/pandora/agent-tasks/mcp-server/dist/server.js]\n env:\n AGENT_TASKS_URL: https://agent-tasks.opentriologue.ai\n health:\n verb: projects_list\n timeout_ms: 5000\n enabled: true\n - name: grounding-mcp\n command: [node, ~/git/pandora/agent-grounding/packages/grounding-mcp/dist/server.js]\n env:\n EVIDENCE_LEDGER_DB: ~/.evidence-ledger/ledger.db\n health:\n verb: ledger_status\n timeout_ms: 5000\n enabled: true\n\n cli:\n - name: git-batch\n binary: git-batch\n min_version: \"0.2.0\"\n required: true\n - name: gh\n binary: gh\n required: true\n - name: ledger\n binary: ledger\n required: false\n\n skills:\n enabled:\n - simplify\n - init\n - review\n - security-review\n source_dirs:\n - ~/.claude/skills\n\n builtin:\n known: [Read, Edit, Write, Bash, Agent, Skill, TaskCreate]\n\nmemory:\n directories:\n - path: ~/.claude/projects/{project}/memory\n scope: project\n router:\n command: [node, ~/git/pandora/agent-memory/packages/memory-router/dist/hooks/user-prompt-submit.js]\n enabled: true\n retention:\n staleness_days: 180\n broken_refs: warn\n scopes:\n default: project\n allowed: [project, user]\n\nhooks:\n - name: git-preflight\n event: SessionStart\n command: ~/.claude/hooks/git-preflight.sh\n blocking: false\n budget_ms: 30000\n description: \"Run agent-preflight on session start; record ready + confidence into the ledger as preflight:${REPO}.\"\n\n - name: require-review-evidence\n event: PreToolUse\n match: \"mcp__agent-tasks__pull_requests_merge\"\n command: ~/.claude/hooks/require-review-evidence.sh\n blocking: hard\n budget_ms: 2000\n\n - name: require-dogfood-evidence\n event: PreToolUse\n match: \"Bash\"\n command: ~/.claude/hooks/require-dogfood-evidence.sh\n blocking: hard\n budget_ms: 2000\n\n - name: require-preflight-evidence\n event: PreToolUse\n match: \"Bash\"\n bash_match: \"^git (status|log|diff|branch)\"\n command: ~/.claude/hooks/require-preflight-evidence.sh\n blocking: hard\n budget_ms: 1000\n\npolicies:\n - name: review-before-merge\n description: Block PR merges unless a ledger entry tagged review:<pr-number> exists for this session.\n trigger:\n event: PreToolUse\n match: \"mcp__agent-tasks__pull_requests_merge\"\n extract:\n PR_NUMBER: \"toolArgs.prNumber\"\n requires:\n ledger_tag: \"review:${PR_NUMBER}\"\n hook: require-review-evidence\n enforcement: block\n\n - name: dogfood-before-release\n description: Block npm publish / git tag v* without a recent dogfood ledger entry.\n trigger:\n event: PreToolUse\n match: \"Bash\"\n bash_match: \"^(npm publish|git tag v.*)\"\n requires:\n ledger_tag: \"dogfood:${SESSION_ID}\"\n within: 24h\n hook: require-dogfood-evidence\n enforcement: block\n\n - name: preflight-before-investigation\n description: Block investigative git reads (status/log/diff/branch) when agent-preflight has not run recently with ready:true for the current repo.\n trigger:\n event: PreToolUse\n match: \"Bash\"\n bash_match: \"^git (status|log|diff|branch)\"\n requires:\n ledger_tag: \"preflight:${REPO}\"\n within: 1h\n hook: require-preflight-evidence\n enforcement: block\n";
|
|
3
|
-
export type TemplateName = "minimal" | "full";
|
|
3
|
+
export type TemplateName = "minimal" | "full" | "solo" | "team";
|
|
4
4
|
export declare function getTemplate(name: TemplateName): string;
|
|
@@ -169,7 +169,17 @@ policies:
|
|
|
169
169
|
hook: require-preflight-evidence
|
|
170
170
|
enforcement: block
|
|
171
171
|
`;
|
|
172
|
+
import { SOLO_TEMPLATE, TEAM_TEMPLATE } from "./profiles.js";
|
|
172
173
|
export function getTemplate(name) {
|
|
173
|
-
|
|
174
|
+
switch (name) {
|
|
175
|
+
case "full":
|
|
176
|
+
return FULL_TEMPLATE;
|
|
177
|
+
case "solo":
|
|
178
|
+
return SOLO_TEMPLATE;
|
|
179
|
+
case "team":
|
|
180
|
+
return TEAM_TEMPLATE;
|
|
181
|
+
case "minimal":
|
|
182
|
+
return MINIMAL_TEMPLATE;
|
|
183
|
+
}
|
|
174
184
|
}
|
|
175
185
|
//# sourceMappingURL=templates.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/cli/init/templates.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;CAqB/B,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoJ5B,CAAC;
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/cli/init/templates.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;CAqB/B,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoJ5B,CAAC;AAEF,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAI7D,MAAM,UAAU,WAAW,CAAC,IAAkB;IAC5C,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,MAAM;YACT,OAAO,aAAa,CAAC;QACvB,KAAK,MAAM;YACT,OAAO,aAAa,CAAC;QACvB,KAAK,MAAM;YACT,OAAO,aAAa,CAAC;QACvB,KAAK,SAAS;YACZ,OAAO,gBAAgB,CAAC;IAC5B,CAAC;AACH,CAAC"}
|
|
@@ -38,10 +38,23 @@ async function readStdin(stream) {
|
|
|
38
38
|
function findGroundingMcp(manifest) {
|
|
39
39
|
return manifest.tools.mcp.find((m) => m.name === "grounding-mcp") ?? null;
|
|
40
40
|
}
|
|
41
|
+
// The Claude Code "block" envelope. Mirrors the runtime/intercept.ts
|
|
42
|
+
// shape (PR #81): `decision: "block"` keeps legacy 2.0.x CLIs blocking,
|
|
43
|
+
// `hookSpecificOutput.permissionDecision: "deny"` is the Claude Code
|
|
44
|
+
// 2.1+ documented contract for PreToolUse. This hook is always wired to
|
|
45
|
+
// PreToolUse (the pack contributes only a PreToolUse hook), so the
|
|
46
|
+
// envelope is unconditional here — no event-kind branch like
|
|
47
|
+
// runtime/intercept.ts needs.
|
|
41
48
|
function blockJson(toolName, reason) {
|
|
49
|
+
const reasonText = `Understanding Gate: ${reason}. Tool: ${toolName}. Run \`harness approve understanding\` once you have produced and confirmed an Understanding Report.`;
|
|
42
50
|
return JSON.stringify({
|
|
43
51
|
decision: "block",
|
|
44
|
-
reason:
|
|
52
|
+
reason: reasonText,
|
|
53
|
+
hookSpecificOutput: {
|
|
54
|
+
hookEventName: "PreToolUse",
|
|
55
|
+
permissionDecision: "deny",
|
|
56
|
+
permissionDecisionReason: reasonText,
|
|
57
|
+
},
|
|
45
58
|
});
|
|
46
59
|
}
|
|
47
60
|
async function checkLedger(manifest, sessionId, opts) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hook-pre-tool-use.js","sourceRoot":"","sources":["../../../src/cli/pack/hook-pre-tool-use.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,EAAE;AACF,yDAAyD;AACzD,wEAAwE;AACxE,qEAAqE;AACrE,kEAAkE;AAClE,yEAAyE;AACzE,2CAA2C;AAC3C,EAAE;AACF,kEAAkE;AAClE,sEAAsE;AACtE,oEAAoE;AACpE,sEAAsE;AACtE,sEAAsE;AACtE,sEAAsE;AACtE,EAAE;AACF,iEAAiE;AACjE,wEAAwE;AACxE,qEAAqE;AACrE,oEAAoE;AACpE,qEAAqE;AACrE,iEAAiE;AAEjE,OAAO,EACL,gBAAgB,GAEjB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,GAEnB,MAAM,sEAAsE,CAAC;AAE9E,OAAO,EAAE,YAAY,EAAsB,MAAM,cAAc,CAAC;AAEhE,MAAM,SAAS,GAAG,gCAAgC,CAAC;AAkCnD,KAAK,UAAU,SAAS,CAAC,MAA6B;IACpD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAC3B,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YAClC,IAAI,IAAI,KAAK,CAAC;QAChB,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QACtC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,gBAAgB,CAAC,QAAkB;IAC1C,OAAO,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,eAAe,CAAC,IAAI,IAAI,CAAC;AAC5E,CAAC;AAED,SAAS,SAAS,CAAC,QAAgB,EAAE,MAAc;IACjD,OAAO,IAAI,CAAC,SAAS,CAAC;QACpB,QAAQ,EAAE,OAAO;QACjB,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"hook-pre-tool-use.js","sourceRoot":"","sources":["../../../src/cli/pack/hook-pre-tool-use.ts"],"names":[],"mappings":"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"}
|
|
@@ -156,6 +156,17 @@ export async function runInterceptCli(opts = {}) {
|
|
|
156
156
|
if (result.blockJson) {
|
|
157
157
|
stdout.write(`${JSON.stringify(result.blockJson)}\n`);
|
|
158
158
|
}
|
|
159
|
+
// No-match diagnostic. Always (not gated on --verbose) when the
|
|
160
|
+
// manifest has at least one policy but none of them matched this
|
|
161
|
+
// event. Catches the common debug footgun where an operator probes
|
|
162
|
+
// `harness policy intercept` by hand and forgets `hook_event_name`,
|
|
163
|
+
// making the engine return exit 0 + empty stdout. The probe then
|
|
164
|
+
// looks like "policy did not load", when in fact the trigger filter
|
|
165
|
+
// simply rejected the input. Emits to stderr so the Claude Code
|
|
166
|
+
// hook contract on stdout is preserved.
|
|
167
|
+
if (result.decisions.length === 0 && manifest.policies.length > 0) {
|
|
168
|
+
stderr.write(formatNoMatchHint(event, manifest));
|
|
169
|
+
}
|
|
159
170
|
if (verbose) {
|
|
160
171
|
for (const decision of result.decisions) {
|
|
161
172
|
if (decision.outcome === "allow")
|
|
@@ -169,4 +180,17 @@ export async function runInterceptCli(opts = {}) {
|
|
|
169
180
|
blocked: result.blockJson !== null,
|
|
170
181
|
};
|
|
171
182
|
}
|
|
183
|
+
function formatNoMatchHint(event, manifest) {
|
|
184
|
+
const observedEvent = typeof event.hook_event_name === "string" && event.hook_event_name.length > 0
|
|
185
|
+
? `"${event.hook_event_name}"`
|
|
186
|
+
: "(missing)";
|
|
187
|
+
const observedTool = typeof event.tool_name === "string" && event.tool_name.length > 0
|
|
188
|
+
? `"${event.tool_name}"`
|
|
189
|
+
: "(missing)";
|
|
190
|
+
const registeredEvents = Array.from(new Set(manifest.policies.map((p) => p.trigger.event))).sort();
|
|
191
|
+
return (`harness policy intercept: no policy matched event ` +
|
|
192
|
+
`hook_event_name=${observedEvent} tool_name=${observedTool} ` +
|
|
193
|
+
`(registered policy events: ${registeredEvents.join(", ")}). ` +
|
|
194
|
+
`If probing by hand, ensure stdin includes hook_event_name (e.g. "PreToolUse" for tool gates).\n`);
|
|
195
|
+
}
|
|
172
196
|
//# sourceMappingURL=intercept.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intercept.js","sourceRoot":"","sources":["../../../src/cli/policy/intercept.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"intercept.js","sourceRoot":"","sources":["../../../src/cli/policy/intercept.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { HookPair, StreamSummary } from "./stream-parser.js";
|
|
2
|
+
export type ExpectDecision = "allow" | "deny" | "warn";
|
|
3
|
+
export interface SmokeExpectations {
|
|
4
|
+
/** Hook names or events that MUST have fired. */
|
|
5
|
+
expectHooks?: string[];
|
|
6
|
+
/** Hook names or events that MUST NOT have fired. */
|
|
7
|
+
expectNoHooks?: string[];
|
|
8
|
+
/** Terminal `result.is_error` is true iff this matches `expect-exit != 0`. */
|
|
9
|
+
expectExit?: number;
|
|
10
|
+
/** Last policy-intercept decision must match. */
|
|
11
|
+
expectDecision?: ExpectDecision;
|
|
12
|
+
}
|
|
13
|
+
export interface AssertionFailure {
|
|
14
|
+
kind: "expect-hook" | "expect-no-hook" | "expect-exit" | "expect-decision";
|
|
15
|
+
expected: string;
|
|
16
|
+
actual: string;
|
|
17
|
+
detail: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Classify the policy decision emitted by `harness policy intercept`.
|
|
21
|
+
*
|
|
22
|
+
* The intercept CLI contract (PR #81): on `deny`, stdout carries the
|
|
23
|
+
* Claude Code 2.1+ envelope (`decision:"block"` AND
|
|
24
|
+
* `hookSpecificOutput.permissionDecision:"deny"`). On `allow`, stdout
|
|
25
|
+
* is empty. On `warn-degraded`, stdout is empty AND stderr carries the
|
|
26
|
+
* Phase 5 #3 diagnostic line (`warn-degraded (ledger unreachable)`)
|
|
27
|
+
* when HARNESS_POLICY_VERBOSE is on. `harness smoke` sets that env var
|
|
28
|
+
* unconditionally when spawning claude, so the warn branch is
|
|
29
|
+
* observable.
|
|
30
|
+
*
|
|
31
|
+
* Order of detection: deny first (any hook stdout containing the
|
|
32
|
+
* envelope), then warn (any hook stderr containing the diagnostic),
|
|
33
|
+
* then allow if at least one policy-shaped hook fired without a deny
|
|
34
|
+
* stdout, else `null` (no policy hook in the stream, so the assertion
|
|
35
|
+
* is N/A and must be reported as a miss).
|
|
36
|
+
*/
|
|
37
|
+
export declare function classifyDecision(hooks: HookPair[]): ExpectDecision | null;
|
|
38
|
+
export declare function evaluateExpectations(summary: StreamSummary, expectations: SmokeExpectations): AssertionFailure[];
|
|
39
|
+
export declare function formatFailures(failures: AssertionFailure[]): string;
|