@orygn/opa-mcp 0.4.0 → 0.6.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 (236) hide show
  1. package/CHANGELOG.md +583 -4
  2. package/README.md +144 -98
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/cli.js +9 -3
  5. package/dist/cli.js.map +1 -1
  6. package/dist/config.d.ts +14 -4
  7. package/dist/config.d.ts.map +1 -1
  8. package/dist/config.js +91 -19
  9. package/dist/config.js.map +1 -1
  10. package/dist/constants.d.ts +1 -6
  11. package/dist/constants.d.ts.map +1 -1
  12. package/dist/constants.js +17 -3
  13. package/dist/constants.js.map +1 -1
  14. package/dist/lib/bundle-signatures.d.ts +23 -0
  15. package/dist/lib/bundle-signatures.d.ts.map +1 -0
  16. package/dist/lib/bundle-signatures.js +152 -0
  17. package/dist/lib/bundle-signatures.js.map +1 -0
  18. package/dist/lib/child-env.d.ts +9 -2
  19. package/dist/lib/child-env.d.ts.map +1 -1
  20. package/dist/lib/child-env.js +38 -6
  21. package/dist/lib/child-env.js.map +1 -1
  22. package/dist/lib/conftest-cli.d.ts +25 -10
  23. package/dist/lib/conftest-cli.d.ts.map +1 -1
  24. package/dist/lib/conftest-cli.js +233 -50
  25. package/dist/lib/conftest-cli.js.map +1 -1
  26. package/dist/lib/errors.d.ts +4 -5
  27. package/dist/lib/errors.d.ts.map +1 -1
  28. package/dist/lib/errors.js +15 -3
  29. package/dist/lib/errors.js.map +1 -1
  30. package/dist/lib/inline-paths.d.ts +37 -0
  31. package/dist/lib/inline-paths.d.ts.map +1 -0
  32. package/dist/lib/inline-paths.js +162 -0
  33. package/dist/lib/inline-paths.js.map +1 -0
  34. package/dist/lib/install-id.d.ts.map +1 -1
  35. package/dist/lib/install-id.js +18 -3
  36. package/dist/lib/install-id.js.map +1 -1
  37. package/dist/lib/json-stream.d.ts +26 -0
  38. package/dist/lib/json-stream.d.ts.map +1 -0
  39. package/dist/lib/json-stream.js +69 -0
  40. package/dist/lib/json-stream.js.map +1 -0
  41. package/dist/lib/opa-cli.d.ts +74 -16
  42. package/dist/lib/opa-cli.d.ts.map +1 -1
  43. package/dist/lib/opa-cli.js +107 -30
  44. package/dist/lib/opa-cli.js.map +1 -1
  45. package/dist/lib/opa-client.d.ts +27 -1
  46. package/dist/lib/opa-client.d.ts.map +1 -1
  47. package/dist/lib/opa-client.js +98 -14
  48. package/dist/lib/opa-client.js.map +1 -1
  49. package/dist/lib/opa-paths.d.ts +34 -0
  50. package/dist/lib/opa-paths.d.ts.map +1 -0
  51. package/dist/lib/opa-paths.js +101 -0
  52. package/dist/lib/opa-paths.js.map +1 -0
  53. package/dist/lib/output.d.ts.map +1 -1
  54. package/dist/lib/output.js +83 -10
  55. package/dist/lib/output.js.map +1 -1
  56. package/dist/lib/regal-cli.d.ts +16 -1
  57. package/dist/lib/regal-cli.d.ts.map +1 -1
  58. package/dist/lib/regal-cli.js +40 -6
  59. package/dist/lib/regal-cli.js.map +1 -1
  60. package/dist/lib/rego-ast-walker.d.ts +0 -6
  61. package/dist/lib/rego-ast-walker.d.ts.map +1 -1
  62. package/dist/lib/rego-ast-walker.js +181 -55
  63. package/dist/lib/rego-ast-walker.js.map +1 -1
  64. package/dist/lib/rego-counterexample.d.ts +15 -2
  65. package/dist/lib/rego-counterexample.d.ts.map +1 -1
  66. package/dist/lib/rego-counterexample.js +63 -15
  67. package/dist/lib/rego-counterexample.js.map +1 -1
  68. package/dist/lib/rego-input-path.d.ts +20 -0
  69. package/dist/lib/rego-input-path.d.ts.map +1 -0
  70. package/dist/lib/rego-input-path.js +70 -0
  71. package/dist/lib/rego-input-path.js.map +1 -0
  72. package/dist/lib/rego-ir.d.ts +34 -3
  73. package/dist/lib/rego-ir.d.ts.map +1 -1
  74. package/dist/lib/rego-smt-encoder.d.ts +88 -5
  75. package/dist/lib/rego-smt-encoder.d.ts.map +1 -1
  76. package/dist/lib/rego-smt-encoder.js +270 -31
  77. package/dist/lib/rego-smt-encoder.js.map +1 -1
  78. package/dist/lib/rego-type-inferencer.d.ts +27 -2
  79. package/dist/lib/rego-type-inferencer.d.ts.map +1 -1
  80. package/dist/lib/rego-type-inferencer.js +71 -3
  81. package/dist/lib/rego-type-inferencer.js.map +1 -1
  82. package/dist/lib/rego-verify-engine.d.ts.map +1 -1
  83. package/dist/lib/rego-verify-engine.js +203 -90
  84. package/dist/lib/rego-verify-engine.js.map +1 -1
  85. package/dist/lib/rego-z3.d.ts +66 -0
  86. package/dist/lib/rego-z3.d.ts.map +1 -1
  87. package/dist/lib/rego-z3.js +312 -5
  88. package/dist/lib/rego-z3.js.map +1 -1
  89. package/dist/lib/security.d.ts +8 -0
  90. package/dist/lib/security.d.ts.map +1 -1
  91. package/dist/lib/security.js +130 -54
  92. package/dist/lib/security.js.map +1 -1
  93. package/dist/lib/subprocess.d.ts +13 -0
  94. package/dist/lib/subprocess.d.ts.map +1 -1
  95. package/dist/lib/subprocess.js +153 -18
  96. package/dist/lib/subprocess.js.map +1 -1
  97. package/dist/lib/tool-helpers.d.ts +12 -25
  98. package/dist/lib/tool-helpers.d.ts.map +1 -1
  99. package/dist/lib/tool-helpers.js +66 -40
  100. package/dist/lib/tool-helpers.js.map +1 -1
  101. package/dist/prompts/index.js +2 -2
  102. package/dist/resources/index.js +1 -1
  103. package/dist/resources/index.js.map +1 -1
  104. package/dist/resources/patterns.d.ts +1 -1
  105. package/dist/resources/patterns.d.ts.map +1 -1
  106. package/dist/resources/patterns.js +42 -15
  107. package/dist/resources/patterns.js.map +1 -1
  108. package/dist/server.d.ts +2 -2
  109. package/dist/server.d.ts.map +1 -1
  110. package/dist/server.js +50 -7
  111. package/dist/server.js.map +1 -1
  112. package/dist/tools/authoring/capabilities.d.ts +4 -0
  113. package/dist/tools/authoring/capabilities.d.ts.map +1 -1
  114. package/dist/tools/authoring/capabilities.js +41 -4
  115. package/dist/tools/authoring/capabilities.js.map +1 -1
  116. package/dist/tools/authoring/check-schema.d.ts +6 -0
  117. package/dist/tools/authoring/check-schema.d.ts.map +1 -1
  118. package/dist/tools/authoring/check-schema.js +56 -3
  119. package/dist/tools/authoring/check-schema.js.map +1 -1
  120. package/dist/tools/authoring/format.d.ts.map +1 -1
  121. package/dist/tools/authoring/format.js +2 -2
  122. package/dist/tools/authoring/format.js.map +1 -1
  123. package/dist/tools/authoring/lint.d.ts.map +1 -1
  124. package/dist/tools/authoring/lint.js +8 -6
  125. package/dist/tools/authoring/lint.js.map +1 -1
  126. package/dist/tools/authoring/migrate-v1.d.ts.map +1 -1
  127. package/dist/tools/authoring/migrate-v1.js +20 -4
  128. package/dist/tools/authoring/migrate-v1.js.map +1 -1
  129. package/dist/tools/authoring/parse.d.ts.map +1 -1
  130. package/dist/tools/authoring/parse.js +3 -3
  131. package/dist/tools/authoring/parse.js.map +1 -1
  132. package/dist/tools/bundles/build.d.ts.map +1 -1
  133. package/dist/tools/bundles/build.js +12 -4
  134. package/dist/tools/bundles/build.js.map +1 -1
  135. package/dist/tools/bundles/sign.d.ts +9 -2
  136. package/dist/tools/bundles/sign.d.ts.map +1 -1
  137. package/dist/tools/bundles/sign.js +125 -19
  138. package/dist/tools/bundles/sign.js.map +1 -1
  139. package/dist/tools/bundles/verify.d.ts +1 -1
  140. package/dist/tools/bundles/verify.d.ts.map +1 -1
  141. package/dist/tools/bundles/verify.js +58 -19
  142. package/dist/tools/bundles/verify.js.map +1 -1
  143. package/dist/tools/conftest/index.d.ts +5 -0
  144. package/dist/tools/conftest/index.d.ts.map +1 -1
  145. package/dist/tools/conftest/index.js.map +1 -1
  146. package/dist/tools/conftest/pull.d.ts.map +1 -1
  147. package/dist/tools/conftest/pull.js +24 -10
  148. package/dist/tools/conftest/pull.js.map +1 -1
  149. package/dist/tools/conftest/push.d.ts.map +1 -1
  150. package/dist/tools/conftest/push.js +17 -7
  151. package/dist/tools/conftest/push.js.map +1 -1
  152. package/dist/tools/conftest/test.d.ts +10 -6
  153. package/dist/tools/conftest/test.d.ts.map +1 -1
  154. package/dist/tools/conftest/test.js +61 -39
  155. package/dist/tools/conftest/test.js.map +1 -1
  156. package/dist/tools/conftest/verify.d.ts +10 -6
  157. package/dist/tools/conftest/verify.d.ts.map +1 -1
  158. package/dist/tools/conftest/verify.js +40 -32
  159. package/dist/tools/conftest/verify.js.map +1 -1
  160. package/dist/tools/evaluation/_shared.js +9 -12
  161. package/dist/tools/evaluation/_shared.js.map +1 -1
  162. package/dist/tools/evaluation/bench.d.ts +29 -2
  163. package/dist/tools/evaluation/bench.d.ts.map +1 -1
  164. package/dist/tools/evaluation/bench.js +53 -9
  165. package/dist/tools/evaluation/bench.js.map +1 -1
  166. package/dist/tools/evaluation/compile.js +4 -4
  167. package/dist/tools/evaluation/compile.js.map +1 -1
  168. package/dist/tools/evaluation/eval.d.ts.map +1 -1
  169. package/dist/tools/evaluation/eval.js +12 -16
  170. package/dist/tools/evaluation/eval.js.map +1 -1
  171. package/dist/tools/evaluation/exec.d.ts +16 -0
  172. package/dist/tools/evaluation/exec.d.ts.map +1 -1
  173. package/dist/tools/evaluation/exec.js +38 -6
  174. package/dist/tools/evaluation/exec.js.map +1 -1
  175. package/dist/tools/evaluation/test-multiroot.d.ts +6 -0
  176. package/dist/tools/evaluation/test-multiroot.d.ts.map +1 -1
  177. package/dist/tools/evaluation/test-multiroot.js +35 -8
  178. package/dist/tools/evaluation/test-multiroot.js.map +1 -1
  179. package/dist/tools/evaluation/test.d.ts +45 -0
  180. package/dist/tools/evaluation/test.d.ts.map +1 -1
  181. package/dist/tools/evaluation/test.js +153 -32
  182. package/dist/tools/evaluation/test.js.map +1 -1
  183. package/dist/tools/helpers/coverage-gaps.d.ts +11 -3
  184. package/dist/tools/helpers/coverage-gaps.d.ts.map +1 -1
  185. package/dist/tools/helpers/coverage-gaps.js +7 -7
  186. package/dist/tools/helpers/coverage-gaps.js.map +1 -1
  187. package/dist/tools/helpers/describe-policy.d.ts.map +1 -1
  188. package/dist/tools/helpers/describe-policy.js +2 -2
  189. package/dist/tools/helpers/describe-policy.js.map +1 -1
  190. package/dist/tools/helpers/explain-decision.d.ts.map +1 -1
  191. package/dist/tools/helpers/explain-decision.js +3 -4
  192. package/dist/tools/helpers/explain-decision.js.map +1 -1
  193. package/dist/tools/helpers/explain-undefined.d.ts +9 -3
  194. package/dist/tools/helpers/explain-undefined.d.ts.map +1 -1
  195. package/dist/tools/helpers/explain-undefined.js +214 -73
  196. package/dist/tools/helpers/explain-undefined.js.map +1 -1
  197. package/dist/tools/helpers/fix.d.ts +11 -5
  198. package/dist/tools/helpers/fix.d.ts.map +1 -1
  199. package/dist/tools/helpers/fix.js +88 -45
  200. package/dist/tools/helpers/fix.js.map +1 -1
  201. package/dist/tools/helpers/generate-test-skeleton.d.ts.map +1 -1
  202. package/dist/tools/helpers/generate-test-skeleton.js +105 -21
  203. package/dist/tools/helpers/generate-test-skeleton.js.map +1 -1
  204. package/dist/tools/helpers/playground-share.d.ts +4 -2
  205. package/dist/tools/helpers/playground-share.d.ts.map +1 -1
  206. package/dist/tools/helpers/playground-share.js +13 -3
  207. package/dist/tools/helpers/playground-share.js.map +1 -1
  208. package/dist/tools/helpers/policy-diff.d.ts.map +1 -1
  209. package/dist/tools/helpers/policy-diff.js +3 -4
  210. package/dist/tools/helpers/policy-diff.js.map +1 -1
  211. package/dist/tools/helpers/security-audit.d.ts.map +1 -1
  212. package/dist/tools/helpers/security-audit.js +19 -19
  213. package/dist/tools/helpers/security-audit.js.map +1 -1
  214. package/dist/tools/helpers/verify.d.ts.map +1 -1
  215. package/dist/tools/helpers/verify.js +5 -1
  216. package/dist/tools/helpers/verify.js.map +1 -1
  217. package/dist/tools/meta/index.d.ts +1 -1
  218. package/dist/tools/server-management/_shared.d.ts +15 -4
  219. package/dist/tools/server-management/_shared.d.ts.map +1 -1
  220. package/dist/tools/server-management/_shared.js +86 -13
  221. package/dist/tools/server-management/_shared.js.map +1 -1
  222. package/dist/tools/server-management/data.d.ts.map +1 -1
  223. package/dist/tools/server-management/data.js +88 -23
  224. package/dist/tools/server-management/data.js.map +1 -1
  225. package/dist/tools/server-management/decisions.d.ts.map +1 -1
  226. package/dist/tools/server-management/decisions.js +16 -3
  227. package/dist/tools/server-management/decisions.js.map +1 -1
  228. package/dist/tools/server-management/policies.d.ts.map +1 -1
  229. package/dist/tools/server-management/policies.js +44 -7
  230. package/dist/tools/server-management/policies.js.map +1 -1
  231. package/dist/tools/server-management/status.d.ts.map +1 -1
  232. package/dist/tools/server-management/status.js +80 -13
  233. package/dist/tools/server-management/status.js.map +1 -1
  234. package/dist/types.d.ts +10 -1
  235. package/dist/types.d.ts.map +1 -1
  236. package/package.json +2 -1
