@specverse/engines 4.1.15 → 4.1.17

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.
@@ -0,0 +1,482 @@
1
+ /**
2
+ * L3 Verification Runner
3
+ *
4
+ * Runs the Quint-transpiled guards against a spec snapshot and reports
5
+ * pass / fail / skipped. A guard is skipped when any of its state-var
6
+ * dependencies is missing from the snapshot — a raw (pre-inference)
7
+ * spec, for example, won't have `inferredControllers`, so guards that
8
+ * need it are skipped rather than failed.
9
+ *
10
+ * Usage:
11
+ * const result = await verifySpec(parsedSpec, { entitiesDir });
12
+ * if (result.failed.length > 0) process.exit(1);
13
+ *
14
+ * The caller is responsible for deciding what "the spec" is — raw,
15
+ * inferred, or something else. `verifySpec` runs whichever guards are
16
+ * applicable.
17
+ */
18
+ import { createRequire } from 'module';
19
+ import { dirname, join } from 'path';
20
+ import { transpileEntityGuards, extractStateVariables, generateGuardsModule } from './quint-transpiler.js';
21
+ /**
22
+ * Build a Quint-shaped snapshot from a SpecVerse AST.
23
+ *
24
+ * The AST nests collections under `components` and uses shorthand
25
+ * strings for relationships and convention-format attributes. The
26
+ * guards were written against a flatter, more structured shape — each
27
+ * top-level state var (`models`, `controllers`, etc.) is an array of
28
+ * entities, and each entity's nested collections (`attributes`,
29
+ * `relationships`, …) are keyed maps.
30
+ *
31
+ * This function performs the normalization. The caller passes any spec
32
+ * (raw or inferred); only keys actually present in the spec are
33
+ * populated in the returned snapshot.
34
+ */
35
+ export function buildSnapshot(spec, stateVars) {
36
+ const toArray = (v) => {
37
+ if (!v)
38
+ return [];
39
+ if (Array.isArray(v))
40
+ return v;
41
+ return Object.entries(v).map(([name, data]) => {
42
+ if (data && typeof data === 'object')
43
+ return { name, ...data };
44
+ return { name, value: data };
45
+ });
46
+ };
47
+ const toKeyedMap = (v) => {
48
+ if (!v)
49
+ return {};
50
+ if (Array.isArray(v)) {
51
+ const out = {};
52
+ for (const item of v) {
53
+ const key = item?.name || item?.id;
54
+ if (key)
55
+ out[key] = item;
56
+ }
57
+ return out;
58
+ }
59
+ return v;
60
+ };
61
+ // Parse shorthand relationship strings into structured objects so
62
+ // Quint guards that read `.relType` and `.targetModel` work on raw
63
+ // specs too. Examples:
64
+ // "hasMany Component" → {relType, targetModel}
65
+ // "hasMany Post cascade" → + {cascade: true}
66
+ // "manyToMany Tag through=TagLink" → + {through: "TagLink"}
67
+ // "belongsTo User" → {relType, targetModel}
68
+ const parseRelationshipShorthand = (s, name) => {
69
+ const parts = s.trim().split(/\s+/);
70
+ const relType = parts[0];
71
+ const targetModel = parts[1];
72
+ const rest = parts.slice(2);
73
+ const obj = { name, relType, targetModel };
74
+ for (const token of rest) {
75
+ if (token.includes('=')) {
76
+ const [k, v] = token.split('=');
77
+ obj[k] = v;
78
+ }
79
+ else {
80
+ obj[token] = true;
81
+ }
82
+ }
83
+ return obj;
84
+ };
85
+ const normalizeRelationships = (rels) => {
86
+ if (!rels)
87
+ return {};
88
+ const result = {};
89
+ const entries = Array.isArray(rels)
90
+ ? rels.map((r) => [r.name, r])
91
+ : Object.entries(rels);
92
+ for (const [name, value] of entries) {
93
+ if (typeof value === 'string') {
94
+ result[name] = parseRelationshipShorthand(value, name);
95
+ }
96
+ else if (value && typeof value === 'object') {
97
+ // The parser stores structured relationships as { type, target }
98
+ // (e.g. { name: 'components', type: 'hasMany', target: 'Component' }).
99
+ // Quint invariants read them as { relType, targetModel }. Map
100
+ // between the two so guards can run against the parsed shape.
101
+ const relType = value.relType ?? value.type;
102
+ const targetModel = value.targetModel ?? value.target;
103
+ result[name] = { ...value, name, relType, targetModel };
104
+ }
105
+ }
106
+ return result;
107
+ };
108
+ const MODEL_NESTED = ['attributes', 'lifecycles', 'behaviors', 'profiles'];
109
+ // relationships handled specially so shorthand strings get parsed
110
+ const CONTROLLER_NESTED = ['endpoints', 'actions', 'operations'];
111
+ const SERVICE_NESTED = ['operations'];
112
+ const EVENT_NESTED = ['attributes'];
113
+ const VIEW_NESTED = ['layouts', 'uiComponents'];
114
+ const DEPLOYMENT_NESTED = ['instances'];
115
+ const normalizeEntity = (entity, keys) => {
116
+ if (!entity || typeof entity !== 'object')
117
+ return entity;
118
+ const out = { ...entity };
119
+ for (const k of keys)
120
+ if (k in out)
121
+ out[k] = toKeyedMap(out[k]);
122
+ // Relationships need their own normalization to parse shorthand strings.
123
+ if ('relationships' in out)
124
+ out.relationships = normalizeRelationships(out.relationships);
125
+ return out;
126
+ };
127
+ const normList = (arr, keys) => arr.map(e => normalizeEntity(e, keys));
128
+ // Field aliases and derivations: convenience flags the Quint specs
129
+ // use that are simple views of data already in the spec. These are
130
+ // NOT synthesizing new information — they expose existing data
131
+ // under Quint's field naming.
132
+ /**
133
+ * Parser stores lifecycle states as a flat array of strings for the
134
+ * shorthand form (`flow: "draft -> open -> closed"` → `states: ['draft',
135
+ * 'open', 'closed']`). Quint invariants expect structured
136
+ * LifecycleState records with `isInitial` / `isTerminal` flags. The
137
+ * shorthand form always makes the first state initial and the last
138
+ * terminal by convention, so we synthesize the structure here.
139
+ */
140
+ const structureLifecycle = (lc) => {
141
+ if (!lc || typeof lc !== 'object')
142
+ return { name: '', states: [], transitions: [] };
143
+ const rawStates = Array.isArray(lc.states) ? lc.states : [];
144
+ const structuredStates = rawStates.map((s, i) => {
145
+ if (typeof s === 'string') {
146
+ return { name: s, isInitial: i === 0, isTerminal: i === rawStates.length - 1 };
147
+ }
148
+ // Already structured — pass through, filling in flags if missing
149
+ return {
150
+ isInitial: false,
151
+ isTerminal: false,
152
+ ...s,
153
+ };
154
+ });
155
+ // Transitions: if the lifecycle has a `flow` shorthand, derive
156
+ // `from`/`to` pairs for adjacent states.
157
+ let structuredTransitions = [];
158
+ if (Array.isArray(lc.transitions) && lc.transitions.length > 0 && typeof lc.transitions[0] === 'object') {
159
+ structuredTransitions = lc.transitions;
160
+ }
161
+ else if (rawStates.length > 1) {
162
+ structuredTransitions = [];
163
+ for (let i = 0; i < rawStates.length - 1; i++) {
164
+ const from = typeof rawStates[i] === 'string' ? rawStates[i] : rawStates[i].name;
165
+ const to = typeof rawStates[i + 1] === 'string' ? rawStates[i + 1] : rawStates[i + 1].name;
166
+ structuredTransitions.push({ name: `${from}_to_${to}`, from, to });
167
+ }
168
+ }
169
+ return {
170
+ ...lc,
171
+ states: structuredStates,
172
+ transitions: structuredTransitions,
173
+ };
174
+ };
175
+ const aliasModelFields = (m) => {
176
+ const lifecycleEntries = m.lifecycles && typeof m.lifecycles === 'object'
177
+ ? Object.values(m.lifecycles)
178
+ : [];
179
+ const firstLifecycle = lifecycleEntries[0];
180
+ return {
181
+ ...m,
182
+ hasLifecycle: lifecycleEntries.length > 0,
183
+ lifecycle: firstLifecycle
184
+ ? structureLifecycle(firstLifecycle)
185
+ : { name: '', states: [], transitions: [] },
186
+ };
187
+ };
188
+ const aliasViewFields = (v) => ({
189
+ ...v,
190
+ // Parser stores `type` (matches YAML `type: list`), Quint uses
191
+ // `viewType` to avoid keyword collision. Keep both.
192
+ viewType: v.viewType ?? v.type,
193
+ });
194
+ // Collect top-level + component-nested entities for each state var.
195
+ // Only populate keys where the spec actually has data; leave others
196
+ // unset so the verification runner can skip dependent guards.
197
+ //
198
+ // When flattening, tag each entity with `.component` (the parent
199
+ // component name) and `.system` (true for entities under
200
+ // build-system / AI / tooling components — these are meta-models
201
+ // describing the language itself and don't need runtime controllers).
202
+ const SYSTEM_COMPONENT_PATTERN = /^(BuildSystem|ToolsSupport|AISupport|Tooling|MetaModel)/i;
203
+ const snapshot = {};
204
+ const componentList = spec?.components
205
+ ? (Array.isArray(spec.components) ? spec.components : Object.entries(spec.components).map(([name, data]) => ({ name, ...(data || {}) })))
206
+ : [];
207
+ const tagWithComponent = (item, componentName) => {
208
+ if (!item || typeof item !== 'object')
209
+ return item;
210
+ const isSystem = SYSTEM_COMPONENT_PATTERN.test(componentName);
211
+ return { component: componentName, system: isSystem, ...item };
212
+ };
213
+ for (const v of stateVars) {
214
+ const topLevel = toArray(spec?.[v]);
215
+ const nested = [];
216
+ for (const comp of componentList) {
217
+ const val = comp?.[v];
218
+ if (val) {
219
+ const compName = comp?.name || '';
220
+ for (const item of toArray(val)) {
221
+ nested.push(tagWithComponent(item, compName));
222
+ }
223
+ }
224
+ }
225
+ if (topLevel.length > 0 || nested.length > 0) {
226
+ snapshot[v] = [...topLevel, ...nested];
227
+ }
228
+ }
229
+ // `components` is its own state var, populated from the list
230
+ if (stateVars.includes('components') && componentList.length > 0) {
231
+ snapshot.components = componentList;
232
+ }
233
+ // Normalize per-entity nested collections
234
+ if (snapshot.models)
235
+ snapshot.models = normList(snapshot.models, MODEL_NESTED).map(aliasModelFields);
236
+ if (snapshot.controllers)
237
+ snapshot.controllers = normList(snapshot.controllers, CONTROLLER_NESTED);
238
+ if (snapshot.services)
239
+ snapshot.services = normList(snapshot.services, SERVICE_NESTED);
240
+ if (snapshot.events)
241
+ snapshot.events = normList(snapshot.events, EVENT_NESTED);
242
+ if (snapshot.views)
243
+ snapshot.views = normList(snapshot.views, VIEW_NESTED).map(aliasViewFields);
244
+ if (snapshot.deployments)
245
+ snapshot.deployments = normList(snapshot.deployments, DEPLOYMENT_NESTED);
246
+ // `inferredControllers` / `inferredServices` are Quint internal aliases
247
+ // for inference output. Populate them only when the respective
248
+ // non-inferred collection is present AND non-empty — this is the
249
+ // signal that inference (or a user writing the expanded form) has run.
250
+ if (stateVars.includes('inferredControllers') && snapshot.controllers?.length) {
251
+ snapshot.inferredControllers = snapshot.controllers;
252
+ }
253
+ if (stateVars.includes('inferredServices') && snapshot.services?.length) {
254
+ snapshot.inferredServices = snapshot.services;
255
+ }
256
+ return snapshot;
257
+ }
258
+ /**
259
+ * Scan a guard body for `<loopVar>.<field>` accesses that are bound to
260
+ * a state-var collection (e.g. `c.depth` inside `commands.forall(c => ...)`).
261
+ * For each such field, check whether it's populated on AT LEAST ONE
262
+ * entity in the relevant snapshot collection. Return the fields that
263
+ * aren't populated anywhere — those are the reason to skip the guard.
264
+ *
265
+ * This is a best-effort heuristic; it only catches the common case
266
+ * where a Quint invariant references a field the runtime data doesn't
267
+ * populate (typically fields added by inference that a raw spec lacks).
268
+ */
269
+ function findUnusableFields(guard, snapshot) {
270
+ const quint = guard.quint || '';
271
+ // Find forall / exists / filter / map bindings: e.g. `commands.forall(c => ...)`
272
+ // produces the binding `c -> commands`. We scan for `<stateVar>.<op>(<var> =>`
273
+ // and then look for `<var>.<field>` accesses elsewhere in the body.
274
+ const bindingRe = /(\w+)\.(?:forall|exists|filter|map|flatMap)\(\s*(\w+)\s*=>/g;
275
+ const bindings = new Map(); // var → state var name
276
+ let m;
277
+ while ((m = bindingRe.exec(quint)) !== null) {
278
+ const [, stateVar, varName] = m;
279
+ if (guard.dependencies.includes(stateVar) && !bindings.has(varName)) {
280
+ bindings.set(varName, stateVar);
281
+ }
282
+ }
283
+ if (bindings.size === 0)
284
+ return [];
285
+ const missing = new Set();
286
+ for (const [varName, stateVar] of bindings) {
287
+ const fieldRe = new RegExp(`\\b${varName}\\.(\\w+)`, 'g');
288
+ const fields = new Set();
289
+ let fm;
290
+ while ((fm = fieldRe.exec(quint)) !== null) {
291
+ // Skip methods (followed by `(`)
292
+ const after = quint[fm.index + fm[0].length];
293
+ if (after === '(')
294
+ continue;
295
+ fields.add(fm[1]);
296
+ }
297
+ const collection = snapshot[stateVar] || [];
298
+ for (const field of fields) {
299
+ const anyHas = collection.some(item => item && typeof item === 'object' && field in item);
300
+ if (!anyHas)
301
+ missing.add(field);
302
+ }
303
+ }
304
+ return [...missing].sort();
305
+ }
306
+ /**
307
+ * Resolve the entities source directory when not explicitly provided.
308
+ */
309
+ function resolveEntitiesDir() {
310
+ const req = createRequire(import.meta.url);
311
+ const pkgPath = req.resolve('@specverse/entities/package.json');
312
+ return join(dirname(pkgPath), 'src');
313
+ }
314
+ /**
315
+ * Run the L3 verification gate against the provided spec.
316
+ *
317
+ * `spec` can be any SpecVerse AST — raw, inferred, or anywhere in
318
+ * between. Only guards whose dependencies are present in the
319
+ * resulting snapshot run; the rest are reported as skipped.
320
+ */
321
+ export async function verifySpec(spec, opts = {}) {
322
+ const entitiesDir = opts.entitiesDir || resolveEntitiesDir();
323
+ const guards = transpileEntityGuards(entitiesDir);
324
+ const stateVars = extractStateVariables(entitiesDir);
325
+ // Deduplicate guards by (kind, name) to match generateGuardsModule
326
+ const seen = new Set();
327
+ const uniqueGuards = guards.filter(g => {
328
+ const key = `${g.kind}:${g.name}`;
329
+ if (seen.has(key))
330
+ return false;
331
+ seen.add(key);
332
+ return true;
333
+ });
334
+ // Build the snapshot — caller can override which vars are "available"
335
+ // by passing an explicit availableVars list, but by default we derive
336
+ // it from what buildSnapshot populates.
337
+ const snapshot = buildSnapshot(spec, stateVars);
338
+ const availableVars = new Set(opts.availableVars || Object.keys(snapshot));
339
+ const invariants = uniqueGuards.filter(g => g.kind === 'invariant');
340
+ const failed = [];
341
+ const skipped = [];
342
+ const errors = [];
343
+ let passed = 0;
344
+ // Partition: which guards can run against this snapshot?
345
+ // A guard is runnable when (a) all its state-var dependencies are in
346
+ // the snapshot AND (b) for every `<loopVar>.<field>` access in its
347
+ // body, that field exists on at least one entity of the relevant
348
+ // state var. This second check catches cases like `c.depth <= 3`
349
+ // where the field is populated only by inference — on a raw spec,
350
+ // the guard would silently return false from `undefined <= 3`, which
351
+ // is a data-completeness issue, not an invariant violation.
352
+ const runnable = [];
353
+ for (const g of invariants) {
354
+ const missingVars = g.dependencies.filter(d => !availableVars.has(d));
355
+ if (missingVars.length > 0) {
356
+ skipped.push({ name: g.name, entity: g.entity, missingDeps: missingVars });
357
+ continue;
358
+ }
359
+ const missingFields = findUnusableFields(g, snapshot);
360
+ if (missingFields.length > 0) {
361
+ skipped.push({ name: g.name, entity: g.entity, missingDeps: missingFields.map(f => `field ${f}`) });
362
+ continue;
363
+ }
364
+ runnable.push(g);
365
+ }
366
+ if (runnable.length === 0) {
367
+ return { total: invariants.length, passed: 0, failed, skipped, errors };
368
+ }
369
+ // Transpile guards to a runnable module — only the ones we need, so
370
+ // state vars filter down naturally.
371
+ const guardsCode = generateGuardsModule(runnable, stateVars);
372
+ const esbuild = await import('esbuild');
373
+ const compiled = esbuild.transformSync(guardsCode, {
374
+ loader: 'ts',
375
+ format: 'esm',
376
+ target: 'es2022',
377
+ }).code;
378
+ const dataUrl = 'data:text/javascript;base64,' + Buffer.from(compiled).toString('base64');
379
+ const mod = await import(dataUrl);
380
+ if (typeof mod.setSpecSnapshot === 'function') {
381
+ mod.setSpecSnapshot(snapshot);
382
+ }
383
+ // Classify errors: a thrown exception from undefined field access
384
+ // (e.g. `.every` on undefined, `.X` on undefined, `X is not a function`
385
+ // on a missing array method) means the guard expected a field the
386
+ // spec doesn't have. Report it as "skipped — data-completeness",
387
+ // not as a transpiler error.
388
+ const classifyError = (msg) => {
389
+ if (/Cannot read properties of (undefined|null)/.test(msg) ||
390
+ /\bof undefined\b/.test(msg) ||
391
+ /Cannot convert undefined or null to object/.test(msg) ||
392
+ / is not a function\b/.test(msg)) {
393
+ const field = msg.match(/reading '([^']+)'/)?.[1]
394
+ || msg.match(/\b(\w+) is not a function/)?.[1];
395
+ return { isShape: true, field };
396
+ }
397
+ return { isShape: false };
398
+ };
399
+ for (const g of runnable) {
400
+ const fn = mod[`check_${g.name}`];
401
+ if (typeof fn !== 'function')
402
+ continue;
403
+ try {
404
+ const ok = fn();
405
+ if (ok === false) {
406
+ failed.push({
407
+ name: g.name,
408
+ entity: g.entity,
409
+ module: g.module,
410
+ quint: g.quint,
411
+ });
412
+ }
413
+ else {
414
+ passed++;
415
+ }
416
+ }
417
+ catch (e) {
418
+ const msg = e.message || String(e);
419
+ const cls = classifyError(msg);
420
+ if (cls.isShape) {
421
+ skipped.push({
422
+ name: g.name,
423
+ entity: g.entity,
424
+ missingDeps: cls.field ? [`field ${cls.field}`] : ['undefined field'],
425
+ });
426
+ }
427
+ else {
428
+ errors.push({ name: g.name, entity: g.entity, message: msg });
429
+ }
430
+ }
431
+ }
432
+ return {
433
+ total: invariants.length,
434
+ passed,
435
+ failed,
436
+ skipped,
437
+ errors,
438
+ };
439
+ }
440
+ /**
441
+ * Format a verification result for CLI output.
442
+ */
443
+ export function formatVerificationResult(result, verbose = false) {
444
+ const lines = [];
445
+ const applicable = result.passed + result.failed.length + result.errors.length;
446
+ lines.push(`L3 verification: ${result.passed}/${applicable} invariants hold`);
447
+ if (result.skipped.length > 0) {
448
+ lines.push(` ${result.skipped.length} skipped (not applicable to this spec)`);
449
+ }
450
+ if (result.failed.length > 0) {
451
+ lines.push(` ${result.failed.length} failed:`);
452
+ const toShow = verbose ? result.failed : result.failed.slice(0, 10);
453
+ for (const f of toShow) {
454
+ lines.push(` ✗ ${f.entity}/${f.name}`);
455
+ if (verbose && f.quint) {
456
+ const first = f.quint.split('\n')[0].slice(0, 120);
457
+ lines.push(` ${first}`);
458
+ }
459
+ }
460
+ if (!verbose && result.failed.length > 10) {
461
+ lines.push(` ...and ${result.failed.length - 10} more`);
462
+ }
463
+ }
464
+ if (result.errors.length > 0) {
465
+ lines.push(` ${result.errors.length} errored (shape mismatch):`);
466
+ const toShow = verbose ? result.errors : result.errors.slice(0, 5);
467
+ for (const e of toShow) {
468
+ lines.push(` ⚠ ${e.entity}/${e.name}: ${e.message}`);
469
+ }
470
+ if (!verbose && result.errors.length > 5) {
471
+ lines.push(` ...and ${result.errors.length - 5} more`);
472
+ }
473
+ }
474
+ if (verbose && result.skipped.length > 0) {
475
+ lines.push(' skipped guards:');
476
+ for (const s of result.skipped) {
477
+ lines.push(` - ${s.entity}/${s.name} (needs: ${s.missingDeps.join(', ')})`);
478
+ }
479
+ }
480
+ return lines.join('\n');
481
+ }
482
+ //# sourceMappingURL=verification.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verification.js","sourceRoot":"","sources":["../../src/inference/verification.ts"],"names":[],"mappings":"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"}
@@ -20,7 +20,7 @@ function generateCommand(context) {
20
20
  const flagType = flag.type?.toLowerCase();
21
21
  const valuePart = flagType === "boolean" ? "" : ` <${flagName.replace(/^--/, "")}>`;
22
22
  const defaultVal = flag.default !== void 0 ? `, ${commanderDefault(flag.default, flagType)}` : "";
23
- const desc = flag.description || `${flagName} option`;
23
+ const desc = escapeSingleQuotes(flag.description || `${flagName} option`);
24
24
  return ` .option('${alias}${flagName}${valuePart}', '${desc}'${defaultVal})`;
25
25
  });
