@vibecheckai/cli 3.8.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 (34) hide show
  1. package/bin/runners/lib/agent-firewall/enforcement/index.js +98 -98
  2. package/bin/runners/lib/agent-firewall/enforcement/mode.js +318 -318
  3. package/bin/runners/lib/agent-firewall/enforcement/orchestrator.js +484 -484
  4. package/bin/runners/lib/agent-firewall/enforcement/proof-artifact.js +418 -418
  5. package/bin/runners/lib/agent-firewall/enforcement/verdict-v2.js +333 -333
  6. package/bin/runners/lib/agent-firewall/intent/alignment-engine.js +634 -622
  7. package/bin/runners/lib/agent-firewall/intent/index.js +102 -102
  8. package/bin/runners/lib/agent-firewall/intent/schema.js +352 -352
  9. package/bin/runners/lib/agent-firewall/intent/store.js +283 -283
  10. package/bin/runners/lib/agent-firewall/interceptor/base.js +7 -3
  11. package/bin/runners/lib/engine/ast-cache.js +210 -210
  12. package/bin/runners/lib/engine/auth-extractor.js +211 -211
  13. package/bin/runners/lib/engine/billing-extractor.js +112 -112
  14. package/bin/runners/lib/engine/enforcement-extractor.js +100 -100
  15. package/bin/runners/lib/engine/env-extractor.js +207 -207
  16. package/bin/runners/lib/engine/express-extractor.js +208 -208
  17. package/bin/runners/lib/engine/extractors.js +849 -849
  18. package/bin/runners/lib/engine/index.js +207 -207
  19. package/bin/runners/lib/engine/repo-index.js +514 -514
  20. package/bin/runners/lib/engine/types.js +124 -124
  21. package/bin/runners/runIntent.js +906 -906
  22. package/bin/runners/runPacks.js +2089 -2089
  23. package/bin/runners/runReality.js +178 -1
  24. package/bin/runners/runShield.js +1282 -1282
  25. package/mcp-server/handlers/index.ts +2 -2
  26. package/mcp-server/handlers/tool-handler.ts +47 -8
  27. package/mcp-server/lib/executor.ts +5 -5
  28. package/mcp-server/lib/index.ts +14 -4
  29. package/mcp-server/lib/sandbox.test.ts +4 -4
  30. package/mcp-server/lib/sandbox.ts +2 -2
  31. package/mcp-server/package.json +1 -1
  32. package/mcp-server/registry.test.ts +18 -12
  33. package/mcp-server/tsconfig.json +1 -0
  34. package/package.json +2 -1