@@ -67,10 +67,9 @@ export function registerRegoCoverageGaps(server, config) {
67
67
  description: 'Run opa test --coverage and return a per-file breakdown of uncovered line ranges. Identifies which rules or branches are not yet exercised by tests. Files are sorted by coverage ascending so the worst-covered files appear first. Use threshold to limit the report to files below a target coverage percentage.',
68
68
  inputSchema: RegoCoverageGapsInput,
69
69
  annotations: {
70
- readOnlyHint: true,
71
- destructiveHint: false,
72
- idempotentHint: true,
73
- openWorldHint: false,
70
+ readOnlyHint: false,
71
+ // Runs Rego supplied by the caller; a policy can reach the network through http.send.
72
+ openWorldHint: true,
74
73
  },
75
74
  }, async ({ paths, threshold, runPattern }, { signal }) => {
76
75
  return withToolEnvelope(config, async () => {
@@ -100,6 +99,9 @@ export function registerRegoCoverageGaps(server, config) {
100
99
  // passing records with any status field, so filtering for pass: true
101
100
  // always produces zero. Subtraction is the correct approach.
102
101
  const testsPassed = testRecords.length - testsFailed - testsSkipped;
102
+ // OPA emits no test records in coverage mode, so reporting three zeros
103
+ // stated that no tests ran when the truth is that it did not say.
104
+ const counts = testRecords.length > 0 ? { testsPassed, testsFailed, testsSkipped } : {};
103
105
  const overallCoverage = coverageReport.coverage ?? 0;
104
106
  const filesWithGaps = [];
105
107
  for (const [file, report] of Object.entries(coverageReport.files ?? {})) {
@@ -124,9 +126,7 @@ export function registerRegoCoverageGaps(server, config) {
124
126
  overallCoverage,
125
127
  totalFiles: Object.keys(coverageReport.files ?? {}).length,
126
128
  filesWithGaps,
127
- testsPassed,
128
- testsFailed,
129
- testsSkipped,
129
+ ...counts,
130
130
  });
131
131
  });
132
132
  });
