@vibecheckai/cli 3.2.5 → 3.3.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 (197) hide show
  1. package/bin/.generated +25 -25
  2. package/bin/dev/run-v2-torture.js +30 -30
  3. package/bin/registry.js +192 -5
  4. package/bin/runners/lib/__tests__/entitlements-v2.test.js +295 -295
  5. package/bin/runners/lib/agent-firewall/change-packet/builder.js +280 -6
  6. package/bin/runners/lib/agent-firewall/critic/index.js +151 -0
  7. package/bin/runners/lib/agent-firewall/critic/judge.js +432 -0
  8. package/bin/runners/lib/agent-firewall/critic/prompts.js +305 -0
  9. package/bin/runners/lib/agent-firewall/lawbook/distributor.js +465 -0
  10. package/bin/runners/lib/agent-firewall/lawbook/evaluator.js +604 -0
  11. package/bin/runners/lib/agent-firewall/lawbook/index.js +304 -0
  12. package/bin/runners/lib/agent-firewall/lawbook/registry.js +514 -0
  13. package/bin/runners/lib/agent-firewall/lawbook/schema.js +420 -0
  14. package/bin/runners/lib/agent-firewall/logger.js +141 -0
  15. package/bin/runners/lib/agent-firewall/policy/loader.js +312 -4
  16. package/bin/runners/lib/agent-firewall/policy/rules/ghost-env.js +113 -1
  17. package/bin/runners/lib/agent-firewall/policy/rules/ghost-route.js +133 -6
  18. package/bin/runners/lib/agent-firewall/proposal/extractor.js +394 -0
  19. package/bin/runners/lib/agent-firewall/proposal/index.js +212 -0
  20. package/bin/runners/lib/agent-firewall/proposal/schema.js +251 -0
  21. package/bin/runners/lib/agent-firewall/proposal/validator.js +386 -0
  22. package/bin/runners/lib/agent-firewall/reality/index.js +332 -0
  23. package/bin/runners/lib/agent-firewall/reality/state.js +625 -0
  24. package/bin/runners/lib/agent-firewall/reality/watcher.js +322 -0
  25. package/bin/runners/lib/agent-firewall/risk/index.js +173 -0
  26. package/bin/runners/lib/agent-firewall/risk/scorer.js +328 -0
  27. package/bin/runners/lib/agent-firewall/risk/thresholds.js +321 -0
  28. package/bin/runners/lib/agent-firewall/risk/vectors.js +421 -0
  29. package/bin/runners/lib/agent-firewall/simulator/diff-simulator.js +472 -0
  30. package/bin/runners/lib/agent-firewall/simulator/import-resolver.js +346 -0
  31. package/bin/runners/lib/agent-firewall/simulator/index.js +181 -0
  32. package/bin/runners/lib/agent-firewall/simulator/route-validator.js +380 -0
  33. package/bin/runners/lib/agent-firewall/time-machine/incident-correlator.js +661 -0
  34. package/bin/runners/lib/agent-firewall/time-machine/index.js +267 -0
  35. package/bin/runners/lib/agent-firewall/time-machine/replay-engine.js +436 -0
  36. package/bin/runners/lib/agent-firewall/time-machine/state-reconstructor.js +490 -0
  37. package/bin/runners/lib/agent-firewall/time-machine/timeline-builder.js +530 -0
  38. package/bin/runners/lib/analyzers.js +81 -18
  39. package/bin/runners/lib/api-client.js +269 -0
  40. package/bin/runners/lib/auth-truth.js +193 -193
  41. package/bin/runners/lib/authority-badge.js +425 -0
  42. package/bin/runners/lib/backup.js +62 -62
  43. package/bin/runners/lib/billing.js +107 -107
  44. package/bin/runners/lib/claims.js +118 -118
  45. package/bin/runners/lib/cli-output.js +7 -1
  46. package/bin/runners/lib/cli-ui.js +540 -540
  47. package/bin/runners/lib/contracts/auth-contract.js +202 -202
  48. package/bin/runners/lib/contracts/env-contract.js +181 -181
  49. package/bin/runners/lib/contracts/external-contract.js +206 -206
  50. package/bin/runners/lib/contracts/guard.js +168 -168
  51. package/bin/runners/lib/contracts/index.js +89 -89
  52. package/bin/runners/lib/contracts/plan-validator.js +311 -311
  53. package/bin/runners/lib/contracts/route-contract.js +199 -199
  54. package/bin/runners/lib/contracts.js +804 -804
  55. package/bin/runners/lib/detect.js +89 -89
  56. package/bin/runners/lib/doctor/autofix.js +254 -254
  57. package/bin/runners/lib/doctor/index.js +37 -37
  58. package/bin/runners/lib/doctor/modules/dependencies.js +325 -325
  59. package/bin/runners/lib/doctor/modules/index.js +46 -46
  60. package/bin/runners/lib/doctor/modules/network.js +250 -250
  61. package/bin/runners/lib/doctor/modules/project.js +312 -312
  62. package/bin/runners/lib/doctor/modules/runtime.js +224 -224
  63. package/bin/runners/lib/doctor/modules/security.js +348 -348
  64. package/bin/runners/lib/doctor/modules/system.js +213 -213
  65. package/bin/runners/lib/doctor/modules/vibecheck.js +394 -394
  66. package/bin/runners/lib/doctor/reporter.js +262 -262
  67. package/bin/runners/lib/doctor/service.js +262 -262
  68. package/bin/runners/lib/doctor/types.js +113 -113
  69. package/bin/runners/lib/doctor/ui.js +263 -263
  70. package/bin/runners/lib/doctor-v2.js +608 -608
  71. package/bin/runners/lib/drift.js +425 -425
  72. package/bin/runners/lib/enforcement.js +72 -72
  73. package/bin/runners/lib/enterprise-detect.js +603 -603
  74. package/bin/runners/lib/enterprise-init.js +942 -942
  75. package/bin/runners/lib/env-resolver.js +417 -417
  76. package/bin/runners/lib/env-template.js +66 -66
  77. package/bin/runners/lib/env.js +189 -189
  78. package/bin/runners/lib/error-handler.js +16 -9
  79. package/bin/runners/lib/exit-codes.js +275 -0
  80. package/bin/runners/lib/extractors/client-calls.js +990 -990
  81. package/bin/runners/lib/extractors/fastify-route-dump.js +573 -573
  82. package/bin/runners/lib/extractors/fastify-routes.js +426 -426
  83. package/bin/runners/lib/extractors/index.js +363 -363
  84. package/bin/runners/lib/extractors/next-routes.js +524 -524
  85. package/bin/runners/lib/extractors/proof-graph.js +431 -431
  86. package/bin/runners/lib/extractors/route-matcher.js +451 -451
  87. package/bin/runners/lib/extractors/truthpack-v2.js +377 -377
  88. package/bin/runners/lib/extractors/ui-bindings.js +547 -547
  89. package/bin/runners/lib/findings-schema.js +281 -281
  90. package/bin/runners/lib/firewall-prompt.js +50 -50
  91. package/bin/runners/lib/global-flags.js +37 -0
  92. package/bin/runners/lib/graph/graph-builder.js +265 -265
  93. package/bin/runners/lib/graph/html-renderer.js +413 -413
  94. package/bin/runners/lib/graph/index.js +32 -32
  95. package/bin/runners/lib/graph/runtime-collector.js +215 -215
  96. package/bin/runners/lib/graph/static-extractor.js +518 -518
  97. package/bin/runners/lib/help-formatter.js +413 -0
  98. package/bin/runners/lib/html-report.js +650 -650
  99. package/bin/runners/lib/llm.js +75 -75
  100. package/bin/runners/lib/logger.js +38 -0
  101. package/bin/runners/lib/meter.js +61 -61
  102. package/bin/runners/lib/missions/evidence.js +126 -126
  103. package/bin/runners/lib/patch.js +40 -40
  104. package/bin/runners/lib/permissions/auth-model.js +213 -213
  105. package/bin/runners/lib/permissions/idor-prover.js +205 -205
  106. package/bin/runners/lib/permissions/index.js +45 -45
  107. package/bin/runners/lib/permissions/matrix-builder.js +198 -198
  108. package/bin/runners/lib/pkgjson.js +28 -28
  109. package/bin/runners/lib/policy.js +295 -295
  110. package/bin/runners/lib/preflight.js +142 -142
  111. package/bin/runners/lib/reality/correlation-detectors.js +359 -359
  112. package/bin/runners/lib/reality/index.js +318 -318
  113. package/bin/runners/lib/reality/request-hashing.js +416 -416
  114. package/bin/runners/lib/reality/request-mapper.js +453 -453
  115. package/bin/runners/lib/reality/safety-rails.js +463 -463
  116. package/bin/runners/lib/reality/semantic-snapshot.js +408 -408
  117. package/bin/runners/lib/reality/toast-detector.js +393 -393
  118. package/bin/runners/lib/reality-findings.js +84 -84
  119. package/bin/runners/lib/receipts.js +179 -179
  120. package/bin/runners/lib/redact.js +29 -29
  121. package/bin/runners/lib/replay/capsule-manager.js +154 -154
  122. package/bin/runners/lib/replay/index.js +263 -263
  123. package/bin/runners/lib/replay/player.js +348 -348
  124. package/bin/runners/lib/replay/recorder.js +331 -331
  125. package/bin/runners/lib/report.js +135 -135
  126. package/bin/runners/lib/route-detection.js +1140 -1140
  127. package/bin/runners/lib/sandbox/index.js +59 -59
  128. package/bin/runners/lib/sandbox/proof-chain.js +399 -399
  129. package/bin/runners/lib/sandbox/sandbox-runner.js +205 -205
  130. package/bin/runners/lib/sandbox/worktree.js +174 -174
  131. package/bin/runners/lib/schema-validator.js +350 -350
  132. package/bin/runners/lib/schemas/contracts.schema.json +160 -160
  133. package/bin/runners/lib/schemas/finding.schema.json +100 -100
  134. package/bin/runners/lib/schemas/mission-pack.schema.json +206 -206
  135. package/bin/runners/lib/schemas/proof-graph.schema.json +176 -176
  136. package/bin/runners/lib/schemas/reality-report.schema.json +162 -162
  137. package/bin/runners/lib/schemas/share-pack.schema.json +180 -180
  138. package/bin/runners/lib/schemas/ship-report.schema.json +117 -117
  139. package/bin/runners/lib/schemas/truthpack-v2.schema.json +303 -303
  140. package/bin/runners/lib/schemas/validator.js +438 -438
  141. package/bin/runners/lib/score-history.js +282 -282
  142. package/bin/runners/lib/share-pack.js +239 -239
  143. package/bin/runners/lib/snippets.js +67 -67
  144. package/bin/runners/lib/unified-cli-output.js +604 -0
  145. package/bin/runners/lib/upsell.js +658 -510
  146. package/bin/runners/lib/usage.js +153 -153
  147. package/bin/runners/lib/validate-patch.js +156 -156
  148. package/bin/runners/lib/verdict-engine.js +628 -628
  149. package/bin/runners/reality/engine.js +917 -917
  150. package/bin/runners/reality/flows.js +122 -122
  151. package/bin/runners/reality/report.js +378 -378
  152. package/bin/runners/reality/session.js +193 -193
  153. package/bin/runners/runAgent.d.ts +5 -0
  154. package/bin/runners/runApprove.js +1200 -0
  155. package/bin/runners/runAuth.js +324 -95
  156. package/bin/runners/runCheckpoint.js +39 -21
  157. package/bin/runners/runClassify.js +859 -0
  158. package/bin/runners/runContext.js +136 -24
  159. package/bin/runners/runDoctor.js +108 -68
  160. package/bin/runners/runFirewall.d.ts +5 -0
  161. package/bin/runners/runFirewallHook.d.ts +5 -0
  162. package/bin/runners/runFix.js +6 -5
  163. package/bin/runners/runGuard.js +262 -168
  164. package/bin/runners/runInit.js +3 -2
  165. package/bin/runners/runMcp.js +130 -52
  166. package/bin/runners/runPolish.js +43 -20
  167. package/bin/runners/runProve.js +1 -2
  168. package/bin/runners/runReport.js +3 -2
  169. package/bin/runners/runScan.js +145 -44
  170. package/bin/runners/runShip.js +3 -4
  171. package/bin/runners/runTruth.d.ts +5 -0
  172. package/bin/runners/runValidate.js +19 -2
  173. package/bin/runners/runWatch.js +104 -53
  174. package/bin/vibecheck.js +106 -19
  175. package/mcp-server/HARDENING_SUMMARY.md +299 -0
  176. package/mcp-server/agent-firewall-interceptor.js +367 -31
  177. package/mcp-server/authority-tools.js +569 -0
  178. package/mcp-server/conductor/conflict-resolver.js +588 -0
  179. package/mcp-server/conductor/execution-planner.js +544 -0
  180. package/mcp-server/conductor/index.js +377 -0
  181. package/mcp-server/conductor/lock-manager.js +615 -0
  182. package/mcp-server/conductor/request-queue.js +550 -0
  183. package/mcp-server/conductor/session-manager.js +500 -0
  184. package/mcp-server/conductor/tools.js +510 -0
  185. package/mcp-server/index.js +1199 -208
  186. package/mcp-server/lib/api-client.cjs +305 -0
  187. package/mcp-server/lib/logger.cjs +30 -0
  188. package/mcp-server/logger.js +173 -0
  189. package/mcp-server/package.json +2 -2
  190. package/mcp-server/premium-tools.js +2 -2
  191. package/mcp-server/tier-auth.js +351 -136
  192. package/mcp-server/tools/index.js +72 -72
  193. package/mcp-server/truth-firewall-tools.js +145 -15
  194. package/mcp-server/vibecheck-tools.js +2 -2
  195. package/package.json +2 -3
  196. package/mcp-server/index.old.js +0 -4137
  197. package/mcp-server/package-lock.json +0 -165
