@vibecheckai/cli 3.7.0 → 3.9.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 (118) hide show
  1. package/README.md +135 -63
  2. package/bin/_deprecations.js +447 -19
  3. package/bin/_router.js +1 -1
  4. package/bin/registry.js +347 -280
  5. package/bin/runners/context/generators/cursor-enhanced.js +2439 -0
  6. package/bin/runners/lib/agent-firewall/enforcement/gateway.js +1059 -0
  7. package/bin/runners/lib/agent-firewall/enforcement/index.js +98 -0
  8. package/bin/runners/lib/agent-firewall/enforcement/mode.js +318 -0
  9. package/bin/runners/lib/agent-firewall/enforcement/orchestrator.js +484 -0
  10. package/bin/runners/lib/agent-firewall/enforcement/proof-artifact.js +418 -0
  11. package/bin/runners/lib/agent-firewall/enforcement/schemas/change-event.schema.json +173 -0
  12. package/bin/runners/lib/agent-firewall/enforcement/schemas/intent.schema.json +181 -0
  13. package/bin/runners/lib/agent-firewall/enforcement/schemas/verdict.schema.json +222 -0
  14. package/bin/runners/lib/agent-firewall/enforcement/verdict-v2.js +333 -0
  15. package/bin/runners/lib/agent-firewall/index.js +200 -0
  16. package/bin/runners/lib/agent-firewall/integration/index.js +20 -0
  17. package/bin/runners/lib/agent-firewall/integration/ship-gate.js +437 -0
  18. package/bin/runners/lib/agent-firewall/intent/alignment-engine.js +634 -0
  19. package/bin/runners/lib/agent-firewall/intent/auto-detect.js +426 -0
  20. package/bin/runners/lib/agent-firewall/intent/index.js +102 -0
  21. package/bin/runners/lib/agent-firewall/intent/schema.js +352 -0
  22. package/bin/runners/lib/agent-firewall/intent/store.js +283 -0
  23. package/bin/runners/lib/agent-firewall/interception/fs-interceptor.js +502 -0
  24. package/bin/runners/lib/agent-firewall/interception/index.js +23 -0
  25. package/bin/runners/lib/agent-firewall/interceptor/base.js +7 -3
  26. package/bin/runners/lib/agent-firewall/session/collector.js +451 -0
  27. package/bin/runners/lib/agent-firewall/session/index.js +26 -0
  28. package/bin/runners/lib/artifact-envelope.js +540 -0
  29. package/bin/runners/lib/auth-shared.js +977 -0
  30. package/bin/runners/lib/checkpoint.js +941 -0
  31. package/bin/runners/lib/cleanup/engine.js +571 -0
  32. package/bin/runners/lib/cleanup/index.js +53 -0
  33. package/bin/runners/lib/cleanup/output.js +375 -0
  34. package/bin/runners/lib/cleanup/rules.js +1060 -0
  35. package/bin/runners/lib/doctor/diagnosis-receipt.js +454 -0
  36. package/bin/runners/lib/doctor/failure-signatures.js +526 -0
  37. package/bin/runners/lib/doctor/fix-script.js +336 -0
  38. package/bin/runners/lib/doctor/modules/build-tools.js +453 -0
  39. package/bin/runners/lib/doctor/modules/index.js +62 -3
  40. package/bin/runners/lib/doctor/modules/os-quirks.js +706 -0
  41. package/bin/runners/lib/doctor/modules/repo-integrity.js +485 -0
  42. package/bin/runners/lib/doctor/safe-repair.js +384 -0
  43. package/bin/runners/lib/engine/ast-cache.js +210 -210
  44. package/bin/runners/lib/engine/auth-extractor.js +211 -211
  45. package/bin/runners/lib/engine/billing-extractor.js +112 -112
  46. package/bin/runners/lib/engine/enforcement-extractor.js +100 -100
  47. package/bin/runners/lib/engine/env-extractor.js +207 -207
  48. package/bin/runners/lib/engine/express-extractor.js +208 -208
  49. package/bin/runners/lib/engine/extractors.js +849 -849
  50. package/bin/runners/lib/engine/index.js +207 -207
  51. package/bin/runners/lib/engine/repo-index.js +514 -514
  52. package/bin/runners/lib/engine/types.js +124 -124
  53. package/bin/runners/lib/engines/attack-detector.js +1192 -0
  54. package/bin/runners/lib/entitlements-v2.js +2 -2
  55. package/bin/runners/lib/missions/briefing.js +427 -0
  56. package/bin/runners/lib/missions/checkpoint.js +753 -0
  57. package/bin/runners/lib/missions/hardening.js +851 -0
  58. package/bin/runners/lib/missions/plan.js +421 -32
  59. package/bin/runners/lib/missions/safety-gates.js +645 -0
  60. package/bin/runners/lib/missions/schema.js +478 -0
  61. package/bin/runners/lib/packs/bundle.js +675 -0
  62. package/bin/runners/lib/packs/evidence-pack.js +671 -0
  63. package/bin/runners/lib/packs/pack-factory.js +837 -0
  64. package/bin/runners/lib/packs/permissions-pack.js +686 -0
  65. package/bin/runners/lib/packs/proof-graph-pack.js +779 -0
  66. package/bin/runners/lib/safelist/index.js +96 -0
  67. package/bin/runners/lib/safelist/integration.js +334 -0
  68. package/bin/runners/lib/safelist/matcher.js +696 -0
  69. package/bin/runners/lib/safelist/schema.js +948 -0
  70. package/bin/runners/lib/safelist/store.js +438 -0
  71. package/bin/runners/lib/schemas/ship-manifest.schema.json +251 -0
  72. package/bin/runners/lib/ship-gate.js +832 -0
  73. package/bin/runners/lib/ship-manifest.js +1153 -0
  74. package/bin/runners/lib/ship-output.js +1 -1
  75. package/bin/runners/lib/unified-cli-output.js +710 -383
  76. package/bin/runners/lib/upsell.js +3 -3
  77. package/bin/runners/lib/why-tree.js +650 -0
  78. package/bin/runners/runAllowlist.js +33 -4
  79. package/bin/runners/runApprove.js +240 -1122
  80. package/bin/runners/runAudit.js +692 -0
  81. package/bin/runners/runAuth.js +325 -29
  82. package/bin/runners/runCheckpoint.js +442 -494
  83. package/bin/runners/runCleanup.js +343 -0
  84. package/bin/runners/runDoctor.js +269 -19
  85. package/bin/runners/runFix.js +411 -32
  86. package/bin/runners/runForge.js +411 -0
  87. package/bin/runners/runIntent.js +906 -0
  88. package/bin/runners/runKickoff.js +878 -0
  89. package/bin/runners/runLaunch.js +2000 -0
  90. package/bin/runners/runLink.js +785 -0
  91. package/bin/runners/runMcp.js +1741 -837
  92. package/bin/runners/runPacks.js +2089 -0
  93. package/bin/runners/runPolish.js +41 -0
  94. package/bin/runners/runReality.js +178 -1
  95. package/bin/runners/runSafelist.js +1190 -0
  96. package/bin/runners/runScan.js +21 -9
  97. package/bin/runners/runShield.js +1282 -0
  98. package/bin/runners/runShip.js +395 -16
  99. package/bin/vibecheck.js +34 -6
  100. package/mcp-server/README.md +117 -158
  101. package/mcp-server/handlers/index.ts +2 -2
  102. package/mcp-server/handlers/tool-handler.ts +50 -11
  103. package/mcp-server/index.js +16 -0
  104. package/mcp-server/intent-firewall-interceptor.js +529 -0
  105. package/mcp-server/lib/executor.ts +5 -5
  106. package/mcp-server/lib/index.ts +14 -4
  107. package/mcp-server/lib/sandbox.test.ts +4 -4
  108. package/mcp-server/lib/sandbox.ts +2 -2
  109. package/mcp-server/manifest.json +473 -0
  110. package/mcp-server/package.json +1 -1
  111. package/mcp-server/registry/tool-registry.js +315 -523
  112. package/mcp-server/registry/tools.json +442 -428
  113. package/mcp-server/registry.test.ts +18 -12
  114. package/mcp-server/tier-auth.js +68 -11
  115. package/mcp-server/tools-v3.js +70 -16
  116. package/mcp-server/tsconfig.json +1 -0
  117. package/package.json +2 -1
  118. package/bin/runners/runProof.zip +0 -0
