@specverse/engines 6.3.1 → 6.5.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.
- package/dist/ai/analyse-runner.d.ts +14 -0
- package/dist/ai/analyse-runner.d.ts.map +1 -1
- package/dist/ai/analyse-runner.js +88 -1
- package/dist/ai/analyse-runner.js.map +1 -1
- package/dist/ai/behavior-cross-check/index.d.ts +49 -0
- package/dist/ai/behavior-cross-check/index.d.ts.map +1 -0
- package/dist/ai/behavior-cross-check/index.js +160 -0
- package/dist/ai/behavior-cross-check/index.js.map +1 -0
- package/dist/analyse-prepass/index.d.ts +31 -1
- package/dist/analyse-prepass/index.d.ts.map +1 -1
- package/dist/analyse-prepass/index.js +85 -0
- package/dist/analyse-prepass/index.js.map +1 -1
- package/dist/inference/quint-gen/index.d.ts +67 -0
- package/dist/inference/quint-gen/index.d.ts.map +1 -0
- package/dist/inference/quint-gen/index.js +411 -0
- package/dist/inference/quint-gen/index.js.map +1 -0
- package/dist/inference/quint-gen/runner.d.ts +36 -0
- package/dist/inference/quint-gen/runner.d.ts.map +1 -0
- package/dist/inference/quint-gen/runner.js +79 -0
- package/dist/inference/quint-gen/runner.js.map +1 -0
- package/package.json +11 -2
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quint generator — emits a per-spec `.qnt` file that asserts lifecycle
|
|
3
|
+
* reachability and behavior precondition validity. v1 of TODO #31.
|
|
4
|
+
*
|
|
5
|
+
* v1 scope (deliberately narrow — see
|
|
6
|
+
* `specverse-self/docs/plans/2026-04-30-DETERMINISTIC-VERIFICATION-GATES.md`):
|
|
7
|
+
* - For each model with a `lifecycles:` block, generate a Quint state
|
|
8
|
+
* machine asserting:
|
|
9
|
+
* 1. States are unique within the lifecycle.
|
|
10
|
+
* 2. Transitions reference declared states only.
|
|
11
|
+
* 3. There is at least one initial state (no incoming transition,
|
|
12
|
+
* or explicitly named in the spec).
|
|
13
|
+
* 4. Behaviors with `requires:` clauses naming a state reference
|
|
14
|
+
* a real state.
|
|
15
|
+
*
|
|
16
|
+
* Out of scope for v1:
|
|
17
|
+
* - Cross-model invariants (e.g. Order belongs to Customer).
|
|
18
|
+
* - Full behavior pre/post encoding as transition guards.
|
|
19
|
+
* - Quint-driven simulation (`run` actions with assertions).
|
|
20
|
+
*
|
|
21
|
+
* Output is a single Quint module per spec with one sub-module per model
|
|
22
|
+
* that has a lifecycle. The runner subprocess (`./runner.ts`) executes
|
|
23
|
+
* `quint typecheck` against the generated file; reachability/transition
|
|
24
|
+
* errors come back as line-numbered Quint diagnostics.
|
|
25
|
+
*/
|
|
26
|
+
export interface QuintGenResult {
|
|
27
|
+
/** Quint module text. Empty when `skipped: true`. */
|
|
28
|
+
content: string;
|
|
29
|
+
/** Number of models that contributed lifecycle invariants. */
|
|
30
|
+
modelCount: number;
|
|
31
|
+
/** Number of behaviors whose `requires:` clauses reference lifecycle states. */
|
|
32
|
+
behaviorPreconditionCount: number;
|
|
33
|
+
/** True when the spec has no lifecycle blocks at all (nothing to verify). */
|
|
34
|
+
skipped: boolean;
|
|
35
|
+
/** Reason for skipping (when skipped=true). */
|
|
36
|
+
skipReason?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Deterministic invariant check results. The Quint typecheck (runner.ts)
|
|
39
|
+
* validates that the generated module is syntactically and type-correct;
|
|
40
|
+
* THIS field carries the value-level checks (states unique, transitions
|
|
41
|
+
* reference declared states, etc.) which Quint's typecheck cannot evaluate.
|
|
42
|
+
*/
|
|
43
|
+
violations: QuintViolation[];
|
|
44
|
+
}
|
|
45
|
+
export interface QuintViolation {
|
|
46
|
+
/** Which model + lifecycle the violation belongs to. (lifecycleName is "" for cross-model checks.) */
|
|
47
|
+
modelName: string;
|
|
48
|
+
lifecycleName: string;
|
|
49
|
+
/**
|
|
50
|
+
* Violation category. v1 covers lifecycle shape; v2 adds cross-model
|
|
51
|
+
* relationship validity + behavior-ensures state references.
|
|
52
|
+
*/
|
|
53
|
+
kind: 'states-not-unique' | 'transition-references-unknown-state' | 'behavior-requires-unknown-state' | 'behavior-ensures-unknown-state' | 'relationship-target-unknown' | 'no-states-declared';
|
|
54
|
+
/** Human-readable explanation suitable for retry-prompt feedback. */
|
|
55
|
+
message: string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Generate a Quint specification from a SpecVerse spec. Walks every
|
|
59
|
+
* component's models, collects lifecycle declarations, and emits Quint
|
|
60
|
+
* `module` text encoding the four v1 invariants.
|
|
61
|
+
*
|
|
62
|
+
* The spec parameter accepts either the parsed AST (with components: array)
|
|
63
|
+
* or an inferred-spec object (flat models map). The function probes shape
|
|
64
|
+
* and adapts.
|
|
65
|
+
*/
|
|
66
|
+
export declare function generateQuintFromSpec(spec: any): QuintGenResult;
|
|
67
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/inference/quint-gen/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,MAAM,WAAW,cAAc;IAC7B,qDAAqD;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,UAAU,EAAE,MAAM,CAAC;IACnB,gFAAgF;IAChF,yBAAyB,EAAE,MAAM,CAAC;IAClC,6EAA6E;IAC7E,OAAO,EAAE,OAAO,CAAC;IACjB,+CAA+C;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,UAAU,EAAE,cAAc,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,cAAc;IAC7B,sGAAsG;IACtG,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,IAAI,EACA,mBAAmB,GACnB,qCAAqC,GACrC,iCAAiC,GACjC,gCAAgC,GAChC,6BAA6B,GAC7B,oBAAoB,CAAC;IACzB,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAC;CACjB;AA4BD;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,GAAG,GAAG,cAAc,CAgO/D"}
|
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quint generator — emits a per-spec `.qnt` file that asserts lifecycle
|
|
3
|
+
* reachability and behavior precondition validity. v1 of TODO #31.
|
|
4
|
+
*
|
|
5
|
+
* v1 scope (deliberately narrow — see
|
|
6
|
+
* `specverse-self/docs/plans/2026-04-30-DETERMINISTIC-VERIFICATION-GATES.md`):
|
|
7
|
+
* - For each model with a `lifecycles:` block, generate a Quint state
|
|
8
|
+
* machine asserting:
|
|
9
|
+
* 1. States are unique within the lifecycle.
|
|
10
|
+
* 2. Transitions reference declared states only.
|
|
11
|
+
* 3. There is at least one initial state (no incoming transition,
|
|
12
|
+
* or explicitly named in the spec).
|
|
13
|
+
* 4. Behaviors with `requires:` clauses naming a state reference
|
|
14
|
+
* a real state.
|
|
15
|
+
*
|
|
16
|
+
* Out of scope for v1:
|
|
17
|
+
* - Cross-model invariants (e.g. Order belongs to Customer).
|
|
18
|
+
* - Full behavior pre/post encoding as transition guards.
|
|
19
|
+
* - Quint-driven simulation (`run` actions with assertions).
|
|
20
|
+
*
|
|
21
|
+
* Output is a single Quint module per spec with one sub-module per model
|
|
22
|
+
* that has a lifecycle. The runner subprocess (`./runner.ts`) executes
|
|
23
|
+
* `quint typecheck` against the generated file; reachability/transition
|
|
24
|
+
* errors come back as line-numbered Quint diagnostics.
|
|
25
|
+
*/
|
|
26
|
+
/**
|
|
27
|
+
* Generate a Quint specification from a SpecVerse spec. Walks every
|
|
28
|
+
* component's models, collects lifecycle declarations, and emits Quint
|
|
29
|
+
* `module` text encoding the four v1 invariants.
|
|
30
|
+
*
|
|
31
|
+
* The spec parameter accepts either the parsed AST (with components: array)
|
|
32
|
+
* or an inferred-spec object (flat models map). The function probes shape
|
|
33
|
+
* and adapts.
|
|
34
|
+
*/
|
|
35
|
+
export function generateQuintFromSpec(spec) {
|
|
36
|
+
const allModels = [];
|
|
37
|
+
// Two shapes to support: AST (components array) and flat (models map).
|
|
38
|
+
if (Array.isArray(spec?.components)) {
|
|
39
|
+
for (const comp of spec.components) {
|
|
40
|
+
const models = normalizeModels(comp.models);
|
|
41
|
+
allModels.push(...models);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else if (spec?.components && typeof spec.components === 'object') {
|
|
45
|
+
for (const comp of Object.values(spec.components)) {
|
|
46
|
+
const models = normalizeModels(comp.models);
|
|
47
|
+
allModels.push(...models);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
else if (spec?.models) {
|
|
51
|
+
allModels.push(...normalizeModels(spec.models));
|
|
52
|
+
}
|
|
53
|
+
const modelsWithLifecycles = allModels.filter((m) => {
|
|
54
|
+
const lc = m.lifecycles;
|
|
55
|
+
if (!lc)
|
|
56
|
+
return false;
|
|
57
|
+
if (Array.isArray(lc))
|
|
58
|
+
return lc.length > 0;
|
|
59
|
+
return Object.keys(lc).length > 0;
|
|
60
|
+
});
|
|
61
|
+
// Cross-model index — every declared model name across all components.
|
|
62
|
+
// v2 cross-model invariants check `relationship.target` against this set.
|
|
63
|
+
const declaredModelNames = new Set(allModels.map((m) => m.name));
|
|
64
|
+
// Cross-model relationship validity (v2). Check every model's
|
|
65
|
+
// relationships, not just those with lifecycles — referential integrity
|
|
66
|
+
// is a property of the spec as a whole.
|
|
67
|
+
const crossModelViolations = [];
|
|
68
|
+
for (const model of allModels) {
|
|
69
|
+
const rels = normalizeRelationships(model.relationships);
|
|
70
|
+
for (const rel of rels) {
|
|
71
|
+
if (!rel.target)
|
|
72
|
+
continue;
|
|
73
|
+
if (!declaredModelNames.has(rel.target)) {
|
|
74
|
+
crossModelViolations.push({
|
|
75
|
+
modelName: model.name,
|
|
76
|
+
lifecycleName: '',
|
|
77
|
+
kind: 'relationship-target-unknown',
|
|
78
|
+
message: `${model.name}.${rel.name || '(unnamed)'}: relationship targets "${rel.target}" but no model with that name is declared (${declaredModelNames.size} models declared)`,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (modelsWithLifecycles.length === 0 && crossModelViolations.length === 0) {
|
|
84
|
+
return { content: '', modelCount: 0, behaviorPreconditionCount: 0, skipped: true, skipReason: 'no models with lifecycles and no relationship issues', violations: [] };
|
|
85
|
+
}
|
|
86
|
+
const lines = [];
|
|
87
|
+
lines.push('// Auto-generated by @specverse/engines/inference/quint-gen');
|
|
88
|
+
lines.push('// v2 — lifecycle reachability + transition validity +');
|
|
89
|
+
lines.push('// behavior-requires + behavior-ensures validity +');
|
|
90
|
+
lines.push('// cross-model relationship-target validity');
|
|
91
|
+
lines.push('// See docs/plans/2026-04-30-DETERMINISTIC-VERIFICATION-GATES.md');
|
|
92
|
+
lines.push('');
|
|
93
|
+
// Cross-model section in the Quint module — declares the universe of
|
|
94
|
+
// model names so future quint-run extensions can use it as a Set.
|
|
95
|
+
if (declaredModelNames.size > 0) {
|
|
96
|
+
lines.push('module Models {');
|
|
97
|
+
lines.push(` pure val modelNames: Set[str] = Set(${[...declaredModelNames].map((n) => `"${n}"`).join(', ')})`);
|
|
98
|
+
lines.push('}');
|
|
99
|
+
lines.push('');
|
|
100
|
+
}
|
|
101
|
+
let behaviorPreconditionCount = 0;
|
|
102
|
+
const violations = [...crossModelViolations];
|
|
103
|
+
for (const model of modelsWithLifecycles) {
|
|
104
|
+
const lifecycles = normalizeLifecycles(model.lifecycles);
|
|
105
|
+
for (const [lcName, lc] of Object.entries(lifecycles)) {
|
|
106
|
+
const states = collectStates(lc);
|
|
107
|
+
if (states.length === 0) {
|
|
108
|
+
violations.push({
|
|
109
|
+
modelName: model.name,
|
|
110
|
+
lifecycleName: lcName,
|
|
111
|
+
kind: 'no-states-declared',
|
|
112
|
+
message: `${model.name}.${lcName}: no states declared (need either flow: "a -> b" or states: [...] + transitions: {...})`,
|
|
113
|
+
});
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
// Value-level invariant checks — Quint's typecheck only validates types,
|
|
117
|
+
// not predicate values, so these run in JS as the actual gate.
|
|
118
|
+
const stateSet = new Set(states);
|
|
119
|
+
// Duplicate detection — `states` is already deduplicated; check the
|
|
120
|
+
// source `lc.states` array directly for repeated entries.
|
|
121
|
+
if (Array.isArray(lc.states)) {
|
|
122
|
+
const seen = new Set();
|
|
123
|
+
const dupes = [];
|
|
124
|
+
for (const s of lc.states) {
|
|
125
|
+
if (seen.has(s) && !dupes.includes(s))
|
|
126
|
+
dupes.push(s);
|
|
127
|
+
seen.add(s);
|
|
128
|
+
}
|
|
129
|
+
if (dupes.length > 0) {
|
|
130
|
+
violations.push({
|
|
131
|
+
modelName: model.name,
|
|
132
|
+
lifecycleName: lcName,
|
|
133
|
+
kind: 'states-not-unique',
|
|
134
|
+
message: `${model.name}.${lcName}: duplicate states declared: ${dupes.join(', ')}`,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
const transitionsRaw = collectTransitions(lc);
|
|
139
|
+
for (const t of transitionsRaw) {
|
|
140
|
+
if (!stateSet.has(t.from)) {
|
|
141
|
+
violations.push({
|
|
142
|
+
modelName: model.name,
|
|
143
|
+
lifecycleName: lcName,
|
|
144
|
+
kind: 'transition-references-unknown-state',
|
|
145
|
+
message: `${model.name}.${lcName}.transitions.${t.name}: source state "${t.from}" not declared (states: [${states.join(', ')}])`,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
if (!stateSet.has(t.to)) {
|
|
149
|
+
violations.push({
|
|
150
|
+
modelName: model.name,
|
|
151
|
+
lifecycleName: lcName,
|
|
152
|
+
kind: 'transition-references-unknown-state',
|
|
153
|
+
message: `${model.name}.${lcName}.transitions.${t.name}: target state "${t.to}" not declared (states: [${states.join(', ')}])`,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
const moduleId = sanitizeIdent(`${model.name}_${lcName}`);
|
|
158
|
+
lines.push(`module ${moduleId} {`);
|
|
159
|
+
lines.push(` // States declared for ${model.name}.${lcName}`);
|
|
160
|
+
lines.push(` pure val states: Set[str] = Set(${states.map((s) => `"${s}"`).join(', ')})`);
|
|
161
|
+
lines.push('');
|
|
162
|
+
// Invariant 1 — states are unique. Implied by Set construction; we
|
|
163
|
+
// additionally check that the COUNT matches the literal-list length so
|
|
164
|
+
// duplicates in the source spec surface as a typecheck failure.
|
|
165
|
+
lines.push(` pure val statesUnique: bool = states.size() == ${states.length}`);
|
|
166
|
+
lines.push('');
|
|
167
|
+
// Invariant 2 — transitions reference declared states only.
|
|
168
|
+
const transitions = collectTransitions(lc);
|
|
169
|
+
if (transitions.length > 0) {
|
|
170
|
+
const transitionsExpr = transitions
|
|
171
|
+
.map(({ name, from, to }) => `("${name}", "${from}", "${to}")`)
|
|
172
|
+
.join(', ');
|
|
173
|
+
lines.push(` pure val transitions: Set[(str, str, str)] = Set(${transitionsExpr})`);
|
|
174
|
+
lines.push(` pure val transitionStatesValid: bool = transitions.forall(t => states.contains(t._2) and states.contains(t._3))`);
|
|
175
|
+
lines.push('');
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
lines.push(' pure val transitions: Set[(str, str, str)] = Set()');
|
|
179
|
+
lines.push(' pure val transitionStatesValid: bool = true');
|
|
180
|
+
lines.push('');
|
|
181
|
+
}
|
|
182
|
+
// Invariant 3 — initial state exists. Heuristic: take the first state
|
|
183
|
+
// in `flow:` declarations, OR any state with no incoming transition.
|
|
184
|
+
const initialState = inferInitial(states, transitions);
|
|
185
|
+
if (initialState) {
|
|
186
|
+
lines.push(` pure val initialState: str = "${initialState}"`);
|
|
187
|
+
lines.push(` pure val initialIsDeclared: bool = states.contains(initialState)`);
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
lines.push(' pure val initialIsDeclared: bool = states.size() > 0');
|
|
191
|
+
}
|
|
192
|
+
lines.push('');
|
|
193
|
+
// Invariant 4 — behavior preconditions referencing this lifecycle's
|
|
194
|
+
// states must reference real states. We extract state references from
|
|
195
|
+
// `requires:` clauses heuristically (look for any of the lifecycle's
|
|
196
|
+
// state names appearing as words in the requires text).
|
|
197
|
+
// The Quint module records the references for documentation; the
|
|
198
|
+
// VALUE-level check happens here.
|
|
199
|
+
const behaviorRefs = collectBehaviorStateReferences(model.behaviors, states);
|
|
200
|
+
if (behaviorRefs.declared.length > 0) {
|
|
201
|
+
behaviorPreconditionCount += behaviorRefs.declared.length;
|
|
202
|
+
const refsExpr = behaviorRefs.declared.map((r) => `"${r}"`).join(', ');
|
|
203
|
+
lines.push(` pure val behaviorRequiredStates: Set[str] = Set(${refsExpr})`);
|
|
204
|
+
lines.push(` pure val behaviorRequiresValid: bool = behaviorRequiredStates.forall(s => states.contains(s))`);
|
|
205
|
+
lines.push('');
|
|
206
|
+
}
|
|
207
|
+
// behavior-requires that name a NON-state token (e.g. "Booking is in
|
|
208
|
+
// confirmd") get flagged here. Heuristic: any token that LOOKS like
|
|
209
|
+
// a state name (matches the case style of declared states) but isn't
|
|
210
|
+
// in stateSet is a likely typo.
|
|
211
|
+
for (const unknown of behaviorRefs.unknown) {
|
|
212
|
+
violations.push({
|
|
213
|
+
modelName: model.name,
|
|
214
|
+
lifecycleName: lcName,
|
|
215
|
+
kind: 'behavior-requires-unknown-state',
|
|
216
|
+
message: `${model.name}.behaviors: requires-clause names state "${unknown}" not in ${lcName} (declared: [${states.join(', ')}])`,
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
// v2 — behavior-ensures cross-check. Same pattern as requires:
|
|
220
|
+
// postconditions naming a state must reference a declared state.
|
|
221
|
+
// Catches typos in `ensures: ["status is now confimed"]` etc.
|
|
222
|
+
const ensuresRefs = collectBehaviorStateReferencesByField(model.behaviors, states, 'ensures');
|
|
223
|
+
if (ensuresRefs.declared.length > 0) {
|
|
224
|
+
const refsExpr = ensuresRefs.declared.map((r) => `"${r}"`).join(', ');
|
|
225
|
+
lines.push(` pure val behaviorEnsuredStates: Set[str] = Set(${refsExpr})`);
|
|
226
|
+
lines.push(` pure val behaviorEnsuresValid: bool = behaviorEnsuredStates.forall(s => states.contains(s))`);
|
|
227
|
+
lines.push('');
|
|
228
|
+
}
|
|
229
|
+
for (const unknown of ensuresRefs.unknown) {
|
|
230
|
+
violations.push({
|
|
231
|
+
modelName: model.name,
|
|
232
|
+
lifecycleName: lcName,
|
|
233
|
+
kind: 'behavior-ensures-unknown-state',
|
|
234
|
+
message: `${model.name}.behaviors: ensures-clause names state "${unknown}" not in ${lcName} (declared: [${states.join(', ')}])`,
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
lines.push('}');
|
|
238
|
+
lines.push('');
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return {
|
|
242
|
+
content: lines.join('\n'),
|
|
243
|
+
modelCount: modelsWithLifecycles.length,
|
|
244
|
+
behaviorPreconditionCount,
|
|
245
|
+
skipped: false,
|
|
246
|
+
violations,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
// ── helpers ──
|
|
250
|
+
function normalizeModels(modelsRaw) {
|
|
251
|
+
if (!modelsRaw)
|
|
252
|
+
return [];
|
|
253
|
+
if (Array.isArray(modelsRaw))
|
|
254
|
+
return modelsRaw;
|
|
255
|
+
return Object.entries(modelsRaw).map(([name, body]) => ({ name, ...body }));
|
|
256
|
+
}
|
|
257
|
+
function normalizeLifecycles(lc) {
|
|
258
|
+
if (Array.isArray(lc)) {
|
|
259
|
+
const out = {};
|
|
260
|
+
for (const item of lc) {
|
|
261
|
+
if (item.name)
|
|
262
|
+
out[item.name] = item;
|
|
263
|
+
}
|
|
264
|
+
return out;
|
|
265
|
+
}
|
|
266
|
+
return lc;
|
|
267
|
+
}
|
|
268
|
+
function collectStates(lc) {
|
|
269
|
+
// States come from EXPLICIT declarations only — `states: [...]` array OR
|
|
270
|
+
// `flow:` chain. Transition targets are NOT inferred into the state set:
|
|
271
|
+
// a typo in a transition target should fail the transitionStatesValid
|
|
272
|
+
// invariant, not get silently auto-added as a "real" state.
|
|
273
|
+
const set = new Set();
|
|
274
|
+
if (Array.isArray(lc.states)) {
|
|
275
|
+
for (const s of lc.states)
|
|
276
|
+
set.add(s);
|
|
277
|
+
}
|
|
278
|
+
if (typeof lc.flow === 'string') {
|
|
279
|
+
for (const part of lc.flow.split('->').map((s) => s.trim()).filter(Boolean)) {
|
|
280
|
+
set.add(part);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return [...set];
|
|
284
|
+
}
|
|
285
|
+
function collectTransitions(lc) {
|
|
286
|
+
const out = [];
|
|
287
|
+
if (lc.transitions && typeof lc.transitions === 'object') {
|
|
288
|
+
for (const [name, arrow] of Object.entries(lc.transitions)) {
|
|
289
|
+
if (typeof arrow !== 'string')
|
|
290
|
+
continue;
|
|
291
|
+
const [from, to] = arrow.split('->').map((s) => s.trim());
|
|
292
|
+
if (from && to)
|
|
293
|
+
out.push({ name, from, to });
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
if (typeof lc.flow === 'string') {
|
|
297
|
+
const states = lc.flow.split('->').map((s) => s.trim()).filter(Boolean);
|
|
298
|
+
for (let i = 0; i < states.length - 1; i++) {
|
|
299
|
+
out.push({ name: `step${i + 1}`, from: states[i], to: states[i + 1] });
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
return out;
|
|
303
|
+
}
|
|
304
|
+
function inferInitial(states, transitions) {
|
|
305
|
+
if (states.length === 0)
|
|
306
|
+
return null;
|
|
307
|
+
const targets = new Set(transitions.map((t) => t.to));
|
|
308
|
+
const sources = states.filter((s) => !targets.has(s));
|
|
309
|
+
if (sources.length === 1)
|
|
310
|
+
return sources[0];
|
|
311
|
+
return states[0]; // fallback
|
|
312
|
+
}
|
|
313
|
+
function collectBehaviorStateReferences(behaviors, states) {
|
|
314
|
+
return collectBehaviorStateReferencesByField(behaviors, states, 'requires');
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Walk every behavior's `requires` OR `ensures` field (v2) and return any
|
|
318
|
+
* state-like tokens found, classified into "declared" (exists in states[])
|
|
319
|
+
* vs "unknown" (looks like a state name but doesn't match — likely typo).
|
|
320
|
+
*
|
|
321
|
+
* Heuristic phrase patterns capture state names after common keyword
|
|
322
|
+
* positions ("is in X" / "transitions to X" / "is now X" — the latter
|
|
323
|
+
* particularly relevant for ensures-clauses).
|
|
324
|
+
*/
|
|
325
|
+
function collectBehaviorStateReferencesByField(behaviors, states, field) {
|
|
326
|
+
if (!behaviors)
|
|
327
|
+
return { declared: [], unknown: [] };
|
|
328
|
+
const map = Array.isArray(behaviors)
|
|
329
|
+
? Object.fromEntries(behaviors.map((b) => [b.name || '', b]))
|
|
330
|
+
: behaviors;
|
|
331
|
+
const stateSet = new Set(states);
|
|
332
|
+
const declared = new Set();
|
|
333
|
+
const unknown = new Set();
|
|
334
|
+
const phrasePatterns = [
|
|
335
|
+
/\bis\s+(?:in|at|now)\s+(\w+)/gi, // "is in X", "is now X" (ensures-style)
|
|
336
|
+
/\btransitions?\s+(?:to|from)\s+(\w+)/gi,
|
|
337
|
+
/\bafter\s+(\w+)/gi,
|
|
338
|
+
/\bbefore\s+(\w+)/gi,
|
|
339
|
+
/\b(?:in|when)\s+state\s+(\w+)/gi,
|
|
340
|
+
/\bbecomes?\s+(\w+)/gi, // "becomes X" (ensures-style)
|
|
341
|
+
/\bmoves?\s+to\s+(\w+)/gi, // "moves to X"
|
|
342
|
+
];
|
|
343
|
+
for (const b of Object.values(map)) {
|
|
344
|
+
const clauses = b?.[field];
|
|
345
|
+
if (!clauses)
|
|
346
|
+
continue;
|
|
347
|
+
const list = Array.isArray(clauses) ? clauses : [clauses];
|
|
348
|
+
for (const clause of list) {
|
|
349
|
+
if (typeof clause !== 'string')
|
|
350
|
+
continue;
|
|
351
|
+
for (const pattern of phrasePatterns) {
|
|
352
|
+
let m;
|
|
353
|
+
const re = new RegExp(pattern.source, pattern.flags);
|
|
354
|
+
while ((m = re.exec(clause)) !== null) {
|
|
355
|
+
const token = m[1];
|
|
356
|
+
if (!token)
|
|
357
|
+
continue;
|
|
358
|
+
if (stateSet.has(token))
|
|
359
|
+
declared.add(token);
|
|
360
|
+
else if (looksLikeStateName(token, states))
|
|
361
|
+
unknown.add(token);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
for (const state of stateSet) {
|
|
365
|
+
const re = new RegExp(`\\b${state.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}\\b`);
|
|
366
|
+
if (re.test(clause))
|
|
367
|
+
declared.add(state);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
return { declared: [...declared], unknown: [...unknown] };
|
|
372
|
+
}
|
|
373
|
+
/** Normalize relationships into a list of {name, type, target}. */
|
|
374
|
+
function normalizeRelationships(relsRaw) {
|
|
375
|
+
if (!relsRaw)
|
|
376
|
+
return [];
|
|
377
|
+
if (Array.isArray(relsRaw)) {
|
|
378
|
+
return relsRaw.map((r) => (typeof r === 'string' ? parseRelationshipShorthand('', r) : r)).filter(Boolean);
|
|
379
|
+
}
|
|
380
|
+
return Object.entries(relsRaw)
|
|
381
|
+
.map(([name, body]) => {
|
|
382
|
+
if (typeof body === 'string')
|
|
383
|
+
return parseRelationshipShorthand(name, body);
|
|
384
|
+
return { name, ...body };
|
|
385
|
+
})
|
|
386
|
+
.filter(Boolean);
|
|
387
|
+
}
|
|
388
|
+
/** Parse "hasMany Booking cascade" / "belongsTo Customer" shorthand into a RelationshipSpec. */
|
|
389
|
+
function parseRelationshipShorthand(name, shorthand) {
|
|
390
|
+
const parts = shorthand.trim().split(/\s+/);
|
|
391
|
+
if (parts.length < 2)
|
|
392
|
+
return null;
|
|
393
|
+
const [type, target] = parts;
|
|
394
|
+
if (!['hasMany', 'hasOne', 'belongsTo', 'manyToMany'].includes(type))
|
|
395
|
+
return null;
|
|
396
|
+
return { name, type: type, target };
|
|
397
|
+
}
|
|
398
|
+
/** Heuristic: a candidate string "looks like" a state name when it matches
|
|
399
|
+
* the case-style of the declared states (snake_case or single-word). */
|
|
400
|
+
function looksLikeStateName(token, states) {
|
|
401
|
+
if (states.length === 0)
|
|
402
|
+
return false;
|
|
403
|
+
const allSnakeCase = states.every((s) => /^[a-z][a-z0-9_]*$/.test(s));
|
|
404
|
+
if (allSnakeCase)
|
|
405
|
+
return /^[a-z][a-z0-9_]*$/.test(token);
|
|
406
|
+
return /^[a-z][a-zA-Z0-9_]*$/.test(token);
|
|
407
|
+
}
|
|
408
|
+
function sanitizeIdent(s) {
|
|
409
|
+
return s.replace(/[^A-Za-z0-9_]/g, '_').replace(/^[0-9]/, '_$&');
|
|
410
|
+
}
|
|
411
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/inference/quint-gen/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quint subprocess runner — mirrors the `validateBundle v2` pattern at
|
|
3
|
+
* `engines/src/bundles/validate.ts:459-504`. Probes `quint --version`
|
|
4
|
+
* once; skips cleanly if the binary isn't on PATH; runs `quint typecheck`
|
|
5
|
+
* with a 15s per-file timeout; returns a structured result.
|
|
6
|
+
*
|
|
7
|
+
* Used by `analyse-runner.ts` to validate the per-spec Quint module
|
|
8
|
+
* generated by `./index.ts`. Failed typecheck = lifecycle inconsistency
|
|
9
|
+
* the LLM didn't catch.
|
|
10
|
+
*/
|
|
11
|
+
export interface QuintRunResult {
|
|
12
|
+
status: 'pass' | 'fail' | 'skip';
|
|
13
|
+
/** Reason for skip (e.g. 'quint binary not on PATH'). Only set when status==='skip'. */
|
|
14
|
+
skipReason?: string;
|
|
15
|
+
/** One entry per typecheck error, slice-truncated to 400 chars. Empty when status==='pass'. */
|
|
16
|
+
errors: string[];
|
|
17
|
+
/** Wall-clock duration of the entire run. */
|
|
18
|
+
durationMs: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Run `quint typecheck` against a single Quint file path. Returns a
|
|
22
|
+
* structured result that the analyse-runner formats into a
|
|
23
|
+
* `verify-behavior.txt` log alongside `verify.txt`.
|
|
24
|
+
*
|
|
25
|
+
* Skip semantics: when the `quint` CLI isn't installed (common on user
|
|
26
|
+
* machines), we skip without failing — Quint is an opt-in formal layer,
|
|
27
|
+
* not a hard dependency.
|
|
28
|
+
*/
|
|
29
|
+
export declare function runQuintTypecheck(filePath: string): QuintRunResult;
|
|
30
|
+
/**
|
|
31
|
+
* Format a `QuintRunResult` as a human-readable text block suitable for
|
|
32
|
+
* writing to `verify-behavior.txt` in the run output dir, OR feeding back
|
|
33
|
+
* to the LLM as an error message in a retry prompt.
|
|
34
|
+
*/
|
|
35
|
+
export declare function formatQuintResult(result: QuintRunResult, sourceFilePath?: string): string;
|
|
36
|
+
//# sourceMappingURL=runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../../src/inference/quint-gen/runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IACjC,wFAAwF;IACxF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+FAA+F;IAC/F,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,6CAA6C;IAC7C,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CAqClE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,cAAc,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,CAezF"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quint subprocess runner — mirrors the `validateBundle v2` pattern at
|
|
3
|
+
* `engines/src/bundles/validate.ts:459-504`. Probes `quint --version`
|
|
4
|
+
* once; skips cleanly if the binary isn't on PATH; runs `quint typecheck`
|
|
5
|
+
* with a 15s per-file timeout; returns a structured result.
|
|
6
|
+
*
|
|
7
|
+
* Used by `analyse-runner.ts` to validate the per-spec Quint module
|
|
8
|
+
* generated by `./index.ts`. Failed typecheck = lifecycle inconsistency
|
|
9
|
+
* the LLM didn't catch.
|
|
10
|
+
*/
|
|
11
|
+
import { spawnSync } from 'child_process';
|
|
12
|
+
/**
|
|
13
|
+
* Run `quint typecheck` against a single Quint file path. Returns a
|
|
14
|
+
* structured result that the analyse-runner formats into a
|
|
15
|
+
* `verify-behavior.txt` log alongside `verify.txt`.
|
|
16
|
+
*
|
|
17
|
+
* Skip semantics: when the `quint` CLI isn't installed (common on user
|
|
18
|
+
* machines), we skip without failing — Quint is an opt-in formal layer,
|
|
19
|
+
* not a hard dependency.
|
|
20
|
+
*/
|
|
21
|
+
export function runQuintTypecheck(filePath) {
|
|
22
|
+
const start = Date.now();
|
|
23
|
+
// Probe quint availability once. Match the validateBundle v2 pattern.
|
|
24
|
+
const probe = spawnSync('quint', ['--version'], { encoding: 'utf8' });
|
|
25
|
+
if (probe.error || probe.status !== 0) {
|
|
26
|
+
return {
|
|
27
|
+
status: 'skip',
|
|
28
|
+
skipReason: 'quint CLI not on PATH (install via `npm install -g @informalsystems/quint`)',
|
|
29
|
+
errors: [],
|
|
30
|
+
durationMs: Date.now() - start,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
const res = spawnSync('quint', ['typecheck', filePath], {
|
|
34
|
+
encoding: 'utf8',
|
|
35
|
+
timeout: 15000,
|
|
36
|
+
});
|
|
37
|
+
if (res.status !== 0) {
|
|
38
|
+
const raw = (res.stderr || res.stdout || '').trim();
|
|
39
|
+
// Truncate per-error to 400 chars (slightly more than validateBundle v2's
|
|
40
|
+
// 200; per-spec lifecycles can accumulate multiple errors at once and we
|
|
41
|
+
// want the LLM's retry to see context).
|
|
42
|
+
const errors = raw.split(/\n\n+/).map((e) => e.slice(0, 400)).filter(Boolean);
|
|
43
|
+
return {
|
|
44
|
+
status: 'fail',
|
|
45
|
+
errors,
|
|
46
|
+
durationMs: Date.now() - start,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
status: 'pass',
|
|
51
|
+
errors: [],
|
|
52
|
+
durationMs: Date.now() - start,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Format a `QuintRunResult` as a human-readable text block suitable for
|
|
57
|
+
* writing to `verify-behavior.txt` in the run output dir, OR feeding back
|
|
58
|
+
* to the LLM as an error message in a retry prompt.
|
|
59
|
+
*/
|
|
60
|
+
export function formatQuintResult(result, sourceFilePath) {
|
|
61
|
+
const lines = [];
|
|
62
|
+
lines.push(`Quint 5b deterministic gate — status: ${result.status} (${result.durationMs}ms)`);
|
|
63
|
+
if (sourceFilePath)
|
|
64
|
+
lines.push(`Source: ${sourceFilePath}`);
|
|
65
|
+
if (result.status === 'skip') {
|
|
66
|
+
lines.push(`Skipped: ${result.skipReason ?? 'unknown'}`);
|
|
67
|
+
}
|
|
68
|
+
else if (result.status === 'fail') {
|
|
69
|
+
lines.push('Errors:');
|
|
70
|
+
for (const err of result.errors) {
|
|
71
|
+
lines.push(` - ${err.replace(/\n/g, '\n ')}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
lines.push('All lifecycle invariants typecheck cleanly.');
|
|
76
|
+
}
|
|
77
|
+
return lines.join('\n');
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../../src/inference/quint-gen/runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAY1C;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAChD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEzB,sEAAsE;IACtE,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;IACtE,IAAI,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtC,OAAO;YACL,MAAM,EAAE,MAAM;YACd,UAAU,EAAE,6EAA6E;YACzF,MAAM,EAAE,EAAE;YACV,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;SAC/B,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC,WAAW,EAAE,QAAQ,CAAC,EAAE;QACtD,QAAQ,EAAE,MAAM;QAChB,OAAO,EAAE,KAAK;KACf,CAAC,CAAC;IAEH,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrB,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACpD,0EAA0E;QAC1E,yEAAyE;QACzE,wCAAwC;QACxC,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC9E,OAAO;YACL,MAAM,EAAE,MAAM;YACd,MAAM;YACN,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;SAC/B,CAAC;IACJ,CAAC;IAED,OAAO;QACL,MAAM,EAAE,MAAM;QACd,MAAM,EAAE,EAAE;QACV,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;KAC/B,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAsB,EAAE,cAAuB;IAC/E,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,yCAAyC,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,UAAU,KAAK,CAAC,CAAC;IAC9F,IAAI,cAAc;QAAE,KAAK,CAAC,IAAI,CAAC,WAAW,cAAc,EAAE,CAAC,CAAC;IAC5D,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,YAAY,MAAM,CAAC,UAAU,IAAI,SAAS,EAAE,CAAC,CAAC;IAC3D,CAAC;SAAM,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QACpC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACtB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAChC,KAAK,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|