@lannguyensi/harness 0.48.0 → 0.50.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 (93) hide show
  1. package/CHANGELOG.md +825 -0
  2. package/dist/cli/add/index.js +15 -3
  3. package/dist/cli/add/index.js.map +1 -1
  4. package/dist/cli/apply/apply.js +19 -3
  5. package/dist/cli/apply/apply.js.map +1 -1
  6. package/dist/cli/approve/risk.d.ts +28 -2
  7. package/dist/cli/approve/risk.js +14 -4
  8. package/dist/cli/approve/risk.js.map +1 -1
  9. package/dist/cli/diff/index.js +22 -1
  10. package/dist/cli/diff/index.js.map +1 -1
  11. package/dist/cli/doctor/format.js +29 -2
  12. package/dist/cli/doctor/format.js.map +1 -1
  13. package/dist/cli/doctor/index.js +62 -3
  14. package/dist/cli/doctor/index.js.map +1 -1
  15. package/dist/cli/doctor/types.d.ts +57 -0
  16. package/dist/cli/explain-policy.d.ts +4 -1
  17. package/dist/cli/explain-policy.js +12 -2
  18. package/dist/cli/explain-policy.js.map +1 -1
  19. package/dist/cli/export.js +12 -1
  20. package/dist/cli/export.js.map +1 -1
  21. package/dist/cli/index.js +29 -7
  22. package/dist/cli/index.js.map +1 -1
  23. package/dist/cli/init/templates.d.ts +34 -1
  24. package/dist/cli/init/templates.js +137 -3
  25. package/dist/cli/init/templates.js.map +1 -1
  26. package/dist/cli/list.js +6 -0
  27. package/dist/cli/list.js.map +1 -1
  28. package/dist/cli/loader.js +15 -0
  29. package/dist/cli/loader.js.map +1 -1
  30. package/dist/cli/pack/hook-codex-pre-tool-use.js +11 -6
  31. package/dist/cli/pack/hook-codex-pre-tool-use.js.map +1 -1
  32. package/dist/cli/pack/hook-post-tool-use.d.ts +6 -4
  33. package/dist/cli/pack/hook-post-tool-use.js.map +1 -1
  34. package/dist/cli/pack/hook-pre-tool-use.js +23 -22
  35. package/dist/cli/pack/hook-pre-tool-use.js.map +1 -1
  36. package/dist/cli/policy/intercept.js +59 -9
  37. package/dist/cli/policy/intercept.js.map +1 -1
  38. package/dist/cli/remove/index.d.ts +12 -0
  39. package/dist/cli/remove/index.js +89 -0
  40. package/dist/cli/remove/index.js.map +1 -1
  41. package/dist/cli/validate/checks.d.ts +49 -0
  42. package/dist/cli/validate/checks.js +416 -9
  43. package/dist/cli/validate/checks.js.map +1 -1
  44. package/dist/cli/validate/index.js +11 -0
  45. package/dist/cli/validate/index.js.map +1 -1
  46. package/dist/policy-packs/builtin/understanding-before-execution/index.d.ts +2 -2
  47. package/dist/policy-packs/builtin/understanding-before-execution/index.js +33 -27
  48. package/dist/policy-packs/builtin/understanding-before-execution/index.js.map +1 -1
  49. package/dist/policy-packs/builtin/understanding-before-execution/markers.js +2 -2
  50. package/dist/policy-packs/builtin/understanding-before-execution/markers.js.map +1 -1
  51. package/dist/policy-packs/builtin/understanding-before-execution/persisted-reports.d.ts +46 -8
  52. package/dist/policy-packs/builtin/understanding-before-execution/persisted-reports.js +71 -12
  53. package/dist/policy-packs/builtin/understanding-before-execution/persisted-reports.js.map +1 -1
  54. package/dist/policy-packs/builtin/understanding-before-execution/post-tool-use-boundary.js +6 -3
  55. package/dist/policy-packs/builtin/understanding-before-execution/post-tool-use-boundary.js.map +1 -1
  56. package/dist/policy-packs/builtin/understanding-before-execution.js +9 -8
  57. package/dist/policy-packs/builtin/understanding-before-execution.js.map +1 -1
  58. package/dist/runtime/bash-prefix-parse.d.ts +12 -1
  59. package/dist/runtime/bash-prefix-parse.js +2 -2
  60. package/dist/runtime/bash-prefix-parse.js.map +1 -1
  61. package/dist/runtime/command-normalize.d.ts +112 -0
  62. package/dist/runtime/command-normalize.js +169 -55
  63. package/dist/runtime/command-normalize.js.map +1 -1
  64. package/dist/runtime/deletion-target-resolve.d.ts +28 -0
  65. package/dist/runtime/deletion-target-resolve.js +1055 -0
  66. package/dist/runtime/deletion-target-resolve.js.map +1 -0
  67. package/dist/runtime/index.d.ts +1 -0
  68. package/dist/runtime/index.js +1 -0
  69. package/dist/runtime/index.js.map +1 -1
  70. package/dist/runtime/intercept.js +17 -1
  71. package/dist/runtime/intercept.js.map +1 -1
  72. package/dist/runtime/kubectl-target-parse.d.ts +31 -0
  73. package/dist/runtime/kubectl-target-parse.js +249 -0
  74. package/dist/runtime/kubectl-target-parse.js.map +1 -0
  75. package/dist/runtime/read-only-bash.d.ts +11 -0
  76. package/dist/runtime/read-only-bash.js +288 -7
  77. package/dist/runtime/read-only-bash.js.map +1 -1
  78. package/dist/runtime/risk-classifier.js +14 -1
  79. package/dist/runtime/risk-classifier.js.map +1 -1
  80. package/dist/runtime/when-eval.d.ts +11 -2
  81. package/dist/runtime/when-eval.js +25 -0
  82. package/dist/runtime/when-eval.js.map +1 -1
  83. package/dist/runtime/workflow-policies.d.ts +164 -0
  84. package/dist/runtime/workflow-policies.js +439 -0
  85. package/dist/runtime/workflow-policies.js.map +1 -0
  86. package/dist/schema/index.d.ts +24 -0
  87. package/dist/schema/policies.d.ts +25 -0
  88. package/dist/schema/policies.js +29 -0
  89. package/dist/schema/policies.js.map +1 -1
  90. package/dist/schema/risk.d.ts +6 -0
  91. package/dist/schema/risk.js +80 -0
  92. package/dist/schema/risk.js.map +1 -1
  93. package/package.json +1 -1
