@specverse/engines 6.42.3 → 6.60.1
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.map +1 -1
- package/dist/ai/analyse-runner.js +53 -1
- package/dist/ai/analyse-runner.js.map +1 -1
- package/dist/ai/prompt-runner.d.ts +39 -1
- package/dist/ai/prompt-runner.d.ts.map +1 -1
- package/dist/ai/prompt-runner.js +44 -3
- package/dist/ai/prompt-runner.js.map +1 -1
- package/dist/ai/providers/claude-cli.d.ts.map +1 -1
- package/dist/ai/providers/claude-cli.js +8 -1
- package/dist/ai/providers/claude-cli.js.map +1 -1
- package/dist/ai/skill-loader.d.ts +50 -0
- package/dist/ai/skill-loader.d.ts.map +1 -0
- package/dist/ai/skill-loader.js +96 -0
- package/dist/ai/skill-loader.js.map +1 -0
- package/dist/analyse-prepass/adapters/index.d.ts +2 -0
- package/dist/analyse-prepass/adapters/index.d.ts.map +1 -1
- package/dist/analyse-prepass/adapters/index.js +2 -0
- package/dist/analyse-prepass/adapters/index.js.map +1 -1
- package/dist/analyse-prepass/adapters/module-functions.d.ts +95 -0
- package/dist/analyse-prepass/adapters/module-functions.d.ts.map +1 -0
- package/dist/analyse-prepass/adapters/module-functions.js +358 -0
- package/dist/analyse-prepass/adapters/module-functions.js.map +1 -0
- package/dist/analyse-prepass/adapters/naming-convention-fks.d.ts +90 -0
- package/dist/analyse-prepass/adapters/naming-convention-fks.d.ts.map +1 -0
- package/dist/analyse-prepass/adapters/naming-convention-fks.js +181 -0
- package/dist/analyse-prepass/adapters/naming-convention-fks.js.map +1 -0
- package/dist/analyse-prepass/index.d.ts +8 -0
- package/dist/analyse-prepass/index.d.ts.map +1 -1
- package/dist/analyse-prepass/index.js +130 -0
- package/dist/analyse-prepass/index.js.map +1 -1
- package/dist/libs/instance-factories/cli/templates/commander/cli-entry-generator.js +11 -12
- package/dist/libs/instance-factories/cli/templates/commander/command-generator.js +2 -2
- package/dist/libs/instance-factories/controllers/templates/fastify/routes-generator.js +29 -10
- package/dist/libs/instance-factories/services/templates/prisma/ai-behaviors-generator.js +10 -9
- package/dist/libs/instance-factories/services/templates/prisma/behavior-generator.js +24 -2
- package/dist/libs/instance-factories/services/templates/prisma/controller-generator.js +28 -20
- package/dist/normalise/index.d.ts +14 -0
- package/dist/normalise/index.d.ts.map +1 -0
- package/dist/normalise/index.js +14 -0
- package/dist/normalise/index.js.map +1 -0
- package/dist/normalise/load-overrides.d.ts +43 -0
- package/dist/normalise/load-overrides.d.ts.map +1 -0
- package/dist/normalise/load-overrides.js +121 -0
- package/dist/normalise/load-overrides.js.map +1 -0
- package/dist/normalise/normalise-rules.d.ts +181 -0
- package/dist/normalise/normalise-rules.d.ts.map +1 -0
- package/dist/normalise/normalise-rules.js +79 -0
- package/dist/normalise/normalise-rules.js.map +1 -0
- package/dist/normalise/rules/cluster-module-functions.d.ts +31 -0
- package/dist/normalise/rules/cluster-module-functions.d.ts.map +1 -0
- package/dist/normalise/rules/cluster-module-functions.js +238 -0
- package/dist/normalise/rules/cluster-module-functions.js.map +1 -0
- package/dist/normalise/rules/crud-into-curved.d.ts +117 -0
- package/dist/normalise/rules/crud-into-curved.d.ts.map +1 -0
- package/dist/normalise/rules/crud-into-curved.js +303 -0
- package/dist/normalise/rules/crud-into-curved.js.map +1 -0
- package/dist/normalise/rules/drop-trivial-passthrough.d.ts +92 -0
- package/dist/normalise/rules/drop-trivial-passthrough.d.ts.map +1 -0
- package/dist/normalise/rules/drop-trivial-passthrough.js +217 -0
- package/dist/normalise/rules/drop-trivial-passthrough.js.map +1 -0
- package/dist/normalise/runner.d.ts +58 -0
- package/dist/normalise/runner.d.ts.map +1 -0
- package/dist/normalise/runner.js +114 -0
- package/dist/normalise/runner.js.map +1 -0
- package/dist/parser/import-resolver/resolver.js +1 -1
- package/dist/parser/import-resolver/resolver.js.map +1 -1
- package/dist/realize/engines/typescript-engine.js +1 -1
- package/dist/realize/engines/typescript-engine.js.map +1 -1
- package/dist/realize/index.d.ts.map +1 -1
- package/dist/realize/index.js +221 -88
- package/dist/realize/index.js.map +1 -1
- package/dist/realize/library/library.js +1 -1
- package/dist/realize/library/library.js.map +1 -1
- package/dist/realize/library/resolver.d.ts.map +1 -1
- package/dist/realize/library/resolver.js +14 -1
- package/dist/realize/library/resolver.js.map +1 -1
- package/dist/realize/owner-emit-shared.d.ts +114 -0
- package/dist/realize/owner-emit-shared.d.ts.map +1 -0
- package/dist/realize/owner-emit-shared.js +227 -0
- package/dist/realize/owner-emit-shared.js.map +1 -0
- package/dist/realize/per-action-recovery.d.ts +74 -0
- package/dist/realize/per-action-recovery.d.ts.map +1 -0
- package/dist/realize/per-action-recovery.js +268 -0
- package/dist/realize/per-action-recovery.js.map +1 -0
- package/dist/realize/per-owner-emit.d.ts +7 -58
- package/dist/realize/per-owner-emit.d.ts.map +1 -1
- package/dist/realize/per-owner-emit.js +67 -215
- package/dist/realize/per-owner-emit.js.map +1 -1
- package/dist/realize/per-owner-runner.d.ts +24 -4
- package/dist/realize/per-owner-runner.d.ts.map +1 -1
- package/dist/realize/per-owner-runner.js +77 -19
- package/dist/realize/per-owner-runner.js.map +1 -1
- package/dist/realize/post-emit-verify/diagnostics.d.ts +107 -0
- package/dist/realize/post-emit-verify/diagnostics.d.ts.map +1 -0
- package/dist/realize/post-emit-verify/diagnostics.js +148 -0
- package/dist/realize/post-emit-verify/diagnostics.js.map +1 -0
- package/dist/realize/post-emit-verify/feedback-runner.d.ts +123 -0
- package/dist/realize/post-emit-verify/feedback-runner.d.ts.map +1 -0
- package/dist/realize/post-emit-verify/feedback-runner.js +232 -0
- package/dist/realize/post-emit-verify/feedback-runner.js.map +1 -0
- package/dist/realize/post-emit-verify/index.d.ts +19 -0
- package/dist/realize/post-emit-verify/index.d.ts.map +1 -0
- package/dist/realize/post-emit-verify/index.js +18 -0
- package/dist/realize/post-emit-verify/index.js.map +1 -0
- package/dist/realize/post-emit-verify/reemit.d.ts +82 -0
- package/dist/realize/post-emit-verify/reemit.d.ts.map +1 -0
- package/dist/realize/post-emit-verify/reemit.js +124 -0
- package/dist/realize/post-emit-verify/reemit.js.map +1 -0
- package/dist/realize/post-emit-verify/types.d.ts +187 -0
- package/dist/realize/post-emit-verify/types.d.ts.map +1 -0
- package/dist/realize/post-emit-verify/types.js +28 -0
- package/dist/realize/post-emit-verify/types.js.map +1 -0
- package/dist/realize/post-emit-verify/verifier-manifest.d.ts +29 -0
- package/dist/realize/post-emit-verify/verifier-manifest.d.ts.map +1 -0
- package/dist/realize/post-emit-verify/verifier-manifest.js +57 -0
- package/dist/realize/post-emit-verify/verifier-manifest.js.map +1 -0
- package/dist/realize/post-emit-verify/verifiers/stub-completeness.d.ts +85 -0
- package/dist/realize/post-emit-verify/verifiers/stub-completeness.d.ts.map +1 -0
- package/dist/realize/post-emit-verify/verifiers/stub-completeness.js +298 -0
- package/dist/realize/post-emit-verify/verifiers/stub-completeness.js.map +1 -0
- package/dist/realize/post-emit-verify/verifiers/tsc.d.ts +24 -0
- package/dist/realize/post-emit-verify/verifiers/tsc.d.ts.map +1 -0
- package/dist/realize/post-emit-verify/verifiers/tsc.js +148 -0
- package/dist/realize/post-emit-verify/verifiers/tsc.js.map +1 -0
- package/dist/realize/realize-context-snapshot.d.ts +70 -0
- package/dist/realize/realize-context-snapshot.d.ts.map +1 -0
- package/dist/realize/realize-context-snapshot.js +96 -0
- package/dist/realize/realize-context-snapshot.js.map +1 -0
- package/dist/realize/realize-rules.d.ts +113 -0
- package/dist/realize/realize-rules.d.ts.map +1 -0
- package/dist/realize/realize-rules.js +271 -0
- package/dist/realize/realize-rules.js.map +1 -0
- package/dist/realize/structural-validator.d.ts +36 -2
- package/dist/realize/structural-validator.d.ts.map +1 -1
- package/dist/realize/structural-validator.js +50 -7
- package/dist/realize/structural-validator.js.map +1 -1
- package/libs/instance-factories/cli/templates/commander/cli-entry-generator.ts +11 -12
- package/libs/instance-factories/cli/templates/commander/command-generator.ts +2 -2
- package/libs/instance-factories/controllers/templates/fastify/routes-generator.ts +49 -15
- package/libs/instance-factories/services/templates/prisma/ai-behaviors-generator.ts +19 -3
- package/libs/instance-factories/services/templates/prisma/behavior-generator.ts +62 -2
- package/libs/instance-factories/services/templates/prisma/controller-generator.ts +47 -20
- package/package.json +9 -1
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Post-emit feedback runner.
|
|
3
|
+
*
|
|
4
|
+
* After all per-owner emits complete, this orchestrator:
|
|
5
|
+
* 1. Runs all applicable verifiers against the realized output
|
|
6
|
+
* 2. Groups errors by source file → owning entity
|
|
7
|
+
* 3. For each owner with errors, asks the caller to re-emit the
|
|
8
|
+
* file via the provided `reemit` callback (with errors + previous
|
|
9
|
+
* content as context — the caller builds the LLM prompt)
|
|
10
|
+
* 4. Re-runs verifiers + records per-pass deltas
|
|
11
|
+
* 5. Bounded retries (default 1 pass)
|
|
12
|
+
*
|
|
13
|
+
* The runner is intentionally framework-agnostic: it does NOT call any
|
|
14
|
+
* specific LLM provider or import the per-owner-emit module. The
|
|
15
|
+
* caller wires `reemit` to whatever re-emission path makes sense for
|
|
16
|
+
* the project. This keeps the runner testable in isolation and
|
|
17
|
+
* forward-compatible with future re-emit strategies.
|
|
18
|
+
*
|
|
19
|
+
* Rollback policy: if a re-emit INCREASES error count for that file,
|
|
20
|
+
* the runner rolls back to the previous content. The LLM doesn't get
|
|
21
|
+
* to make things worse.
|
|
22
|
+
*/
|
|
23
|
+
import { readFileSync, writeFileSync } from 'fs';
|
|
24
|
+
import { join } from 'path';
|
|
25
|
+
import { runAllVerifiers } from './verifier-manifest.js';
|
|
26
|
+
/**
|
|
27
|
+
* Default file→owner mapping for the SpecVerse TypeScript layout:
|
|
28
|
+
* `backend/src/behaviors/<Owner>.ai.ts` → `<Owner>`
|
|
29
|
+
* `<anything>/<Owner>.ai.ts` → `<Owner>` (relaxed fallback)
|
|
30
|
+
* Returns null for files that don't match.
|
|
31
|
+
*/
|
|
32
|
+
export function defaultMapFileToOwner(file) {
|
|
33
|
+
const m = /(?:^|\/)([A-Za-z_][\w-]*)\.ai\.ts$/.exec(file);
|
|
34
|
+
return m ? m[1] : null;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Default treatment policy (Phase 2 of
|
|
38
|
+
* 2026-05-13-VERIFIER-DIAGNOSTIC-TREATMENT-SPLIT):
|
|
39
|
+
*
|
|
40
|
+
* - `STUB002` (LLM-throw stubs) → `surface-spec-gap`. The LLM already
|
|
41
|
+
* signaled "I lack context for this action" via the throw message;
|
|
42
|
+
* re-prompting either no-ops or hallucinates cross-file regressions.
|
|
43
|
+
* Better to tell the user about the gap so they can adjust the
|
|
44
|
+
* spec / manifest / provider choice.
|
|
45
|
+
*
|
|
46
|
+
* - Everything else (tsc errors, STUB001 γ-fallback, STUB003 trivial-
|
|
47
|
+
* return, STUB004 empty-body, future codes) → `auto-reemit`.
|
|
48
|
+
*
|
|
49
|
+
* Override at the call site for testing or for advanced policies.
|
|
50
|
+
*/
|
|
51
|
+
export function defaultTreatmentSelector(error) {
|
|
52
|
+
if (error.code === 'STUB002')
|
|
53
|
+
return 'surface-spec-gap';
|
|
54
|
+
return 'auto-reemit';
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Group verifier errors by file (preserving error order within each
|
|
58
|
+
* file). Files with no errors are absent from the map.
|
|
59
|
+
*/
|
|
60
|
+
function groupErrorsByFile(errors) {
|
|
61
|
+
const out = new Map();
|
|
62
|
+
for (const e of errors) {
|
|
63
|
+
let bucket = out.get(e.file);
|
|
64
|
+
if (!bucket) {
|
|
65
|
+
bucket = [];
|
|
66
|
+
out.set(e.file, bucket);
|
|
67
|
+
}
|
|
68
|
+
bucket.push(e);
|
|
69
|
+
}
|
|
70
|
+
return out;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Sum the error count for a specific file across a result set.
|
|
74
|
+
*/
|
|
75
|
+
function errorCountForFile(errors, file) {
|
|
76
|
+
let n = 0;
|
|
77
|
+
for (const e of errors)
|
|
78
|
+
if (e.file === file)
|
|
79
|
+
n++;
|
|
80
|
+
return n;
|
|
81
|
+
}
|
|
82
|
+
export async function runPostEmitFeedback(ctx, reemit, options = {}) {
|
|
83
|
+
const maxPasses = options.maxPasses ?? 1;
|
|
84
|
+
const maxFilesPerPass = options.maxFilesPerPass ?? 20;
|
|
85
|
+
const mapFileToOwner = options.mapFileToOwner ?? defaultMapFileToOwner;
|
|
86
|
+
const enabledOverrides = options.enabledOverrides;
|
|
87
|
+
const treatmentSelector = options.treatmentSelector ?? defaultTreatmentSelector;
|
|
88
|
+
const passes = [];
|
|
89
|
+
const verifierNotes = [];
|
|
90
|
+
const specGaps = [];
|
|
91
|
+
const seenSpecGaps = new Set();
|
|
92
|
+
/** Pull out spec-gap classified errors into the result's specGaps[]
|
|
93
|
+
* while leaving auto-reemit errors in place for the loop. Dedups
|
|
94
|
+
* across passes (same error from re-running verifiers shouldn't
|
|
95
|
+
* appear twice in the sidecar). */
|
|
96
|
+
function partitionErrors(errors) {
|
|
97
|
+
const actionable = [];
|
|
98
|
+
for (const e of errors) {
|
|
99
|
+
const strategy = treatmentSelector(e);
|
|
100
|
+
if (strategy === 'surface-spec-gap') {
|
|
101
|
+
const key = `${e.file}:${e.line ?? 0}:${e.col ?? 0}:${e.code}`;
|
|
102
|
+
if (!seenSpecGaps.has(key)) {
|
|
103
|
+
seenSpecGaps.add(key);
|
|
104
|
+
specGaps.push({
|
|
105
|
+
ownerName: mapFileToOwner(e.file),
|
|
106
|
+
file: e.file,
|
|
107
|
+
...(e.line !== undefined ? { line: e.line } : {}),
|
|
108
|
+
...(e.col !== undefined ? { col: e.col } : {}),
|
|
109
|
+
code: e.code,
|
|
110
|
+
message: e.message,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
if (strategy === 'skip')
|
|
116
|
+
continue;
|
|
117
|
+
actionable.push(e);
|
|
118
|
+
}
|
|
119
|
+
return actionable;
|
|
120
|
+
}
|
|
121
|
+
// Initial verifier pass.
|
|
122
|
+
let currentResults = await runAllVerifiers(ctx, enabledOverrides);
|
|
123
|
+
for (const r of currentResults) {
|
|
124
|
+
if (r.notes.length > 0)
|
|
125
|
+
verifierNotes.push({ verifierId: r.verifierId, notes: r.notes });
|
|
126
|
+
}
|
|
127
|
+
const initialErrorsRaw = currentResults.flatMap((r) => r.errors);
|
|
128
|
+
const initialErrors = partitionErrors(initialErrorsRaw);
|
|
129
|
+
let currentErrors = initialErrors;
|
|
130
|
+
for (let pass = 1; pass <= maxPasses; pass++) {
|
|
131
|
+
const errorsBefore = currentErrors.length;
|
|
132
|
+
if (errorsBefore === 0)
|
|
133
|
+
break;
|
|
134
|
+
const byFile = groupErrorsByFile(currentErrors);
|
|
135
|
+
const passResult = {
|
|
136
|
+
passNumber: pass,
|
|
137
|
+
errorsBefore,
|
|
138
|
+
errorsAfter: errorsBefore,
|
|
139
|
+
ownersAttempted: 0,
|
|
140
|
+
ownersImproved: 0,
|
|
141
|
+
ownersUnchanged: 0,
|
|
142
|
+
ownersRolledBack: 0,
|
|
143
|
+
ownersUnmappable: 0,
|
|
144
|
+
ownersReemitFailed: 0,
|
|
145
|
+
ownersOverBudget: 0,
|
|
146
|
+
};
|
|
147
|
+
// Per-file backup so we can roll back if the LLM makes it worse.
|
|
148
|
+
const backups = new Map();
|
|
149
|
+
// Apply the per-pass file budget. Iteration order over Map mirrors
|
|
150
|
+
// insertion order — which mirrors verifier emit order — so the
|
|
151
|
+
// first N files are deterministic across runs.
|
|
152
|
+
const fileEntries = [...byFile.entries()];
|
|
153
|
+
const allowed = fileEntries.slice(0, maxFilesPerPass);
|
|
154
|
+
const overBudget = fileEntries.slice(maxFilesPerPass);
|
|
155
|
+
passResult.ownersOverBudget = overBudget.length;
|
|
156
|
+
for (const [file, fileErrors] of allowed) {
|
|
157
|
+
const ownerName = mapFileToOwner(file);
|
|
158
|
+
if (!ownerName) {
|
|
159
|
+
passResult.ownersUnmappable++;
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
const absFile = join(ctx.outputDir, file);
|
|
163
|
+
let previousContent;
|
|
164
|
+
try {
|
|
165
|
+
previousContent = readFileSync(absFile, 'utf8');
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
passResult.ownersReemitFailed++;
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
passResult.ownersAttempted++;
|
|
172
|
+
const newContent = await reemit({
|
|
173
|
+
ownerName,
|
|
174
|
+
file,
|
|
175
|
+
errors: fileErrors,
|
|
176
|
+
previousContent,
|
|
177
|
+
});
|
|
178
|
+
if (!newContent) {
|
|
179
|
+
passResult.ownersReemitFailed++;
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
backups.set(file, previousContent);
|
|
183
|
+
writeFileSync(absFile, newContent);
|
|
184
|
+
}
|
|
185
|
+
// Re-run verifiers, then compare per-file error counts.
|
|
186
|
+
const newResults = await runAllVerifiers(ctx, enabledOverrides);
|
|
187
|
+
let newErrors = partitionErrors(newResults.flatMap((r) => r.errors));
|
|
188
|
+
// Rollback pass: any file whose error count INCREASED gets restored.
|
|
189
|
+
// Only consider files we actually attempted (within the budget).
|
|
190
|
+
const filesToRestore = [];
|
|
191
|
+
for (const [file, fileErrors] of allowed) {
|
|
192
|
+
const before = fileErrors.length;
|
|
193
|
+
const after = errorCountForFile(newErrors, file);
|
|
194
|
+
if (after > before && backups.has(file)) {
|
|
195
|
+
filesToRestore.push(file);
|
|
196
|
+
passResult.ownersRolledBack++;
|
|
197
|
+
}
|
|
198
|
+
else if (after < before) {
|
|
199
|
+
passResult.ownersImproved++;
|
|
200
|
+
}
|
|
201
|
+
else if (after === before && after > 0) {
|
|
202
|
+
passResult.ownersUnchanged++;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
if (filesToRestore.length > 0) {
|
|
206
|
+
for (const file of filesToRestore) {
|
|
207
|
+
const absFile = join(ctx.outputDir, file);
|
|
208
|
+
writeFileSync(absFile, backups.get(file));
|
|
209
|
+
}
|
|
210
|
+
// Re-run verifiers one more time so the reported `errorsAfter`
|
|
211
|
+
// reflects the post-rollback state.
|
|
212
|
+
const finalResults = await runAllVerifiers(ctx, enabledOverrides);
|
|
213
|
+
newErrors = partitionErrors(finalResults.flatMap((r) => r.errors));
|
|
214
|
+
}
|
|
215
|
+
passResult.errorsAfter = newErrors.length;
|
|
216
|
+
passes.push(passResult);
|
|
217
|
+
currentResults = newResults;
|
|
218
|
+
currentErrors = newErrors;
|
|
219
|
+
// Early exit: if a pass produced no improvement, more passes
|
|
220
|
+
// unlikely to help.
|
|
221
|
+
if (passResult.errorsAfter >= passResult.errorsBefore)
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
return {
|
|
225
|
+
initialErrors,
|
|
226
|
+
finalErrors: currentErrors,
|
|
227
|
+
passes,
|
|
228
|
+
verifierNotes,
|
|
229
|
+
specGaps,
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=feedback-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback-runner.js","sourceRoot":"","sources":["../../../src/realize/post-emit-verify/feedback-runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @specverse/engines/realize/post-emit-verify — post-emit verification
|
|
3
|
+
* + feedback runner.
|
|
4
|
+
*
|
|
5
|
+
* Generic framework for running compile / lint / typecheck verifiers
|
|
6
|
+
* on the realized output and feeding errors back to the LLM for a
|
|
7
|
+
* surgical fix pass.
|
|
8
|
+
*
|
|
9
|
+
* See `specverse-self/docs/proposals/...` (TBD) for the design rationale
|
|
10
|
+
* + empirical evidence from idle-meta 2026-05-13.
|
|
11
|
+
*/
|
|
12
|
+
export { type PostEmitVerifier, type VerifyContext, type VerifyError, type VerifyResult, type OwnerMapping, type TreatmentStrategy, type TreatmentSelector, type SpecGapEntry, } from './types.js';
|
|
13
|
+
export { VERIFIERS, runAllVerifiers, findVerifier, } from './verifier-manifest.js';
|
|
14
|
+
export { runPostEmitFeedback, defaultMapFileToOwner, defaultTreatmentSelector, type Reemit, type ReemitRequest, type FeedbackRunOptions, type FeedbackRunResult, type PassResult, } from './feedback-runner.js';
|
|
15
|
+
export { TSC_VERIFIER } from './verifiers/tsc.js';
|
|
16
|
+
export { buildLlmReemit, formatFeedbackPrompt, type BuildReemitOptions, } from './reemit.js';
|
|
17
|
+
export { runDiagnostics, formatSummaryLine, appendSpecGaps, formatSpecGapLine, type RealizeQualitySidecar, type RealizeQualitySummary, type OwnerQualityEntry, type OwnerStubIssue, } from './diagnostics.js';
|
|
18
|
+
export { STUB_COMPLETENESS_VERIFIER } from './verifiers/stub-completeness.js';
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/realize/post-emit-verify/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,YAAY,GAClB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,SAAS,EACT,eAAe,EACf,YAAY,GACb,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,wBAAwB,EACxB,KAAK,MAAM,EACX,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,UAAU,GAChB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,KAAK,kBAAkB,GACxB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,cAAc,GACpB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,0BAA0B,EAAE,MAAM,kCAAkC,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @specverse/engines/realize/post-emit-verify — post-emit verification
|
|
3
|
+
* + feedback runner.
|
|
4
|
+
*
|
|
5
|
+
* Generic framework for running compile / lint / typecheck verifiers
|
|
6
|
+
* on the realized output and feeding errors back to the LLM for a
|
|
7
|
+
* surgical fix pass.
|
|
8
|
+
*
|
|
9
|
+
* See `specverse-self/docs/proposals/...` (TBD) for the design rationale
|
|
10
|
+
* + empirical evidence from idle-meta 2026-05-13.
|
|
11
|
+
*/
|
|
12
|
+
export { VERIFIERS, runAllVerifiers, findVerifier, } from './verifier-manifest.js';
|
|
13
|
+
export { runPostEmitFeedback, defaultMapFileToOwner, defaultTreatmentSelector, } from './feedback-runner.js';
|
|
14
|
+
export { TSC_VERIFIER } from './verifiers/tsc.js';
|
|
15
|
+
export { buildLlmReemit, formatFeedbackPrompt, } from './reemit.js';
|
|
16
|
+
export { runDiagnostics, formatSummaryLine, appendSpecGaps, formatSpecGapLine, } from './diagnostics.js';
|
|
17
|
+
export { STUB_COMPLETENESS_VERIFIER } from './verifiers/stub-completeness.js';
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/realize/post-emit-verify/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAaH,OAAO,EACL,SAAS,EACT,eAAe,EACf,YAAY,GACb,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,wBAAwB,GAMzB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EACL,cAAc,EACd,oBAAoB,GAErB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,iBAAiB,GAKlB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,0BAA0B,EAAE,MAAM,kCAAkC,CAAC"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default `Reemit` implementation — builds a feedback prompt from
|
|
3
|
+
* verifier errors + previous file content and calls the LLM to
|
|
4
|
+
* re-emit a single file.
|
|
5
|
+
*
|
|
6
|
+
* The realize-emit skill (at ~/.claude/skills/realize-emit/) is
|
|
7
|
+
* auto-loaded by claude-cli when its description matches the prompt
|
|
8
|
+
* shape — that carries all the per-owner emission conventions
|
|
9
|
+
* (typing rules, _input convention, γ-stub shape, etc.) so the
|
|
10
|
+
* feedback re-emit benefits from the same guidance as the original
|
|
11
|
+
* emission.
|
|
12
|
+
*
|
|
13
|
+
* The prompt is intentionally minimal:
|
|
14
|
+
* - Errors (verifier-formatted)
|
|
15
|
+
* - Previous file content
|
|
16
|
+
* - A request to re-emit
|
|
17
|
+
*
|
|
18
|
+
* Future iterations may augment with AVAILABLE SPEC SURFACE (cross-
|
|
19
|
+
* service signatures) when the errors are arity-shape — empirically,
|
|
20
|
+
* the skill + basic prompt suffices for most null-safety / type
|
|
21
|
+
* mismatch / unused-decl cases.
|
|
22
|
+
*/
|
|
23
|
+
import type { LanguageModel } from 'ai';
|
|
24
|
+
import type { Reemit, ReemitRequest } from './feedback-runner.js';
|
|
25
|
+
export interface BuildReemitOptions {
|
|
26
|
+
/** LLM model — same shared model used by per-owner-emit. */
|
|
27
|
+
model: LanguageModel;
|
|
28
|
+
/** Max retries per file when the LLM produces empty / unparseable
|
|
29
|
+
* output. Default 1. */
|
|
30
|
+
maxAttempts?: number;
|
|
31
|
+
/** Per-call timeout. Default 3min — feedback re-emits are typically
|
|
32
|
+
* faster than fresh emissions because the LLM has the previous
|
|
33
|
+
* content to anchor on. */
|
|
34
|
+
timeoutMs?: number;
|
|
35
|
+
/**
|
|
36
|
+
* Skills whose content should be inlined into the system prompt for
|
|
37
|
+
* non-claude-cli providers. claude-cli auto-loads skills via
|
|
38
|
+
* filesystem-based resolution; other providers (`openai-compatible`,
|
|
39
|
+
* `anthropic`, `stub`) need explicit inlining of the skill content.
|
|
40
|
+
*
|
|
41
|
+
* Defaults to `['realize-emit']` — the realize-emit skill carries the
|
|
42
|
+
* per-owner emission CONSTRAINTS / GUIDANCE / EXAMPLE that's directly
|
|
43
|
+
* relevant to the feedback re-emit task (typing conventions, _input
|
|
44
|
+
* convention, γ-stub shape).
|
|
45
|
+
*/
|
|
46
|
+
skills?: string[];
|
|
47
|
+
/**
|
|
48
|
+
* Optional context loader (Phase 3 of
|
|
49
|
+
* 2026-05-13-VERIFIER-DIAGNOSTIC-TREATMENT-SPLIT).
|
|
50
|
+
*
|
|
51
|
+
* For each owner whose file is being re-emitted, return the per-owner
|
|
52
|
+
* realize-context snapshot (TARGET RUNTIME + [PRE-BAKED] step bullets
|
|
53
|
+
* + cross-service surface + capabilities) as a markdown blob, or null
|
|
54
|
+
* if no snapshot exists. The returned blob is prepended to the
|
|
55
|
+
* reemit user prompt — same shape the original per-owner emit used.
|
|
56
|
+
*
|
|
57
|
+
* The default-built loader (in realize/index.ts) reads from
|
|
58
|
+
* `<outputDir>/.realize-context/<Owner>.md`. Tests may inject fakes.
|
|
59
|
+
*/
|
|
60
|
+
contextLoader?: (ownerName: string) => string | null;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Build a `Reemit` callback that uses the provided LLM model.
|
|
64
|
+
*
|
|
65
|
+
* The returned closure can be passed straight to `runPostEmitFeedback`.
|
|
66
|
+
*/
|
|
67
|
+
export declare function buildLlmReemit(options: BuildReemitOptions): Reemit;
|
|
68
|
+
/**
|
|
69
|
+
* Format the feedback prompt body. Caller's LLM provider (e.g.
|
|
70
|
+
* claude-cli) loads the realize-emit skill as system context.
|
|
71
|
+
*
|
|
72
|
+
* The optional `ownerContext` (Phase 3) is the per-owner realize-context
|
|
73
|
+
* snapshot — TARGET RUNTIME + [PRE-BAKED] step bullets + cross-service
|
|
74
|
+
* surface + capabilities — prepended to the prompt so the LLM sees the
|
|
75
|
+
* same input the original per-owner emit had. Without this, smaller
|
|
76
|
+
* models (Ollama / MarrBox) hallucinate cross-file calls; with it,
|
|
77
|
+
* they have the canonical contract to anchor against.
|
|
78
|
+
*
|
|
79
|
+
* Exported for tests + so callers can override the prompt shape.
|
|
80
|
+
*/
|
|
81
|
+
export declare function formatFeedbackPrompt(req: ReemitRequest, ownerContext?: string | null): string;
|
|
82
|
+
//# sourceMappingURL=reemit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reemit.d.ts","sourceRoot":"","sources":["../../../src/realize/post-emit-verify/reemit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAGxC,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAGlE,MAAM,WAAW,kBAAkB;IACjC,4DAA4D;IAC5D,KAAK,EAAE,aAAa,CAAC;IACrB;6BACyB;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;gCAE4B;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;;;;OAUG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB;;;;;;;;;;;;OAYG;IACH,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CACtD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,CA8ClE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,aAAa,EAClB,YAAY,GAAE,MAAM,GAAG,IAAW,GACjC,MAAM,CAiCR"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default `Reemit` implementation — builds a feedback prompt from
|
|
3
|
+
* verifier errors + previous file content and calls the LLM to
|
|
4
|
+
* re-emit a single file.
|
|
5
|
+
*
|
|
6
|
+
* The realize-emit skill (at ~/.claude/skills/realize-emit/) is
|
|
7
|
+
* auto-loaded by claude-cli when its description matches the prompt
|
|
8
|
+
* shape — that carries all the per-owner emission conventions
|
|
9
|
+
* (typing rules, _input convention, γ-stub shape, etc.) so the
|
|
10
|
+
* feedback re-emit benefits from the same guidance as the original
|
|
11
|
+
* emission.
|
|
12
|
+
*
|
|
13
|
+
* The prompt is intentionally minimal:
|
|
14
|
+
* - Errors (verifier-formatted)
|
|
15
|
+
* - Previous file content
|
|
16
|
+
* - A request to re-emit
|
|
17
|
+
*
|
|
18
|
+
* Future iterations may augment with AVAILABLE SPEC SURFACE (cross-
|
|
19
|
+
* service signatures) when the errors are arity-shape — empirically,
|
|
20
|
+
* the skill + basic prompt suffices for most null-safety / type
|
|
21
|
+
* mismatch / unused-decl cases.
|
|
22
|
+
*/
|
|
23
|
+
import { generateText } from 'ai';
|
|
24
|
+
import { assembleSystemWithSkills } from '../../ai/prompt-runner.js';
|
|
25
|
+
import { resolveProviderId } from '../../ai/model-resolver.js';
|
|
26
|
+
/**
|
|
27
|
+
* Build a `Reemit` callback that uses the provided LLM model.
|
|
28
|
+
*
|
|
29
|
+
* The returned closure can be passed straight to `runPostEmitFeedback`.
|
|
30
|
+
*/
|
|
31
|
+
export function buildLlmReemit(options) {
|
|
32
|
+
const maxAttempts = options.maxAttempts ?? 1;
|
|
33
|
+
const timeoutMs = options.timeoutMs ?? 3 * 60_000;
|
|
34
|
+
const skills = options.skills ?? ['realize-emit'];
|
|
35
|
+
const contextLoader = options.contextLoader;
|
|
36
|
+
// Provider-aware skill inlining: claude-cli auto-loads skills via the
|
|
37
|
+
// CLI's filesystem resolution; everyone else needs the skill content
|
|
38
|
+
// prepended to the system prompt. Compute once at build time — the
|
|
39
|
+
// provider can't change mid-loop.
|
|
40
|
+
const providerId = resolveProviderId();
|
|
41
|
+
const systemPrompt = assembleSystemWithSkills('', providerId, skills);
|
|
42
|
+
return async (req) => {
|
|
43
|
+
const ownerContext = contextLoader?.(req.ownerName) ?? null;
|
|
44
|
+
const prompt = formatFeedbackPrompt(req, ownerContext);
|
|
45
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
46
|
+
try {
|
|
47
|
+
const result = await Promise.race([
|
|
48
|
+
generateText({
|
|
49
|
+
model: options.model,
|
|
50
|
+
prompt,
|
|
51
|
+
// For non-claude-cli providers, `systemPrompt` carries the
|
|
52
|
+
// skill content; for claude-cli it's empty and the CLI
|
|
53
|
+
// auto-loads.
|
|
54
|
+
...(systemPrompt ? { system: systemPrompt } : {}),
|
|
55
|
+
}),
|
|
56
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error('reemit timeout')), timeoutMs)),
|
|
57
|
+
]);
|
|
58
|
+
const extracted = extractTypeScriptBlock(result.text ?? '');
|
|
59
|
+
if (!extracted) {
|
|
60
|
+
if (attempt + 1 < maxAttempts)
|
|
61
|
+
continue;
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
return extracted;
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
if (attempt + 1 < maxAttempts)
|
|
68
|
+
continue;
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return null;
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Format the feedback prompt body. Caller's LLM provider (e.g.
|
|
77
|
+
* claude-cli) loads the realize-emit skill as system context.
|
|
78
|
+
*
|
|
79
|
+
* The optional `ownerContext` (Phase 3) is the per-owner realize-context
|
|
80
|
+
* snapshot — TARGET RUNTIME + [PRE-BAKED] step bullets + cross-service
|
|
81
|
+
* surface + capabilities — prepended to the prompt so the LLM sees the
|
|
82
|
+
* same input the original per-owner emit had. Without this, smaller
|
|
83
|
+
* models (Ollama / MarrBox) hallucinate cross-file calls; with it,
|
|
84
|
+
* they have the canonical contract to anchor against.
|
|
85
|
+
*
|
|
86
|
+
* Exported for tests + so callers can override the prompt shape.
|
|
87
|
+
*/
|
|
88
|
+
export function formatFeedbackPrompt(req, ownerContext = null) {
|
|
89
|
+
const errorLines = req.errors
|
|
90
|
+
.map(formatError)
|
|
91
|
+
.join('\n');
|
|
92
|
+
const parts = [];
|
|
93
|
+
if (ownerContext) {
|
|
94
|
+
parts.push(ownerContext);
|
|
95
|
+
parts.push('');
|
|
96
|
+
parts.push('---');
|
|
97
|
+
parts.push('');
|
|
98
|
+
}
|
|
99
|
+
parts.push(`Re-emit the entire contents of \`${req.file}\`.`, '', `Your previous emission had the following compile / lint errors:`, '', errorLines, '', `Previous file content (re-emit this with the errors fixed):`, '', '```typescript', req.previousContent, '```', '', `Fix the errors and emit the ENTIRE updated file inside one \`\`\`typescript code block.`, `Honour the [PRE-BAKED] step bodies above verbatim where present; do not paraphrase.`, `Do not change any logic beyond what's needed to fix the errors.`);
|
|
100
|
+
return parts.join('\n');
|
|
101
|
+
}
|
|
102
|
+
function formatError(e) {
|
|
103
|
+
const pos = e.line !== undefined
|
|
104
|
+
? `:${e.line}${e.col !== undefined ? `:${e.col}` : ''}`
|
|
105
|
+
: '';
|
|
106
|
+
return ` ${e.file}${pos} [${e.code}] ${e.message}`;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Pull the TypeScript code out of the LLM response. Matches the
|
|
110
|
+
* canonical ```typescript ... ``` block; falls back to ``` ... ``` if
|
|
111
|
+
* the LLM omitted the language tag.
|
|
112
|
+
*/
|
|
113
|
+
function extractTypeScriptBlock(text) {
|
|
114
|
+
if (!text)
|
|
115
|
+
return null;
|
|
116
|
+
const tsMatch = /```typescript\s*\n([\s\S]*?)\n```/.exec(text);
|
|
117
|
+
if (tsMatch)
|
|
118
|
+
return tsMatch[1];
|
|
119
|
+
const anyMatch = /```\s*\n([\s\S]*?)\n```/.exec(text);
|
|
120
|
+
if (anyMatch)
|
|
121
|
+
return anyMatch[1];
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=reemit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reemit.js","sourceRoot":"","sources":["../../../src/realize/post-emit-verify/reemit.ts"],"names":[],"mappings":"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"}
|