@vibecheckai/cli 3.4.0 → 3.5.1

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 (228) hide show
  1. package/bin/registry.js +154 -338
  2. package/bin/runners/context/generators/mcp.js +13 -15
  3. package/bin/runners/context/proof-context.js +1 -248
  4. package/bin/runners/lib/analysis-core.js +180 -198
  5. package/bin/runners/lib/analyzers.js +223 -1669
  6. package/bin/runners/lib/cli-output.js +210 -242
  7. package/bin/runners/lib/detectors-v2.js +785 -547
  8. package/bin/runners/lib/entitlements-v2.js +458 -96
  9. package/bin/runners/lib/error-handler.js +9 -16
  10. package/bin/runners/lib/global-flags.js +0 -37
  11. package/bin/runners/lib/route-truth.js +322 -1167
  12. package/bin/runners/lib/scan-output.js +469 -448
  13. package/bin/runners/lib/ship-output.js +27 -280
  14. package/bin/runners/lib/terminal-ui.js +733 -231
  15. package/bin/runners/lib/truth.js +321 -1004
  16. package/bin/runners/lib/unified-output.js +158 -162
  17. package/bin/runners/lib/upsell.js +204 -104
  18. package/bin/runners/runAllowlist.js +324 -0
  19. package/bin/runners/runAuth.js +95 -324
  20. package/bin/runners/runCheckpoint.js +21 -39
  21. package/bin/runners/runContext.js +24 -136
  22. package/bin/runners/runDoctor.js +67 -115
  23. package/bin/runners/runEvidencePack.js +219 -0
  24. package/bin/runners/runFix.js +5 -6
  25. package/bin/runners/runGuard.js +118 -212
  26. package/bin/runners/runInit.js +2 -14
  27. package/bin/runners/runInstall.js +281 -0
  28. package/bin/runners/runLabs.js +341 -0
  29. package/bin/runners/runMcp.js +52 -130
  30. package/bin/runners/runPolish.js +20 -43
  31. package/bin/runners/runProve.js +3 -13
  32. package/bin/runners/runReality.js +0 -14
  33. package/bin/runners/runReport.js +2 -3
  34. package/bin/runners/runScan.js +44 -511
  35. package/bin/runners/runShip.js +14 -28
  36. package/bin/runners/runValidate.js +2 -19
  37. package/bin/runners/runWatch.js +54 -118
  38. package/bin/vibecheck.js +41 -148
  39. package/mcp-server/ARCHITECTURE.md +339 -0
  40. package/mcp-server/__tests__/cache.test.ts +313 -0
  41. package/mcp-server/__tests__/executor.test.ts +239 -0
  42. package/mcp-server/__tests__/fixtures/exclusion-test/.cache/webpack/cache.pack +1 -0
  43. package/mcp-server/__tests__/fixtures/exclusion-test/.next/server/chunk.js +3 -0
  44. package/mcp-server/__tests__/fixtures/exclusion-test/.turbo/cache.json +3 -0
  45. package/mcp-server/__tests__/fixtures/exclusion-test/.venv/lib/env.py +3 -0
  46. package/mcp-server/__tests__/fixtures/exclusion-test/dist/bundle.js +3 -0
  47. package/mcp-server/__tests__/fixtures/exclusion-test/package.json +5 -0
  48. package/mcp-server/__tests__/fixtures/exclusion-test/src/app.ts +5 -0
  49. package/mcp-server/__tests__/fixtures/exclusion-test/venv/lib/config.py +4 -0
  50. package/mcp-server/__tests__/ids.test.ts +345 -0
  51. package/mcp-server/__tests__/integration/tools.test.ts +410 -0
  52. package/mcp-server/__tests__/registry.test.ts +365 -0
  53. package/mcp-server/__tests__/sandbox.test.ts +323 -0
  54. package/mcp-server/__tests__/schemas.test.ts +372 -0
  55. package/mcp-server/benchmarks/run-benchmarks.ts +304 -0
  56. package/mcp-server/examples/doctor.request.json +14 -0
  57. package/mcp-server/examples/doctor.response.json +53 -0
  58. package/mcp-server/examples/error.response.json +15 -0
  59. package/mcp-server/examples/scan.request.json +14 -0
  60. package/mcp-server/examples/scan.response.json +108 -0
  61. package/mcp-server/handlers/tool-handler.ts +671 -0
  62. package/mcp-server/index-v3.ts +293 -0
  63. package/mcp-server/index.js +1072 -1573
  64. package/mcp-server/index.old.js +4137 -0
  65. package/mcp-server/lib/cache.ts +341 -0
  66. package/mcp-server/lib/errors.ts +346 -0
  67. package/mcp-server/lib/executor.ts +792 -0
  68. package/mcp-server/lib/ids.ts +238 -0
  69. package/mcp-server/lib/logger.ts +368 -0
  70. package/mcp-server/lib/metrics.ts +365 -0
  71. package/mcp-server/lib/sandbox.ts +337 -0
  72. package/mcp-server/lib/validator.ts +229 -0
  73. package/mcp-server/package-lock.json +165 -0
  74. package/mcp-server/package.json +32 -7
  75. package/mcp-server/premium-tools.js +2 -2
  76. package/mcp-server/registry/tools.json +476 -0
  77. package/mcp-server/schemas/error-envelope.schema.json +125 -0
  78. package/mcp-server/schemas/finding.schema.json +167 -0
  79. package/mcp-server/schemas/report-artifact.schema.json +88 -0
  80. package/mcp-server/schemas/run-request.schema.json +75 -0
  81. package/mcp-server/schemas/verdict.schema.json +168 -0
  82. package/mcp-server/tier-auth.d.ts +71 -0
  83. package/mcp-server/tier-auth.js +371 -183
  84. package/mcp-server/truth-context.js +90 -131
  85. package/mcp-server/truth-firewall-tools.js +1000 -1611
  86. package/mcp-server/tsconfig.json +34 -0
  87. package/mcp-server/vibecheck-tools.js +2 -2
  88. package/mcp-server/vitest.config.ts +16 -0
  89. package/package.json +3 -4
  90. package/bin/runners/lib/agent-firewall/ai/false-positive-analyzer.js +0 -474
  91. package/bin/runners/lib/agent-firewall/change-packet/builder.js +0 -488
  92. package/bin/runners/lib/agent-firewall/change-packet/schema.json +0 -228
  93. package/bin/runners/lib/agent-firewall/change-packet/store.js +0 -200
  94. package/bin/runners/lib/agent-firewall/claims/claim-types.js +0 -21
  95. package/bin/runners/lib/agent-firewall/claims/extractor.js +0 -303
  96. package/bin/runners/lib/agent-firewall/claims/patterns.js +0 -24
  97. package/bin/runners/lib/agent-firewall/critic/index.js +0 -151
  98. package/bin/runners/lib/agent-firewall/critic/judge.js +0 -432
  99. package/bin/runners/lib/agent-firewall/critic/prompts.js +0 -305
  100. package/bin/runners/lib/agent-firewall/evidence/auth-evidence.js +0 -88
  101. package/bin/runners/lib/agent-firewall/evidence/contract-evidence.js +0 -75
  102. package/bin/runners/lib/agent-firewall/evidence/env-evidence.js +0 -127
  103. package/bin/runners/lib/agent-firewall/evidence/resolver.js +0 -102
  104. package/bin/runners/lib/agent-firewall/evidence/route-evidence.js +0 -213
  105. package/bin/runners/lib/agent-firewall/evidence/side-effect-evidence.js +0 -145
  106. package/bin/runners/lib/agent-firewall/fs-hook/daemon.js +0 -19
  107. package/bin/runners/lib/agent-firewall/fs-hook/installer.js +0 -87
  108. package/bin/runners/lib/agent-firewall/fs-hook/watcher.js +0 -184
  109. package/bin/runners/lib/agent-firewall/git-hook/pre-commit.js +0 -163
  110. package/bin/runners/lib/agent-firewall/ide-extension/cursor.js +0 -107
  111. package/bin/runners/lib/agent-firewall/ide-extension/vscode.js +0 -68
  112. package/bin/runners/lib/agent-firewall/ide-extension/windsurf.js +0 -66
  113. package/bin/runners/lib/agent-firewall/interceptor/base.js +0 -304
  114. package/bin/runners/lib/agent-firewall/interceptor/cursor.js +0 -35
  115. package/bin/runners/lib/agent-firewall/interceptor/vscode.js +0 -35
  116. package/bin/runners/lib/agent-firewall/interceptor/windsurf.js +0 -34
  117. package/bin/runners/lib/agent-firewall/lawbook/distributor.js +0 -465
  118. package/bin/runners/lib/agent-firewall/lawbook/evaluator.js +0 -604
  119. package/bin/runners/lib/agent-firewall/lawbook/index.js +0 -304
  120. package/bin/runners/lib/agent-firewall/lawbook/registry.js +0 -514
  121. package/bin/runners/lib/agent-firewall/lawbook/schema.js +0 -420
  122. package/bin/runners/lib/agent-firewall/logger.js +0 -141
  123. package/bin/runners/lib/agent-firewall/policy/default-policy.json +0 -90
  124. package/bin/runners/lib/agent-firewall/policy/engine.js +0 -103
  125. package/bin/runners/lib/agent-firewall/policy/loader.js +0 -451
  126. package/bin/runners/lib/agent-firewall/policy/rules/auth-drift.js +0 -50
  127. package/bin/runners/lib/agent-firewall/policy/rules/contract-drift.js +0 -50
  128. package/bin/runners/lib/agent-firewall/policy/rules/fake-success.js +0 -86
  129. package/bin/runners/lib/agent-firewall/policy/rules/ghost-env.js +0 -162
  130. package/bin/runners/lib/agent-firewall/policy/rules/ghost-route.js +0 -189
  131. package/bin/runners/lib/agent-firewall/policy/rules/scope.js +0 -93
  132. package/bin/runners/lib/agent-firewall/policy/rules/unsafe-side-effect.js +0 -57
  133. package/bin/runners/lib/agent-firewall/policy/schema.json +0 -183
  134. package/bin/runners/lib/agent-firewall/policy/verdict.js +0 -54
  135. package/bin/runners/lib/agent-firewall/proposal/extractor.js +0 -394
  136. package/bin/runners/lib/agent-firewall/proposal/index.js +0 -212
  137. package/bin/runners/lib/agent-firewall/proposal/schema.js +0 -251
  138. package/bin/runners/lib/agent-firewall/proposal/validator.js +0 -386
  139. package/bin/runners/lib/agent-firewall/reality/index.js +0 -332
  140. package/bin/runners/lib/agent-firewall/reality/state.js +0 -625
  141. package/bin/runners/lib/agent-firewall/reality/watcher.js +0 -322
  142. package/bin/runners/lib/agent-firewall/risk/index.js +0 -173
  143. package/bin/runners/lib/agent-firewall/risk/scorer.js +0 -328
  144. package/bin/runners/lib/agent-firewall/risk/thresholds.js +0 -321
  145. package/bin/runners/lib/agent-firewall/risk/vectors.js +0 -421
  146. package/bin/runners/lib/agent-firewall/simulator/diff-simulator.js +0 -472
  147. package/bin/runners/lib/agent-firewall/simulator/import-resolver.js +0 -346
  148. package/bin/runners/lib/agent-firewall/simulator/index.js +0 -181
  149. package/bin/runners/lib/agent-firewall/simulator/route-validator.js +0 -380
  150. package/bin/runners/lib/agent-firewall/time-machine/incident-correlator.js +0 -661
  151. package/bin/runners/lib/agent-firewall/time-machine/index.js +0 -267
  152. package/bin/runners/lib/agent-firewall/time-machine/replay-engine.js +0 -436
  153. package/bin/runners/lib/agent-firewall/time-machine/state-reconstructor.js +0 -490
  154. package/bin/runners/lib/agent-firewall/time-machine/timeline-builder.js +0 -530
  155. package/bin/runners/lib/agent-firewall/truthpack/index.js +0 -67
  156. package/bin/runners/lib/agent-firewall/truthpack/loader.js +0 -137
  157. package/bin/runners/lib/agent-firewall/unblock/planner.js +0 -337
  158. package/bin/runners/lib/agent-firewall/utils/ignore-checker.js +0 -118
  159. package/bin/runners/lib/api-client.js +0 -269
  160. package/bin/runners/lib/authority-badge.js +0 -425
  161. package/bin/runners/lib/engines/accessibility-engine.js +0 -190
  162. package/bin/runners/lib/engines/api-consistency-engine.js +0 -162
  163. package/bin/runners/lib/engines/ast-cache.js +0 -99
  164. package/bin/runners/lib/engines/code-quality-engine.js +0 -255
  165. package/bin/runners/lib/engines/console-logs-engine.js +0 -115
  166. package/bin/runners/lib/engines/cross-file-analysis-engine.js +0 -268
  167. package/bin/runners/lib/engines/dead-code-engine.js +0 -198
  168. package/bin/runners/lib/engines/deprecated-api-engine.js +0 -226
  169. package/bin/runners/lib/engines/empty-catch-engine.js +0 -150
  170. package/bin/runners/lib/engines/file-filter.js +0 -131
  171. package/bin/runners/lib/engines/hardcoded-secrets-engine.js +0 -251
  172. package/bin/runners/lib/engines/mock-data-engine.js +0 -272
  173. package/bin/runners/lib/engines/parallel-processor.js +0 -71
  174. package/bin/runners/lib/engines/performance-issues-engine.js +0 -265
  175. package/bin/runners/lib/engines/security-vulnerabilities-engine.js +0 -243
  176. package/bin/runners/lib/engines/todo-fixme-engine.js +0 -115
  177. package/bin/runners/lib/engines/type-aware-engine.js +0 -152
  178. package/bin/runners/lib/engines/unsafe-regex-engine.js +0 -225
  179. package/bin/runners/lib/engines/vibecheck-engines/README.md +0 -53
  180. package/bin/runners/lib/engines/vibecheck-engines/index.js +0 -15
  181. package/bin/runners/lib/engines/vibecheck-engines/lib/ast-cache.js +0 -164
  182. package/bin/runners/lib/engines/vibecheck-engines/lib/code-quality-engine.js +0 -291
  183. package/bin/runners/lib/engines/vibecheck-engines/lib/console-logs-engine.js +0 -83
  184. package/bin/runners/lib/engines/vibecheck-engines/lib/dead-code-engine.js +0 -198
  185. package/bin/runners/lib/engines/vibecheck-engines/lib/deprecated-api-engine.js +0 -275
  186. package/bin/runners/lib/engines/vibecheck-engines/lib/empty-catch-engine.js +0 -167
  187. package/bin/runners/lib/engines/vibecheck-engines/lib/file-filter.js +0 -217
  188. package/bin/runners/lib/engines/vibecheck-engines/lib/hardcoded-secrets-engine.js +0 -139
  189. package/bin/runners/lib/engines/vibecheck-engines/lib/mock-data-engine.js +0 -140
  190. package/bin/runners/lib/engines/vibecheck-engines/lib/parallel-processor.js +0 -164
  191. package/bin/runners/lib/engines/vibecheck-engines/lib/performance-issues-engine.js +0 -234
  192. package/bin/runners/lib/engines/vibecheck-engines/lib/type-aware-engine.js +0 -217
  193. package/bin/runners/lib/engines/vibecheck-engines/lib/unsafe-regex-engine.js +0 -78
  194. package/bin/runners/lib/engines/vibecheck-engines/package.json +0 -13
  195. package/bin/runners/lib/exit-codes.js +0 -275
  196. package/bin/runners/lib/fingerprint.js +0 -377
  197. package/bin/runners/lib/help-formatter.js +0 -413
  198. package/bin/runners/lib/logger.js +0 -38
  199. package/bin/runners/lib/ship-output-enterprise.js +0 -239
  200. package/bin/runners/lib/unified-cli-output.js +0 -604
  201. package/bin/runners/runAgent.d.ts +0 -5
  202. package/bin/runners/runAgent.js +0 -161
  203. package/bin/runners/runApprove.js +0 -1200
  204. package/bin/runners/runClassify.js +0 -859
  205. package/bin/runners/runContext.d.ts +0 -4
  206. package/bin/runners/runFirewall.d.ts +0 -5
  207. package/bin/runners/runFirewall.js +0 -134
  208. package/bin/runners/runFirewallHook.d.ts +0 -5
  209. package/bin/runners/runFirewallHook.js +0 -56
  210. package/bin/runners/runPolish.d.ts +0 -4
  211. package/bin/runners/runProof.zip +0 -0
  212. package/bin/runners/runTruth.d.ts +0 -5
  213. package/bin/runners/runTruth.js +0 -101
  214. package/mcp-server/HARDENING_SUMMARY.md +0 -299
  215. package/mcp-server/agent-firewall-interceptor.js +0 -500
  216. package/mcp-server/authority-tools.js +0 -569
  217. package/mcp-server/conductor/conflict-resolver.js +0 -588
  218. package/mcp-server/conductor/execution-planner.js +0 -544
  219. package/mcp-server/conductor/index.js +0 -377
  220. package/mcp-server/conductor/lock-manager.js +0 -615
  221. package/mcp-server/conductor/request-queue.js +0 -550
  222. package/mcp-server/conductor/session-manager.js +0 -500
  223. package/mcp-server/conductor/tools.js +0 -510
  224. package/mcp-server/lib/api-client.cjs +0 -13
  225. package/mcp-server/lib/logger.cjs +0 -30
  226. package/mcp-server/logger.js +0 -173
  227. package/mcp-server/tools-v3.js +0 -706
  228. package/mcp-server/vibecheck-mcp-server-3.2.0.tgz +0 -0
