@vibecheckai/cli 3.5.1 → 3.5.2

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 (272) hide show
  1. package/bin/registry.js +406 -154
  2. package/bin/runners/context/analyzer.js +52 -1
  3. package/bin/runners/context/generators/mcp.js +15 -13
  4. package/bin/runners/context/git-context.js +3 -1
  5. package/bin/runners/context/proof-context.js +248 -1
  6. package/bin/runners/context/team-conventions.js +33 -7
  7. package/bin/runners/lib/agent-firewall/ai/false-positive-analyzer.js +474 -0
  8. package/bin/runners/lib/agent-firewall/change-packet/builder.js +488 -0
  9. package/bin/runners/lib/agent-firewall/change-packet/schema.json +228 -0
  10. package/bin/runners/lib/agent-firewall/change-packet/store.js +200 -0
  11. package/bin/runners/lib/agent-firewall/claims/claim-types.js +21 -0
  12. package/bin/runners/lib/agent-firewall/claims/extractor.js +303 -0
  13. package/bin/runners/lib/agent-firewall/claims/patterns.js +24 -0
  14. package/bin/runners/lib/agent-firewall/critic/index.js +151 -0
  15. package/bin/runners/lib/agent-firewall/critic/judge.js +432 -0
  16. package/bin/runners/lib/agent-firewall/critic/prompts.js +305 -0
  17. package/bin/runners/lib/agent-firewall/evidence/auth-evidence.js +88 -0
  18. package/bin/runners/lib/agent-firewall/evidence/contract-evidence.js +75 -0
  19. package/bin/runners/lib/agent-firewall/evidence/env-evidence.js +127 -0
  20. package/bin/runners/lib/agent-firewall/evidence/resolver.js +102 -0
  21. package/bin/runners/lib/agent-firewall/evidence/route-evidence.js +213 -0
  22. package/bin/runners/lib/agent-firewall/evidence/side-effect-evidence.js +145 -0
  23. package/bin/runners/lib/agent-firewall/fs-hook/daemon.js +19 -0
  24. package/bin/runners/lib/agent-firewall/fs-hook/installer.js +87 -0
  25. package/bin/runners/lib/agent-firewall/fs-hook/watcher.js +184 -0
  26. package/bin/runners/lib/agent-firewall/git-hook/pre-commit.js +163 -0
  27. package/bin/runners/lib/agent-firewall/ide-extension/cursor.js +107 -0
  28. package/bin/runners/lib/agent-firewall/ide-extension/vscode.js +68 -0
  29. package/bin/runners/lib/agent-firewall/ide-extension/windsurf.js +66 -0
  30. package/bin/runners/lib/agent-firewall/interceptor/base.js +304 -0
  31. package/bin/runners/lib/agent-firewall/interceptor/cursor.js +35 -0
  32. package/bin/runners/lib/agent-firewall/interceptor/vscode.js +35 -0
  33. package/bin/runners/lib/agent-firewall/interceptor/windsurf.js +34 -0
  34. package/bin/runners/lib/agent-firewall/lawbook/distributor.js +465 -0
  35. package/bin/runners/lib/agent-firewall/lawbook/evaluator.js +604 -0
  36. package/bin/runners/lib/agent-firewall/lawbook/index.js +304 -0
  37. package/bin/runners/lib/agent-firewall/lawbook/registry.js +514 -0
  38. package/bin/runners/lib/agent-firewall/lawbook/schema.js +420 -0
  39. package/bin/runners/lib/agent-firewall/logger.js +141 -0
  40. package/bin/runners/lib/agent-firewall/policy/default-policy.json +90 -0
  41. package/bin/runners/lib/agent-firewall/policy/engine.js +103 -0
  42. package/bin/runners/lib/agent-firewall/policy/loader.js +451 -0
  43. package/bin/runners/lib/agent-firewall/policy/rules/auth-drift.js +50 -0
  44. package/bin/runners/lib/agent-firewall/policy/rules/contract-drift.js +50 -0
  45. package/bin/runners/lib/agent-firewall/policy/rules/fake-success.js +86 -0
  46. package/bin/runners/lib/agent-firewall/policy/rules/ghost-env.js +162 -0
  47. package/bin/runners/lib/agent-firewall/policy/rules/ghost-route.js +189 -0
  48. package/bin/runners/lib/agent-firewall/policy/rules/scope.js +93 -0
  49. package/bin/runners/lib/agent-firewall/policy/rules/unsafe-side-effect.js +57 -0
  50. package/bin/runners/lib/agent-firewall/policy/schema.json +183 -0
  51. package/bin/runners/lib/agent-firewall/policy/verdict.js +54 -0
  52. package/bin/runners/lib/agent-firewall/proposal/extractor.js +394 -0
  53. package/bin/runners/lib/agent-firewall/proposal/index.js +212 -0
  54. package/bin/runners/lib/agent-firewall/proposal/schema.js +251 -0
  55. package/bin/runners/lib/agent-firewall/proposal/validator.js +386 -0
  56. package/bin/runners/lib/agent-firewall/reality/index.js +332 -0
  57. package/bin/runners/lib/agent-firewall/reality/state.js +625 -0
  58. package/bin/runners/lib/agent-firewall/reality/watcher.js +322 -0
  59. package/bin/runners/lib/agent-firewall/risk/index.js +173 -0
  60. package/bin/runners/lib/agent-firewall/risk/scorer.js +328 -0
  61. package/bin/runners/lib/agent-firewall/risk/thresholds.js +321 -0
  62. package/bin/runners/lib/agent-firewall/risk/vectors.js +421 -0
  63. package/bin/runners/lib/agent-firewall/simulator/diff-simulator.js +472 -0
  64. package/bin/runners/lib/agent-firewall/simulator/import-resolver.js +346 -0
  65. package/bin/runners/lib/agent-firewall/simulator/index.js +181 -0
  66. package/bin/runners/lib/agent-firewall/simulator/route-validator.js +380 -0
  67. package/bin/runners/lib/agent-firewall/time-machine/incident-correlator.js +661 -0
  68. package/bin/runners/lib/agent-firewall/time-machine/index.js +267 -0
  69. package/bin/runners/lib/agent-firewall/time-machine/replay-engine.js +436 -0
  70. package/bin/runners/lib/agent-firewall/time-machine/state-reconstructor.js +490 -0
  71. package/bin/runners/lib/agent-firewall/time-machine/timeline-builder.js +530 -0
  72. package/bin/runners/lib/agent-firewall/truthpack/index.js +67 -0
  73. package/bin/runners/lib/agent-firewall/truthpack/loader.js +137 -0
  74. package/bin/runners/lib/agent-firewall/unblock/planner.js +337 -0
  75. package/bin/runners/lib/agent-firewall/utils/ignore-checker.js +118 -0
  76. package/bin/runners/lib/analysis-core.js +220 -182
  77. package/bin/runners/lib/analyzers.js +2145 -224
  78. package/bin/runners/lib/api-client.js +269 -0
  79. package/bin/runners/lib/authority-badge.js +425 -0
  80. package/bin/runners/lib/cli-output.js +242 -210
  81. package/bin/runners/lib/default-config.js +127 -0
  82. package/bin/runners/lib/detectors-v2.js +547 -785
  83. package/bin/runners/lib/doctor/modules/security.js +3 -1
  84. package/bin/runners/lib/engine/ast-cache.js +210 -0
  85. package/bin/runners/lib/engine/auth-extractor.js +211 -0
  86. package/bin/runners/lib/engine/billing-extractor.js +112 -0
  87. package/bin/runners/lib/engine/enforcement-extractor.js +100 -0
  88. package/bin/runners/lib/engine/env-extractor.js +207 -0
  89. package/bin/runners/lib/engine/express-extractor.js +208 -0
  90. package/bin/runners/lib/engine/extractors.js +849 -0
  91. package/bin/runners/lib/engine/index.js +207 -0
  92. package/bin/runners/lib/engine/repo-index.js +514 -0
  93. package/bin/runners/lib/engine/types.js +124 -0
  94. package/bin/runners/lib/engines/accessibility-engine.js +190 -0
  95. package/bin/runners/lib/engines/api-consistency-engine.js +162 -0
  96. package/bin/runners/lib/engines/ast-cache.js +99 -0
  97. package/bin/runners/lib/engines/code-quality-engine.js +255 -0
  98. package/bin/runners/lib/engines/console-logs-engine.js +115 -0
  99. package/bin/runners/lib/engines/cross-file-analysis-engine.js +268 -0
  100. package/bin/runners/lib/engines/dead-code-engine.js +198 -0
  101. package/bin/runners/lib/engines/deprecated-api-engine.js +226 -0
  102. package/bin/runners/lib/engines/empty-catch-engine.js +150 -0
  103. package/bin/runners/lib/engines/file-filter.js +131 -0
  104. package/bin/runners/lib/engines/hardcoded-secrets-engine.js +251 -0
  105. package/bin/runners/lib/engines/mock-data-engine.js +272 -0
  106. package/bin/runners/lib/engines/parallel-processor.js +71 -0
  107. package/bin/runners/lib/engines/performance-issues-engine.js +265 -0
  108. package/bin/runners/lib/engines/security-vulnerabilities-engine.js +243 -0
  109. package/bin/runners/lib/engines/todo-fixme-engine.js +115 -0
  110. package/bin/runners/lib/engines/type-aware-engine.js +152 -0
  111. package/bin/runners/lib/engines/unsafe-regex-engine.js +225 -0
  112. package/bin/runners/lib/engines/vibecheck-engines/README.md +53 -0
  113. package/bin/runners/lib/engines/vibecheck-engines/index.js +15 -0
  114. package/bin/runners/lib/engines/vibecheck-engines/lib/ast-cache.js +164 -0
  115. package/bin/runners/lib/engines/vibecheck-engines/lib/code-quality-engine.js +291 -0
  116. package/bin/runners/lib/engines/vibecheck-engines/lib/console-logs-engine.js +83 -0
  117. package/bin/runners/lib/engines/vibecheck-engines/lib/dead-code-engine.js +198 -0
  118. package/bin/runners/lib/engines/vibecheck-engines/lib/deprecated-api-engine.js +275 -0
  119. package/bin/runners/lib/engines/vibecheck-engines/lib/empty-catch-engine.js +167 -0
  120. package/bin/runners/lib/engines/vibecheck-engines/lib/file-filter.js +217 -0
  121. package/bin/runners/lib/engines/vibecheck-engines/lib/hardcoded-secrets-engine.js +139 -0
  122. package/bin/runners/lib/engines/vibecheck-engines/lib/mock-data-engine.js +140 -0
  123. package/bin/runners/lib/engines/vibecheck-engines/lib/parallel-processor.js +164 -0
  124. package/bin/runners/lib/engines/vibecheck-engines/lib/performance-issues-engine.js +234 -0
  125. package/bin/runners/lib/engines/vibecheck-engines/lib/type-aware-engine.js +217 -0
  126. package/bin/runners/lib/engines/vibecheck-engines/lib/unsafe-regex-engine.js +78 -0
  127. package/bin/runners/lib/engines/vibecheck-engines/package.json +13 -0
  128. package/bin/runners/lib/entitlements-v2.js +152 -446
  129. package/bin/runners/lib/error-handler.js +60 -12
  130. package/bin/runners/lib/error-messages.js +289 -0
  131. package/bin/runners/lib/evidence-pack.js +7 -1
  132. package/bin/runners/lib/exit-codes.js +275 -0
  133. package/bin/runners/lib/finding-id.js +69 -0
  134. package/bin/runners/lib/finding-sorter.js +89 -0
  135. package/bin/runners/lib/fingerprint.js +377 -0
  136. package/bin/runners/lib/global-flags.js +37 -0
  137. package/bin/runners/lib/help-formatter.js +413 -0
  138. package/bin/runners/lib/logger.js +38 -0
  139. package/bin/runners/lib/next-action.js +560 -0
  140. package/bin/runners/lib/prerequisites.js +149 -0
  141. package/bin/runners/lib/route-detection.js +137 -68
  142. package/bin/runners/lib/route-truth.js +1167 -322
  143. package/bin/runners/lib/scan-output.js +504 -463
  144. package/bin/runners/lib/scan-runner.js +135 -0
  145. package/bin/runners/lib/schemas/ajv-validator.js +464 -0
  146. package/bin/runners/lib/schemas/error-envelope.schema.json +105 -0
  147. package/bin/runners/lib/schemas/finding-v3.schema.json +151 -0
  148. package/bin/runners/lib/schemas/report-artifact.schema.json +120 -0
  149. package/bin/runners/lib/schemas/run-request.schema.json +108 -0
  150. package/bin/runners/lib/schemas/validator.js +27 -0
  151. package/bin/runners/lib/schemas/verdict.schema.json +140 -0
  152. package/bin/runners/lib/ship-output-enterprise.js +239 -0
  153. package/bin/runners/lib/ship-output.js +328 -31
  154. package/bin/runners/lib/terminal-ui.js +234 -731
  155. package/bin/runners/lib/truth.js +1332 -308
  156. package/bin/runners/lib/unified-cli-output.js +604 -0
  157. package/bin/runners/lib/unified-output.js +163 -155
  158. package/bin/runners/lib/upsell.js +104 -204
  159. package/bin/runners/runAgent.d.ts +5 -0
  160. package/bin/runners/runAgent.js +161 -0
  161. package/bin/runners/runAllowlist.js +166 -101
  162. package/bin/runners/runApprove.js +1200 -0
  163. package/bin/runners/runAuth.js +373 -95
  164. package/bin/runners/runCheckpoint.js +59 -21
  165. package/bin/runners/runClassify.js +926 -0
  166. package/bin/runners/runContext.d.ts +4 -0
  167. package/bin/runners/runContext.js +136 -24
  168. package/bin/runners/runDoctor.js +115 -67
  169. package/bin/runners/runEvidencePack.js +239 -96
  170. package/bin/runners/runFirewall.d.ts +5 -0
  171. package/bin/runners/runFirewall.js +134 -0
  172. package/bin/runners/runFirewallHook.d.ts +5 -0
  173. package/bin/runners/runFirewallHook.js +56 -0
  174. package/bin/runners/runFix.js +6 -5
  175. package/bin/runners/runGuard.js +212 -118
  176. package/bin/runners/runInit.js +66 -21
  177. package/bin/runners/runLabs.js +204 -121
  178. package/bin/runners/runMcp.js +131 -60
  179. package/bin/runners/runPolish.d.ts +4 -0
  180. package/bin/runners/runPolish.js +43 -20
  181. package/bin/runners/runProof.zip +0 -0
  182. package/bin/runners/runProve.js +15 -5
  183. package/bin/runners/runQuickstart.js +531 -0
  184. package/bin/runners/runReality.js +14 -0
  185. package/bin/runners/runReport.js +36 -4
  186. package/bin/runners/runScan.js +689 -91
  187. package/bin/runners/runShip.js +96 -40
  188. package/bin/runners/runTruth.d.ts +5 -0
  189. package/bin/runners/runTruth.js +101 -0
  190. package/bin/runners/runValidate.js +21 -4
  191. package/bin/runners/runWatch.js +118 -54
  192. package/bin/scan.js +6 -1
  193. package/bin/vibecheck.js +297 -52
  194. package/mcp-server/HARDENING_SUMMARY.md +299 -0
  195. package/mcp-server/agent-firewall-interceptor.js +500 -0
  196. package/mcp-server/authority-tools.js +569 -0
  197. package/mcp-server/conductor/conflict-resolver.js +588 -0
  198. package/mcp-server/conductor/execution-planner.js +544 -0
  199. package/mcp-server/conductor/index.js +377 -0
  200. package/mcp-server/conductor/lock-manager.js +615 -0
  201. package/mcp-server/conductor/request-queue.js +550 -0
  202. package/mcp-server/conductor/session-manager.js +500 -0
  203. package/mcp-server/conductor/tools.js +510 -0
  204. package/mcp-server/deprecation-middleware.js +282 -0
  205. package/mcp-server/handlers/index.ts +15 -0
  206. package/mcp-server/handlers/tool-handler.ts +474 -591
  207. package/mcp-server/index.js +1748 -1099
  208. package/mcp-server/lib/api-client.cjs +13 -0
  209. package/mcp-server/lib/cache-wrapper.cjs +383 -0
  210. package/mcp-server/lib/error-envelope.js +138 -0
  211. package/mcp-server/lib/executor.ts +428 -721
  212. package/mcp-server/lib/index.ts +19 -0
  213. package/mcp-server/lib/logger.cjs +30 -0
  214. package/mcp-server/lib/rate-limiter.js +166 -0
  215. package/mcp-server/lib/sandbox.test.ts +519 -0
  216. package/mcp-server/lib/sandbox.ts +342 -284
  217. package/mcp-server/lib/types.ts +267 -0
  218. package/mcp-server/logger.js +173 -0
  219. package/mcp-server/package.json +11 -27
  220. package/mcp-server/premium-tools.js +2 -2
  221. package/mcp-server/registry/tool-registry.js +794 -0
  222. package/mcp-server/registry/tools.json +507 -378
  223. package/mcp-server/registry.test.ts +334 -0
  224. package/mcp-server/tests/tier-gating.test.js +297 -0
  225. package/mcp-server/tier-auth.js +492 -347
  226. package/mcp-server/tools-v3.js +950 -0
  227. package/mcp-server/truth-context.js +131 -90
  228. package/mcp-server/truth-firewall-tools.js +1612 -1001
  229. package/mcp-server/tsconfig.json +8 -5
  230. package/mcp-server/vibecheck-2.0-tools.js +14 -1
  231. package/mcp-server/vibecheck-mcp-server-3.2.0.tgz +0 -0
  232. package/mcp-server/vibecheck-tools.js +2 -2
  233. package/package.json +4 -3
  234. package/bin/runners/runInstall.js +0 -281
  235. package/mcp-server/ARCHITECTURE.md +0 -339
  236. package/mcp-server/__tests__/cache.test.ts +0 -313
  237. package/mcp-server/__tests__/executor.test.ts +0 -239
  238. package/mcp-server/__tests__/fixtures/exclusion-test/.cache/webpack/cache.pack +0 -1
  239. package/mcp-server/__tests__/fixtures/exclusion-test/.next/server/chunk.js +0 -3
  240. package/mcp-server/__tests__/fixtures/exclusion-test/.turbo/cache.json +0 -3
  241. package/mcp-server/__tests__/fixtures/exclusion-test/.venv/lib/env.py +0 -3
  242. package/mcp-server/__tests__/fixtures/exclusion-test/dist/bundle.js +0 -3
  243. package/mcp-server/__tests__/fixtures/exclusion-test/package.json +0 -5
  244. package/mcp-server/__tests__/fixtures/exclusion-test/src/app.ts +0 -5
  245. package/mcp-server/__tests__/fixtures/exclusion-test/venv/lib/config.py +0 -4
  246. package/mcp-server/__tests__/ids.test.ts +0 -345
  247. package/mcp-server/__tests__/integration/tools.test.ts +0 -410
  248. package/mcp-server/__tests__/registry.test.ts +0 -365
  249. package/mcp-server/__tests__/sandbox.test.ts +0 -323
  250. package/mcp-server/__tests__/schemas.test.ts +0 -372
  251. package/mcp-server/benchmarks/run-benchmarks.ts +0 -304
  252. package/mcp-server/examples/doctor.request.json +0 -14
  253. package/mcp-server/examples/doctor.response.json +0 -53
  254. package/mcp-server/examples/error.response.json +0 -15
  255. package/mcp-server/examples/scan.request.json +0 -14
  256. package/mcp-server/examples/scan.response.json +0 -108
  257. package/mcp-server/index-v3.ts +0 -293
  258. package/mcp-server/index.old.js +0 -4137
  259. package/mcp-server/lib/cache.ts +0 -341
  260. package/mcp-server/lib/errors.ts +0 -346
  261. package/mcp-server/lib/ids.ts +0 -238
  262. package/mcp-server/lib/logger.ts +0 -368
  263. package/mcp-server/lib/metrics.ts +0 -365
  264. package/mcp-server/lib/validator.ts +0 -229
  265. package/mcp-server/package-lock.json +0 -165
  266. package/mcp-server/schemas/error-envelope.schema.json +0 -125
  267. package/mcp-server/schemas/finding.schema.json +0 -167
  268. package/mcp-server/schemas/report-artifact.schema.json +0 -88
  269. package/mcp-server/schemas/run-request.schema.json +0 -75
  270. package/mcp-server/schemas/verdict.schema.json +0 -168
  271. package/mcp-server/tier-auth.d.ts +0 -71
  272. package/mcp-server/vitest.config.ts +0 -16
