@lannguyensi/harness 0.52.0 → 0.54.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/CHANGELOG.md +82 -0
  2. package/dist/cli/delegate/index.d.ts +15 -2
  3. package/dist/cli/delegate/index.js +128 -4
  4. package/dist/cli/delegate/index.js.map +1 -1
  5. package/dist/cli/doctor/bypass-without-auto-approve.d.ts +38 -0
  6. package/dist/cli/doctor/bypass-without-auto-approve.js +95 -0
  7. package/dist/cli/doctor/bypass-without-auto-approve.js.map +1 -0
  8. package/dist/cli/doctor/format.js +7 -0
  9. package/dist/cli/doctor/format.js.map +1 -1
  10. package/dist/cli/doctor/index.js +17 -0
  11. package/dist/cli/doctor/index.js.map +1 -1
  12. package/dist/cli/doctor/types.d.ts +11 -0
  13. package/dist/cli/doctor/types.js.map +1 -1
  14. package/dist/cli/doctor/ug-auto-approvals.js +18 -43
  15. package/dist/cli/doctor/ug-auto-approvals.js.map +1 -1
  16. package/dist/cli/dry-run.js +32 -1
  17. package/dist/cli/dry-run.js.map +1 -1
  18. package/dist/cli/gc/index.d.ts +13 -2
  19. package/dist/cli/gc/index.js +203 -1
  20. package/dist/cli/gc/index.js.map +1 -1
  21. package/dist/cli/index.js +57 -11
  22. package/dist/cli/index.js.map +1 -1
  23. package/dist/cli/init/composer.js +9 -0
  24. package/dist/cli/init/composer.js.map +1 -1
  25. package/dist/cli/init/profiles.d.ts +2 -2
  26. package/dist/cli/init/profiles.js +100 -8
  27. package/dist/cli/init/profiles.js.map +1 -1
  28. package/dist/cli/init/templates.d.ts +1 -1
  29. package/dist/cli/init/templates.js +174 -3
  30. package/dist/cli/init/templates.js.map +1 -1
  31. package/dist/cli/pack/hook-pre-tool-use.js +219 -115
  32. package/dist/cli/pack/hook-pre-tool-use.js.map +1 -1
  33. package/dist/cli/pack/index.d.ts +1 -0
  34. package/dist/cli/pack/index.js +1 -0
  35. package/dist/cli/pack/index.js.map +1 -1
  36. package/dist/cli/pack/upgrade.d.ts +32 -0
  37. package/dist/cli/pack/upgrade.js +273 -0
  38. package/dist/cli/pack/upgrade.js.map +1 -0
  39. package/dist/cli/record/index.d.ts +8 -0
  40. package/dist/cli/record/index.js +55 -7
  41. package/dist/cli/record/index.js.map +1 -1
  42. package/dist/cli/validate/checks.js +61 -9
  43. package/dist/cli/validate/checks.js.map +1 -1
  44. package/dist/io/extract.d.ts +29 -0
  45. package/dist/io/extract.js +36 -0
  46. package/dist/io/extract.js.map +1 -1
  47. package/dist/io/read-json-dir-entries.d.ts +36 -0
  48. package/dist/io/read-json-dir-entries.js +38 -0
  49. package/dist/io/read-json-dir-entries.js.map +1 -0
  50. package/dist/policies/index.d.ts +1 -1
  51. package/dist/policies/index.js +1 -1
  52. package/dist/policies/index.js.map +1 -1
  53. package/dist/policy-packs/builtin/understanding-before-execution/auto-approve-default.d.ts +35 -0
  54. package/dist/policy-packs/builtin/understanding-before-execution/auto-approve-default.js +86 -0
  55. package/dist/policy-packs/builtin/understanding-before-execution/auto-approve-default.js.map +1 -0
  56. package/dist/policy-packs/builtin/understanding-before-execution/delegation-markers.d.ts +51 -0
  57. package/dist/policy-packs/builtin/understanding-before-execution/delegation-markers.js +55 -1
  58. package/dist/policy-packs/builtin/understanding-before-execution/delegation-markers.js.map +1 -1
  59. package/dist/policy-packs/builtin/understanding-before-execution/index.d.ts +3 -1
  60. package/dist/policy-packs/builtin/understanding-before-execution/index.js +18 -1
  61. package/dist/policy-packs/builtin/understanding-before-execution/index.js.map +1 -1
  62. package/dist/policy-packs/builtin/understanding-before-execution/permission-mode-observations.d.ts +71 -0
  63. package/dist/policy-packs/builtin/understanding-before-execution/permission-mode-observations.js +175 -0
  64. package/dist/policy-packs/builtin/understanding-before-execution/permission-mode-observations.js.map +1 -0
  65. package/dist/runtime/destructive-shell-floor.d.ts +19 -0
  66. package/dist/runtime/destructive-shell-floor.js +597 -0
  67. package/dist/runtime/destructive-shell-floor.js.map +1 -0
  68. package/dist/runtime/git-context.js +7 -1
  69. package/dist/runtime/git-context.js.map +1 -1
  70. package/dist/runtime/intercept.d.ts +10 -7
  71. package/dist/runtime/intercept.js +108 -9
  72. package/dist/runtime/intercept.js.map +1 -1
  73. package/dist/runtime/read-only-bash.d.ts +21 -0
  74. package/dist/runtime/read-only-bash.js +484 -0
  75. package/dist/runtime/read-only-bash.js.map +1 -1
  76. package/dist/runtime/risk-classifier.js +68 -13
  77. package/dist/runtime/risk-classifier.js.map +1 -1
  78. package/dist/runtime/when-eval.d.ts +18 -5
  79. package/dist/runtime/when-eval.js +64 -11
  80. package/dist/runtime/when-eval.js.map +1 -1
  81. package/dist/runtime/workflow-policies.d.ts +43 -1
  82. package/dist/runtime/workflow-policies.js +158 -1
  83. package/dist/runtime/workflow-policies.js.map +1 -1
  84. package/dist/schema/extract.d.ts +4 -0
  85. package/dist/schema/extract.js +64 -1
  86. package/dist/schema/extract.js.map +1 -1
  87. package/dist/schema/index.d.ts +13 -0
  88. package/dist/schema/policies.d.ts +19 -0
  89. package/dist/schema/policies.js +17 -1
  90. package/dist/schema/policies.js.map +1 -1
  91. package/package.json +1 -1