26
26
  const optionTypes = Object.entries(flags).map(([flagName, flag]) => {
@@ -123,6 +123,27 @@ import type { ParserEngine } from '@specverse/types';`,
123
123
  console.warn('Warnings:');
124
124
  result.warnings.forEach((w: string) => console.warn(' ', w));
125
125
  }
126
+ }
127
+
128
+ // L3 verification \u2014 opt-in via --verify flag. Runs the
129
+ // transpiled Quint guards against the parsed spec. Guards
130
+ // whose state-var dependencies aren't present in this spec
131
+ // are reported as skipped (not failed).
132
+ if (options.verify) {
133
+ try {
134
+ const { verifySpec, formatVerificationResult } = await import('@specverse/engines/inference');
135
+ const verification = await verifySpec(result.ast);
136
+ if (options.json) {
137
+ console.log(JSON.stringify({ valid: true, verification }, null, 2));
138
+ } else {
139
+ console.log('');
140
+ console.log(formatVerificationResult(verification, options.verbose));
141
+ }
142
+ if (verification.failed.length > 0) process.exit(1);
143
+ } catch (ve: any) {
144
+ console.error('Verification error:', ve.message);
145
+ process.exit(1);
146
+ }
126
147
  }`
127
148
  },
128
149
  infer: {
@@ -862,7 +883,7 @@ function generateLeafCommand(name, description, commandStr, optionDefs, actionPa
862
883
  const finalActionParams = renameUnusedActionParams(actionParams, handler);
863
884
  return `program
864
885
  .command('${commandStr}')
865
- .description('${description}')
886
+ .description('${escapeSingleQuotes(description)}')
866
887
  ${optionDefs.join("\n")}
867
888
  .action(async (${finalActionParams}) => {
868
889
  try {
@@ -873,6 +894,9 @@ ${optionDefs.join("\n")}
873
894
  }
874
895
  });`;
875
896
  }
897
+ function escapeSingleQuotes(s) {
898
+ return s.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
899
+ }
876
900
  function commanderDefault(value, flagType) {
877
901
  if (flagType === "boolean") return JSON.stringify(Boolean(value));
878
902
  if (typeof value === "number") return JSON.stringify(String(value));
@@ -903,7 +927,8 @@ function generateCommandWithSubcommands(name, description, subcommands, optionDe
903
927
  const flagType = flag.type?.toLowerCase();
904
928
  const valuePart = flagType === "boolean" ? "" : ` <${flagName.replace(/^--/, "")}>`;
905
929
  const defaultVal = flag.default !== void 0 ? `, ${commanderDefault(flag.default, flagType)}` : "";
906
- return ` .option('${alias}${flagName}${valuePart}', '${flag.description || flagName}'${defaultVal})`;
930
+ const desc = escapeSingleQuotes(flag.description || flagName);
931
+ return ` .option('${alias}${flagName}${valuePart}', '${desc}'${defaultVal})`;
907
932
  });
908
933
  const handlerKey = `${name}.${subName}`;
909
934
  const engineHandler = ENGINE_HANDLERS[handlerKey];
@@ -914,7 +939,7 @@ function generateCommandWithSubcommands(name, description, subcommands, optionDe
914
939
  return `
915
940
  cmd
916
941
  .command('${subCmdStr}')
917
- .description('${subDesc}')
942
+ .description('${escapeSingleQuotes(subDesc)}')
918
943
  ${subOptionDefs.join("\n")}
919
944
  .action(async (${finalSubActionParams}) => {
920
945
  try {
@@ -927,7 +952,7 @@ ${subOptionDefs.join("\n")}
927
952
  });
928
953
  return `const cmd = program
929
954
  .command('${name}')
930
- .description('${description}');
955
+ .description('${escapeSingleQuotes(description)}');
931
956
  ${subcmdRegistrations.join("\n")}`;
932
957
  }
933
958
  function generateSubcommandRegistrations(_parentName, _subcommands) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/realize/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,cAAc,kBAAkB,CAAC;AAGjC,cAAc,kBAAkB,CAAC;AAGjC,cAAc,uBAAuB,CAAC;AAGtC,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACpF,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAGvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAMlE,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AASnF,cAAM,sBAAuB,YAAW,aAAa;IACnD,IAAI,SAAa;IACjB,OAAO,SAAW;IAClB,YAAY,WAA+E;IAE3F,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,QAAQ,CAAa;IAC7B,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAa;IAC7B,OAAO,CAAC,WAAW,CAAS;IAEtB,UAAU,CAAC,MAAM,CAAC,EAAE;QACxB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBjB,OAAO,IAAI,UAAU;IAIrB,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,GAAG;IAK1B,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,eAAe,CAAC;IAKvF;;;OAGG;IACG,UAAU,CAAC,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAklB9F;;;OAGG;YACW,UAAU;IAwDxB,OAAO,CAAC,oBAAoB;CAuB7B;AAED,eAAO,MAAM,MAAM,wBAA+B,CAAC;AACnD,eAAe,MAAM,CAAC;AACtB,OAAO,EAAE,sBAAsB,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/realize/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,cAAc,kBAAkB,CAAC;AAGjC,cAAc,kBAAkB,CAAC;AAGjC,cAAc,uBAAuB,CAAC;AAGtC,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACpF,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAGvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAMlE,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AASnF,cAAM,sBAAuB,YAAW,aAAa;IACnD,IAAI,SAAa;IACjB,OAAO,SAAW;IAClB,YAAY,WAA+E;IAE3F,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,QAAQ,CAAa;IAC7B,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAa;IAC7B,OAAO,CAAC,WAAW,CAAS;IAEtB,UAAU,CAAC,MAAM,CAAC,EAAE;QACxB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBjB,OAAO,IAAI,UAAU;IAIrB,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,GAAG;IAK1B,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,eAAe,CAAC;IAKvF;;;OAGG;IACG,UAAU,CAAC,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAskB9F;;;OAGG;YACW,UAAU;IAwDxB,OAAO,CAAC,oBAAoB;CAuB7B;AAED,eAAO,MAAM,MAAM,wBAA+B,CAAC;AACnD,eAAe,MAAM,CAAC;AACtB,OAAO,EAAE,sBAAsB,EAAE,CAAC"}
@@ -68,6 +68,10 @@ class SpecVerseRealizeEngine {
68
68
  const files = [];
69
69
  const errors = [];
70
70
  const allModels = Object.values(spec.models || {});
71
+ // L3 verification (Quint guards) is NOT run here. It lives in
72
+ // `validate --verify` so users can opt into it explicitly and run
73
+ // it on any spec — raw or inferred — without also generating code.
74
+ // See engines/src/inference/verification.ts.
71
75
  const writeOutput = (output) => {
72
76
  // A generator can signal "skip this file" by returning an empty string.
73
77
  if (output.code === '')
@@ -529,32 +533,11 @@ export default {
529
533
  errors.push(`SharedUtils: ${e.message}`);
530
534
  }
531
535
  }
532
- // 9b. Runtime guards transpiled from Quint specifications.
533
- // Only emit when the manifest declares a backend; a frontend-only
534
- // layout has no `backend/src/` to write into.
535
- const hasBackendForGuards = !!(tryResolve('service.controller') || tryResolve('api.rest') || tryResolve('orm.schema'));
536
- if (hasBackendForGuards) {
537
- try {
538
- const { transpileEntityGuards, generateGuardsModule } = await import('../inference/index.js');
539
- const { createRequire } = await import('module');
540
- const req = createRequire(import.meta.url);
541
- const entitiesPkg = req.resolve('@specverse/entities/package.json');
542
- const entitiesSrc = join(dirname(entitiesPkg), 'src');
543
- const guards = transpileEntityGuards(entitiesSrc);
544
- if (guards.length > 0) {
545
- const guardsCode = generateGuardsModule(guards);
546
- const guardsPath = join(outputDir, 'backend', 'src', 'guards.ts');
547
- const guardsDir = dirname(guardsPath);
548
- if (!existsSync(guardsDir))
549
- mkdirSync(guardsDir, { recursive: true });
550
- writeFileSync(guardsPath, guardsCode);
551
- console.log(` ✅ Runtime guards: ${guards.length} guards (${guards.filter((g) => g.kind === 'function').length} functions, ${guards.filter((g) => g.kind === 'invariant').length} invariants) from Quint specs`);
552
- }
553
- }
554
- catch (e) {
555
- errors.push(`Guards: ${e.message}`);
556
- }
557
- }
536
+ // 9b. Quint guards are no longer emitted to the generated backend.
537
+ // They are L3 verification assertions about the SPEC, not runtime
538
+ // checks on the user's data so they run at realize time (see the
539
+ // L3 verification gate at the start of realizeAll) and don't ship
540
+ // to the user's project.
558
541
  // 10. CLI commands (Commander.js)
559
542
  try {
560
543
  const cliDir = join(dirname(fileURLToPath(import.meta.url)), '..', '..', 'libs', 'instance-factories', 'cli', 'templates', 'commander');