@@ -1,352 +1,352 @@
1
- /**
2
- * Intent Schema v2 - Enforcement-Grade Intent Declaration
3
- *
4
- * ═══════════════════════════════════════════════════════════════════════════════
5
- * AGENT FIREWALL™ - INTENT DECLARATION SYSTEM
6
- * ═══════════════════════════════════════════════════════════════════════════════
7
- *
8
- * Intent is the foundation of the Agent Firewall enforcement model.
9
- * All AI actions MUST be checked against declared intent.
10
- *
11
- * Properties:
12
- * - Intent is explicit, human-written, short, and structured
13
- * - Intent is captured BEFORE any AI code generation
14
- * - Intent is IMMUTABLE during a session unless explicitly updated
15
- * - If intent is missing → Agent Firewall defaults to BLOCK
16
- *
17
- * @module intent/schema
18
- * @version 2.0.0
19
- */
20
-
21
- "use strict";
22
-
23
- const crypto = require("crypto");
24
-
25
- /**
26
- * Intent Declaration JSON Schema
27
- */
28
- const INTENT_SCHEMA = {
29
- $schema: "http://json-schema.org/draft-07/schema#",
30
- $id: "https://vibecheckai.dev/schemas/intent/v2",
31
- type: "object",
32
- required: ["summary", "constraints", "created_at", "hash"],
33
- properties: {
34
- // Core required fields
35
- summary: {
36
- type: "string",
37
- description: "Human-written summary of what the change intends to accomplish",
38
- minLength: 10,
39
- maxLength: 500,
40
- },
41
- constraints: {
42
- type: "array",
43
- description: "Explicit constraints that MUST be respected. Violations = BLOCK.",
44
- items: {
45
- type: "string",
46
- minLength: 5,
47
- },
48
- minItems: 0,
49
- },
50
- allowed_changes: {
51
- type: "array",
52
- description: "Explicit list of allowed modifications (files, routes, env vars)",
53
- items: {
54
- type: "object",
55
- required: ["type", "target"],
56
- properties: {
57
- type: {
58
- type: "string",
59
- enum: ["file_create", "file_modify", "file_delete", "route_add", "route_modify", "env_add", "permission_modify", "config_change"],
60
- description: "Type of allowed change",
61
- },
62
- target: {
63
- type: "string",
64
- description: "Target of the change (file path, route pattern, env var name)",
65
- },
66
- pattern: {
67
- type: "string",
68
- description: "Glob pattern for matching multiple targets",
69
- },
70
- reason: {
71
- type: "string",
72
- description: "Why this change is allowed",
73
- },
74
- },
75
- },
76
- },
77
- created_at: {
78
- type: "string",
79
- format: "date-time",
80
- description: "ISO timestamp when intent was declared",
81
- },
82
- hash: {
83
- type: "string",
84
- pattern: "^[a-f0-9]{64}$",
85
- description: "SHA-256 hash of intent content for immutability verification",
86
- },
87
-
88
- // Optional metadata
89
- session_id: {
90
- type: "string",
91
- description: "Session identifier for tracking",
92
- },
93
- author: {
94
- type: "string",
95
- description: "Who declared the intent (user identifier)",
96
- },
97
- version: {
98
- type: "number",
99
- description: "Intent version (increments on explicit update)",
100
- minimum: 1,
101
- },
102
- parent_hash: {
103
- type: "string",
104
- description: "Hash of parent intent if this is an update",
105
- },
106
- expires_at: {
107
- type: "string",
108
- format: "date-time",
109
- description: "Optional expiration time for the intent",
110
- },
111
- scope: {
112
- type: "object",
113
- description: "Scope restrictions for the intent",
114
- properties: {
115
- directories: {
116
- type: "array",
117
- items: { type: "string" },
118
- description: "Allowed directories for changes",
119
- },
120
- file_patterns: {
121
- type: "array",
122
- items: { type: "string" },
123
- description: "Allowed file glob patterns",
124
- },
125
- domains: {
126
- type: "array",
127
- items: {
128
- type: "string",
129
- enum: ["auth", "payments", "routes", "contracts", "ui", "database", "config", "general"],
130
- },
131
- description: "Allowed domains for changes",
132
- },
133
- excluded_paths: {
134
- type: "array",
135
- items: { type: "string" },
136
- description: "Explicitly excluded paths",
137
- },
138
- },
139
- },
140
- },
141
- additionalProperties: false,
142
- };
143
-
144
- /**
145
- * Compute content hash for intent immutability verification
146
- * @param {Object} intent - Intent object (without hash)
147
- * @returns {string} SHA-256 hash
148
- */
149
- function computeIntentHash(intent) {
150
- // Normalize intent for consistent hashing
151
- const normalized = {
152
- summary: intent.summary?.trim() || "",
153
- constraints: (intent.constraints || []).map(c => c.trim()).sort(),
154
- allowed_changes: (intent.allowed_changes || [])
155
- .map(c => ({ type: c.type, target: c.target, pattern: c.pattern }))
156
- .sort((a, b) => `${a.type}:${a.target}`.localeCompare(`${b.type}:${b.target}`)),
157
- created_at: intent.created_at,
158
- };
159
-
160
- const content = JSON.stringify(normalized, null, 0);
161
- return crypto.createHash("sha256").update(content).digest("hex");
162
- }
163
-
164
- /**
165
- * Create a new intent declaration
166
- * @param {Object} params - Intent parameters
167
- * @param {string} params.summary - Human-readable summary
168
- * @param {string[]} params.constraints - Constraints to enforce
169
- * @param {Object[]} params.allowed_changes - Explicitly allowed changes
170
- * @param {Object} params.scope - Scope restrictions
171
- * @param {string} params.author - Who declared the intent
172
- * @param {string} params.session_id - Session identifier
173
- * @returns {Object} Complete intent object with hash
174
- */
175
- function createIntent({
176
- summary,
177
- constraints = [],
178
- allowed_changes = [],
179
- scope = null,
180
- author = null,
181
- session_id = null,
182
- }) {
183
- const created_at = new Date().toISOString();
184
-
185
- const intent = {
186
- summary: summary?.trim(),
187
- constraints: constraints.map(c => c.trim()).filter(Boolean),
188
- allowed_changes,
189
- created_at,
190
- version: 1,
191
- hash: "", // Placeholder
192
- };
193
-
194
- // Add optional fields
195
- if (scope) intent.scope = scope;
196
- if (author) intent.author = author;
197
- if (session_id) intent.session_id = session_id;
198
-
199
- // Compute and set hash
200
- intent.hash = computeIntentHash(intent);
201
-
202
- return intent;
203
- }
204
-
205
- /**
206
- * Verify intent has not been tampered with
207
- * @param {Object} intent - Intent to verify
208
- * @returns {Object} Verification result { valid, computed_hash, stored_hash }
209
- */
210
- function verifyIntentIntegrity(intent) {
211
- if (!intent || !intent.hash) {
212
- return {
213
- valid: false,
214
- reason: "MISSING_HASH",
215
- computed_hash: null,
216
- stored_hash: null,
217
- };
218
- }
219
-
220
- const computed = computeIntentHash(intent);
221
- const stored = intent.hash;
222
-
223
- return {
224
- valid: computed === stored,
225
- reason: computed === stored ? "VERIFIED" : "HASH_MISMATCH",
226
- computed_hash: computed,
227
- stored_hash: stored,
228
- };
229
- }
230
-
231
- /**
232
- * Update an existing intent (creates new version with parent reference)
233
- * @param {Object} currentIntent - Current intent
234
- * @param {Object} updates - Fields to update
235
- * @returns {Object} New intent with incremented version
236
- */
237
- function updateIntent(currentIntent, updates) {
238
- const parent_hash = currentIntent.hash;
239
- const version = (currentIntent.version || 1) + 1;
240
-
241
- const newIntent = {
242
- ...currentIntent,
243
- ...updates,
244
- created_at: new Date().toISOString(),
245
- version,
246
- parent_hash,
247
- hash: "", // Will be recomputed
248
- };
249
-
250
- // Ensure constraints are clean
251
- if (newIntent.constraints) {
252
- newIntent.constraints = newIntent.constraints.map(c => c.trim()).filter(Boolean);
253
- }
254
-
255
- // Recompute hash
256
- newIntent.hash = computeIntentHash(newIntent);
257
-
258
- return newIntent;
259
- }
260
-
261
- /**
262
- * Check if intent is expired
263
- * @param {Object} intent - Intent to check
264
- * @returns {boolean} True if expired
265
- */
266
- function isIntentExpired(intent) {
267
- if (!intent.expires_at) return false;
268
- return new Date(intent.expires_at) < new Date();
269
- }
270
-
271
- /**
272
- * Create a minimal blocking intent (for when no intent is declared)
273
- * This intent blocks ALL changes by having no allowed_changes.
274
- * @returns {Object} Blocking intent
275
- */
276
- function createBlockingIntent() {
277
- return createIntent({
278
- summary: "NO INTENT DECLARED - ALL CHANGES BLOCKED BY DEFAULT",
279
- constraints: [
280
- "No changes allowed without explicit intent declaration",
281
- "All file operations blocked",
282
- "All route additions blocked",
283
- "All env var references blocked",
284
- ],
285
- allowed_changes: [],
286
- scope: {
287
- directories: [],
288
- file_patterns: [],
289
- domains: [],
290
- },
291
- });
292
- }
293
-
294
- /**
295
- * Intent constraint types for enforcement
296
- */
297
- const CONSTRAINT_TYPES = {
298
- NO_NEW_ROUTES: "no_new_routes",
299
- NO_AUTH_CHANGES: "no_auth_changes",
300
- NO_PAYMENT_CHANGES: "no_payment_changes",
301
- NO_DATABASE_MIGRATIONS: "no_database_migrations",
302
- NO_ENV_ADDITIONS: "no_env_additions",
303
- NO_PERMISSION_CHANGES: "no_permission_changes",
304
- NO_EXTERNAL_CALLS: "no_external_calls",
305
- NO_FILE_DELETIONS: "no_file_deletions",
306
- SINGLE_FILE_ONLY: "single_file_only",
307
- TESTS_REQUIRED: "tests_required",
308
- REVIEW_REQUIRED: "review_required",
309
- };
310
-
311
- /**
312
- * Pre-built constraint templates
313
- */
314
- const CONSTRAINT_TEMPLATES = {
315
- STRICT_BUGFIX: [
316
- "No new routes allowed",
317
- "No auth logic changes",
318
- "No new environment variables",
319
- "Changes limited to specified file(s)",
320
- "No new dependencies",
321
- ],
322
- FEATURE_ADDITION: [
323
- "New routes must be documented in intent",
324
- "No changes to existing auth logic",
325
- "New env vars must be declared",
326
- "Tests required for new functionality",
327
- ],
328
- REFACTOR: [
329
- "No behavior changes",
330
- "No new routes",
331
- "No API contract changes",
332
- "No auth boundary changes",
333
- ],
334
- SECURITY_PATCH: [
335
- "Auth changes must be explicit in intent",
336
- "No new external endpoints",
337
- "No permission relaxation",
338
- "Review required before ship",
339
- ],
340
- };
341
-
342
- module.exports = {
343
- INTENT_SCHEMA,
344
- createIntent,
345
- computeIntentHash,
346
- verifyIntentIntegrity,
347
- updateIntent,
348
- isIntentExpired,
349
- createBlockingIntent,
350
- CONSTRAINT_TYPES,
351
- CONSTRAINT_TEMPLATES,
352
- };
1
+ /**
2
+ * Intent Schema v2 - Enforcement-Grade Intent Declaration
3
+ *
4
+ * ═══════════════════════════════════════════════════════════════════════════════
5
+ * AGENT FIREWALL™ - INTENT DECLARATION SYSTEM
6
+ * ═══════════════════════════════════════════════════════════════════════════════
7
+ *
8
+ * Intent is the foundation of the Agent Firewall enforcement model.
9
+ * All AI actions MUST be checked against declared intent.
10
+ *
11
+ * Properties:
12
+ * - Intent is explicit, human-written, short, and structured
13
+ * - Intent is captured BEFORE any AI code generation
14
+ * - Intent is IMMUTABLE during a session unless explicitly updated
15
+ * - If intent is missing → Agent Firewall defaults to BLOCK
16
+ *
17
+ * @module intent/schema
18
+ * @version 2.0.0
19
+ */
20
+
21
+ "use strict";
22
+
23
+ const crypto = require("crypto");
24
+
25
+ /**
26
+ * Intent Declaration JSON Schema
27
+ */
28
+ const INTENT_SCHEMA = {
29
+ $schema: "http://json-schema.org/draft-07/schema#",
30
+ $id: "https://vibecheckai.dev/schemas/intent/v2",
31
+ type: "object",
32
+ required: ["summary", "constraints", "created_at", "hash"],
33
+ properties: {
34
+ // Core required fields
35
+ summary: {
36
+ type: "string",
37
+ description: "Human-written summary of what the change intends to accomplish",
38
+ minLength: 10,
39
+ maxLength: 500,
40
+ },
41
+ constraints: {
42
+ type: "array",
43
+ description: "Explicit constraints that MUST be respected. Violations = BLOCK.",
44
+ items: {
45
+ type: "string",
46
+ minLength: 5,
47
+ },
48
+ minItems: 0,
49
+ },
50
+ allowed_changes: {
51
+ type: "array",
52
+ description: "Explicit list of allowed modifications (files, routes, env vars)",
53
+ items: {
54
+ type: "object",
55
+ required: ["type", "target"],
56
+ properties: {
57
+ type: {
58
+ type: "string",
59
+ enum: ["file_create", "file_modify", "file_delete", "route_add", "route_modify", "env_add", "permission_modify", "config_change"],
60
+ description: "Type of allowed change",
61
+ },
62
+ target: {
63
+ type: "string",
64
+ description: "Target of the change (file path, route pattern, env var name)",
65
+ },
66
+ pattern: {
67
+ type: "string",
68
+ description: "Glob pattern for matching multiple targets",
69
+ },
70
+ reason: {
71
+ type: "string",
72
+ description: "Why this change is allowed",
73
+ },
74
+ },
75
+ },
76
+ },
77
+ created_at: {
78
+ type: "string",
79
+ format: "date-time",
80
+ description: "ISO timestamp when intent was declared",
81
+ },
82
+ hash: {
83
+ type: "string",
84
+ pattern: "^[a-f0-9]{64}$",
85
+ description: "SHA-256 hash of intent content for immutability verification",
86
+ },
87
+
88
+ // Optional metadata
89
+ session_id: {
90
+ type: "string",
91
+ description: "Session identifier for tracking",
92
+ },
93
+ author: {
94
+ type: "string",
95
+ description: "Who declared the intent (user identifier)",
96
+ },
97
+ version: {
98
+ type: "number",
99
+ description: "Intent version (increments on explicit update)",
100
+ minimum: 1,
101
+ },
102
+ parent_hash: {
103
+ type: "string",
104
+ description: "Hash of parent intent if this is an update",
105
+ },
106
+ expires_at: {
107
+ type: "string",
108
+ format: "date-time",
109
+ description: "Optional expiration time for the intent",
110
+ },
111
+ scope: {
112
+ type: "object",
113
+ description: "Scope restrictions for the intent",
114
+ properties: {
115
+ directories: {
116
+ type: "array",
117
+ items: { type: "string" },
118
+ description: "Allowed directories for changes",
119
+ },
120
+ file_patterns: {
121
+ type: "array",
122
+ items: { type: "string" },
123
+ description: "Allowed file glob patterns",
124
+ },
125
+ domains: {
126
+ type: "array",
127
+ items: {
128
+ type: "string",
129
+ enum: ["auth", "payments", "routes", "contracts", "ui", "database", "config", "general"],
130
+ },
131
+ description: "Allowed domains for changes",
132
+ },
133
+ excluded_paths: {
134
+ type: "array",
135
+ items: { type: "string" },
136
+ description: "Explicitly excluded paths",
137
+ },
138
+ },
139
+ },
140
+ },
141
+ additionalProperties: false,
142
+ };
143
+
144
+ /**
145
+ * Compute content hash for intent immutability verification
146
+ * @param {Object} intent - Intent object (without hash)
147
+ * @returns {string} SHA-256 hash
148
+ */
149
+ function computeIntentHash(intent) {
150
+ // Normalize intent for consistent hashing
151
+ const normalized = {
152
+ summary: intent.summary?.trim() || "",
153
+ constraints: (intent.constraints || []).map(c => c.trim()).sort(),
154
+ allowed_changes: (intent.allowed_changes || [])
155
+ .map(c => ({ type: c.type, target: c.target, pattern: c.pattern }))
156
+ .sort((a, b) => `${a.type}:${a.target}`.localeCompare(`${b.type}:${b.target}`)),
157
+ created_at: intent.created_at,
158
+ };
159
+
160
+ const content = JSON.stringify(normalized, null, 0);
161
+ return crypto.createHash("sha256").update(content).digest("hex");
162
+ }
163
+
164
+ /**
165
+ * Create a new intent declaration
166
+ * @param {Object} params - Intent parameters
167
+ * @param {string} params.summary - Human-readable summary
168
+ * @param {string[]} params.constraints - Constraints to enforce
169
+ * @param {Object[]} params.allowed_changes - Explicitly allowed changes
170
+ * @param {Object} params.scope - Scope restrictions
171
+ * @param {string} params.author - Who declared the intent
172
+ * @param {string} params.session_id - Session identifier
173
+ * @returns {Object} Complete intent object with hash
174
+ */
175
+ function createIntent({
176
+ summary,
177
+ constraints = [],
178
+ allowed_changes = [],
179
+ scope = null,
180
+ author = null,
181
+ session_id = null,
182
+ }) {
183
+ const created_at = new Date().toISOString();
184
+
185
+ const intent = {
186
+ summary: summary?.trim(),
187
+ constraints: constraints.map(c => c.trim()).filter(Boolean),
188
+ allowed_changes,
189
+ created_at,
190
+ version: 1,
191
+ hash: "", // Placeholder
192
+ };
193
+
194
+ // Add optional fields
195
+ if (scope) intent.scope = scope;
196
+ if (author) intent.author = author;
197
+ if (session_id) intent.session_id = session_id;
198
+
199
+ // Compute and set hash
200
+ intent.hash = computeIntentHash(intent);
201
+
202
+ return intent;
203
+ }
204
+
205
+ /**
206
+ * Verify intent has not been tampered with
207
+ * @param {Object} intent - Intent to verify
208
+ * @returns {Object} Verification result { valid, computed_hash, stored_hash }
209
+ */
210
+ function verifyIntentIntegrity(intent) {
211
+ if (!intent || !intent.hash) {
212
+ return {
213
+ valid: false,
214
+ reason: "MISSING_HASH",
215
+ computed_hash: null,
216
+ stored_hash: null,
217
+ };
218
+ }
219
+
220
+ const computed = computeIntentHash(intent);
221
+ const stored = intent.hash;
222
+
223
+ return {
224
+ valid: computed === stored,
225
+ reason: computed === stored ? "VERIFIED" : "HASH_MISMATCH",
226
+ computed_hash: computed,
227
+ stored_hash: stored,
228
+ };
229
+ }
230
+
231
+ /**
232
+ * Update an existing intent (creates new version with parent reference)
233
+ * @param {Object} currentIntent - Current intent
234
+ * @param {Object} updates - Fields to update
235
+ * @returns {Object} New intent with incremented version
236
+ */
237
+ function updateIntent(currentIntent, updates) {
238
+ const parent_hash = currentIntent.hash;
239
+ const version = (currentIntent.version || 1) + 1;
240
+
241
+ const newIntent = {
242
+ ...currentIntent,
243
+ ...updates,
244
+ created_at: new Date().toISOString(),
245
+ version,
246
+ parent_hash,
247
+ hash: "", // Will be recomputed
248
+ };
249
+
250
+ // Ensure constraints are clean
251
+ if (newIntent.constraints) {
252
+ newIntent.constraints = newIntent.constraints.map(c => c.trim()).filter(Boolean);
253
+ }
254
+
255
+ // Recompute hash
256
+ newIntent.hash = computeIntentHash(newIntent);
257
+
258
+ return newIntent;
259
+ }
260
+
261
+ /**
262
+ * Check if intent is expired
263
+ * @param {Object} intent - Intent to check
264
+ * @returns {boolean} True if expired
265
+ */
266
+ function isIntentExpired(intent) {
267
+ if (!intent.expires_at) return false;
268
+ return new Date(intent.expires_at) < new Date();
269
+ }
270
+
271
+ /**
272
+ * Create a minimal blocking intent (for when no intent is declared)
273
+ * This intent blocks ALL changes by having no allowed_changes.
274
+ * @returns {Object} Blocking intent
275
+ */
276
+ function createBlockingIntent() {
277
+ return createIntent({
278
+ summary: "NO INTENT DECLARED - ALL CHANGES BLOCKED BY DEFAULT",
279
+ constraints: [
280
+ "No changes allowed without explicit intent declaration",
281
+ "All file operations blocked",
282
+ "All route additions blocked",
283
+ "All env var references blocked",
284
+ ],
285
+ allowed_changes: [],
286
+ scope: {
287
+ directories: [],
288
+ file_patterns: [],
289
+ domains: [],
290
+ },
291
+ });
292
+ }
293
+
294
+ /**
295
+ * Intent constraint types for enforcement
296
+ */
297
+ const CONSTRAINT_TYPES = {
298
+ NO_NEW_ROUTES: "no_new_routes",
299
+ NO_AUTH_CHANGES: "no_auth_changes",
300
+ NO_PAYMENT_CHANGES: "no_payment_changes",
301
+ NO_DATABASE_MIGRATIONS: "no_database_migrations",
302
+ NO_ENV_ADDITIONS: "no_env_additions",
303
+ NO_PERMISSION_CHANGES: "no_permission_changes",
304
+ NO_EXTERNAL_CALLS: "no_external_calls",
305
+ NO_FILE_DELETIONS: "no_file_deletions",
306
+ SINGLE_FILE_ONLY: "single_file_only",
307
+ TESTS_REQUIRED: "tests_required",
308
+ REVIEW_REQUIRED: "review_required",
309
+ };
310
+
311
+ /**
312
+ * Pre-built constraint templates
313
+ */
314
+ const CONSTRAINT_TEMPLATES = {
315
+ STRICT_BUGFIX: [
316
+ "No new routes allowed",
317
+ "No auth logic changes",
318
+ "No new environment variables",
319
+ "Changes limited to specified file(s)",
320
+ "No new dependencies",
321
+ ],
322
+ FEATURE_ADDITION: [
323
+ "New routes must be documented in intent",
324
+ "No changes to existing auth logic",
325
+ "New env vars must be declared",
326
+ "Tests required for new functionality",
327
+ ],
328
+ REFACTOR: [
329
+ "No behavior changes",
330
+ "No new routes",
331
+ "No API contract changes",
332
+ "No auth boundary changes",
333
+ ],
334
+ SECURITY_PATCH: [
335
+ "Auth changes must be explicit in intent",
336
+ "No new external endpoints",
337
+ "No permission relaxation",
338
+ "Review required before ship",
339
+ ],
340
+ };
341
+
342
+ module.exports = {
343
+ INTENT_SCHEMA,
344
+ createIntent,
345
+ computeIntentHash,
346
+ verifyIntentIntegrity,
347
+ updateIntent,
348
+ isIntentExpired,
349
+ createBlockingIntent,
350
+ CONSTRAINT_TYPES,
351
+ CONSTRAINT_TEMPLATES,
352
+ };