@@ -1,86 +0,0 @@
1
- /**
2
- * Fake Success UI Rule
3
- *
4
- * Warns/blocks if UI shows success without mutation.
5
- */
6
-
7
- "use strict";
8
-
9
- const { CLAIM_TYPES } = require("../../claims/claim-types");
10
-
11
- /**
12
- * Evaluate fake success UI rule
13
- * @param {object} params
14
- * @param {array} params.claims - Extracted claims
15
- * @param {array} params.evidence - Evidence resolution results
16
- * @param {object} params.policy - Policy configuration
17
- * @returns {object|null} Violation or null
18
- */
19
- function evaluate({ claims, evidence, policy }) {
20
- const ruleConfig = policy.rules?.fake_success_ui;
21
-
22
- if (!ruleConfig || !ruleConfig.enabled) {
23
- return null;
24
- }
25
-
26
- // Find UI success claims
27
- const successClaims = claims.filter(c => c.type === CLAIM_TYPES.UI_SUCCESS);
28
-
29
- if (successClaims.length === 0) {
30
- return null;
31
- }
32
-
33
- // Filter out false positives: if there's an HTTP call in the same file, it's likely a response check
34
- const realSuccessClaims = successClaims.filter(claim => {
35
- const claimFile = claim.pointer ? claim.pointer.split(":")[0] : "";
36
- if (!claimFile) return true;
37
-
38
- // Check if there's an HTTP call in the same file (within reasonable distance)
39
- const claimLine = claim.pointer ? parseInt(claim.pointer.split(":")[1]?.split("-")[0] || "0", 10) : 0;
40
- const hasNearbyHttpCall = claims.some(c => {
41
- if (c.type !== CLAIM_TYPES.HTTP_CALL && c.type !== CLAIM_TYPES.ROUTE) return false;
42
- const cFile = c.pointer ? c.pointer.split(":")[0] : "";
43
- if (cFile !== claimFile) return false;
44
- const cLine = c.pointer ? parseInt(c.pointer.split(":")[1]?.split("-")[0] || "0", 10) : 0;
45
- // Within 50 lines is considered "nearby"
46
- return Math.abs(cLine - claimLine) <= 50;
47
- });
48
-
49
- // If there's a nearby HTTP call, this is likely checking the response, not showing UI
50
- // Only flag if there's NO HTTP call nearby
51
- return !hasNearbyHttpCall;
52
- });
53
-
54
- if (realSuccessClaims.length === 0) {
55
- return null; // All were false positives (likely API response checks)
56
- }
57
-
58
- // Check if there's a corresponding HTTP call or side effect globally
59
- const hasHttpCall = claims.some(c =>
60
- c.type === CLAIM_TYPES.HTTP_CALL || c.type === CLAIM_TYPES.ROUTE
61
- );
62
-
63
- const hasSideEffect = claims.some(c => c.type === CLAIM_TYPES.SIDE_EFFECT);
64
-
65
- if (!hasHttpCall && !hasSideEffect) {
66
- // Check if domain requires blocking
67
- const blockDomains = ruleConfig.block_if_domain || [];
68
- const fileDomain = realSuccessClaims[0].domain || "general";
69
-
70
- const shouldBlock = blockDomains.includes(fileDomain);
71
-
72
- return {
73
- rule: "fake_success_ui",
74
- severity: shouldBlock ? "block" : (ruleConfig.severity || "warn"),
75
- message: `Fake success UI: Success message shown but no HTTP call or side effect detected`,
76
- claimId: `claim_${claims.indexOf(realSuccessClaims[0])}`,
77
- claim: realSuccessClaims[0]
78
- };
79
- }
80
-
81
- return null;
82
- }
83
-
84
- module.exports = {
85
- evaluate
86
- };
@@ -1,162 +0,0 @@
1
- /**
2
- * Ghost Env Rule
3
- *
4
- * Blocks if process.env.X used but not declared.
5
- * Includes smart whitelisting to reduce false positives.
6
- */
7
-
8
- "use strict";
9
-
10
- const { CLAIM_TYPES } = require("../../claims/claim-types");
11
-
12
- /**
13
- * Common environment variables that are safe to use without explicit declaration.
14
- * These are well-known Node.js, Next.js, and common deployment platform vars.
15
- */
16
- const SAFE_ENV_VARS = new Set([
17
- // Node.js core
18
- "NODE_ENV",
19
- "NODE_OPTIONS",
20
- "NODE_PATH",
21
- "NODE_DEBUG",
22
-
23
- // Next.js / React
24
- "NEXT_PUBLIC_", // Prefix pattern
25
- "REACT_APP_", // Prefix pattern
26
- "VERCEL",
27
- "VERCEL_ENV",
28
- "VERCEL_URL",
29
- "NEXT_RUNTIME",
30
-
31
- // Common deployment
32
- "PORT",
33
- "HOST",
34
- "HOSTNAME",
35
- "CI",
36
- "DEBUG",
37
- "LOG_LEVEL",
38
- "TZ",
39
- "LANG",
40
- "HOME",
41
- "USER",
42
- "PATH",
43
- "PWD",
44
- "SHELL",
45
- "TERM",
46
-
47
- // Testing
48
- "TEST",
49
- "JEST_WORKER_ID",
50
- "VITEST",
51
-
52
- // Build tools
53
- "npm_package_name",
54
- "npm_package_version",
55
- "npm_lifecycle_event",
56
- ]);
57
-
58
- /**
59
- * Prefix patterns that are safe
60
- */
61
- const SAFE_ENV_PREFIXES = [
62
- "NEXT_PUBLIC_",
63
- "REACT_APP_",
64
- "VITE_",
65
- "npm_",
66
- "GITHUB_",
67
- "CI_",
68
- "VERCEL_",
69
- "RAILWAY_",
70
- "RENDER_",
71
- "HEROKU_",
72
- "AWS_",
73
- ];
74
-
75
- /**
76
- * Check if an env var is in the safe list
77
- * @param {string} varName - Environment variable name
78
- * @returns {boolean} Is safe
79
- */
80
- function isSafeEnvVar(varName) {
81
- if (!varName || typeof varName !== 'string') return false;
82
-
83
- const normalized = varName.toUpperCase();
84
-
85
- // Direct match
86
- if (SAFE_ENV_VARS.has(normalized)) return true;
87
-
88
- // Prefix match
89
- for (const prefix of SAFE_ENV_PREFIXES) {
90
- if (normalized.startsWith(prefix)) return true;
91
- }
92
-
93
- return false;
94
- }
95
-
96
- /**
97
- * Evaluate ghost env rule
98
- * @param {object} params
99
- * @param {array} params.claims - Extracted claims
100
- * @param {array} params.evidence - Evidence resolution results
101
- * @param {object} params.policy - Policy configuration
102
- * @returns {object|null} Violation or null
103
- */
104
- function evaluate({ claims, evidence, policy }) {
105
- const ruleConfig = policy.rules?.ghost_env;
106
-
107
- if (!ruleConfig || !ruleConfig.enabled) {
108
- return null;
109
- }
110
-
111
- // Get custom whitelist from policy
112
- const customWhitelist = new Set(ruleConfig.whitelist || []);
113
-
114
- // Find env claims with UNPROVEN evidence
115
- for (let i = 0; i < claims.length; i++) {
116
- const claim = claims[i];
117
-
118
- if (claim.type === CLAIM_TYPES.ENV) {
119
- const ev = evidence.find(e => e.claimId === `claim_${i}`);
120
-
121
- if (ev && ev.result === "UNPROVEN") {
122
- const envVar = String(claim.value || claim.key || "");
123
-
124
- // Skip if it's a known safe env var
125
- if (isSafeEnvVar(envVar)) {
126
- continue;
127
- }
128
-
129
- // Skip if in custom whitelist
130
- if (customWhitelist.has(envVar)) {
131
- continue;
132
- }
133
-
134
- // Skip if it's a fallback pattern (e.g., process.env.X || 'default')
135
- if (claim.hasFallback) {
136
- // Downgrade to warning instead of block
137
- return {
138
- rule: "ghost_env",
139
- severity: "warn",
140
- message: `Env var ${envVar} is used with fallback but not declared`,
141
- claimId: `claim_${i}`,
142
- claim
143
- };
144
- }
145
-
146
- return {
147
- rule: "ghost_env",
148
- severity: ruleConfig.severity || "block",
149
- message: `Ghost env var: ${envVar} is used but not declared`,
150
- claimId: `claim_${i}`,
151
- claim
152
- };
153
- }
154
- }
155
- }
156
-
157
- return null;
158
- }
159
-
160
- module.exports = {
161
- evaluate
162
- };
@@ -1,189 +0,0 @@
1
- /**
2
- * Ghost Route Rule
3
- *
4
- * Blocks if UI references route not registered in truthpack.
5
- * Includes smart detection of external APIs and common patterns.
6
- */
7
-
8
- "use strict";
9
-
10
- const { CLAIM_TYPES } = require("../../claims/claim-types");
11
-
12
- /**
13
- * Patterns that indicate an external API (not a local route)
14
- */
15
- const EXTERNAL_API_PATTERNS = [
16
- // Full URLs
17
- /^https?:\/\//i,
18
- /^\/\/[a-z]/i,
19
-
20
- // Common external API domains
21
- /api\.github\.com/i,
22
- /api\.stripe\.com/i,
23
- /api\.openai\.com/i,
24
- /api\.anthropic\.com/i,
25
- /api\.twilio\.com/i,
26
- /api\.sendgrid\.com/i,
27
- /graph\.facebook\.com/i,
28
- /api\.twitter\.com/i,
29
- /googleapis\.com/i,
30
- /aws\.amazon\.com/i,
31
- /cloudflare\.com/i,
32
- /api\.clerk\.dev/i,
33
- /api\.auth0\.com/i,
34
- /api\.supabase\.co/i,
35
- /api\.vercel\.app/i,
36
-
37
- // GraphQL endpoints
38
- /graphql/i,
39
-
40
- // Webhook patterns
41
- /webhook/i,
42
- /hook\//i,
43
- ];
44
-
45
- /**
46
- * Path patterns that are safe to skip (dynamic or template)
47
- */
48
- const SAFE_ROUTE_PATTERNS = [
49
- // Dynamic segments
50
- /\$\{/, // Template literals
51
- /\[.*\]/, // Dynamic route segments [id]
52
- /:\w+/, // URL params :id
53
- /\{\{.*\}\}/, // Template syntax
54
-
55
- // Hash-only routes
56
- /^#/,
57
-
58
- // Query-only
59
- /^\?/,
60
-
61
- // Empty or undefined
62
- /^undefined$/i,
63
- /^null$/i,
64
- ];
65
-
66
- /**
67
- * Check if a route is external
68
- * @param {string} route - Route path
69
- * @returns {boolean} Is external
70
- */
71
- function isExternalRoute(route) {
72
- if (!route || typeof route !== 'string') return true;
73
-
74
- const trimmed = route.trim();
75
-
76
- // Check external patterns
77
- for (const pattern of EXTERNAL_API_PATTERNS) {
78
- if (pattern.test(trimmed)) return true;
79
- }
80
-
81
- return false;
82
- }
83
-
84
- /**
85
- * Check if a route should be skipped
86
- * @param {string} route - Route path
87
- * @returns {boolean} Should skip
88
- */
89
- function shouldSkipRoute(route) {
90
- if (!route || typeof route !== 'string') return true;
91
-
92
- const trimmed = route.trim();
93
-
94
- // Skip empty routes
95
- if (trimmed.length === 0) return true;
96
-
97
- // Check safe patterns
98
- for (const pattern of SAFE_ROUTE_PATTERNS) {
99
- if (pattern.test(trimmed)) return true;
100
- }
101
-
102
- return false;
103
- }
104
-
105
- /**
106
- * Check if route is a local API route
107
- * @param {string} route - Route path
108
- * @returns {boolean} Is local API
109
- */
110
- function isLocalApiRoute(route) {
111
- if (!route || typeof route !== 'string') return false;
112
-
113
- const trimmed = route.trim().toLowerCase();
114
-
115
- // Must start with /api/ to be a local Next.js API route
116
- return trimmed.startsWith('/api/');
117
- }
118
-
119
- /**
120
- * Evaluate ghost route rule
121
- * @param {object} params
122
- * @param {array} params.claims - Extracted claims
123
- * @param {array} params.evidence - Evidence resolution results
124
- * @param {object} params.policy - Policy configuration
125
- * @returns {object|null} Violation or null
126
- */
127
- function evaluate({ claims, evidence, policy }) {
128
- const ruleConfig = policy.rules?.ghost_route;
129
-
130
- if (!ruleConfig || !ruleConfig.enabled) {
131
- return null;
132
- }
133
-
134
- // Get custom whitelist from policy
135
- const customWhitelist = new Set(ruleConfig.whitelist || []);
136
-
137
- // Find route claims with UNPROVEN evidence
138
- for (let i = 0; i < claims.length; i++) {
139
- const claim = claims[i];
140
-
141
- if (claim.type === CLAIM_TYPES.ROUTE || claim.type === CLAIM_TYPES.HTTP_CALL) {
142
- const ev = evidence.find(e => e.claimId === `claim_${i}`);
143
-
144
- // Skip if evidence shows it's already proven
145
- if (ev && ev.result === "PROVEN") {
146
- continue;
147
- }
148
-
149
- if (ev && ev.result === "UNPROVEN") {
150
- const routePath = String(claim.value || "").trim();
151
-
152
- // Skip dynamic or template routes
153
- if (shouldSkipRoute(routePath)) {
154
- continue;
155
- }
156
-
157
- // Skip external API calls
158
- if (isExternalRoute(routePath)) {
159
- continue;
160
- }
161
-
162
- // Only flag local API routes
163
- if (!isLocalApiRoute(routePath)) {
164
- // Not a local API route - could be page navigation, skip
165
- continue;
166
- }
167
-
168
- // Skip if in custom whitelist
169
- if (customWhitelist.has(routePath)) {
170
- continue;
171
- }
172
-
173
- return {
174
- rule: "ghost_route",
175
- severity: ruleConfig.severity || "block",
176
- message: `Ghost route: ${routePath} is referenced but not registered in truthpack`,
177
- claimId: `claim_${i}`,
178
- claim
179
- };
180
- }
181
- }
182
- }
183
-
184
- return null;
185
- }
186
-
187
- module.exports = {
188
- evaluate
189
- };
@@ -1,93 +0,0 @@
1
- /**
2
- * Scope Explosion Rule
3
- *
4
- * Blocks if too many files touched.
5
- */
6
-
7
- "use strict";
8
-
9
- /**
10
- * Evaluate scope explosion rule
11
- * @param {object} params
12
- * @param {array} params.files - Changed files
13
- * @param {string} params.intent - Agent intent message
14
- * @param {object} params.policy - Policy configuration
15
- * @returns {object|null} Violation or null
16
- */
17
- function evaluate({ files, intent, policy }) {
18
- const ruleConfig = policy.rules?.scope_explosion;
19
-
20
- if (!ruleConfig || !ruleConfig.enabled) {
21
- return null;
22
- }
23
-
24
- const scope = policy.scope || {};
25
- const maxFiles = scope.max_files_touched || 10;
26
- const maxLines = scope.max_lines_changed || 600;
27
- const requireIntent = scope.require_intent_for_expand_scope || false;
28
-
29
- const totalFiles = files.length;
30
- const totalLines = files.reduce((sum, f) => sum + (f.linesChanged || 0), 0);
31
-
32
- // Check file count
33
- if (totalFiles > maxFiles) {
34
- const hasIntent = intent && intent.trim().length > 0;
35
-
36
- if (requireIntent && !hasIntent) {
37
- return {
38
- rule: "scope_explosion",
39
- severity: ruleConfig.severity || "block",
40
- message: `Scope explosion: ${totalFiles} files touched (max: ${maxFiles}). Intent required for scope expansion.`,
41
- metadata: {
42
- totalFiles,
43
- maxFiles,
44
- hasIntent
45
- }
46
- };
47
- } else if (!requireIntent) {
48
- return {
49
- rule: "scope_explosion",
50
- severity: ruleConfig.severity || "block",
51
- message: `Scope explosion: ${totalFiles} files touched (max: ${maxFiles})`,
52
- metadata: {
53
- totalFiles,
54
- maxFiles
55
- }
56
- };
57
- }
58
- }
59
-
60
- // Check line count
61
- if (totalLines > maxLines) {
62
- const hasIntent = intent && intent.trim().length > 0;
63
-
64
- if (requireIntent && !hasIntent) {
65
- return {
66
- rule: "scope_explosion",
67
- severity: ruleConfig.severity || "block",
68
- message: `Scope explosion: ${totalLines} lines changed (max: ${maxLines}). Intent required for scope expansion.`,
69
- metadata: {
70
- totalLines,
71
- maxLines,
72
- hasIntent
73
- }
74
- };
75
- } else if (!requireIntent) {
76
- return {
77
- rule: "scope_explosion",
78
- severity: ruleConfig.severity || "block",
79
- message: `Scope explosion: ${totalLines} lines changed (max: ${maxLines})`,
80
- metadata: {
81
- totalLines,
82
- maxLines
83
- }
84
- };
85
- }
86
- }
87
-
88
- return null;
89
- }
90
-
91
- module.exports = {
92
- evaluate
93
- };
@@ -1,57 +0,0 @@
1
- /**
2
- * Unsafe Side Effect Rule
3
- *
4
- * Blocks unverified side effects.
5
- */
6
-
7
- "use strict";
8
-
9
- const { CLAIM_TYPES } = require("../../claims/claim-types");
10
-
11
- /**
12
- * Evaluate unsafe side effect rule
13
- * @param {object} params
14
- * @param {array} params.claims - Extracted claims
15
- * @param {array} params.evidence - Evidence resolution results
16
- * @param {object} params.policy - Policy configuration
17
- * @returns {object|null} Violation or null
18
- */
19
- function evaluate({ claims, evidence, policy }) {
20
- const ruleConfig = policy.rules?.unsafe_side_effect;
21
-
22
- if (!ruleConfig || !ruleConfig.enabled) {
23
- return null;
24
- }
25
-
26
- const verification = policy.verification || {};
27
- const requireForDomains = verification.require_for_domains || [];
28
-
29
- // Find side effect claims
30
- for (let i = 0; i < claims.length; i++) {
31
- const claim = claims[i];
32
-
33
- if (claim.type === CLAIM_TYPES.SIDE_EFFECT) {
34
- const ev = evidence.find(e => e.claimId === `claim_${i}`);
35
-
36
- // Check if domain requires verification
37
- const claimDomain = claim.domain || "general";
38
- const requiresVerification = requireForDomains.includes(claimDomain);
39
-
40
- if (requiresVerification && ev && ev.result === "UNPROVEN") {
41
- return {
42
- rule: "unsafe_side_effect",
43
- severity: ruleConfig.severity || "block",
44
- message: `Unsafe side effect: ${claim.value} requires verification (test coverage or reality proof)`,
45
- claimId: `claim_${i}`,
46
- claim
47
- };
48
- }
49
- }
50
- }
51
-
52
- return null;
53
- }
54
-
55
- module.exports = {
56
- evaluate
57
- };