@@ -0,0 +1,418 @@
1
+ /**
2
+ * Proof Artifact System - Reality Mode Integration
3
+ *
4
+ * ═══════════════════════════════════════════════════════════════════════════════
5
+ * AGENT FIREWALL™ - REALITY PROOF SYSTEM
6
+ * ═══════════════════════════════════════════════════════════════════════════════
7
+ *
8
+ * After intent-aligned changes pass structural checks:
9
+ * - Trigger Reality Mode execution
10
+ * - Verify routes are reachable
11
+ * - Verify auth gates are enforced
12
+ * - Verify UI success paths are actually reachable
13
+ * - Verify no dead code paths remain
14
+ *
15
+ * Generate Proof Artifacts:
16
+ * - proof.id
17
+ * - proof.type (route | auth | ui | integration)
18
+ * - proof.status (verified | failed)
19
+ * - proof.trace (pointer or reference)
20
+ *
21
+ * If ANY required proof fails → BLOCK SHIP.
22
+ *
23
+ * @module enforcement/proof-artifact
24
+ * @version 2.0.0
25
+ */
26
+
27
+ "use strict";
28
+
29
+ const crypto = require("crypto");
30
+
31
+ /**
32
+ * Proof types
33
+ */
34
+ const PROOF_TYPE = {
35
+ ROUTE: "route",
36
+ AUTH: "auth",
37
+ UI: "ui",
38
+ INTEGRATION: "integration",
39
+ ENV: "env",
40
+ CONTRACT: "contract",
41
+ SIDE_EFFECT: "side_effect",
42
+ };
43
+
44
+ /**
45
+ * Proof status
46
+ */
47
+ const PROOF_STATUS = {
48
+ VERIFIED: "verified",
49
+ FAILED: "failed",
50
+ PENDING: "pending",
51
+ SKIPPED: "skipped",
52
+ };
53
+
54
+ /**
55
+ * Generate proof ID
56
+ * @param {string} type - Proof type
57
+ * @returns {string} Unique proof ID
58
+ */
59
+ function generateProofId(type) {
60
+ return `prf-${type.slice(0, 3)}-${Date.now().toString(36)}-${crypto.randomBytes(3).toString("hex")}`;
61
+ }
62
+
63
+ /**
64
+ * Proof Artifact
65
+ * @typedef {Object} ProofArtifact
66
+ * @property {string} id - Unique proof identifier
67
+ * @property {string} type - Type of proof
68
+ * @property {string} status - Verification status
69
+ * @property {string} target - What was verified
70
+ * @property {string} trace - Reference to evidence
71
+ * @property {string} timestamp - When proof was generated
72
+ * @property {Object} details - Type-specific details
73
+ * @property {string} error - Error message if failed
74
+ */
75
+
76
+ /**
77
+ * Create a proof artifact
78
+ * @param {Object} params - Proof parameters
79
+ * @param {string} params.type - Proof type
80
+ * @param {string} params.status - Verification status
81
+ * @param {string} params.target - What was verified
82
+ * @param {string} params.trace - Reference to evidence
83
+ * @param {Object} params.details - Additional details
84
+ * @param {string} params.error - Error message if failed
85
+ * @returns {ProofArtifact} Proof artifact
86
+ */
87
+ function createProofArtifact({
88
+ type,
89
+ status,
90
+ target,
91
+ trace = null,
92
+ details = {},
93
+ error = null,
94
+ }) {
95
+ return {
96
+ id: generateProofId(type),
97
+ type,
98
+ status,
99
+ target,
100
+ trace,
101
+ timestamp: new Date().toISOString(),
102
+ details,
103
+ error,
104
+ };
105
+ }
106
+
107
+ /**
108
+ * Create route reachability proof
109
+ * @param {string} method - HTTP method
110
+ * @param {string} path - Route path
111
+ * @param {Object} result - Verification result
112
+ * @returns {ProofArtifact} Proof artifact
113
+ */
114
+ function createRouteProof(method, path, result) {
115
+ return createProofArtifact({
116
+ type: PROOF_TYPE.ROUTE,
117
+ status: result.reachable ? PROOF_STATUS.VERIFIED : PROOF_STATUS.FAILED,
118
+ target: `${method} ${path}`,
119
+ trace: result.trace || result.file,
120
+ details: {
121
+ method,
122
+ path,
123
+ statusCode: result.statusCode,
124
+ responseTime: result.responseTime,
125
+ handler: result.handler,
126
+ },
127
+ error: result.reachable ? null : (result.error || "Route not reachable"),
128
+ });
129
+ }
130
+
131
+ /**
132
+ * Create auth gate proof
133
+ * @param {string} route - Route being protected
134
+ * @param {Object} result - Verification result
135
+ * @returns {ProofArtifact} Proof artifact
136
+ */
137
+ function createAuthProof(route, result) {
138
+ return createProofArtifact({
139
+ type: PROOF_TYPE.AUTH,
140
+ status: result.enforced ? PROOF_STATUS.VERIFIED : PROOF_STATUS.FAILED,
141
+ target: route,
142
+ trace: result.trace || result.middlewareFile,
143
+ details: {
144
+ middleware: result.middleware,
145
+ authType: result.authType,
146
+ roles: result.roles,
147
+ unauthenticatedBlocked: result.unauthenticatedBlocked,
148
+ unauthorizedBlocked: result.unauthorizedBlocked,
149
+ },
150
+ error: result.enforced ? null : (result.error || "Auth gate not properly enforced"),
151
+ });
152
+ }
153
+
154
+ /**
155
+ * Create UI success path proof
156
+ * @param {string} component - UI component/path
157
+ * @param {Object} result - Verification result
158
+ * @returns {ProofArtifact} Proof artifact
159
+ */
160
+ function createUIProof(component, result) {
161
+ return createProofArtifact({
162
+ type: PROOF_TYPE.UI,
163
+ status: result.reachable ? PROOF_STATUS.VERIFIED : PROOF_STATUS.FAILED,
164
+ target: component,
165
+ trace: result.trace || result.screenshot,
166
+ details: {
167
+ selector: result.selector,
168
+ url: result.url,
169
+ stateRequired: result.stateRequired,
170
+ backendCalled: result.backendCalled,
171
+ screenshotPath: result.screenshotPath,
172
+ },
173
+ error: result.reachable ? null : (result.error || "UI success path not reachable"),
174
+ });
175
+ }
176
+
177
+ /**
178
+ * Create integration proof
179
+ * @param {string} integration - Integration name
180
+ * @param {Object} result - Verification result
181
+ * @returns {ProofArtifact} Proof artifact
182
+ */
183
+ function createIntegrationProof(integration, result) {
184
+ return createProofArtifact({
185
+ type: PROOF_TYPE.INTEGRATION,
186
+ status: result.working ? PROOF_STATUS.VERIFIED : PROOF_STATUS.FAILED,
187
+ target: integration,
188
+ trace: result.trace,
189
+ details: {
190
+ endpoint: result.endpoint,
191
+ requestSent: result.requestSent,
192
+ responseReceived: result.responseReceived,
193
+ dataFlowVerified: result.dataFlowVerified,
194
+ },
195
+ error: result.working ? null : (result.error || "Integration not working"),
196
+ });
197
+ }
198
+
199
+ /**
200
+ * Create env var proof
201
+ * @param {string} varName - Environment variable name
202
+ * @param {Object} result - Verification result
203
+ * @returns {ProofArtifact} Proof artifact
204
+ */
205
+ function createEnvProof(varName, result) {
206
+ return createProofArtifact({
207
+ type: PROOF_TYPE.ENV,
208
+ status: result.exists ? PROOF_STATUS.VERIFIED : PROOF_STATUS.FAILED,
209
+ target: varName,
210
+ trace: result.source,
211
+ details: {
212
+ declaredIn: result.declaredIn,
213
+ usedIn: result.usedIn,
214
+ hasValue: result.hasValue,
215
+ isSecret: result.isSecret,
216
+ },
217
+ error: result.exists ? null : `Environment variable ${varName} not declared or missing`,
218
+ });
219
+ }
220
+
221
+ /**
222
+ * Create contract proof (API schema validation)
223
+ * @param {string} endpoint - API endpoint
224
+ * @param {Object} result - Verification result
225
+ * @returns {ProofArtifact} Proof artifact
226
+ */
227
+ function createContractProof(endpoint, result) {
228
+ return createProofArtifact({
229
+ type: PROOF_TYPE.CONTRACT,
230
+ status: result.valid ? PROOF_STATUS.VERIFIED : PROOF_STATUS.FAILED,
231
+ target: endpoint,
232
+ trace: result.schemaPath,
233
+ details: {
234
+ schemaVersion: result.schemaVersion,
235
+ requestValid: result.requestValid,
236
+ responseValid: result.responseValid,
237
+ missingFields: result.missingFields,
238
+ extraFields: result.extraFields,
239
+ },
240
+ error: result.valid ? null : (result.error || "Contract validation failed"),
241
+ });
242
+ }
243
+
244
+ /**
245
+ * Proof Collection - aggregates all proofs for a change
246
+ */
247
+ class ProofCollection {
248
+ constructor() {
249
+ this.proofs = [];
250
+ this.required = new Set();
251
+ }
252
+
253
+ /**
254
+ * Add a proof to the collection
255
+ * @param {ProofArtifact} proof - Proof to add
256
+ */
257
+ add(proof) {
258
+ this.proofs.push(proof);
259
+ }
260
+
261
+ /**
262
+ * Mark a proof type as required
263
+ * @param {string} type - Proof type
264
+ */
265
+ require(type) {
266
+ this.required.add(type);
267
+ }
268
+
269
+ /**
270
+ * Check if all required proofs are verified
271
+ * @returns {Object} Verification result
272
+ */
273
+ checkRequired() {
274
+ const missing = [];
275
+ const failed = [];
276
+
277
+ for (const type of this.required) {
278
+ const proofsOfType = this.proofs.filter(p => p.type === type);
279
+
280
+ if (proofsOfType.length === 0) {
281
+ missing.push(type);
282
+ } else {
283
+ const failedProofs = proofsOfType.filter(p => p.status === PROOF_STATUS.FAILED);
284
+ if (failedProofs.length > 0) {
285
+ failed.push(...failedProofs);
286
+ }
287
+ }
288
+ }
289
+
290
+ return {
291
+ satisfied: missing.length === 0 && failed.length === 0,
292
+ missing,
293
+ failed,
294
+ };
295
+ }
296
+
297
+ /**
298
+ * Get all proofs
299
+ * @returns {ProofArtifact[]} All proofs
300
+ */
301
+ getAll() {
302
+ return this.proofs;
303
+ }
304
+
305
+ /**
306
+ * Get proofs by type
307
+ * @param {string} type - Proof type
308
+ * @returns {ProofArtifact[]} Proofs of specified type
309
+ */
310
+ getByType(type) {
311
+ return this.proofs.filter(p => p.type === type);
312
+ }
313
+
314
+ /**
315
+ * Get failed proofs
316
+ * @returns {ProofArtifact[]} Failed proofs
317
+ */
318
+ getFailed() {
319
+ return this.proofs.filter(p => p.status === PROOF_STATUS.FAILED);
320
+ }
321
+
322
+ /**
323
+ * Get verified proofs
324
+ * @returns {ProofArtifact[]} Verified proofs
325
+ */
326
+ getVerified() {
327
+ return this.proofs.filter(p => p.status === PROOF_STATUS.VERIFIED);
328
+ }
329
+
330
+ /**
331
+ * Get summary
332
+ * @returns {Object} Summary object
333
+ */
334
+ getSummary() {
335
+ const total = this.proofs.length;
336
+ const verified = this.getVerified().length;
337
+ const failed = this.getFailed().length;
338
+ const pending = this.proofs.filter(p => p.status === PROOF_STATUS.PENDING).length;
339
+
340
+ return {
341
+ total,
342
+ verified,
343
+ failed,
344
+ pending,
345
+ required: Array.from(this.required),
346
+ satisfied: this.checkRequired().satisfied,
347
+ };
348
+ }
349
+
350
+ /**
351
+ * Export as JSON
352
+ * @returns {Object} JSON representation
353
+ */
354
+ toJSON() {
355
+ return {
356
+ proofs: this.proofs,
357
+ required: Array.from(this.required),
358
+ summary: this.getSummary(),
359
+ timestamp: new Date().toISOString(),
360
+ };
361
+ }
362
+ }
363
+
364
+ /**
365
+ * Determine required proofs based on change types
366
+ * @param {Object[]} claims - Extracted claims from change
367
+ * @param {Object} intent - Intent declaration
368
+ * @returns {string[]} Array of required proof types
369
+ */
370
+ function determineRequiredProofs(claims, intent) {
371
+ const required = new Set();
372
+
373
+ for (const claim of claims) {
374
+ switch (claim.type) {
375
+ case "route":
376
+ required.add(PROOF_TYPE.ROUTE);
377
+ break;
378
+ case "auth_boundary":
379
+ required.add(PROOF_TYPE.AUTH);
380
+ break;
381
+ case "ui_success_claim":
382
+ required.add(PROOF_TYPE.UI);
383
+ break;
384
+ case "http_call":
385
+ required.add(PROOF_TYPE.INTEGRATION);
386
+ break;
387
+ case "env_used":
388
+ required.add(PROOF_TYPE.ENV);
389
+ break;
390
+ case "data_contract":
391
+ required.add(PROOF_TYPE.CONTRACT);
392
+ break;
393
+ }
394
+ }
395
+
396
+ // Intent can specify additional required proofs
397
+ if (intent?.verification?.requiresRealityCheck) {
398
+ required.add(PROOF_TYPE.UI);
399
+ required.add(PROOF_TYPE.ROUTE);
400
+ }
401
+
402
+ return Array.from(required);
403
+ }
404
+
405
+ module.exports = {
406
+ PROOF_TYPE,
407
+ PROOF_STATUS,
408
+ generateProofId,
409
+ createProofArtifact,
410
+ createRouteProof,
411
+ createAuthProof,
412
+ createUIProof,
413
+ createIntegrationProof,
414
+ createEnvProof,
415
+ createContractProof,
416
+ ProofCollection,
417
+ determineRequiredProofs,
418
+ };
@@ -0,0 +1,173 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://vibecheckai.dev/schemas/change-event/v3",
4
+ "title": "Agent Firewall Change Event Schema v3",
5
+ "description": "Represents a single atomic change intercepted by the firewall",
6
+ "type": "object",
7
+ "required": ["id", "type", "timestamp", "source"],
8
+ "properties": {
9
+ "id": {
10
+ "type": "string",
11
+ "pattern": "^chg-[a-z0-9]{8,}$",
12
+ "description": "Unique change event ID"
13
+ },
14
+ "type": {
15
+ "enum": [
16
+ "file_write",
17
+ "file_create",
18
+ "file_delete",
19
+ "file_rename",
20
+ "route_add",
21
+ "route_modify",
22
+ "route_delete",
23
+ "env_ref",
24
+ "env_write",
25
+ "permission_change",
26
+ "ui_state",
27
+ "config_change",
28
+ "migration",
29
+ "dependency_add",
30
+ "dependency_remove"
31
+ ]
32
+ },
33
+ "source": {
34
+ "type": "object",
35
+ "required": ["agent_id", "interception_point"],
36
+ "properties": {
37
+ "agent_id": {
38
+ "type": "string",
39
+ "description": "Agent that generated the change (cursor, windsurf, copilot, etc)"
40
+ },
41
+ "interception_point": {
42
+ "enum": ["mcp_tool", "fs_hook", "git_hook", "ide_hook", "cli"],
43
+ "description": "Where the change was intercepted"
44
+ },
45
+ "tool_name": {
46
+ "type": "string",
47
+ "description": "MCP tool name if applicable"
48
+ },
49
+ "session_id": {
50
+ "type": "string"
51
+ }
52
+ }
53
+ },
54
+ "location": {
55
+ "type": "string",
56
+ "description": "File path, route path, or component identifier"
57
+ },
58
+ "diff": {
59
+ "type": "object",
60
+ "properties": {
61
+ "before": { "type": "string" },
62
+ "after": { "type": "string" },
63
+ "unified": { "type": "string" },
64
+ "lines_added": { "type": "integer" },
65
+ "lines_removed": { "type": "integer" },
66
+ "hunks": {
67
+ "type": "array",
68
+ "items": {
69
+ "type": "object",
70
+ "properties": {
71
+ "start_line": { "type": "integer" },
72
+ "end_line": { "type": "integer" },
73
+ "content": { "type": "string" }
74
+ }
75
+ }
76
+ }
77
+ }
78
+ },
79
+ "content": {
80
+ "type": "string",
81
+ "description": "New content (for creates) or full file content"
82
+ },
83
+ "domain": {
84
+ "enum": ["auth", "payments", "routes", "contracts", "ui", "database", "config", "general", "tests"]
85
+ },
86
+ "claims": {
87
+ "type": "array",
88
+ "description": "Claims extracted from the change",
89
+ "items": {
90
+ "$ref": "#/definitions/Claim"
91
+ }
92
+ },
93
+ "code_quality": {
94
+ "type": "object",
95
+ "description": "Code quality signals detected",
96
+ "properties": {
97
+ "has_mock_data": { "type": "boolean" },
98
+ "has_todo": { "type": "boolean" },
99
+ "has_fixme": { "type": "boolean" },
100
+ "has_placeholder": { "type": "boolean" },
101
+ "has_fake_handler": { "type": "boolean" },
102
+ "has_console_log": { "type": "boolean" },
103
+ "has_any_type": { "type": "boolean" },
104
+ "detected_patterns": {
105
+ "type": "array",
106
+ "items": {
107
+ "type": "object",
108
+ "properties": {
109
+ "pattern": { "type": "string" },
110
+ "line": { "type": "integer" },
111
+ "severity": { "enum": ["block", "warn"] }
112
+ }
113
+ }
114
+ }
115
+ }
116
+ },
117
+ "timestamp": {
118
+ "type": "string",
119
+ "format": "date-time"
120
+ },
121
+ "metadata": {
122
+ "type": "object",
123
+ "description": "Additional type-specific metadata",
124
+ "properties": {
125
+ "http_method": { "type": "string" },
126
+ "route_path": { "type": "string" },
127
+ "env_var_name": { "type": "string" },
128
+ "env_exists_in_file": { "type": "boolean" },
129
+ "permission_scope": { "type": "string" },
130
+ "migration_type": { "type": "string" }
131
+ }
132
+ }
133
+ },
134
+ "definitions": {
135
+ "Claim": {
136
+ "type": "object",
137
+ "required": ["type", "value", "criticality"],
138
+ "properties": {
139
+ "type": {
140
+ "enum": [
141
+ "route",
142
+ "env_used",
143
+ "env_declared",
144
+ "auth_boundary",
145
+ "auth_bypass",
146
+ "data_contract",
147
+ "http_call",
148
+ "ui_success_claim",
149
+ "side_effect",
150
+ "database_write",
151
+ "external_api"
152
+ ]
153
+ },
154
+ "value": {
155
+ "type": "string",
156
+ "description": "The claimed value (route path, env var name, etc)"
157
+ },
158
+ "criticality": {
159
+ "enum": ["hard", "soft"],
160
+ "description": "hard = BLOCK if unproven, soft = WARN"
161
+ },
162
+ "pointer": {
163
+ "type": "string",
164
+ "description": "File:line reference"
165
+ },
166
+ "evidence_required": {
167
+ "type": "boolean",
168
+ "description": "Whether this claim requires evidence before shipping"
169
+ }
170
+ }
171
+ }
172
+ }
173
+ }