@@ -3,6 +3,12 @@
3
3
  *
4
4
  * Builds change packets from diffs + agent intent.
5
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
6
12
  */
7
13
 
8
14
  "use strict";
@@ -10,6 +16,22 @@
10
16
  const crypto = require("crypto");
11
17
  const path = require("path");
12
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
+
13
35
  /**
14
36
  * Build a change packet from diff and agent intent
15
37
  * @param {object} params
@@ -22,6 +44,11 @@ const path = require("path");
22
44
  * @param {object} params.verdict - Policy verdict
23
45
  * @param {object} params.unblockPlan - Unblock plan (if blocked)
24
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
25
52
  * @returns {object} Change packet
26
53
  */
27
54
  function buildChangePacket({
@@ -33,7 +60,12 @@ function buildChangePacket({
33
60
  evidence = [],
34
61
  verdict,
35
62
  unblockPlan = null,
36
- policy = null
63
+ policy = null,
64
+ riskScore = null,
65
+ simulationResult = null,
66
+ criticVerdict = null,
67
+ proposal = null,
68
+ override = null
37
69
  }) {
38
70
  const timestamp = new Date().toISOString();
39
71
 
@@ -61,27 +93,83 @@ function buildChangePacket({
61
93
  domain: classifyFileDomain(filePath)
62
94
  }];
63
95
 
64
- // Build packet
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
65
107
  const packet = {
66
108
  id,
67
109
  timestamp,
68
110
  agentId,
69
111
  intent: intent || "No intent provided",
112
+
113
+ // Original fields
70
114
  diff: diff || null,
71
115
  files,
72
116
  claims,
73
117
  evidence,
118
+
119
+ // Verdict and decision
74
120
  verdict: verdict || {
75
121
  decision: "ALLOW",
76
122
  violations: [],
77
123
  message: "No verdict provided"
78
124
  },
79
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
80
166
  metadata: {
81
167
  totalFiles: files.length,
82
168
  totalLines: linesChanged,
83
169
  policyVersion: policy?.version || "unknown",
84
- policyProfile: policy?.profile || "unknown"
170
+ policyProfile: policy?.profile || "unknown",
171
+ policyMode: policy?.mode || "unknown",
172
+ domains: [...new Set(files.map(f => f.domain))],
85
173
  }
86
174
  };
87
175
 
@@ -98,6 +186,11 @@ function buildChangePacket({
98
186
  * @param {object} params.verdict - Policy verdict
99
187
  * @param {object} params.unblockPlan - Unblock plan (if blocked)
100
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
101
194
  * @returns {object} Change packet
102
195
  */
103
196
  function buildMultiFileChangePacket({
@@ -107,7 +200,12 @@ function buildMultiFileChangePacket({
107
200
  evidence = [],
108
201
  verdict,
109
202
  unblockPlan = null,
110
- policy = null
203
+ policy = null,
204
+ riskScore = null,
205
+ simulationResult = null,
206
+ criticVerdict = null,
207
+ proposal = null,
208
+ override = null
111
209
  }) {
112
210
  const timestamp = new Date().toISOString();
113
211
 
@@ -148,30 +246,86 @@ function buildMultiFileChangePacket({
148
246
  .filter(Boolean)
149
247
  .join("\n\n");
150
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
+
151
259
  const packet = {
152
260
  id,
153
261
  timestamp,
154
262
  agentId,
155
263
  intent: intent || "No intent provided",
264
+
265
+ // Original fields
156
266
  diff: unifiedDiff ? {
157
267
  unified: unifiedDiff,
158
- before: null, // Multi-file diffs don't store full before/after
268
+ before: null,
159
269
  after: null
160
270
  } : null,
161
271
  files,
162
272
  claims,
163
273
  evidence,
274
+
275
+ // Verdict and decision
164
276
  verdict: verdict || {
165
277
  decision: "ALLOW",
166
278
  violations: [],
167
279
  message: "No verdict provided"
168
280
  },
169
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
170
322
  metadata: {
171
323
  totalFiles: files.length,
172
324
  totalLines: files.reduce((sum, f) => sum + f.linesChanged, 0),
173
325
  policyVersion: policy?.version || "unknown",
174
- policyProfile: policy?.profile || "unknown"
326
+ policyProfile: policy?.profile || "unknown",
327
+ policyMode: policy?.mode || "unknown",
328
+ domains: [...new Set(files.map(f => f.domain))],
175
329
  }
176
330
  };
177
331
 
@@ -206,9 +360,129 @@ function classifyFileDomain(filePath) {
206
360
  return "general";
207
361
  }
208
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
+
209
480
  module.exports = {
210
481
  buildChangePacket,
211
482
  buildMultiFileChangePacket,
483
+ buildProofArtifact,
484
+ extractProofArtifact,
485
+ formatProofArtifact,
212
486
  calculateLinesChanged,
213
487
  classifyFileDomain
214
488
  };
@@ -0,0 +1,151 @@
1
+ /**
2
+ * Critic Module
3
+ *
4
+ * Entry point for the Critic LLM judge.
5
+ * The "savage" that evaluates proposal quality.
6
+ *
7
+ * Usage:
8
+ * const { critic } = require('./critic');
9
+ *
10
+ * // Configure with LLM client
11
+ * critic.setClient(async (params) => {
12
+ * return await callOpenAI(params);
13
+ * });
14
+ *
15
+ * // Evaluate a proposal
16
+ * const verdict = await critic.evaluate({
17
+ * proposal,
18
+ * validationResults,
19
+ * riskScore,
20
+ * simulationResult,
21
+ * realityState,
22
+ * });
23
+ */
24
+
25
+ "use strict";
26
+
27
+ const {
28
+ CriticJudge,
29
+ createJudge,
30
+ defaultJudge,
31
+ } = require("./judge");
32
+
33
+ const {
34
+ CRITIC_SYSTEM_PROMPT,
35
+ EVALUATION_PROMPT_TEMPLATE,
36
+ VAGUENESS_CHECK_PROMPT,
37
+ ASSUMPTION_VERIFICATION_PROMPT,
38
+ buildEvaluationPrompt,
39
+ buildVaguenessPrompt,
40
+ buildVerificationPrompt,
41
+ parseCriticResponse,
42
+ } = require("./prompts");
43
+
44
+ /**
45
+ * Critic singleton interface
46
+ */
47
+ const critic = {
48
+ /**
49
+ * Set the LLM client for the default judge
50
+ * @param {Function} client - LLM client function
51
+ */
52
+ setClient(client) {
53
+ defaultJudge.setClient(client);
54
+ },
55
+
56
+ /**
57
+ * Check if critic is available
58
+ * @returns {boolean} Is available
59
+ */
60
+ isAvailable() {
61
+ return defaultJudge.isAvailable();
62
+ },
63
+
64
+ /**
65
+ * Evaluate a proposal
66
+ * @param {Object} params - Evaluation parameters
67
+ * @returns {Promise<Object>} Critic verdict
68
+ */
69
+ async evaluate(params) {
70
+ return defaultJudge.evaluate(params);
71
+ },
72
+
73
+ /**
74
+ * Check for vagueness
75
+ * @param {Object} proposal - Proposal to check
76
+ * @returns {Promise<Object>} Vagueness analysis
77
+ */
78
+ async checkVagueness(proposal) {
79
+ return defaultJudge.checkVagueness(proposal);
80
+ },
81
+
82
+ /**
83
+ * Verify assumptions
84
+ * @param {Array} assumptions - Assumptions to verify
85
+ * @param {Object} realityState - Repository state
86
+ * @returns {Promise<Object>} Verification results
87
+ */
88
+ async verifyAssumptions(assumptions, realityState) {
89
+ return defaultJudge.verifyAssumptions(assumptions, realityState);
90
+ },
91
+
92
+ /**
93
+ * Create a new judge instance
94
+ * @param {Object} options - Configuration
95
+ * @returns {CriticJudge} New judge instance
96
+ */
97
+ createJudge(options) {
98
+ return createJudge(options);
99
+ },
100
+
101
+ /**
102
+ * Get the system prompt
103
+ * @returns {string} System prompt
104
+ */
105
+ getSystemPrompt() {
106
+ return CRITIC_SYSTEM_PROMPT;
107
+ },
108
+
109
+ /**
110
+ * Build an evaluation prompt
111
+ * @param {Object} data - Prompt data
112
+ * @returns {string} Filled prompt
113
+ */
114
+ buildPrompt(data) {
115
+ return buildEvaluationPrompt(data);
116
+ },
117
+
118
+ /**
119
+ * Parse a critic response
120
+ * @param {string} response - LLM response
121
+ * @returns {Object} Parsed verdict
122
+ */
123
+ parseResponse(response) {
124
+ return parseCriticResponse(response);
125
+ },
126
+
127
+ /**
128
+ * Quick rule-based evaluation (no LLM)
129
+ * @param {Object} params - Evaluation params
130
+ * @returns {Object} Verdict
131
+ */
132
+ quickEvaluate(params) {
133
+ return defaultJudge.ruleBasedEvaluation(params);
134
+ },
135
+ };
136
+
137
+ module.exports = {
138
+ critic,
139
+ CriticJudge,
140
+ createJudge,
141
+ defaultJudge,
142
+ // Prompt exports
143
+ CRITIC_SYSTEM_PROMPT,
144
+ EVALUATION_PROMPT_TEMPLATE,
145
+ VAGUENESS_CHECK_PROMPT,
146
+ ASSUMPTION_VERIFICATION_PROMPT,
147
+ buildEvaluationPrompt,
148
+ buildVaguenessPrompt,
149
+ buildVerificationPrompt,
150
+ parseCriticResponse,
151
+ };