@@ -1 +1 @@
1
- {"version":3,"file":"coverage-gaps.js","sourceRoot":"","sources":["../../../src/tools/helpers/coverage-gaps.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"coverage-gaps.js","sourceRoot":"","sources":["../../../src/tools/helpers/coverage-gaps.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"describe-policy.d.ts","sourceRoot":"","sources":["../../../src/tools/helpers/describe-policy.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAc9C,UAAU,cAAc;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,OAAO,EAAE,CAAC;IAC9B,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,EAAE,CAAC;CAC3B;AAqBD,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,SAAS,EAAE,OAAO,CAAC;IACnB,iEAAiE;IACjE,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,wEAAwE;IACxE,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,cAAc,CAAC;CAC9B;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,kBAAkB,CAAC,EAAE,cAAc,EAAE,CAAC;CACvC;AAUD,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CA6ElF"}
1
+ {"version":3,"file":"describe-policy.d.ts","sourceRoot":"","sources":["../../../src/tools/helpers/describe-policy.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAmB9C,UAAU,cAAc;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,OAAO,EAAE,CAAC;IAC9B,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,EAAE,CAAC;CAC3B;AAqBD,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,SAAS,EAAE,OAAO,CAAC;IACnB,iEAAiE;IACjE,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,wEAAwE;IACxE,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,cAAc,CAAC;CAC9B;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,kBAAkB,CAAC,EAAE,cAAc,EAAE,CAAC;CACvC;AAUD,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CA6ElF"}
@@ -5,7 +5,7 @@
5
5
  import { z } from 'zod';
6
6
  import { OpaCli } from '../../lib/opa-cli.js';
7
7
  import { err, ok } from '../../lib/errors.js';
8
- import { mapSubprocessFailure, tryParseJson, withToolEnvelope } from '../../lib/tool-helpers.js';
8
+ import { mapSubprocessFailure, sanitizeInlinePathsDeep, tryParseJson, withToolEnvelope, } from '../../lib/tool-helpers.js';
9
9
  const RegoDescribePolicyInput = {
10
10
  source: z.string().min(1).describe('Rego source to describe.'),
11
11
  };
@@ -37,7 +37,7 @@ export function registerRegoDescribePolicy(server, config) {
37
37
  return subprocessFailure;
38
38
  if (result.exitCode !== 0) {
39
39
  return err('INVALID_REGO', 'opa parse rejected the source.', {
40
- details: { stderr: result.stderr.trim() },
40
+ details: sanitizeInlinePathsDeep({ stderr: result.stderr.trim() }),
41
41
  });
42
42
  }
43
43
  const ast = tryParseJson(result.stdout);
@@ -1 +1 @@
1
- {"version":3,"file":"describe-policy.js","sourceRoot":"","sources":["../../../src/tools/helpers/describe-policy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"describe-policy.js","sourceRoot":"","sources":["../../../src/tools/helpers/describe-policy.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"explain-decision.d.ts","sourceRoot":"","sources":["../../../src/tools/helpers/explain-decision.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAM9C,UAAU,UAAU;IAClB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACzD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;IACnB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,OAAO,EAAE;QACP,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAwCD,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAoDnF"}
1
+ {"version":3,"file":"explain-decision.d.ts","sourceRoot":"","sources":["../../../src/tools/helpers/explain-decision.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAM9C,UAAU,UAAU;IAClB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACzD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;IACnB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,OAAO,EAAE;QACP,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAwCD,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAmDnF"}
@@ -47,10 +47,9 @@ export function registerRegoExplainDecision(server, config) {
47
47
  description: 'Evaluate a Rego query with full tracing and return a structured trace plus per-rule fired/not-fired summary. Use this when you need to answer "why was this denied?" -- the agent reads the structured trace and narrates the cause without re-implementing the trace parser.',
48
48
  inputSchema: SharedEvalInput,
49
49
  annotations: {
50
- readOnlyHint: true,
51
- destructiveHint: false,
52
- idempotentHint: true,
53
- openWorldHint: false,
50
+ readOnlyHint: false,
51
+ // Runs Rego supplied by the caller; a policy can reach the network through http.send.
52
+ openWorldHint: true,
54
53
  },
55
54
  }, async (args, { signal }) => {
56
55
  return withToolEnvelope(config, async () => {
@@ -1 +1 @@
1
- {"version":3,"file":"explain-decision.js","sourceRoot":"","sources":["../../../src/tools/helpers/explain-decision.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"explain-decision.js","sourceRoot":"","sources":["../../../src/tools/helpers/explain-decision.ts"],"names":[],"mappings":"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"}
@@ -33,9 +33,15 @@ export interface RuleAnalysis {
33
33
  source: 'trace' | 'standalone-eval';
34
34
  }
35
35
  export interface RegoExplainUndefinedOutput {
36
- /** Whether the query produced a value or not. */
37
- queryResult: 'undefined' | 'defined';
38
- /** Present only when queryResult is "defined". */
36
+ /**
37
+ * Whether the query produced a value.
38
+ *
39
+ * `default` means it produced one only because a `default` rule supplied it:
40
+ * no other definition of the rule matched. The per-rule breakdown says why,
41
+ * which is the same question `undefined` asks.
42
+ */
43
+ queryResult: 'undefined' | 'defined' | 'default';
44
+ /** Present when queryResult is "defined" or "default". */
39
45
  value?: unknown;
40
46
  /** Human-readable explanation. */
41
47
  summary: string;
@@ -1 +1 @@
1
- {"version":3,"file":"explain-undefined.d.ts","sourceRoot":"","sources":["../../../src/tools/helpers/explain-undefined.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AA6E9C,MAAM,WAAW,eAAe;IAC9B,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,4BAA4B;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,6CAA6C;IAC7C,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,aAAa,CAAC;IACzC,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,6DAA6D;IAC7D,SAAS,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,SAAS,EAAE,OAAO,CAAC;IACnB,wCAAwC;IACxC,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACrD,sDAAsD;IACtD,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,sEAAsE;IACtE,iBAAiB,EAAE,eAAe,GAAG,IAAI,CAAC;IAC1C,0CAA0C;IAC1C,MAAM,EAAE,OAAO,GAAG,iBAAiB,CAAC;CACrC;AAED,MAAM,WAAW,0BAA0B;IACzC,iDAAiD;IACjD,WAAW,EAAE,WAAW,GAAG,SAAS,CAAC;IACrC,kDAAkD;IAClD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,sDAAsD;IACtD,UAAU,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,0BAA0B;IAC1B,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB;AA+KD,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CA4NpF"}
1
+ {"version":3,"file":"explain-undefined.d.ts","sourceRoot":"","sources":["../../../src/tools/helpers/explain-undefined.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AA+E9C,MAAM,WAAW,eAAe;IAC9B,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,4BAA4B;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,6CAA6C;IAC7C,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,aAAa,CAAC;IACzC,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,6DAA6D;IAC7D,SAAS,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,SAAS,EAAE,OAAO,CAAC;IACnB,wCAAwC;IACxC,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACrD,sDAAsD;IACtD,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,sEAAsE;IACtE,iBAAiB,EAAE,eAAe,GAAG,IAAI,CAAC;IAC1C,0CAA0C;IAC1C,MAAM,EAAE,OAAO,GAAG,iBAAiB,CAAC;CACrC;AAED,MAAM,WAAW,0BAA0B;IACzC;;;;;;OAMG;IACH,WAAW,EAAE,WAAW,GAAG,SAAS,GAAG,SAAS,CAAC;IACjD,0DAA0D;IAC1D,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,sDAAsD;IACtD,UAAU,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,0BAA0B;IAC1B,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB;AAsPD,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CA6SpF"}
@@ -15,8 +15,9 @@
15
15
  * For rules that appear in the trace (OPA entered them), the blocking
16
16
  * condition is identified by matching Fail-event rows against body-
17
17
  * expression rows from the AST. For rules that do not appear in the trace
18
- * (indexed out), each body expression is evaluated as a standalone query
19
- * to determine which one is not satisfied.
18
+ * (indexed out), the body is evaluated as cumulative prefixes inside the
19
+ * rule's package, with its imports, to find the first condition that does
20
+ * not hold.
20
21
  */
21
22
  import { readFile } from 'node:fs/promises';
22
23
  import { z } from 'zod';
@@ -75,20 +76,35 @@ function queryToPackageAndRule(query) {
75
76
  packagePath: parts.slice(0, -1).join('.'),
76
77
  };
77
78
  }
79
+ /**
80
+ * The source row a trace event refers to.
81
+ *
82
+ * OPA does not populate `Node.location` on trace events; the row lives on the
83
+ * event's own `Location`. Reading only the node meant every row comparison fell
84
+ * through to matching on the rule name alone, so all clauses of a multi-clause
85
+ * rule looked present in the trace as soon as any one of them was, and the ones
86
+ * the indexer had eliminated were never evaluated standalone. They came back as
87
+ * `unevaluable` with no blocking condition, which is the answer this tool
88
+ * exists to give.
89
+ */
90
+ function traceEventRow(ev) {
91
+ return ev.Node?.location?.row ?? ev.Location?.row;
92
+ }
93
+ function matchesRule(ev, ruleName, ruleRow) {
94
+ if (ev.Op?.toLowerCase() !== 'enter')
95
+ return false;
96
+ if (!ev.Node)
97
+ return false;
98
+ if (extractRuleHeadName(ev.Node.head) !== ruleName)
99
+ return false;
100
+ const row = traceEventRow(ev);
101
+ // Disambiguate the clauses of an incremental rule by source row.
102
+ if (ruleRow !== undefined && row !== undefined)
103
+ return row === ruleRow;
104
+ return true;
105
+ }
78
106
  function ruleAppearsInTrace(ruleName, ruleRow, trace) {
79
- return trace.some((ev) => {
80
- if (ev.Op?.toLowerCase() !== 'enter')
81
- return false;
82
- if (!ev.Node)
83
- return false;
84
- if (extractRuleHeadName(ev.Node.head) !== ruleName)
85
- return false;
86
- // When we have source row information, use it to disambiguate incremental rules.
87
- if (ruleRow !== undefined && ev.Node.location?.row !== undefined) {
88
- return ev.Node.location.row === ruleRow;
89
- }
90
- return true;
91
- });
107
+ return trace.some((ev) => matchesRule(ev, ruleName, ruleRow));
92
108
  }
93
109
  function findBlockingRowFromTrace(rule, trace) {
94
110
  const ruleName = extractRuleHeadName(rule.head);
@@ -97,16 +113,7 @@ function findBlockingRowFromTrace(rule, trace) {
97
113
  if (bodyRows.size === 0)
98
114
  return undefined;
99
115
  // Locate the Enter event for this specific rule definition.
100
- const enterIdx = trace.findIndex((ev) => {
101
- if (ev.Op?.toLowerCase() !== 'enter')
102
- return false;
103
- if (extractRuleHeadName(ev.Node?.head) !== ruleName)
104
- return false;
105
- if (ruleRow !== undefined && ev.Node?.location?.row !== undefined) {
106
- return ev.Node.location.row === ruleRow;
107
- }
108
- return true;
109
- });
116
+ const enterIdx = trace.findIndex((ev) => matchesRule(ev, ruleName ?? '', ruleRow));
110
117
  if (enterIdx < 0)
111
118
  return undefined;
112
119
  // Find the first Fail event after the Enter that falls on a body expression row.
@@ -126,24 +133,66 @@ function findBlockingRowFromTrace(rule, trace) {
126
133
  }
127
134
  return undefined;
128
135
  }
129
- async function evalConditionStandalone(exprText, evalBase, opa, signal) {
136
+ /**
137
+ * The module's import statements as `--import` takes them: the path as
138
+ * written, plus the alias when there is one. `--package` alone does not bring
139
+ * them, and a body expression through an import is unsafe without them.
140
+ */
141
+ function moduleImports(ast) {
142
+ const out = [];
143
+ for (const imp of ast.imports ?? []) {
144
+ const path = decodeBase64Text(imp.path?.location?.text);
145
+ if (!path)
146
+ continue;
147
+ out.push(imp.alias ? `${path} as ${imp.alias}` : path);
148
+ }
149
+ return out;
150
+ }
151
+ /**
152
+ * Ceiling on the query text handed to opa. Windows caps a command line at
153
+ * 32 KiB, and the prefixes grow with every condition that held.
154
+ */
155
+ const MAX_PREFIX_CHARS = 16_000;
156
+ /**
157
+ * Evaluate a prefix of a rule body as a query inside the rule's package. The
158
+ * prefix carries the locals assigned earlier, and the package makes a bare
159
+ * reference to a sibling rule resolve, so the answer is the one the rule
160
+ * itself would get up to that point.
161
+ */
162
+ async function evalPrefixStandalone(prefixText, pkg, imports, evalBase, opa, signal) {
130
163
  const result = await opa.eval({
131
- query: exprText,
164
+ query: prefixText,
132
165
  source: evalBase.source,
133
166
  paths: evalBase.paths,
134
167
  input: evalBase.input,
135
168
  inputPath: evalBase.inputPath,
169
+ // The parsed path carries the `data` root; the flag takes the package
170
+ // name as written in the module.
171
+ package: pkg.replace(/^data\./, '') || undefined,
172
+ imports,
136
173
  }, signal);
174
+ // A binary that could not be run, or a run that was killed, is the tool's
175
+ // failure, not a fact about this condition.
176
+ const spawnFailure = mapSubprocessFailure(result, 'opa');
177
+ if (spawnFailure)
178
+ return { spawnFailure };
137
179
  if (result.exitCode === null || result.exitCode !== 0) {
138
- const firstLine = (result.stderr.trim() || result.stdout.trim()).split('\n')[0] ?? 'unknown error';
139
- return { result: 'unevaluable', note: `Standalone eval failed: ${firstLine}` };
180
+ // With --format=json OPA writes its error document to stdout; the first
181
+ // line of that is a brace. Read the messages out of it.
182
+ const errors = tryParseJson(result.stdout)?.errors;
183
+ const detail = errors
184
+ ?.map((e) => e.message)
185
+ .filter((m) => typeof m === 'string' && m.length > 0)
186
+ .join('; ') ||
187
+ (result.stderr.trim() || result.stdout.trim()).split('\n')[0] ||
188
+ 'unknown error';
189
+ return { result: 'unevaluable', note: `Standalone eval failed: ${detail}` };
140
190
  }
141
- // OPA returns a result row for a body expression even when it evaluates to a
142
- // false value -- e.g. `input.user.tier == "premium"` against tier "free"
143
- // yields a row whose expression value is `false`, not an empty result. A
144
- // condition is satisfied only when it produces a solution whose expressions
145
- // are all defined and not `false`, so inspect the expression values rather
146
- // than merely the presence of a row (which would mark every comparison true).
191
+ // For a single-expression query OPA returns a row even when the value is
192
+ // `false`; with several expressions an unsatisfied one yields no row at
193
+ // all. Either way a condition is satisfied only when some row has every
194
+ // expression defined and not `false`, so inspect the values rather than the
195
+ // presence of a row.
147
196
  const parsed = tryParseJson(result.stdout);
148
197
  const satisfied = (parsed?.result ?? []).some((row) => {
149
198
  const exprs = row.expressions ?? [];
@@ -151,14 +200,25 @@ async function evalConditionStandalone(exprText, evalBase, opa, signal) {
151
200
  });
152
201
  return satisfied ? { result: 'true' } : { result: 'false' };
153
202
  }
154
- function buildSummary(query, rules, defaultValue) {
203
+ /** Structural equality, enough for the scalars and small literals a default holds. */
204
+ function deepEqual(a, b) {
205
+ if (a === b)
206
+ return true;
207
+ if (a === null || b === null || typeof a !== 'object' || typeof b !== 'object')
208
+ return false;
209
+ return JSON.stringify(a) === JSON.stringify(b);
210
+ }
211
+ function buildSummary(query, rules, defaultValue, viaDefault) {
155
212
  const lines = [];
213
+ const state = viaDefault
214
+ ? `falls back to its default value ${JSON.stringify(defaultValue)} because no other definition matched`
215
+ : 'is undefined';
156
216
  if (rules.length === 0) {
157
- lines.push(`${query} is undefined: no matching rules found in the analysed source.`);
217
+ lines.push(`${query} ${state}: no matching rules found in the analysed source.`);
158
218
  }
159
219
  else {
160
220
  const count = rules.length;
161
- lines.push(`${query} is undefined. ${count} rule definition${count !== 1 ? 's' : ''} analysed:`);
221
+ lines.push(`${query} ${state}. ${count} rule definition${count !== 1 ? 's' : ''} analysed:`);
162
222
  for (const r of rules) {
163
223
  const loc = r.location.row > 0 ? ` (row ${r.location.row})` : '';
164
224
  const bc = r.blockingCondition;
@@ -171,13 +231,15 @@ function buildSummary(query, rules, defaultValue) {
171
231
  lines.push(` Rule ${r.ruleIndex}${loc}: no analysable body conditions.`);
172
232
  }
173
233
  else {
174
- const unevalCount = r.conditions.filter((c) => c.result === 'unevaluable').length;
234
+ // Conditions behind the one that stopped evaluation were never attempted
235
+ // and are not what the summary is warning about.
236
+ const unevalCount = r.conditions.filter((c) => c.result === 'unevaluable' && !/^Not (reached|evaluated):/.test(c.note ?? '')).length;
175
237
  lines.push(` Rule ${r.ruleIndex}${loc}: blocking condition could not be determined ` +
176
238
  `(${unevalCount} unevaluable expression${unevalCount !== 1 ? 's' : ''}).`);
177
239
  }
178
240
  }
179
241
  }
180
- if (defaultValue !== undefined) {
242
+ if (!viaDefault && defaultValue !== undefined) {
181
243
  lines.push(`Default value: ${JSON.stringify(defaultValue)}.`);
182
244
  }
183
245
  return lines.join('\n');
@@ -188,16 +250,18 @@ export function registerRegoExplainUndefined(server, config) {
188
250
  server.registerTool('rego_explain_undefined', {
189
251
  title: 'Explain why a Rego query is undefined',
190
252
  description: 'Diagnose why a fully-qualified Rego query (e.g. "data.authz.allow") produces no ' +
191
- 'value. Combines a plain eval, a full-trace eval, and per-condition AST analysis to ' +
192
- 'identify the exact body expression blocking each rule. Handles both runtime failures ' +
193
- '(trace-based) and indexer elimination (standalone condition eval). Returns a structured ' +
253
+ 'value, or falls back to its default. Combines a plain eval, a full-trace eval, and ' +
254
+ 'per-condition AST analysis to identify the exact body expression blocking each rule. ' +
255
+ 'Handles both runtime failures (trace-based) and indexer elimination (standalone ' +
256
+ 'condition eval). A rule written with `default allow := false` always has a value, so ' +
257
+ '`queryResult` reports `default` for it and the same per-rule breakdown follows: the ' +
258
+ 'question "why is allow false" is the question this answers. Returns a structured ' +
194
259
  'breakdown of which conditions blocked each rule plus a human-readable summary.',
195
260
  inputSchema: RegoExplainUndefinedInput,
196
261
  annotations: {
197
- readOnlyHint: true,
198
- destructiveHint: false,
199
- idempotentHint: true,
200
- openWorldHint: false,
262
+ readOnlyHint: false,
263
+ // Runs Rego supplied by the caller; a policy can reach the network through http.send.
264
+ openWorldHint: true,
201
265
  },
202
266
  }, async (args, { signal }) => {
203
267
  return withToolEnvelope(config, async () => {
@@ -209,17 +273,19 @@ export function registerRegoExplainUndefined(server, config) {
209
273
  return pv.error;
210
274
  resolvedPaths = pv.resolved;
211
275
  }
276
+ let resolvedInputPath;
212
277
  if (args.inputPath) {
213
278
  const iv = validatePaths([args.inputPath], config, { mustExist: true });
214
279
  if (!iv.ok)
215
280
  return iv.error;
281
+ resolvedInputPath = iv.resolved[0];
216
282
  }
217
283
  const evalBase = {
218
284
  query: args.query,
219
285
  source: args.source,
220
286
  paths: resolvedPaths.length > 0 ? resolvedPaths : undefined,
221
287
  input: args.input,
222
- inputPath: args.inputPath,
288
+ inputPath: resolvedInputPath,
223
289
  };
224
290
  // ── Step 1: plain eval ────────────────────────────────────────────
225
291
  const plainResult = await opa.eval(evalBase, signal);
@@ -237,27 +303,17 @@ export function registerRegoExplainUndefined(server, config) {
237
303
  }
238
304
  const plainJson = tryParseJson(plainResult.stdout);
239
305
  const isDefined = (plainJson?.result?.length ?? 0) > 0;
240
- if (isDefined) {
241
- const value = plainJson.result[0]?.expressions?.[0]?.value;
242
- return ok({
243
- queryResult: 'defined',
244
- value,
245
- summary: `${args.query} is defined with value: ${JSON.stringify(value)}.`,
246
- rulesFound: 0,
247
- rules: [],
248
- });
249
- }
250
- // ── Step 2: eval with --explain=full ──────────────────────────────
251
- const traceResult = await opa.eval({ ...evalBase, explain: 'full' }, signal);
252
- const traceSpawnErr = mapSubprocessFailure(traceResult, 'opa');
253
- if (traceSpawnErr)
254
- return traceSpawnErr;
255
- const traceJson = tryParseJson(traceResult.stdout);
256
- const trace = traceJson?.explanation ?? [];
257
- // ── Step 3: parse AST(s) ──────────────────────────────────────────
306
+ const definedValue = isDefined
307
+ ? plainJson.result[0]
308
+ ?.expressions?.[0]?.value
309
+ : undefined;
310
+ // ── Step 2: parse AST(s) ──────────────────────────────────────────
258
311
  const asts = [];
259
312
  if (args.source) {
260
313
  const pr = await opa.parse({ source: args.source, includeLocations: true }, signal);
314
+ const parseFailure = mapSubprocessFailure(pr, 'opa');
315
+ if (parseFailure)
316
+ return parseFailure;
261
317
  if (pr.exitCode === 0) {
262
318
  const ast = tryParseJson(pr.stdout);
263
319
  if (ast)
@@ -270,6 +326,9 @@ export function registerRegoExplainUndefined(server, config) {
270
326
  try {
271
327
  const src = await readFile(filePath, 'utf8');
272
328
  const pr = await opa.parse({ source: src, includeLocations: true }, signal);
329
+ const parseFailure = mapSubprocessFailure(pr, 'opa');
330
+ if (parseFailure)
331
+ return parseFailure;
273
332
  if (pr.exitCode === 0) {
274
333
  const ast = tryParseJson(pr.stdout);
275
334
  if (ast)
@@ -281,9 +340,12 @@ export function registerRegoExplainUndefined(server, config) {
281
340
  }
282
341
  }
283
342
  }
284
- // ── Step 4: find matching rules ───────────────────────────────────
343
+ // ── Step 3: find matching rules ───────────────────────────────────
285
344
  const queryParsed = queryToPackageAndRule(args.query);
286
345
  const matchedRules = [];
346
+ /** Package and imports of each matched rule, index-aligned with matchedRules. */
347
+ const matchedPackages = [];
348
+ const matchedImports = [];
287
349
  for (const ast of asts) {
288
350
  const pkgPath = extractPackagePath(ast);
289
351
  if (queryParsed && pkgPath !== queryParsed.packagePath)
@@ -292,9 +354,35 @@ export function registerRegoExplainUndefined(server, config) {
292
354
  const name = extractRuleHeadName(rule.head);
293
355
  if (!queryParsed || name === queryParsed.ruleName) {
294
356
  matchedRules.push(rule);
357
+ matchedPackages.push(pkgPath);
358
+ matchedImports.push(moduleImports(ast));
295
359
  }
296
360
  }
297
361
  }
362
+ // A rule written with `default allow := false` always has a value, so the
363
+ // query is never undefined and the analysis below used to be skipped for
364
+ // the shape most policies are written in. When the value came from the
365
+ // default and nothing else matched, the interesting question is unchanged.
366
+ const defaultRule = matchedRules.find((r) => r.default === true);
367
+ const viaDefault = isDefined &&
368
+ defaultRule !== undefined &&
369
+ deepEqual(defaultRule.head?.value?.value, definedValue);
370
+ if (isDefined && !viaDefault) {
371
+ return ok({
372
+ queryResult: 'defined',
373
+ value: definedValue,
374
+ summary: `${args.query} is defined with value: ${JSON.stringify(definedValue)}.`,
375
+ rulesFound: 0,
376
+ rules: [],
377
+ });
378
+ }
379
+ // ── Step 4: eval with --explain=full ──────────────────────────────
380
+ const traceResult = await opa.eval({ ...evalBase, explain: 'full' }, signal);
381
+ const traceSpawnErr = mapSubprocessFailure(traceResult, 'opa');
382
+ if (traceSpawnErr)
383
+ return traceSpawnErr;
384
+ const traceJson = tryParseJson(traceResult.stdout);
385
+ const trace = traceJson?.explanation ?? [];
298
386
  // ── Step 5: analyse each rule ─────────────────────────────────────
299
387
  let defaultValue;
300
388
  const rules = [];
@@ -353,18 +441,70 @@ export function registerRegoExplainUndefined(server, config) {
353
441
  }
354
442
  else {
355
443
  // Standalone eval: OPA's indexer eliminated this rule before
356
- // entering its body. Evaluate each condition independently.
444
+ // entering its body. Each condition is judged inside the rule's
445
+ // package, with its imports, and with the conditions before it in
446
+ // scope, so a local assigned earlier and a bare reference to a
447
+ // sibling rule both resolve. Evaluation stops at the first
448
+ // condition that does not hold, as on the traced path.
449
+ // Evaluating each condition alone left the dependent ones
450
+ // unevaluable and named the first non-true one as the blocker,
451
+ // often a satisfied guard sitting ahead of the real one.
452
+ const pkg = matchedPackages[ruleIndex] ?? '';
453
+ const imports = matchedImports[ruleIndex] ?? [];
454
+ const held = [];
455
+ let stopped;
357
456
  for (const cond of conditions) {
358
457
  if (cond.text === '<expression>') {
359
458
  cond.note = 'No location text available; cannot evaluate standalone.';
360
- continue;
459
+ stopped = 'Not evaluated: an earlier condition has no location text.';
460
+ break;
461
+ }
462
+ // Keep the query under the command-line limit by dropping the
463
+ // oldest held terms. A shorter prefix only widens the solutions,
464
+ // so a false stays a real blocker; a dropped assignment makes a
465
+ // later term unsafe, which comes back unevaluable, not guessed.
466
+ let prefix = [...held, cond.text];
467
+ while (prefix.length > 1 && prefix.join('; ').length > MAX_PREFIX_CHARS) {
468
+ prefix = prefix.slice(1);
361
469
  }
362
- const evalOut = await evalConditionStandalone(cond.text, evalBase, opa, signal);
470
+ let evalOut;
471
+ try {
472
+ evalOut = await evalPrefixStandalone(prefix.join('; '), pkg, imports, evalBase, opa, signal);
473
+ }
474
+ catch (e) {
475
+ if (signal?.aborted)
476
+ throw e;
477
+ evalOut = {
478
+ result: 'unevaluable',
479
+ note: `Standalone eval failed: ${e instanceof Error ? e.message : String(e)}`,
480
+ };
481
+ }
482
+ if ('spawnFailure' in evalOut)
483
+ return evalOut.spawnFailure;
363
484
  cond.result = evalOut.result;
364
485
  if (evalOut.note)
365
486
  cond.note = evalOut.note;
487
+ if (evalOut.result === 'true') {
488
+ held.push(cond.text);
489
+ continue;
490
+ }
491
+ stopped =
492
+ evalOut.result === 'false'
493
+ ? 'Not reached: an earlier condition does not hold.'
494
+ : 'Not evaluated: an earlier condition could not be evaluated.';
495
+ break;
496
+ }
497
+ if (stopped !== undefined) {
498
+ for (const cond of conditions) {
499
+ if (cond.result === 'unevaluable' && cond.note === undefined)
500
+ cond.note = stopped;
501
+ }
366
502
  }
367
- const blockingCondition = conditions.find((c) => c.result !== 'true') ?? null;
503
+ // The blocker is the first condition that is not true, and only
504
+ // when it is a definite false; past one that could not be
505
+ // evaluated, naming a later condition would be a guess.
506
+ const firstNotTrue = conditions.find((c) => c.result !== 'true');
507
+ const blockingCondition = firstNotTrue?.result === 'false' ? firstNotTrue : null;
368
508
  rules.push({
369
509
  ruleIndex,
370
510
  isDefault: false,
@@ -376,9 +516,10 @@ export function registerRegoExplainUndefined(server, config) {
376
516
  }
377
517
  }
378
518
  const nonDefaultRules = rules.filter((r) => !r.isDefault);
379
- const summary = buildSummary(args.query, nonDefaultRules, defaultValue);
519
+ const summary = buildSummary(args.query, nonDefaultRules, defaultValue, viaDefault);
380
520
  return ok({
381
- queryResult: 'undefined',
521
+ queryResult: viaDefault ? 'default' : 'undefined',
522
+ ...(viaDefault ? { value: definedValue } : {}),
382
523
  summary,
383
524
  rulesFound: nonDefaultRules.length,
384
525
  defaultValue,