@@ -0,0 +1,273 @@
1
+ // `harness pack upgrade <name>`: text-level insertion of a pack's
2
+ // missing default config block into an existing manifest, WITHOUT
3
+ // parsing and reserializing the operator's YAML (unlike `pack add` /
4
+ // `pack reseed`, which both mutate via the `yaml` Document API). Task
5
+ // 8f637efd: the one upgrade this ships is `auto_approve` for
6
+ // `understanding-before-execution` (D-004,
7
+ // docs/decisions/2026-08-27-ug-auto-mode-approval.md, "Amendment:
8
+ // install default").
9
+ //
10
+ // WHY TEXT-LEVEL, NOT DOCUMENT-LEVEL. The `yaml` package's Document API
11
+ // (`withDocument`, used by `pack reseed`) round-trips comments
12
+ // reasonably well for a single field REPLACEMENT, but this upgrade
13
+ // INSERTS a brand-new key with its own multi-line comment block into an
14
+ // operator manifest that may carry hand edits `pack add` / `reseed`
15
+ // never touch (custom producers, an extra top-level key, a reordered
16
+ // field). Re-serializing the whole document risks reformatting content
17
+ // this verb has no business touching. Insertion by line position,
18
+ // guided by indentation, keeps every byte outside the inserted block
19
+ // untouched.
20
+ //
21
+ // IDEMPOTENT. If `auto_approve:` already exists anywhere inside the
22
+ // pack's `config:` mapping (any indentation), this is a no-op: the
23
+ // output is byte-identical to the input. An operator who already
24
+ // hand-applied the workaround (the ADR's own "Workaround, bereits
25
+ // angewendet" paragraph) gets nothing rewritten out from under them.
26
+ //
27
+ // REFUSES ON AMBIGUITY. Zero or more than one
28
+ // `understanding-before-execution` pack block, more than one `config:`
29
+ // key inside it, or no `config:` key found at all, is a refusal
30
+ // (non-zero exit, a clear message), never a guess at where to insert.
31
+ import * as fs from "node:fs";
32
+ import * as path from "node:path";
33
+ import { parse as parseYaml } from "yaml";
34
+ import { atomicWriteFile } from "../../io/atomic-write.js";
35
+ import { unifiedDiff } from "../../io/patch.js";
36
+ import { withFileLock } from "../../io/lock.js";
37
+ import { formatValidationErrors, validateBeforeWrite, } from "../../io/validate-before-write.js";
38
+ import { resolveHomeDir } from "../../runtime/home-dir.js";
39
+ import { renderAutoApproveSnippet } from "../../policy-packs/builtin/understanding-before-execution-runtime.js";
40
+ import { EX_FAIL, EX_NOINPUT, HarnessExitError } from "../exit-codes.js";
41
+ const DEFAULT_BASENAME = "harness.yaml";
42
+ const LOCK_BASENAME = ".harness.lock";
43
+ function resolveTargetPath(opts) {
44
+ if (opts.configPath)
45
+ return path.resolve(opts.configPath);
46
+ return path.join(resolveHomeDir({ ...(opts.homeDir !== undefined ? { homeDir: opts.homeDir } : {}) }).path, DEFAULT_BASENAME);
47
+ }
48
+ function countLeadingSpaces(line) {
49
+ return line.length - line.trimStart().length;
50
+ }
51
+ /**
52
+ * Text-level insertion of the `auto_approve` default snippet into the
53
+ * `understanding-before-execution` pack's `config:` mapping. Pure: text
54
+ * in, text (+ a change flag) out, or an error string on ambiguity.
55
+ * Exported for direct unit testing without going through the CLI/file
56
+ * layer.
57
+ */
58
+ /**
59
+ * The line ending most of `text` uses, so an insertion into a CRLF
60
+ * manifest does not mix in bare-LF lines (task 8f637efd review round 2
61
+ * F6): counts `\r\n` occurrences against LF-only ones (every `\n` not
62
+ * part of a `\r\n` pair) and picks whichever is more common, defaulting
63
+ * to `\n` on a tie or an all-LF file.
64
+ */
65
+ function detectDominantEol(text) {
66
+ const crlfCount = (text.match(/\r\n/g) ?? []).length;
67
+ const totalLf = (text.match(/\n/g) ?? []).length;
68
+ const lfOnlyCount = totalLf - crlfCount;
69
+ return crlfCount > lfOnlyCount ? "\r\n" : "\n";
70
+ }
71
+ export function applyAutoApproveUpgrade(original) {
72
+ const eol = detectDominantEol(original);
73
+ // Split on either line ending so every line in `lines` is `\r`-free
74
+ // (its own trailing `\r`, if any, is consumed by the delimiter, not
75
+ // left dangling on the line content); the array is rejoined with the
76
+ // detected `eol` below, so a CRLF manifest stays CRLF end to end
77
+ // instead of picking up bare-LF lines from the inserted snippet.
78
+ const lines = original.split(/\r\n|\n/);
79
+ // Accepts a bare, double-quoted, or single-quoted scalar for the pack
80
+ // name (task 8f637efd review round 2 F4): `- name: understanding-before-execution`,
81
+ // `- name: "understanding-before-execution"`, and
82
+ // `- name: 'understanding-before-execution'` are all schema-valid YAML
83
+ // for the same value; the bare-only form previously refused the
84
+ // quoted spellings with "could not find a ... entry".
85
+ const packNameRe = /^(\s*)-\s*name:\s*(?:"understanding-before-execution"|'understanding-before-execution'|understanding-before-execution)\s*(#.*)?$/;
86
+ const packMatches = [];
87
+ for (let i = 0; i < lines.length; i++) {
88
+ const m = packNameRe.exec(lines[i] ?? "");
89
+ if (m)
90
+ packMatches.push({ index: i, indent: (m[1] ?? "").length });
91
+ }
92
+ if (packMatches.length === 0) {
93
+ return {
94
+ ok: false,
95
+ error: "could not find a `- name: understanding-before-execution` policy_packs entry in this manifest",
96
+ };
97
+ }
98
+ if (packMatches.length > 1) {
99
+ return {
100
+ ok: false,
101
+ error: `found ${packMatches.length} \`understanding-before-execution\` policy_packs entries; refusing (ambiguous)`,
102
+ };
103
+ }
104
+ const pack = packMatches[0];
105
+ const itemIndent = pack.indent;
106
+ function findBoundary(startIdx, indentThreshold) {
107
+ for (let i = startIdx; i < lines.length; i++) {
108
+ const line = lines[i] ?? "";
109
+ if (line.trim() === "")
110
+ continue;
111
+ if (countLeadingSpaces(line) <= indentThreshold)
112
+ return i;
113
+ }
114
+ return lines.length;
115
+ }
116
+ const packEnd = findBoundary(pack.index + 1, itemIndent);
117
+ const configIndent = itemIndent + 2;
118
+ const configRe = /^config:\s*(#.*)?$/;
119
+ let configIdx = -1;
120
+ for (let i = pack.index + 1; i < packEnd; i++) {
121
+ const line = lines[i] ?? "";
122
+ if (line.trim() === "")
123
+ continue;
124
+ if (countLeadingSpaces(line) === configIndent && configRe.test(line.trim())) {
125
+ if (configIdx !== -1) {
126
+ return {
127
+ ok: false,
128
+ error: "found more than one `config:` key in the understanding-before-execution pack block; refusing (ambiguous)",
129
+ };
130
+ }
131
+ configIdx = i;
132
+ }
133
+ }
134
+ if (configIdx === -1) {
135
+ return {
136
+ ok: false,
137
+ error: "could not find a `config:` key in the understanding-before-execution pack block",
138
+ };
139
+ }
140
+ let lastContentIdx = configIdx;
141
+ let autoApprovePresent = false;
142
+ for (let i = configIdx + 1; i < packEnd; i++) {
143
+ const line = lines[i] ?? "";
144
+ const trimmed = line.trim();
145
+ if (trimmed === "")
146
+ continue;
147
+ const indent = countLeadingSpaces(line);
148
+ if (indent <= configIndent)
149
+ break;
150
+ lastContentIdx = i;
151
+ // Review round 3, F3: any line whose trimmed form starts with
152
+ // `auto_approve:` counts as "already present", not only the exact
153
+ // bare-key spelling `auto_approve:` with nothing else on the line.
154
+ // That exact-equality check missed a hand-applied flow-style value
155
+ // (`auto_approve: {when: [bypassPermissions], ...}`) and a bare key
156
+ // with a trailing comment (`auto_approve: # already configured`):
157
+ // both are schema-valid YAML for the same key, but neither passed
158
+ // `trimmed === "auto_approve:"`, so this verb would insert a SECOND
159
+ // `auto_approve` key and `parseYaml` below would throw "Map keys
160
+ // must be unique" uncaught (exit 70, a raw YAML message) instead of
161
+ // recognizing the upgrade as already applied.
162
+ // Known limit: a line starting with `auto_approve:` inside a block scalar
163
+ // under another key would also count as present; the verb then no-ops
164
+ // (fail-safe, never a corrupted manifest) rather than inserting twice.
165
+ if (trimmed.startsWith("auto_approve:"))
166
+ autoApprovePresent = true;
167
+ }
168
+ if (autoApprovePresent) {
169
+ return { ok: true, text: original, changed: false };
170
+ }
171
+ const snippetLines = renderAutoApproveSnippet(configIndent + 2).split("\n");
172
+ const insertAt = lastContentIdx + 1;
173
+ const next = [...lines.slice(0, insertAt), ...snippetLines, ...lines.slice(insertAt)];
174
+ return { ok: true, text: next.join(eol), changed: true };
175
+ }
176
+ /**
177
+ * `parseYaml`, but a parse failure on the PROPOSED (post-insertion) text
178
+ * surfaces as this verb's own refusal (`HarnessExitError`, `EX_FAIL`,
179
+ * naming the pack and that the proposed text did not parse) rather than
180
+ * an uncaught exception (review round 3, F3: before this wrapper, a
181
+ * proposal `applyAutoApproveUpgrade` mis-recognized as a genuine
182
+ * insertion (e.g. a duplicate key under a different quoting style this
183
+ * heuristic does not special-case) reached the operator as a raw
184
+ * "Map keys must be unique" crash at exit 70 instead of a normal
185
+ * refusal). `original` is never passed here: it is the operator's own
186
+ * file, already on disk, and is not re-validated by this verb.
187
+ */
188
+ function parseProposedYamlOrRefuse(text, name, context) {
189
+ try {
190
+ return parseYaml(text);
191
+ }
192
+ catch (err) {
193
+ throw new HarnessExitError(`harness pack upgrade: proposed manifest for pack ${JSON.stringify(name)} did not parse as YAML (${context}): ${err instanceof Error ? err.message : String(err)}`, EX_FAIL);
194
+ }
195
+ }
196
+ /**
197
+ * `harness pack upgrade <name>` implementation. `name` is validated
198
+ * against the (currently one-entry) set of known upgrades before any
199
+ * file I/O; an unknown name refuses with `EX_FAIL` rather than silently
200
+ * doing nothing.
201
+ */
202
+ export async function packUpgrade(name, opts = {}) {
203
+ if (name !== "understanding-before-execution") {
204
+ throw new HarnessExitError(`harness pack upgrade does not support ${JSON.stringify(name)} yet; only "understanding-before-execution" (auto_approve default, task 8f637efd) is wired.`, EX_FAIL);
205
+ }
206
+ const target = resolveTargetPath(opts);
207
+ if (!fs.existsSync(target)) {
208
+ throw new HarnessExitError(`harness manifest not found at ${target}; run \`harness init\` first`, EX_NOINPUT);
209
+ }
210
+ const original = fs.readFileSync(target, "utf8");
211
+ const result = applyAutoApproveUpgrade(original);
212
+ if (!result.ok) {
213
+ throw new HarnessExitError(`harness pack upgrade: ${result.error}`, EX_FAIL);
214
+ }
215
+ const diff = unifiedDiff({
216
+ fileName: path.basename(target),
217
+ oldText: original,
218
+ newText: result.text,
219
+ oldHeader: "current",
220
+ newHeader: "proposed",
221
+ });
222
+ if (!result.changed) {
223
+ return { path: target, name, diff, applied: false, alreadyPresent: true };
224
+ }
225
+ // Schema gate before ever touching disk, mirroring `pack add` / `pack
226
+ // reseed`: catches an insertion that would somehow produce an invalid
227
+ // manifest (e.g. a config: key this heuristic mis-located) before it
228
+ // reaches the operator's file.
229
+ const schemaResult = validateBeforeWrite(parseProposedYamlOrRefuse(result.text, name, "post-insertion validation"));
230
+ if (!schemaResult.ok) {
231
+ throw new HarnessExitError(`proposed manifest fails schema validation:\n${formatValidationErrors(schemaResult.errors)}`, EX_FAIL);
232
+ }
233
+ if (opts.dryRun) {
234
+ return { path: target, name, diff, applied: false, alreadyPresent: false };
235
+ }
236
+ const lockPath = path.join(path.dirname(target), LOCK_BASENAME);
237
+ // Review round 3, F4: whether the locked callback actually WROTE is
238
+ // tracked here rather than assumed. The pre-lock read above can be
239
+ // stale by the time the lock is acquired: if a concurrent writer
240
+ // already inserted the block, the callback below returns early
241
+ // (`recomputed.changed === false`) without writing anything, and the
242
+ // result reported to the caller/CLI must say so (`applied: false,
243
+ // alreadyPresent: true`, so `harness pack upgrade` prints the
244
+ // "already carries this upgrade" message) instead of the hardcoded
245
+ // `applied: true` this used to return unconditionally.
246
+ let wroteUnderLock = false;
247
+ await withFileLock(lockPath, () => {
248
+ // Re-read and recompute under the lock (mirrors `pack add`): a
249
+ // concurrent writer may have inserted the block (or changed the
250
+ // file entirely) between the pre-lock read above and now.
251
+ const current = fs.readFileSync(target, "utf8");
252
+ const recomputed = applyAutoApproveUpgrade(current);
253
+ if (!recomputed.ok) {
254
+ throw new HarnessExitError(`harness pack upgrade: ${recomputed.error}`, EX_FAIL);
255
+ }
256
+ if (!recomputed.changed)
257
+ return; // raced: someone else already inserted it
258
+ const recheck = validateBeforeWrite(parseProposedYamlOrRefuse(recomputed.text, name, "post-insertion validation after lock acquisition"));
259
+ if (!recheck.ok) {
260
+ throw new HarnessExitError(`proposed manifest fails schema validation after lock acquisition:\n${formatValidationErrors(recheck.errors)}`, EX_FAIL);
261
+ }
262
+ atomicWriteFile(target, recomputed.text);
263
+ wroteUnderLock = true;
264
+ });
265
+ return {
266
+ path: target,
267
+ name,
268
+ diff,
269
+ applied: wroteUnderLock,
270
+ alreadyPresent: !wroteUnderLock,
271
+ };
272
+ }
273
+ //# sourceMappingURL=upgrade.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upgrade.js","sourceRoot":"","sources":["../../../src/cli/pack/upgrade.ts"],"names":[],"mappings":"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"}
@@ -42,6 +42,14 @@ export interface RecordReviewOptions extends RecordCommonOptions {
42
42
  base?: string;
43
43
  /** Explicit branch override (otherwise resolved via resolveGitContext(cwd)). */
44
44
  branch?: string;
45
+ /**
46
+ * agent-tasks task id for the `review:<task-id>` tag the two task-scoped
47
+ * merge gates read (`review-before-task-merge` /
48
+ * `review-before-task-finish-automerge`, task 2699b476). Optional: the
49
+ * PR/branch/base tags are what the pull_requests_merge and `gh pr merge`
50
+ * gates read, and an operator on those surfaces has no task id to pass.
51
+ */
52
+ task?: string;
45
53
  /** Free-form review summary — required, non-empty. */
46
54
  summary: string;
47
55
  }
@@ -29,6 +29,11 @@ import { resolveManifestLedgerWriter } from "../../runtime/ledger-writer.js";
29
29
  import { resolveReadSessionId, } from "../../runtime/session-id.js";
30
30
  import { EX_FAIL, EX_USAGE } from "../exit-codes.js";
31
31
  import { loadManifest } from "../loader.js";
32
+ // U+2014 EM DASH, written as an escape so the literal never appears in
33
+ // source. The emitted fact content is byte-identical to what `harness
34
+ // record review` has always written; every gate reads the tags before it,
35
+ // never this separator.
36
+ const TAG_SUMMARY_SEPARATOR = "\u2014";
32
37
  const LEDGER_SOURCE_REVIEW = "harness-record-review";
33
38
  const LEDGER_SOURCE_REVIEW_SUBAGENT = "harness-record-review-subagent";
34
39
  const LEDGER_SOURCE_DOGFOOD = "harness-record-dogfood";
@@ -80,6 +85,20 @@ function initRecordVerb(opts, verbName) {
80
85
  };
81
86
  return { note, cwd: opts.cwd ?? process.cwd(), sessionId: resolveSession(opts) };
82
87
  }
88
+ /**
89
+ * The one shared "this flag was misused" failure shape: warn on stderr and
90
+ * hand back the ready-to-`return` EX_USAGE `RecordResult`. Extracted when
91
+ * `optionalTagValue` (task 2699b476) grew the second copy of this
92
+ * five-line construction and the duplication fitness function
93
+ * (`scripts/check-duplication.mjs`) flagged it.
94
+ */
95
+ function usageFailure(reason, sessionId, note) {
96
+ note(reason);
97
+ return {
98
+ ok: false,
99
+ result: { exitCode: EX_USAGE, wrote: false, content: "", sessionId, branch: "", reason },
100
+ };
101
+ }
83
102
  /**
84
103
  * Trim `value` and refuse it if empty (a required flag / positional
85
104
  * argument left blank). Returns the ready-to-`return`ed EX_USAGE
@@ -90,12 +109,25 @@ function initRecordVerb(opts, verbName) {
90
109
  function requireNonEmpty(value, flagLabel, sessionId, note) {
91
110
  const trimmed = (value ?? "").trim();
92
111
  if (trimmed.length === 0) {
93
- const reason = `${flagLabel} must not be empty`;
94
- note(reason);
95
- return {
96
- ok: false,
97
- result: { exitCode: EX_USAGE, wrote: false, content: "", sessionId, branch: "", reason },
98
- };
112
+ return usageFailure(`${flagLabel} must not be empty`, sessionId, note);
113
+ }
114
+ return { ok: true, value: trimmed };
115
+ }
116
+ /**
117
+ * An OPTIONAL tag value: absent stays absent, present must be a non-empty
118
+ * token with no internal whitespace. The shape check is deliberately loose
119
+ * (task 2699b476): the id only namespaces a ledger tag, so anything the
120
+ * gate's `${TASK_ID}` substitution can compare against is acceptable, but
121
+ * a value carrying whitespace would split into two tags in the fact
122
+ * content and silently satisfy a gate keyed on the first half.
123
+ */
124
+ function optionalTagValue(value, flagLabel, sessionId, note) {
125
+ if (value === undefined)
126
+ return { ok: true, value: undefined };
127
+ const trimmed = value.trim();
128
+ if (trimmed.length === 0 || /\s/.test(trimmed)) {
129
+ return usageFailure(`${flagLabel} must be a non-empty value with no whitespace ` +
130
+ `(it namespaces one ledger tag); got ${JSON.stringify(value)}`, sessionId, note);
99
131
  }
100
132
  return { ok: true, value: trimmed };
101
133
  }
@@ -177,8 +209,24 @@ export async function runRecordReview(opts) {
177
209
  if (!branchResult.ok)
178
210
  return branchResult.result;
179
211
  const branch = branchResult.branch;
212
+ const taskResult = optionalTagValue(opts.task, "--task", sessionId, note);
213
+ if (!taskResult.ok)
214
+ return taskResult.result;
215
+ const task = taskResult.value;
180
216
  const base = resolveBase(cwd, opts.base, note);
181
- const content = `review:${pr} review:${branch}${base ? ` review:${base}` : ""} — ${summary}`;
217
+ // One fact, every tag family a merge/PR gate can key on: the PR number,
218
+ // the working branch, the base branch, and (task 2699b476) the
219
+ // agent-tasks task id the two task-scoped merge gates read. Recording a
220
+ // review once therefore satisfies whichever surface actually fires,
221
+ // instead of asking the operator to predict it (docs/CLI.md, "The
222
+ // merge-surface trap"). TAG_SUMMARY_SEPARATOR keeps the emitted content
223
+ // byte-identical to what this verb has always written.
224
+ const tags = [`review:${pr}`, `review:${branch}`];
225
+ if (base !== undefined)
226
+ tags.push(`review:${base}`);
227
+ if (task !== undefined)
228
+ tags.push(`review:${task}`);
229
+ const content = `${tags.join(" ")} ${TAG_SUMMARY_SEPARATOR} ${summary}`;
182
230
  return finishRecordWrite(opts, sessionId, branch, LEDGER_SOURCE_REVIEW, content, note);
183
231
  }
184
232
  export async function runRecordReviewSubagent(opts) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/record/index.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,gEAAgE;AAChE,oEAAoE;AACpE,+DAA+D;AAC/D,gDAAgD;AAChD,EAAE;AACF,qEAAqE;AACrE,sEAAsE;AACtE,oEAAoE;AACpE,mEAAmE;AACnE,uEAAuE;AACvE,oEAAoE;AACpE,mEAAmE;AACnE,sEAAsE;AACtE,sEAAsE;AACtE,qEAAqE;AACrE,mCAAmC;AACnC,EAAE;AACF,qEAAqE;AACrE,kEAAkE;AAClE,wEAAwE;AACxE,gEAAgE;AAChE,wEAAwE;AACxE,uEAAuE;AACvE,mEAAmE;AACnE,6BAA6B;AAE7B,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,2BAA2B,EAAsB,MAAM,gCAAgC,CAAC;AACjG,OAAO,EACL,oBAAoB,GAErB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAsB,MAAM,cAAc,CAAC;AAEhE,MAAM,oBAAoB,GAAG,uBAAuB,CAAC;AACrD,MAAM,6BAA6B,GAAG,gCAAgC,CAAC;AACvE,MAAM,qBAAqB,GAAG,wBAAwB,CAAC;AAsCvD,SAAS,cAAc,CAAC,IAAyB;IAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,IAAI,oBAAoB,CAAC;IAC5D,OAAO,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AACnC,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,eAAe,CAC5B,IAAyB,EACzB,SAAiB,EACjB,MAAc,EACd,OAAe;IAEf,IAAI,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;IACnC,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,IAAI,QAAkB,CAAC;QACvB,IAAI,CAAC;YACH,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC;QACzC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,yBAA0B,GAAa,CAAC,OAAO,EAAE,EAAE,CAAC;QAClF,CAAC;QACD,MAAM,QAAQ,GAAG,2BAA2B,CAAC,QAAQ,EAAE;YACrD,GAAG,CAAC,IAAI,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACzF,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,mBAAmB,MAAM,MAAM,EAAE,CAAC;QAClF,CAAC;QACD,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC;IAC/B,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;IACjE,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,wBAAwB,MAAM,CAAC,MAAM,IAAI,eAAe,EAAE,EAAE,CAAC;IAC3F,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;AACtB,CAAC;AAED;;;;;;GAMG;AACH,SAAS,cAAc,CACrB,IAAyB,EACzB,QAAgB;IAEhB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC;IAC7C,MAAM,IAAI,GAAG,CAAC,GAAW,EAAQ,EAAE;QACjC,MAAM,CAAC,KAAK,CAAC,kBAAkB,QAAQ,KAAK,GAAG,IAAI,CAAC,CAAC;IACvD,CAAC,CAAC;IACF,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;AACnF,CAAC;AAED;;;;;;GAMG;AACH,SAAS,eAAe,CACtB,KAAyB,EACzB,SAAiB,EACjB,SAAiB,EACjB,IAA2B;IAE3B,MAAM,OAAO,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACrC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,GAAG,SAAS,oBAAoB,CAAC;QAChD,IAAI,CAAC,MAAM,CAAC,CAAC;QACb,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE;SACzF,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AACtC,CAAC;AAED;;;;;;GAMG;AACH,SAAS,qBAAqB,CAC5B,GAAW,EACX,cAAkC,EAClC,SAAiB,EACjB,IAA2B;IAE3B,MAAM,UAAU,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,UAAU,CAAC,MAAM,CAAC;IAClE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,MAAM,GACV,qGAAqG,CAAC;QACxG,IAAI,CAAC,MAAM,CAAC,CAAC;QACb,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE;SACxF,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAC9B,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,iBAAiB,CAC9B,IAAyB,EACzB,SAAiB,EACjB,MAAc,EACd,MAAc,EACd,OAAe,EACf,IAA2B;IAE3B,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IACxE,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;QAChB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACrB,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;IACjG,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;AAClE,CAAC;AAED,8EAA8E;AAC9E,wEAAwE;AACxE,kEAAkE;AAClE,mEAAmE;AACnE,wEAAwE;AACxE,sEAAsE;AACtE,2EAA2E;AAC3E,wEAAwE;AACxE,wEAAwE;AACxE,aAAa;AACb,8EAA8E;AAE9E;;;;;GAKG;AACH,SAAS,WAAW,CAClB,GAAW,EACX,YAAgC,EAChC,IAA2B;IAE3B,MAAM,IAAI,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACzC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACjC,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACzC,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,IAAI,GAAG,qBAAqB,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;QAC7D,IAAI,IAAI;YAAE,OAAO,IAAI,CAAC;IACxB,CAAC;IACD,IAAI,CACF,iEAAiE;QAC/D,6EAA6E;QAC7E,+CAA+C,CAClD,CAAC;IACF,OAAO,SAAS,CAAC;AACnB,CAAC;AAiBD,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAAyB;IAC7D,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,cAAc,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAEhE,MAAM,aAAa,GAAG,eAAe,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IAChF,IAAI,CAAC,aAAa,CAAC,EAAE;QAAE,OAAO,aAAa,CAAC,MAAM,CAAC;IACnD,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC;IAEpC,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IACnE,IAAI,CAAC,QAAQ,CAAC,EAAE;QAAE,OAAO,QAAQ,CAAC,MAAM,CAAC;IACzC,MAAM,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC;IAE1B,MAAM,YAAY,GAAG,qBAAqB,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IAC9E,IAAI,CAAC,YAAY,CAAC,EAAE;QAAE,OAAO,YAAY,CAAC,MAAM,CAAC;IACjD,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC;IAEnC,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC/C,MAAM,OAAO,GAAG,UAAU,EAAE,WAAW,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,OAAO,EAAE,CAAC;IAE7F,OAAO,iBAAiB,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,oBAAoB,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;AACzF,CAAC;AAiBD,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,IAAiC;IAEjC,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,cAAc,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;IAEzE,MAAM,UAAU,GAAG,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IACzE,IAAI,CAAC,UAAU,CAAC,EAAE;QAAE,OAAO,UAAU,CAAC,MAAM,CAAC;IAC7C,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC;IAE9B,MAAM,aAAa,GAAG,eAAe,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IAClF,IAAI,CAAC,aAAa,CAAC,EAAE;QAAE,OAAO,aAAa,CAAC,MAAM,CAAC;IACnD,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC;IAEpC,MAAM,YAAY,GAAG,qBAAqB,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IAC9E,IAAI,CAAC,YAAY,CAAC,EAAE;QAAE,OAAO,YAAY,CAAC,MAAM,CAAC;IACjD,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC;IAEnC,MAAM,OAAO,GAAG,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5E,MAAM,OAAO,GAAG,mBAAmB,IAAI,oBAAoB,MAAM,YAAY,OAAO,GAClF,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,OAAO,EAAE,CAAC,CAAC,CAAC,EACzC,EAAE,CAAC;IAEH,OAAO,iBAAiB,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,6BAA6B,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;AAClG,CAAC;AAWD,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAA0B;IAC/D,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,cAAc,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAE5D,MAAM,aAAa,GAAG,eAAe,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IAChF,IAAI,CAAC,aAAa,CAAC,EAAE;QAAE,OAAO,aAAa,CAAC,MAAM,CAAC;IACnD,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC;IAEpC,MAAM,OAAO,GAAG,WAAW,SAAS,MAAM,OAAO,EAAE,CAAC;IAEpD,OAAO,iBAAiB,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,qBAAqB,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;AACtF,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/record/index.ts"],"names":[],"mappings":"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"}
@@ -10,7 +10,7 @@ import { PACK_NAME as UNDERSTANDING_BEFORE_EXECUTION_PACK_NAME } from "../../pol
10
10
  import { isMeasuredPermissionModeFor, measuredPermissionModeLiteralsFor, } from "../../policy-packs/builtin/understanding-before-execution/measured-permission-modes.js";
11
11
  import { AUTO_APPROVE_HARNESS_VALUES, DEFAULT_AUTO_APPROVE_HARNESSES, } from "../../policy-packs/builtin/understanding-before-execution/auto-approve.js";
12
12
  import { DEFAULT_SAFE_DELETION_ROOTS } from "../../schema/risk.js";
13
- import { deriveWorkflowGatePolicies, findWeakGatePolicyOverlaps, handAuthoredPolicies, MERGE_BASH_MATCH, MERGE_MCP_MATCH, REVIEW_EVIDENCE_HOOK_BASH, REVIEW_EVIDENCE_HOOK_MCP, workflowRequiresMergeGate, } from "../../runtime/workflow-policies.js";
13
+ import { deriveWorkflowGatePolicies, findWeakGatePolicyOverlaps, handAuthoredPolicies, MERGE_BASH_MATCH, MERGE_MCP_MATCH, REVIEW_EVIDENCE_HOOK_BASH, REVIEW_EVIDENCE_HOOK_MCP, REVIEW_EVIDENCE_HOOK_TASK_FINISH, REVIEW_EVIDENCE_HOOK_TASK_MERGE, workflowRequiresMergeGate, } from "../../runtime/workflow-policies.js";
14
14
  const DEFAULT_RUNTIME_BUILTINS = [
15
15
  "Read",
16
16
  "Edit",
@@ -344,17 +344,69 @@ export function checkWorkflowGateWiring(manifest) {
344
344
  if (missing.length > 0) {
345
345
  problems.unshift(`hooks[] is missing ${missing.join(" and ")}`);
346
346
  }
347
- if (problems.length === 0)
347
+ const errors = problems.length === 0
348
+ ? []
349
+ : offending.map((wf) => ({
350
+ severity: "error",
351
+ path: "workflows",
352
+ message: `workflow "${wf.name}" declares a review_subagent step with spawn: "required" ` +
353
+ `followed by a merge step, but the runtime merge gate is not wired: ${problems.join("; ")}. ` +
354
+ "Without both hooks correctly wired, harness policy intercept never derives this " +
355
+ "workflow's merge-gate policy and the merge is NOT blocked (silent non-enforcement). " +
356
+ "See docs/for-agents.md, or src/cli/init/templates.ts's require-review-evidence / " +
357
+ 'require-review-evidence-bash entries, or drop spawn: "required".',
358
+ }));
359
+ return [...errors, ...checkTaskVerbGateWiring(manifest, offending)];
360
+ }
361
+ /**
362
+ * MEDIUM security (review round 1, task 2699b476 round 2): a manifest can
363
+ * wire the ORIGINAL pair of review-evidence hooks
364
+ * (`require-review-evidence` / `require-review-evidence-bash`, gating
365
+ * `mcp__agent-tasks__pull_requests_merge` and `gh pr merge`) without ever
366
+ * adding the two task-scoped ones task 2699b476 introduced
367
+ * (`require-review-evidence-task-merge` / `require-review-evidence-task-finish`,
368
+ * gating `mcp__agent-tasks__task_merge` and `task_finish { autoMerge: true }`).
369
+ * `deriveWorkflowGatePolicies` derives the task-scoped gate ONLY when its
370
+ * own hook is present (same "quietly returns nothing" shape
371
+ * `checkWorkflowGateWiring` already guards for the original pair), so a
372
+ * manifest predating that task keeps the two newer verbs completely
373
+ * uncovered: a PR can be merged via `task_merge` or an auto-merging
374
+ * `task_finish` with no recorded review at all, while `harness validate`
375
+ * stayed silent about it. This is a `warning`, not an `error`, because the
376
+ * ORIGINAL surfaces (`pull_requests_merge`, `gh pr merge`) are still
377
+ * enforced when this fires: the gap is narrower than the fully-unwired
378
+ * case above, but still silent non-enforcement for the two verbs it names.
379
+ */
380
+ function checkTaskVerbGateWiring(manifest, offending) {
381
+ const mcpHook = manifest.hooks.find((h) => h.name === REVIEW_EVIDENCE_HOOK_MCP);
382
+ const bashHook = manifest.hooks.find((h) => h.name === REVIEW_EVIDENCE_HOOK_BASH);
383
+ if (!mcpHook || !bashHook)
384
+ return [];
385
+ const taskMergeHook = manifest.hooks.find((h) => h.name === REVIEW_EVIDENCE_HOOK_TASK_MERGE);
386
+ const taskFinishHook = manifest.hooks.find((h) => h.name === REVIEW_EVIDENCE_HOOK_TASK_FINISH);
387
+ const uncoveredVerbs = [];
388
+ const missingHookNames = [];
389
+ if (!taskMergeHook) {
390
+ uncoveredVerbs.push("mcp__agent-tasks__task_merge");
391
+ missingHookNames.push(`"${REVIEW_EVIDENCE_HOOK_TASK_MERGE}"`);
392
+ }
393
+ if (!taskFinishHook) {
394
+ uncoveredVerbs.push("mcp__agent-tasks__task_finish (autoMerge: true)");
395
+ missingHookNames.push(`"${REVIEW_EVIDENCE_HOOK_TASK_FINISH}"`);
396
+ }
397
+ if (uncoveredVerbs.length === 0)
348
398
  return [];
349
399
  return offending.map((wf) => ({
350
- severity: "error",
400
+ severity: "warning",
351
401
  path: "workflows",
352
- message: `workflow "${wf.name}" declares a review_subagent step with spawn: "required" ` +
353
- `followed by a merge step, but the runtime merge gate is not wired: ${problems.join("; ")}. ` +
354
- "Without both hooks correctly wired, harness policy intercept never derives this " +
355
- "workflow's merge-gate policy and the merge is NOT blocked (silent non-enforcement). " +
356
- "See docs/for-agents.md, or src/cli/init/templates.ts's require-review-evidence / " +
357
- 'require-review-evidence-bash entries, or drop spawn: "required".',
402
+ message: `workflow "${wf.name}" wires the review-evidence gate for mcp__agent-tasks__pull_requests_merge ` +
403
+ `and gh pr merge, but not for ${uncoveredVerbs.join(" or ")}: ` +
404
+ `hooks[] is missing ${missingHookNames.join(" and ")}. ` +
405
+ "Without them harness policy intercept never derives the task-scoped merge gate (task 2699b476) " +
406
+ "and a PR can be merged through those verbs with no recorded review, even though the original " +
407
+ "pull_requests_merge / gh pr merge surfaces are still gated. See docs/for-agents.md, or " +
408
+ "src/cli/init/templates.ts's require-review-evidence-task-merge / " +
409
+ "require-review-evidence-task-finish entries.",
358
410
  }));
359
411
  }
360
412
  /**