@@ -6,6 +6,8 @@ import { resolveHomeDir } from "../../runtime/home-dir.js";
6
6
  import { withFileLock } from "../../io/lock.js";
7
7
  import { unifiedDiff } from "../../io/patch.js";
8
8
  import { formatValidationErrors, validateBeforeWrite, } from "../../io/validate-before-write.js";
9
+ import { ManifestParseError, parseManifest } from "../../schema/index.js";
10
+ import { deriveWorkflowGatePolicies, REVIEW_EVIDENCE_HOOK_BASH, REVIEW_EVIDENCE_HOOK_MCP, } from "../../runtime/workflow-policies.js";
9
11
  import { EX_FAIL, EX_NOINPUT, HarnessExitError } from "../exit-codes.js";
10
12
  import { applyRemove, planRemove } from "./mutate.js";
11
13
  const DEFAULT_BASENAME = "harness.yaml";
@@ -20,6 +22,66 @@ function formatNameList(names) {
20
22
  return "(none declared)";
21
23
  return names.map((n) => ` - ${n}`).join("\n");
22
24
  }
25
+ /**
26
+ * F8 (review round 2, 99f47307 Slice 1): `planRemove`'s
27
+ * `referencingPolicies` only ever sees HAND-authored `policies:` entries
28
+ * (it walks the raw YAML document). A `require-review-evidence[-bash]`
29
+ * hook referenced ONLY by a `workflows[]`-derived merge gate (no
30
+ * hand-authored policy names it) passed that check silently — `harness
31
+ * remove hook require-review-evidence` would delete the hook and the
32
+ * next `harness apply`/`policy intercept` would derive nothing for it
33
+ * (hasWiredMergeGateHooks requires BOTH hooks), a silent regression from
34
+ * "enforced" to "not enforced" for every workflow with `spawn:
35
+ * "required"`. This consults the SAME derivation `withDerivedPolicies`
36
+ * uses (`deriveWorkflowGatePolicies`) against the manifest as it stands
37
+ * BEFORE the removal, and returns the names of workflows whose derived
38
+ * gate references `hookName` — empty for any type/name that isn't one of
39
+ * the two evidence hooks, or when the manifest fails to parse (the
40
+ * existing schema-gate checks further down handle a malformed manifest;
41
+ * this is a best-effort pre-check, not the safety net).
42
+ */
43
+ function derivedGateReferencingWorkflows(yamlText, type, hookName) {
44
+ if (type !== "hook")
45
+ return [];
46
+ if (hookName !== REVIEW_EVIDENCE_HOOK_MCP && hookName !== REVIEW_EVIDENCE_HOOK_BASH)
47
+ return [];
48
+ let manifest;
49
+ try {
50
+ manifest = parseManifest(parseYaml(yamlText));
51
+ }
52
+ catch (err) {
53
+ if (err instanceof ManifestParseError)
54
+ return [];
55
+ throw err;
56
+ }
57
+ // Non-empty only when BOTH evidence hooks are currently wired (see
58
+ // `hasWiredMergeGateHooks`) — if only one is present already, no
59
+ // workflow has an enforced gate to lose from removing the other.
60
+ const derivedPolicies = deriveWorkflowGatePolicies(manifest);
61
+ if (derivedPolicies.length === 0)
62
+ return [];
63
+ // F5 (review round 3 follow-up, 99f47307 Slice 1): this used to return
64
+ // every workflow matching `workflowRequiresMergeGate` (the SHAPE test),
65
+ // not the workflows the derivation actually produced a policy for (the
66
+ // dedupe an equivalent hand-authored policy already covers on the same
67
+ // surface derives NOTHING for; see `deriveWorkflowGates`'s `seen` set).
68
+ // A manifest with two qualifying workflows where only one is actually
69
+ // derived would name both here even though only one's gate is really
70
+ // lost. Project the workflow name back out of each derived policy's
71
+ // name instead (`workflow:<name>:review-before-merge[-bash]`), filtered
72
+ // to the hook being removed so a `require-review-evidence`-only removal
73
+ // does not also name workflows whose gate only depends on the bash hook.
74
+ const affected = new Set();
75
+ for (const policy of derivedPolicies) {
76
+ if (policy.hook !== hookName)
77
+ continue;
78
+ const match = /^workflow:(.+):review-before-merge(?:-bash)?$/.exec(policy.name);
79
+ const workflowName = match?.[1];
80
+ if (workflowName !== undefined)
81
+ affected.add(workflowName);
82
+ }
83
+ return manifest.workflows.filter((wf) => affected.has(wf.name)).map((wf) => wf.name);
84
+ }
23
85
  export async function remove(type, name, opts = {}) {
24
86
  const target = resolveTargetPath(opts);
25
87
  if (!fs.existsSync(target)) {
@@ -35,6 +97,23 @@ export async function remove(type, name, opts = {}) {
35
97
  const verb = plan.referencingPolicies.length === 1 ? "policy" : "policies";
36
98
  throw new HarnessExitError(`${verb} ${refList} reference${plan.referencingPolicies.length === 1 ? "s" : ""} this hook; remove the ${verb} first or pass --force`, EX_FAIL);
37
99
  }
100
+ // F8 (review round 2, 99f47307 Slice 1): the check above only sees
101
+ // hand-authored `policies:` entries; a hook referenced ONLY by a
102
+ // workflows[]-derived merge gate must get the same protection, or
103
+ // `harness remove hook require-review-evidence` silently disables the
104
+ // gate for every workflow with `spawn: "required"` (no dangling
105
+ // schema reference to catch it afterwards — see
106
+ // `derivedGateReferencingWorkflows`'s header for why there is no
107
+ // schema-level safety net here the way there is for hand policies).
108
+ const derivedGateWorkflows = derivedGateReferencingWorkflows(original, type, name);
109
+ if (derivedGateWorkflows.length > 0 && !opts.force) {
110
+ const wfList = derivedGateWorkflows.map((n) => `"${n}"`).join(", ");
111
+ const verb = derivedGateWorkflows.length === 1 ? "workflow" : "workflows";
112
+ throw new HarnessExitError(`${verb} ${wfList} derive${derivedGateWorkflows.length === 1 ? "s" : ""} a runtime merge gate ` +
113
+ `from this hook (a review_subagent step with spawn: "required" followed by a merge step); ` +
114
+ `removing it would silently disable that gate. Drop spawn: "required" on the workflow step ` +
115
+ "first, or pass --force.", EX_FAIL);
116
+ }
38
117
  const proposed = applyRemove(original, type, name);
39
118
  const diff = unifiedDiff({
40
119
  fileName: path.basename(target),
@@ -52,6 +131,14 @@ export async function remove(type, name, opts = {}) {
52
131
  if (!schemaResult.ok) {
53
132
  throw new HarnessExitError(`proposed manifest fails schema validation:\n${formatValidationErrors(schemaResult.errors)}`, EX_FAIL);
54
133
  }
134
+ // derivedGateWorkflows is non-empty here only under --force (the
135
+ // pre-check above threw otherwise), on BOTH paths: unlike a dangling
136
+ // policy.hook reference, nothing downstream refuses a --force'd
137
+ // derived-gate removal (see `derivedGateReferencingWorkflows`), so the
138
+ // write path must report it too, not only the dry-run (F3, review
139
+ // round 3; the round-2 code hard-coded `[]` on the write path and the
140
+ // CLI never printed either).
141
+ const derivedGateReferences = derivedGateWorkflows;
55
142
  if (opts.dryRun) {
56
143
  // forcedReferences is informational on dry-run: it shows the user which
57
144
  // policies would have been overridden if the schema gate did not refuse.
@@ -64,6 +151,7 @@ export async function remove(type, name, opts = {}) {
64
151
  diff,
65
152
  applied: false,
66
153
  forcedReferences: opts.force ? plan.referencingPolicies : [],
154
+ derivedGateReferences,
67
155
  };
68
156
  }
69
157
  const lockPath = path.join(path.dirname(target), LOCK_BASENAME);
@@ -86,6 +174,7 @@ export async function remove(type, name, opts = {}) {
86
174
  // hook, so the only way to reach here with --force is when there are no
87
175
  // referencing policies to begin with.
88
176
  forcedReferences: [],
177
+ derivedGateReferences,
89
178
  };
90
179
  }
91
180
  export const KNOWN_REMOVE_TYPES = ["mcp", "cli", "skill", "hook"];
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/remove/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/remove/index.ts"],"names":[],"mappings":"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"}
@@ -20,6 +20,53 @@ declare function resolveOnPath(binary: string, pathEnv: string): string | null;
20
20
  declare function compareVersions(actual: string, required: string): number;
21
21
  export declare function checkPolicyGroundingMcp(manifest: Manifest): Diagnostic[];
22
22
  export declare function checkSolutionAcceptanceProducer(manifest: Manifest): Diagnostic[];
23
+ export declare function checkWorkflowGateWiring(manifest: Manifest): Diagnostic[];
24
+ /**
25
+ * F1 (review round 2): a hand-authored policy on the identical trigger
26
+ * surface + ledger_tag as a derived block gate, but weaker than it
27
+ * (`enforcement: "warn"`/`"require_approval"`, or `when:`-scoped), no
28
+ * longer suppresses the derived gate (see `isAtLeastAsStrongAsDerivedGate`
29
+ * in workflow-policies.ts) — both apply. This check surfaces that overlap
30
+ * as a warning so an operator reading the weaker policy does not mistake
31
+ * it for the ONLY gate on the surface.
32
+ */
33
+ export declare function checkWorkflowGateWeakOverlap(manifest: Manifest): Diagnostic[];
34
+ /**
35
+ * F6 (review round 2): a workflow that declares BOTH a `merge` step and a
36
+ * `review_subagent` step with `spawn: "required"`, but with the review
37
+ * step coming AFTER the merge step, derives no gate at all
38
+ * (`workflowRequiresMergeGate` only looks for review-then-merge). That
39
+ * ordering is likely a mistake (a review that runs after the PR already
40
+ * merged cannot gate it), but step-ordering validation in general is out
41
+ * of scope for this slice (module doc, src/runtime/workflow-policies.ts).
42
+ * This warns instead of silently doing nothing.
43
+ */
44
+ export declare function checkWorkflowMergeBeforeReview(manifest: Manifest): Diagnostic[];
45
+ /**
46
+ * Review round 3 (99f47307 Slice 1): a hand-authored policy whose name
47
+ * equals a derived policy's name (`workflow:<name>:review-before-merge[-
48
+ * bash]`) is not deduped by name (dedupe keys on surface, not name), so
49
+ * the derived view carries two policies with one name. This fires both
50
+ * when the hand-authored policy sits on a DIFFERENT surface (dedupe never
51
+ * even compares them), and when it sits on the SAME surface but is not
52
+ * `isAtLeastAsStrongAsDerivedGate` (weaker enforcement or a `when:` scope
53
+ * — that case IS a surface match, so `findWeakGatePolicyOverlaps` also
54
+ * reports it as an overlap; the two checks are not mutually exclusive).
55
+ * Either way the runtime evaluates both policies (fail-safe), but every
56
+ * by-name reader (`explain`, `explain-policy`, `audit`, `diff`'s
57
+ * name-keyed policy list) resolves the name to the hand-authored one and
58
+ * silently hides the derived gate. The schema's duplicate-name refinement
59
+ * cannot see this (it runs on the hand-authored view), so it is an error
60
+ * here.
61
+ */
62
+ export declare function checkWorkflowDerivedNameCollision(manifest: Manifest): Diagnostic[];
63
+ /**
64
+ * Every `workflows[]` check in one list, so `harness validate`
65
+ * (`runAssetChecks`) and `harness doctor`'s Workflows section run the
66
+ * SAME set (review round 3, 99f47307 Slice 1: doctor previously picked
67
+ * two of the three by hand and was missing `checkWorkflowMergeBeforeReview`).
68
+ */
69
+ export declare function checkWorkflows(manifest: Manifest): Diagnostic[];
23
70
  /**
24
71
  * Answers "is `relPath` git-ignored here?": `true` / `false`, or `null`
25
72
  * when the question has no answer (not a git repository, git not
@@ -37,7 +84,9 @@ export declare function createDefaultGitIgnoreProbe(cwd?: string): GitIgnoreProb
37
84
  export declare function checkSolutionAcceptanceKnobIgnored(manifest: Manifest, probe: GitIgnoreProbe): Diagnostic[];
38
85
  export declare function checkPolicySelfAttestation(manifest: Manifest): Diagnostic[];
39
86
  export declare function checkPolicyRiskWithoutEnvScope(manifest: Manifest): Diagnostic[];
87
+ export declare function checkSafeDeletionRootsSyntax(manifest: Manifest): Diagnostic[];
40
88
  export declare function checkTemplatePolicyDrift(manifest: Manifest): Diagnostic[];
89
+ export declare function checkTriggerBoundaryDrift(manifest: Manifest): Diagnostic[];
41
90
  export declare function checkHookBudgetLedgerMargin(manifest: Manifest): Diagnostic[];
42
91
  export declare function runAssetChecks(manifest: Manifest, opts?: CheckOptions): Diagnostic[];
43
92
  export declare const __testables: {