@@ -0,0 +1,488 @@
1
+ /**
2
+ * Change Packet Builder
3
+ *
4
+ * Builds change packets from diffs + agent intent.
5
+ * Each packet is a complete audit artifact of an AI code change attempt.
6
+ *
7
+ * Enhanced with:
8
+ * - Risk scoring
9
+ * - Simulation results
10
+ * - Critic verdict
11
+ * - Override tracking
12
+ */
13
+
14
+ "use strict";
15
+
16
+ const crypto = require("crypto");
17
+ const path = require("path");
18
+
19
+ /**
20
+ * @typedef {Object} ProofArtifact
21
+ * @property {string} changeId - Unique change identifier
22
+ * @property {string} decision - ALLOW, BLOCK, or REQUIRE_CONFIRMATION
23
+ * @property {Array} rulesTriggered - Rules that were triggered
24
+ * @property {Array} assumptionsFailed - Failed assumptions
25
+ * @property {number} riskScore - Numerical risk score
26
+ * @property {string} riskLevel - LOW, MEDIUM, HIGH, CRITICAL
27
+ * @property {Object} simulationResult - Result of diff simulation
28
+ * @property {Object} criticVerdict - Critic LLM verdict
29
+ * @property {string} timestamp - ISO timestamp
30
+ * @property {boolean} overrideUsed - Whether override was used
31
+ * @property {string} overrideBy - Who overrode (if applicable)
32
+ * @property {string} overrideReason - Reason for override
33
+ */
34
+
35
+ /**
36
+ * Build a change packet from diff and agent intent
37
+ * @param {object} params
38
+ * @param {string} params.agentId - Agent identifier
39
+ * @param {string} params.intent - Agent's stated intent
40
+ * @param {object} params.diff - Diff object { before, after, unified }
41
+ * @param {string} params.filePath - File path (relative to repo root)
42
+ * @param {object} params.claims - Extracted claims
43
+ * @param {object} params.evidence - Evidence resolution results
44
+ * @param {object} params.verdict - Policy verdict
45
+ * @param {object} params.unblockPlan - Unblock plan (if blocked)
46
+ * @param {object} params.policy - Policy used for evaluation
47
+ * @param {object} params.riskScore - Risk scoring result
48
+ * @param {object} params.simulationResult - Diff simulation result
49
+ * @param {object} params.criticVerdict - Critic LLM verdict
50
+ * @param {object} params.proposal - Structured change proposal
51
+ * @param {object} params.override - Override information
52
+ * @returns {object} Change packet
53
+ */
54
+ function buildChangePacket({
55
+ agentId,
56
+ intent,
57
+ diff,
58
+ filePath,
59
+ claims = [],
60
+ evidence = [],
61
+ verdict,
62
+ unblockPlan = null,
63
+ policy = null,
64
+ riskScore = null,
65
+ simulationResult = null,
66
+ criticVerdict = null,
67
+ proposal = null,
68
+ override = null
69
+ }) {
70
+ const timestamp = new Date().toISOString();
71
+
72
+ // Generate unique packet ID from content hash
73
+ const packetContent = JSON.stringify({
74
+ agentId,
75
+ intent,
76
+ filePath,
77
+ timestamp,
78
+ diff: diff?.unified || ""
79
+ });
80
+ const id = crypto.createHash("sha256")
81
+ .update(packetContent)
82
+ .digest("hex")
83
+ .slice(0, 16);
84
+
85
+ // Calculate file statistics
86
+ const linesChanged = diff?.unified
87
+ ? diff.unified.split('\n').filter(line => line.startsWith('+') || line.startsWith('-')).length
88
+ : 0;
89
+
90
+ const files = [{
91
+ path: filePath,
92
+ linesChanged,
93
+ domain: classifyFileDomain(filePath)
94
+ }];
95
+
96
+ // Extract failed assumptions from evidence
97
+ const assumptionsFailed = evidence
98
+ .filter(e => e.status === "UNPROVEN" || !e.verified)
99
+ .map(e => e.claim?.key || e.claim?.type || e.assumption || "unknown");
100
+
101
+ // Extract triggered rules from verdict
102
+ const rulesTriggered = (verdict?.violations || [])
103
+ .map(v => v.rule || v.type || v.id)
104
+ .filter(Boolean);
105
+
106
+ // Build packet with enhanced proof artifact fields
107
+ const packet = {
108
+ id,
109
+ timestamp,
110
+ agentId,
111
+ intent: intent || "No intent provided",
112
+
113
+ // Original fields
114
+ diff: diff || null,
115
+ files,
116
+ claims,
117
+ evidence,
118
+
119
+ // Verdict and decision
120
+ verdict: verdict || {
121
+ decision: "ALLOW",
122
+ violations: [],
123
+ message: "No verdict provided"
124
+ },
125
+ unblockPlan: unblockPlan || null,
126
+
127
+ // Enhanced proof artifact fields
128
+ proof: {
129
+ changeId: `c-${id}`,
130
+ decision: verdict?.decision || "ALLOW",
131
+ rulesTriggered,
132
+ assumptionsFailed,
133
+ riskScore: riskScore?.total ?? null,
134
+ riskLevel: riskScore?.level || null,
135
+ riskFactors: riskScore?.reasons || [],
136
+ simulationResult: simulationResult ? {
137
+ passed: simulationResult.passed,
138
+ errorCount: simulationResult.errors?.length || 0,
139
+ warningCount: simulationResult.warnings?.length || 0,
140
+ errors: (simulationResult.errors || []).slice(0, 5).map(e => e.message || e),
141
+ warnings: (simulationResult.warnings || []).slice(0, 5).map(w => w.message || w),
142
+ } : null,
143
+ criticVerdict: criticVerdict ? {
144
+ verdict: criticVerdict.verdict,
145
+ confidence: criticVerdict.confidence,
146
+ reasoning: criticVerdict.reasoning || [],
147
+ violations: criticVerdict.violations || [],
148
+ } : null,
149
+ overrideUsed: override?.used || false,
150
+ overrideBy: override?.by || null,
151
+ overrideReason: override?.reason || null,
152
+ overrideTimestamp: override?.timestamp || null,
153
+ },
154
+
155
+ // Structured proposal (if provided)
156
+ proposal: proposal ? {
157
+ intent: proposal.intent,
158
+ summary: proposal.summary,
159
+ confidence: proposal.confidence,
160
+ assumptions: proposal.assumptions,
161
+ filesTouched: proposal.filesTouched,
162
+ operationCount: proposal.operations?.length || 0,
163
+ } : null,
164
+
165
+ // Metadata
166
+ metadata: {
167
+ totalFiles: files.length,
168
+ totalLines: linesChanged,
169
+ policyVersion: policy?.version || "unknown",
170
+ policyProfile: policy?.profile || "unknown",
171
+ policyMode: policy?.mode || "unknown",
172
+ domains: [...new Set(files.map(f => f.domain))],
173
+ }
174
+ };
175
+
176
+ return packet;
177
+ }
178
+
179
+ /**
180
+ * Build change packet from multiple files
181
+ * @param {object} params
182
+ * @param {string} params.agentId - Agent identifier
183
+ * @param {string} params.intent - Agent's stated intent
184
+ * @param {array} params.changes - Array of { filePath, diff, claims }
185
+ * @param {array} params.evidence - Evidence resolution results
186
+ * @param {object} params.verdict - Policy verdict
187
+ * @param {object} params.unblockPlan - Unblock plan (if blocked)
188
+ * @param {object} params.policy - Policy used for evaluation
189
+ * @param {object} params.riskScore - Risk scoring result
190
+ * @param {object} params.simulationResult - Diff simulation result
191
+ * @param {object} params.criticVerdict - Critic LLM verdict
192
+ * @param {object} params.proposal - Structured change proposal
193
+ * @param {object} params.override - Override information
194
+ * @returns {object} Change packet
195
+ */
196
+ function buildMultiFileChangePacket({
197
+ agentId,
198
+ intent,
199
+ changes = [],
200
+ evidence = [],
201
+ verdict,
202
+ unblockPlan = null,
203
+ policy = null,
204
+ riskScore = null,
205
+ simulationResult = null,
206
+ criticVerdict = null,
207
+ proposal = null,
208
+ override = null
209
+ }) {
210
+ const timestamp = new Date().toISOString();
211
+
212
+ // Aggregate all file changes
213
+ const files = changes.map(change => ({
214
+ path: change.filePath,
215
+ linesChanged: calculateLinesChanged(change.diff),
216
+ domain: classifyFileDomain(change.filePath)
217
+ }));
218
+
219
+ // Aggregate all claims
220
+ const claims = changes.flatMap(change =>
221
+ (change.claims || []).map(claim => ({
222
+ ...claim,
223
+ file: change.filePath
224
+ }))
225
+ );
226
+
227
+ // Generate unique packet ID from all changes
228
+ const packetContent = JSON.stringify({
229
+ agentId,
230
+ intent,
231
+ timestamp,
232
+ files: files.map(f => f.path),
233
+ claims: claims.map(c => `${c.type}:${c.value}`)
234
+ });
235
+ const id = crypto.createHash("sha256")
236
+ .update(packetContent)
237
+ .digest("hex")
238
+ .slice(0, 16);
239
+
240
+ // Build unified diff (concatenate all diffs)
241
+ const unifiedDiff = changes
242
+ .map(change => {
243
+ const diff = change.diff?.unified || "";
244
+ return diff ? `--- ${change.filePath}\n+++ ${change.filePath}\n${diff}` : "";
245
+ })
246
+ .filter(Boolean)
247
+ .join("\n\n");
248
+
249
+ // Extract failed assumptions from evidence
250
+ const assumptionsFailed = evidence
251
+ .filter(e => e.status === "UNPROVEN" || !e.verified)
252
+ .map(e => e.claim?.key || e.claim?.type || e.assumption || "unknown");
253
+
254
+ // Extract triggered rules from verdict
255
+ const rulesTriggered = (verdict?.violations || [])
256
+ .map(v => v.rule || v.type || v.id)
257
+ .filter(Boolean);
258
+
259
+ const packet = {
260
+ id,
261
+ timestamp,
262
+ agentId,
263
+ intent: intent || "No intent provided",
264
+
265
+ // Original fields
266
+ diff: unifiedDiff ? {
267
+ unified: unifiedDiff,
268
+ before: null,
269
+ after: null
270
+ } : null,
271
+ files,
272
+ claims,
273
+ evidence,
274
+
275
+ // Verdict and decision
276
+ verdict: verdict || {
277
+ decision: "ALLOW",
278
+ violations: [],
279
+ message: "No verdict provided"
280
+ },
281
+ unblockPlan: unblockPlan || null,
282
+
283
+ // Enhanced proof artifact fields
284
+ proof: {
285
+ changeId: `c-${id}`,
286
+ decision: verdict?.decision || "ALLOW",
287
+ rulesTriggered,
288
+ assumptionsFailed,
289
+ riskScore: riskScore?.total ?? null,
290
+ riskLevel: riskScore?.level || null,
291
+ riskFactors: riskScore?.reasons || [],
292
+ simulationResult: simulationResult ? {
293
+ passed: simulationResult.passed,
294
+ errorCount: simulationResult.errors?.length || 0,
295
+ warningCount: simulationResult.warnings?.length || 0,
296
+ errors: (simulationResult.errors || []).slice(0, 5).map(e => e.message || e),
297
+ warnings: (simulationResult.warnings || []).slice(0, 5).map(w => w.message || w),
298
+ } : null,
299
+ criticVerdict: criticVerdict ? {
300
+ verdict: criticVerdict.verdict,
301
+ confidence: criticVerdict.confidence,
302
+ reasoning: criticVerdict.reasoning || [],
303
+ violations: criticVerdict.violations || [],
304
+ } : null,
305
+ overrideUsed: override?.used || false,
306
+ overrideBy: override?.by || null,
307
+ overrideReason: override?.reason || null,
308
+ overrideTimestamp: override?.timestamp || null,
309
+ },
310
+
311
+ // Structured proposal (if provided)
312
+ proposal: proposal ? {
313
+ intent: proposal.intent,
314
+ summary: proposal.summary,
315
+ confidence: proposal.confidence,
316
+ assumptions: proposal.assumptions,
317
+ filesTouched: proposal.filesTouched,
318
+ operationCount: proposal.operations?.length || 0,
319
+ } : null,
320
+
321
+ // Metadata
322
+ metadata: {
323
+ totalFiles: files.length,
324
+ totalLines: files.reduce((sum, f) => sum + f.linesChanged, 0),
325
+ policyVersion: policy?.version || "unknown",
326
+ policyProfile: policy?.profile || "unknown",
327
+ policyMode: policy?.mode || "unknown",
328
+ domains: [...new Set(files.map(f => f.domain))],
329
+ }
330
+ };
331
+
332
+ return packet;
333
+ }
334
+
335
+ /**
336
+ * Calculate number of lines changed from diff
337
+ * @param {object} diff - Diff object
338
+ * @returns {number} Number of lines changed
339
+ */
340
+ function calculateLinesChanged(diff) {
341
+ if (!diff || !diff.unified) return 0;
342
+ return diff.unified
343
+ .split('\n')
344
+ .filter(line => line.startsWith('+') || line.startsWith('-'))
345
+ .length;
346
+ }
347
+
348
+ /**
349
+ * Classify file domain from path
350
+ * @param {string} filePath - File path
351
+ * @returns {string} Domain classification
352
+ */
353
+ function classifyFileDomain(filePath) {
354
+ const s = filePath.toLowerCase();
355
+ if (s.includes("auth")) return "auth";
356
+ if (s.includes("stripe") || s.includes("payment")) return "payments";
357
+ if (s.includes("routes") || s.includes("router") || s.includes("api")) return "routes";
358
+ if (s.includes("schema") || s.includes("contract") || s.includes("openapi")) return "contracts";
359
+ if (s.includes("ui") || s.includes("components") || s.includes("pages")) return "ui";
360
+ return "general";
361
+ }
362
+
363
+ /**
364
+ * Build a standalone proof artifact for compliance
365
+ * @param {object} params - Proof parameters
366
+ * @returns {ProofArtifact} Proof artifact
367
+ */
368
+ function buildProofArtifact({
369
+ changeId,
370
+ decision,
371
+ rulesTriggered = [],
372
+ assumptionsFailed = [],
373
+ riskScore = null,
374
+ simulationResult = null,
375
+ criticVerdict = null,
376
+ override = null,
377
+ }) {
378
+ const timestamp = new Date().toISOString();
379
+
380
+ return {
381
+ changeId: changeId || `c-${crypto.randomBytes(8).toString("hex")}`,
382
+ decision: decision || "BLOCK",
383
+ rulesTriggered,
384
+ assumptionsFailed,
385
+ riskScore: riskScore?.total ?? null,
386
+ riskLevel: riskScore?.level || "UNKNOWN",
387
+ riskFactors: riskScore?.reasons || [],
388
+ simulationResult: simulationResult ? {
389
+ passed: simulationResult.passed,
390
+ errorCount: simulationResult.errors?.length || 0,
391
+ warningCount: simulationResult.warnings?.length || 0,
392
+ brokenImports: (simulationResult.errors || [])
393
+ .filter(e => e.type === "broken_import" || e.type === "unresolved_import")
394
+ .map(e => e.import),
395
+ } : null,
396
+ criticVerdict: criticVerdict ? {
397
+ verdict: criticVerdict.verdict,
398
+ confidence: criticVerdict.confidence,
399
+ reasoning: criticVerdict.reasoning || [],
400
+ } : null,
401
+ timestamp,
402
+ overrideUsed: override?.used || false,
403
+ overrideBy: override?.by || null,
404
+ overrideReason: override?.reason || null,
405
+ };
406
+ }
407
+
408
+ /**
409
+ * Extract proof artifact from a change packet
410
+ * @param {object} packet - Change packet
411
+ * @returns {ProofArtifact} Proof artifact
412
+ */
413
+ function extractProofArtifact(packet) {
414
+ if (packet.proof) {
415
+ return {
416
+ ...packet.proof,
417
+ timestamp: packet.timestamp,
418
+ };
419
+ }
420
+
421
+ // Build from legacy packet format
422
+ return {
423
+ changeId: `c-${packet.id}`,
424
+ decision: packet.verdict?.decision || "UNKNOWN",
425
+ rulesTriggered: (packet.verdict?.violations || []).map(v => v.rule || v.type),
426
+ assumptionsFailed: packet.evidence
427
+ ?.filter(e => e.status === "UNPROVEN")
428
+ .map(e => e.claim?.key) || [],
429
+ riskScore: null,
430
+ riskLevel: "UNKNOWN",
431
+ simulationResult: null,
432
+ criticVerdict: null,
433
+ timestamp: packet.timestamp,
434
+ overrideUsed: false,
435
+ overrideBy: null,
436
+ overrideReason: null,
437
+ };
438
+ }
439
+
440
+ /**
441
+ * Format proof artifact for display
442
+ * @param {ProofArtifact} proof - Proof artifact
443
+ * @returns {string} Formatted string
444
+ */
445
+ function formatProofArtifact(proof) {
446
+ const lines = [
447
+ `Change ID: ${proof.changeId}`,
448
+ `Decision: ${proof.decision}`,
449
+ `Timestamp: ${proof.timestamp}`,
450
+ "",
451
+ ];
452
+
453
+ if (proof.riskScore !== null) {
454
+ lines.push(`Risk Score: ${proof.riskScore} (${proof.riskLevel})`);
455
+ }
456
+
457
+ if (proof.rulesTriggered.length > 0) {
458
+ lines.push(`Rules Triggered: ${proof.rulesTriggered.join(", ")}`);
459
+ }
460
+
461
+ if (proof.assumptionsFailed.length > 0) {
462
+ lines.push(`Assumptions Failed: ${proof.assumptionsFailed.join(", ")}`);
463
+ }
464
+
465
+ if (proof.simulationResult) {
466
+ lines.push(`Simulation: ${proof.simulationResult.passed ? "PASSED" : "FAILED"} (${proof.simulationResult.errorCount} errors)`);
467
+ }
468
+
469
+ if (proof.criticVerdict) {
470
+ lines.push(`Critic: ${proof.criticVerdict.verdict} (${(proof.criticVerdict.confidence * 100).toFixed(0)}% confidence)`);
471
+ }
472
+
473
+ if (proof.overrideUsed) {
474
+ lines.push(`Override: Used by ${proof.overrideBy} - ${proof.overrideReason}`);
475
+ }
476
+
477
+ return lines.join("\n");
478
+ }
479
+
480
+ module.exports = {
481
+ buildChangePacket,
482
+ buildMultiFileChangePacket,
483
+ buildProofArtifact,
484
+ extractProofArtifact,
485
+ formatProofArtifact,
486
+ calculateLinesChanged,
487
+ classifyFileDomain
488
+ };
@@ -0,0 +1,228 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "type": "object",
4
+ "required": ["id", "timestamp", "agentId", "intent", "files", "claims", "verdict"],
5
+ "properties": {
6
+ "id": {
7
+ "type": "string",
8
+ "description": "Unique packet ID (hash-based)"
9
+ },
10
+ "timestamp": {
11
+ "type": "string",
12
+ "format": "date-time",
13
+ "description": "ISO timestamp of the change"
14
+ },
15
+ "agentId": {
16
+ "type": "string",
17
+ "description": "Identifier for the AI agent (e.g., 'cursor', 'windsurf', 'copilot')"
18
+ },
19
+ "intent": {
20
+ "type": "string",
21
+ "description": "Agent's stated intent for the change"
22
+ },
23
+ "diff": {
24
+ "type": "object",
25
+ "properties": {
26
+ "before": {
27
+ "type": "string",
28
+ "description": "File content before change"
29
+ },
30
+ "after": {
31
+ "type": "string",
32
+ "description": "File content after change"
33
+ },
34
+ "unified": {
35
+ "type": "string",
36
+ "description": "Unified diff format"
37
+ }
38
+ }
39
+ },
40
+ "files": {
41
+ "type": "array",
42
+ "items": {
43
+ "type": "object",
44
+ "required": ["path", "linesChanged"],
45
+ "properties": {
46
+ "path": {
47
+ "type": "string",
48
+ "description": "Relative file path"
49
+ },
50
+ "linesChanged": {
51
+ "type": "number",
52
+ "description": "Number of lines changed"
53
+ },
54
+ "domain": {
55
+ "type": "string",
56
+ "enum": ["auth", "payments", "routes", "contracts", "ui", "general"],
57
+ "description": "File domain classification"
58
+ }
59
+ }
60
+ },
61
+ "description": "List of changed files"
62
+ },
63
+ "claims": {
64
+ "type": "array",
65
+ "items": {
66
+ "type": "object",
67
+ "required": ["type", "value", "criticality"],
68
+ "properties": {
69
+ "type": {
70
+ "type": "string",
71
+ "enum": ["route", "env_used", "auth_boundary", "data_contract", "http_call", "ui_success_claim", "side_effect"],
72
+ "description": "Claim type"
73
+ },
74
+ "value": {
75
+ "type": "string",
76
+ "description": "Claim value (e.g., route path, env var name)"
77
+ },
78
+ "criticality": {
79
+ "type": "string",
80
+ "enum": ["hard", "soft"],
81
+ "description": "Claim criticality"
82
+ },
83
+ "pointer": {
84
+ "type": "string",
85
+ "description": "File:line pointer (e.g., 'file.ts:42-45')"
86
+ },
87
+ "reason": {
88
+ "type": "string",
89
+ "description": "Reason for claim extraction"
90
+ },
91
+ "file": {
92
+ "type": "string",
93
+ "description": "File where claim was found"
94
+ },
95
+ "domain": {
96
+ "type": "string",
97
+ "enum": ["auth", "payments", "routes", "contracts", "ui", "general"]
98
+ }
99
+ }
100
+ },
101
+ "description": "Extracted claims from the change"
102
+ },
103
+ "evidence": {
104
+ "type": "array",
105
+ "items": {
106
+ "type": "object",
107
+ "required": ["claimId", "result"],
108
+ "properties": {
109
+ "claimId": {
110
+ "type": "string",
111
+ "description": "Reference to claim in claims array"
112
+ },
113
+ "result": {
114
+ "type": "string",
115
+ "enum": ["PROVEN", "UNPROVEN", "CONTRADICTS"],
116
+ "description": "Evidence resolution result"
117
+ },
118
+ "sources": {
119
+ "type": "array",
120
+ "items": {
121
+ "type": "object",
122
+ "properties": {
123
+ "type": {
124
+ "type": "string",
125
+ "enum": ["truthpack.routes", "truthpack.env", "truthpack.auth", "truthpack.contracts", "repo.search"]
126
+ },
127
+ "pointer": {
128
+ "type": "string"
129
+ },
130
+ "confidence": {
131
+ "type": "number",
132
+ "minimum": 0,
133
+ "maximum": 1
134
+ }
135
+ }
136
+ }
137
+ }
138
+ }
139
+ },
140
+ "description": "Evidence resolution results"
141
+ },
142
+ "verdict": {
143
+ "type": "object",
144
+ "required": ["decision", "violations"],
145
+ "properties": {
146
+ "decision": {
147
+ "type": "string",
148
+ "enum": ["ALLOW", "WARN", "BLOCK"],
149
+ "description": "Final verdict"
150
+ },
151
+ "violations": {
152
+ "type": "array",
153
+ "items": {
154
+ "type": "object",
155
+ "required": ["rule", "severity", "message"],
156
+ "properties": {
157
+ "rule": {
158
+ "type": "string",
159
+ "description": "Rule ID that was violated"
160
+ },
161
+ "severity": {
162
+ "type": "string",
163
+ "enum": ["allow", "warn", "block"]
164
+ },
165
+ "message": {
166
+ "type": "string",
167
+ "description": "Violation message"
168
+ },
169
+ "claimId": {
170
+ "type": "string",
171
+ "description": "Related claim ID"
172
+ }
173
+ }
174
+ }
175
+ },
176
+ "message": {
177
+ "type": "string",
178
+ "description": "Human-readable verdict message"
179
+ }
180
+ }
181
+ },
182
+ "unblockPlan": {
183
+ "type": "object",
184
+ "properties": {
185
+ "steps": {
186
+ "type": "array",
187
+ "items": {
188
+ "type": "object",
189
+ "required": ["action", "file", "description"],
190
+ "properties": {
191
+ "action": {
192
+ "type": "string",
193
+ "enum": ["add", "modify", "create"]
194
+ },
195
+ "file": {
196
+ "type": "string"
197
+ },
198
+ "line": {
199
+ "type": "number"
200
+ },
201
+ "description": {
202
+ "type": "string"
203
+ }
204
+ }
205
+ }
206
+ }
207
+ },
208
+ "description": "Plan to unblock if verdict is BLOCK"
209
+ },
210
+ "metadata": {
211
+ "type": "object",
212
+ "properties": {
213
+ "totalFiles": {
214
+ "type": "number"
215
+ },
216
+ "totalLines": {
217
+ "type": "number"
218
+ },
219
+ "policyVersion": {
220
+ "type": "string"
221
+ },
222
+ "policyProfile": {
223
+ "type": "string"
224
+ }
225
+ }
226
+ }
227
+ }
228
+ }