@specverse/engines 6.53.1 → 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/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/controller-generator.js +1 -1
- package/dist/realize/index.d.ts.map +1 -1
- package/dist/realize/index.js +91 -10
- package/dist/realize/index.js.map +1 -1
- 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 +6 -0
- package/dist/realize/per-owner-emit.d.ts.map +1 -1
- package/dist/realize/per-owner-emit.js +22 -6
- package/dist/realize/per-owner-emit.js.map +1 -1
- package/dist/realize/per-owner-runner.d.ts +23 -2
- package/dist/realize/per-owner-runner.d.ts.map +1 -1
- package/dist/realize/per-owner-runner.js +76 -18
- 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 +40 -1
- package/dist/realize/post-emit-verify/feedback-runner.d.ts.map +1 -1
- package/dist/realize/post-emit-verify/feedback-runner.js +61 -6
- package/dist/realize/post-emit-verify/feedback-runner.js.map +1 -1
- package/dist/realize/post-emit-verify/index.d.ts +4 -2
- package/dist/realize/post-emit-verify/index.d.ts.map +1 -1
- package/dist/realize/post-emit-verify/index.js +3 -1
- package/dist/realize/post-emit-verify/index.js.map +1 -1
- package/dist/realize/post-emit-verify/reemit.d.ts +22 -1
- package/dist/realize/post-emit-verify/reemit.d.ts.map +1 -1
- package/dist/realize/post-emit-verify/reemit.js +20 -18
- package/dist/realize/post-emit-verify/reemit.js.map +1 -1
- package/dist/realize/post-emit-verify/types.d.ts +49 -0
- package/dist/realize/post-emit-verify/types.d.ts.map +1 -1
- package/dist/realize/post-emit-verify/verifier-manifest.d.ts.map +1 -1
- package/dist/realize/post-emit-verify/verifier-manifest.js +2 -0
- package/dist/realize/post-emit-verify/verifier-manifest.js.map +1 -1
- 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/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/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/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/controller-generator.ts +6 -1
- package/package.json +1 -1
|
@@ -32,6 +32,7 @@ export function buildLlmReemit(options) {
|
|
|
32
32
|
const maxAttempts = options.maxAttempts ?? 1;
|
|
33
33
|
const timeoutMs = options.timeoutMs ?? 3 * 60_000;
|
|
34
34
|
const skills = options.skills ?? ['realize-emit'];
|
|
35
|
+
const contextLoader = options.contextLoader;
|
|
35
36
|
// Provider-aware skill inlining: claude-cli auto-loads skills via the
|
|
36
37
|
// CLI's filesystem resolution; everyone else needs the skill content
|
|
37
38
|
// prepended to the system prompt. Compute once at build time — the
|
|
@@ -39,7 +40,8 @@ export function buildLlmReemit(options) {
|
|
|
39
40
|
const providerId = resolveProviderId();
|
|
40
41
|
const systemPrompt = assembleSystemWithSkills('', providerId, skills);
|
|
41
42
|
return async (req) => {
|
|
42
|
-
const
|
|
43
|
+
const ownerContext = contextLoader?.(req.ownerName) ?? null;
|
|
44
|
+
const prompt = formatFeedbackPrompt(req, ownerContext);
|
|
43
45
|
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
44
46
|
try {
|
|
45
47
|
const result = await Promise.race([
|
|
@@ -74,28 +76,28 @@ export function buildLlmReemit(options) {
|
|
|
74
76
|
* Format the feedback prompt body. Caller's LLM provider (e.g.
|
|
75
77
|
* claude-cli) loads the realize-emit skill as system context.
|
|
76
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
|
+
*
|
|
77
86
|
* Exported for tests + so callers can override the prompt shape.
|
|
78
87
|
*/
|
|
79
|
-
export function formatFeedbackPrompt(req) {
|
|
88
|
+
export function formatFeedbackPrompt(req, ownerContext = null) {
|
|
80
89
|
const errorLines = req.errors
|
|
81
90
|
.map(formatError)
|
|
82
91
|
.join('\n');
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
''
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
'```typescript',
|
|
93
|
-
req.previousContent,
|
|
94
|
-
'```',
|
|
95
|
-
'',
|
|
96
|
-
`Fix the errors and emit the ENTIRE updated file inside one \`\`\`typescript code block.`,
|
|
97
|
-
`Do not change any logic beyond what's needed to fix the errors.`,
|
|
98
|
-
].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');
|
|
99
101
|
}
|
|
100
102
|
function formatError(e) {
|
|
101
103
|
const pos = e.line !== undefined
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reemit.js","sourceRoot":"","sources":["../../../src/realize/post-emit-verify/reemit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAElC,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"reemit.js","sourceRoot":"","sources":["../../../src/realize/post-emit-verify/reemit.ts"],"names":[],"mappings":"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"}
|
|
@@ -135,4 +135,53 @@ export interface OwnerMapping {
|
|
|
135
135
|
* per-owner LLM emit — those should NOT receive feedback re-emits). */
|
|
136
136
|
ownerName: string | null;
|
|
137
137
|
}
|
|
138
|
+
/**
|
|
139
|
+
* Per-error fix strategy. Phase 2 of
|
|
140
|
+
* 2026-05-13-VERIFIER-DIAGNOSTIC-TREATMENT-SPLIT — different verifier
|
|
141
|
+
* errors need different fix strategies, not a single "always reemit"
|
|
142
|
+
* path:
|
|
143
|
+
*
|
|
144
|
+
* - `auto-reemit`: include this error in the file's reemit prompt;
|
|
145
|
+
* the LLM should try to fix it. Right for tsc errors (unambiguous
|
|
146
|
+
* fix) + γ-fallback / trivial-return / empty-body stubs (LLM never
|
|
147
|
+
* produced real output the first time; a second try with focused
|
|
148
|
+
* context is high-success).
|
|
149
|
+
*
|
|
150
|
+
* - `surface-spec-gap`: do NOT reemit; surface the error to the user
|
|
151
|
+
* via the `realize-quality.json` sidecar (`specGaps` field).
|
|
152
|
+
* Right for STUB002 (LLM-throw stubs) where the LLM already
|
|
153
|
+
* signaled a context gap on the original emit — re-prompting
|
|
154
|
+
* either no-ops or hallucinates cross-file regressions (measured
|
|
155
|
+
* on idle-meta 2026-05-13 at engines 6.54.0).
|
|
156
|
+
*
|
|
157
|
+
* - `skip`: ignore entirely. Right for unmappable errors (already
|
|
158
|
+
* filtered) and for future categories the framework doesn't know
|
|
159
|
+
* how to treat.
|
|
160
|
+
*/
|
|
161
|
+
export type TreatmentStrategy = 'auto-reemit' | 'surface-spec-gap' | 'skip';
|
|
162
|
+
/**
|
|
163
|
+
* Decides how each verifier error should be treated. The default
|
|
164
|
+
* selector lives in `feedback-runner.ts::defaultTreatmentSelector`;
|
|
165
|
+
* callers may override for advanced cases (testing, custom verifiers,
|
|
166
|
+
* different LLM tolerance profiles).
|
|
167
|
+
*/
|
|
168
|
+
export type TreatmentSelector = (error: VerifyError) => TreatmentStrategy;
|
|
169
|
+
/**
|
|
170
|
+
* A single spec-level gap surfaced from a verifier error that the
|
|
171
|
+
* framework chose NOT to auto-fix. Goes into the realize-quality.json
|
|
172
|
+
* sidecar's `specGaps` array; users read it and decide whether to
|
|
173
|
+
* adjust the spec/manifest, switch providers, or hand-edit.
|
|
174
|
+
*/
|
|
175
|
+
export interface SpecGapEntry {
|
|
176
|
+
/** Owner name (e.g. "AuthController"). null when unmappable. */
|
|
177
|
+
ownerName: string | null;
|
|
178
|
+
/** Source file path, relative to outputDir. */
|
|
179
|
+
file: string;
|
|
180
|
+
line?: number;
|
|
181
|
+
col?: number;
|
|
182
|
+
/** Verifier code (e.g. "STUB002"). */
|
|
183
|
+
code: string;
|
|
184
|
+
/** Verifier-formatted message — directly suitable for user reading. */
|
|
185
|
+
message: string;
|
|
186
|
+
}
|
|
138
187
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/realize/post-emit-verify/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,oEAAoE;IACpE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,IAAI,EAAE,MAAM,CAAC;IACb;yEACqE;IACrE,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,mDAAmD;IACnD,UAAU,EAAE,MAAM,CAAC;IACnB,4DAA4D;IAC5D,UAAU,EAAE,MAAM,CAAC;IACnB;;+EAE2E;IAC3E,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB;;mBAEe;IACf,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B;mDAC+C;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB;kEAC8D;IAC9D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;uEACmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;;;;OAUG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,gBAAgB;IAC/B,oEAAoE;IACpE,EAAE,EAAE,MAAM,CAAC;IACX,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;;OAQG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,gEAAgE;IAChE,OAAO,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,OAAO,CAAC;IACzC,0EAA0E;IAC1E,MAAM,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;CACvD;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,YAAY;IAC3B,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb;;4EAEwE;IACxE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/realize/post-emit-verify/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,oEAAoE;IACpE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,IAAI,EAAE,MAAM,CAAC;IACb;yEACqE;IACrE,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,mDAAmD;IACnD,UAAU,EAAE,MAAM,CAAC;IACnB,4DAA4D;IAC5D,UAAU,EAAE,MAAM,CAAC;IACnB;;+EAE2E;IAC3E,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB;;mBAEe;IACf,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B;mDAC+C;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB;kEAC8D;IAC9D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;uEACmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;;;;OAUG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,gBAAgB;IAC/B,oEAAoE;IACpE,EAAE,EAAE,MAAM,CAAC;IACX,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;;OAQG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,gEAAgE;IAChE,OAAO,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,OAAO,CAAC;IACzC,0EAA0E;IAC1E,MAAM,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;CACvD;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,YAAY;IAC3B,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb;;4EAEwE;IACxE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,MAAM,iBAAiB,GAAG,aAAa,GAAG,kBAAkB,GAAG,MAAM,CAAC;AAE5E;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE,WAAW,KAAK,iBAAiB,CAAC;AAE1E;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,gEAAgE;IAChE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,OAAO,EAAE,MAAM,CAAC;CACjB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verifier-manifest.d.ts","sourceRoot":"","sources":["../../../src/realize/post-emit-verify/verifier-manifest.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"verifier-manifest.d.ts","sourceRoot":"","sources":["../../../src/realize/post-emit-verify/verifier-manifest.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAIhF,eAAO,MAAM,SAAS,EAAE,gBAAgB,EAQvC,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,aAAa,EAClB,gBAAgB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAC7B,OAAO,CAAC,YAAY,EAAE,CAAC,CAqBzB;AAED,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAErE"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { TSC_VERIFIER } from './verifiers/tsc.js';
|
|
2
|
+
import { STUB_COMPLETENESS_VERIFIER } from './verifiers/stub-completeness.js';
|
|
2
3
|
export const VERIFIERS = [
|
|
3
4
|
TSC_VERIFIER,
|
|
5
|
+
STUB_COMPLETENESS_VERIFIER,
|
|
4
6
|
// Future:
|
|
5
7
|
// PY_MYPY_VERIFIER — `mypy --strict src/`
|
|
6
8
|
// GO_VET_VERIFIER — `go vet ./...`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verifier-manifest.js","sourceRoot":"","sources":["../../../src/realize/post-emit-verify/verifier-manifest.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"verifier-manifest.js","sourceRoot":"","sources":["../../../src/realize/post-emit-verify/verifier-manifest.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,0BAA0B,EAAE,MAAM,kCAAkC,CAAC;AAE9E,MAAM,CAAC,MAAM,SAAS,GAAuB;IAC3C,YAAY;IACZ,0BAA0B;IAC1B,UAAU;IACV,6CAA6C;IAC7C,uCAAuC;IACvC,yCAAyC;IACzC,8CAA8C;CAC/C,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,GAAkB,EAClB,gBAA8B;IAE9B,MAAM,GAAG,GAAmB,EAAE,CAAC;IAC/B,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,MAAM,gBAAgB,GAAG,CAAC,CAAC,gBAAgB,KAAK,KAAK,CAAC;QACtD,MAAM,iBAAiB,GAAG,gBAAgB,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,KAAK,CAAC;QAC/D,IAAI,CAAC,gBAAgB,IAAI,CAAC,iBAAiB;YAAE,SAAS;QACtD,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC;YAAE,SAAS;QAC9B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACnC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACnB,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,GAAG,CAAC,IAAI,CAAC;gBACP,UAAU,EAAE,CAAC,CAAC,EAAE;gBAChB,UAAU,EAAE,CAAC;gBACb,EAAE,EAAE,KAAK;gBACT,MAAM,EAAE,EAAE;gBACV,KAAK,EAAE,CAAC,aAAa,CAAC,CAAC,EAAE,YAAY,GAAG,EAAE,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;aACpE,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,EAAU;IACrC,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;AAC5C,CAAC"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stub-completeness verifier — detects placeholder/stub bodies in
|
|
3
|
+
* emitted `.ai.ts` files and reports them as VerifyErrors so the
|
|
4
|
+
* existing feedback runner re-emits real bodies.
|
|
5
|
+
*
|
|
6
|
+
* Why this exists:
|
|
7
|
+
* The tsc verifier catches code that DOESN'T COMPILE. It says nothing
|
|
8
|
+
* about code that compiles but ships no behavior — the dominant
|
|
9
|
+
* failure mode for smaller/open LLMs on per-owner emit:
|
|
10
|
+
* - Engine γ-stubs (LLM declined → fallback placeholder file)
|
|
11
|
+
* - LLM-emitted throw stubs ("not implemented", "TODO: ...")
|
|
12
|
+
* - LLM-emitted trivial returns (`return null as any`)
|
|
13
|
+
*
|
|
14
|
+
* Empirical at 2026-05-13:
|
|
15
|
+
* - idle-meta Ollama: 58% real-LLM fill, 80 tsc errors → 0 tsc
|
|
16
|
+
* errors looks clean but 42% of bodies are stubs.
|
|
17
|
+
* - idle-meta MarrBox: 69% real-LLM fill, 40 → ? tsc errors,
|
|
18
|
+
* 31% bodies still stubs.
|
|
19
|
+
*
|
|
20
|
+
* Reporting stubs as VerifyErrors lets the feedback runner re-emit
|
|
21
|
+
* them with a targeted prompt. The existing rollback machinery
|
|
22
|
+
* prevents regressions if the LLM can't do better.
|
|
23
|
+
*
|
|
24
|
+
* Design:
|
|
25
|
+
* - Regex-only — no TS compiler API import. The `.ai.ts` files have
|
|
26
|
+
* a narrow shape: top-level `export async function NAME(...):
|
|
27
|
+
* Promise<X> { ... }` declarations. Brace-balanced extraction with
|
|
28
|
+
* a single line scanner is enough.
|
|
29
|
+
* - Conservative: ONLY flags single-statement bodies that match
|
|
30
|
+
* stub patterns. A real function body with a stub-shaped throw
|
|
31
|
+
* inside a conditional is NOT flagged.
|
|
32
|
+
* - Severity `warning` not `error` — these don't break the build,
|
|
33
|
+
* but the feedback runner counts them as errors-to-fix.
|
|
34
|
+
*
|
|
35
|
+
* Initial release: `enabledByDefault: false` — opt in via
|
|
36
|
+
* `SPECVERSE_REALIZE_POST_VERIFY_ENABLE=stub-completeness`. Once the
|
|
37
|
+
* empirical hit-rate is measured we flip default-on.
|
|
38
|
+
*/
|
|
39
|
+
import type { PostEmitVerifier } from '../types.js';
|
|
40
|
+
/** Stub error codes — surfaced to the feedback prompt as the verifier
|
|
41
|
+
* code; the LLM doesn't see them directly but they appear in the
|
|
42
|
+
* audit sidecar + logs. */
|
|
43
|
+
export declare const STUB_CODES: {
|
|
44
|
+
readonly GAMMA_FALLBACK: "STUB001";
|
|
45
|
+
readonly LLM_THROW: "STUB002";
|
|
46
|
+
readonly TRIVIAL_RETURN: "STUB003";
|
|
47
|
+
readonly EMPTY_BODY: "STUB004";
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Find every top-level `export async function NAME(...): Promise<X> {`
|
|
51
|
+
* declaration in a file and return its name + body + start-line.
|
|
52
|
+
*
|
|
53
|
+
* Brace counting handles nested blocks and template-literal expression
|
|
54
|
+
* holes. We don't try to parse strings/regexes/comments precisely; the
|
|
55
|
+
* narrow shape of `.ai.ts` files makes this safe in practice (each
|
|
56
|
+
* function is independent and bodies don't contain `}` in odd places
|
|
57
|
+
* at the start of a line at depth 0).
|
|
58
|
+
*/
|
|
59
|
+
interface ExtractedFunction {
|
|
60
|
+
name: string;
|
|
61
|
+
body: string;
|
|
62
|
+
/** 1-based line number of the `export async function` declaration. */
|
|
63
|
+
declLine: number;
|
|
64
|
+
/** 1-based line number of the first body line (after the opening `{`). */
|
|
65
|
+
bodyStartLine: number;
|
|
66
|
+
}
|
|
67
|
+
export declare function extractAsyncFunctions(source: string): ExtractedFunction[];
|
|
68
|
+
/**
|
|
69
|
+
* Strip line + block comments and blank lines, then trim.
|
|
70
|
+
* Used to normalize bodies before stub-pattern matching.
|
|
71
|
+
*/
|
|
72
|
+
export declare function stripCommentsAndBlanks(body: string): string;
|
|
73
|
+
export interface StubMatch {
|
|
74
|
+
kind: 'gamma-fallback' | 'llm-throw' | 'trivial-return' | 'empty';
|
|
75
|
+
code: string;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Classify a function body as a stub (or not). Conservative: requires
|
|
79
|
+
* the body to be a single-statement match to avoid false positives on
|
|
80
|
+
* real bodies that happen to contain a throw deep inside a conditional.
|
|
81
|
+
*/
|
|
82
|
+
export declare function classifyBody(body: string): StubMatch | null;
|
|
83
|
+
export declare const STUB_COMPLETENESS_VERIFIER: PostEmitVerifier;
|
|
84
|
+
export {};
|
|
85
|
+
//# sourceMappingURL=stub-completeness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stub-completeness.d.ts","sourceRoot":"","sources":["../../../../src/realize/post-emit-verify/verifiers/stub-completeness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAIH,OAAO,KAAK,EACV,gBAAgB,EAIjB,MAAM,aAAa,CAAC;AAErB;;4BAE4B;AAC5B,eAAO,MAAM,UAAU;;;;;CAKb,CAAC;AAQX;;;;;;;;;GASG;AACH,UAAU,iBAAiB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,sEAAsE;IACtE,QAAQ,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAuFzE;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQ3D;AAaD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,gBAAgB,GAAG,WAAW,GAAG,gBAAgB,GAAG,OAAO,CAAC;IAClE,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAwB3D;AA2CD,eAAO,MAAM,0BAA0B,EAAE,gBAoExC,CAAC"}
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stub-completeness verifier — detects placeholder/stub bodies in
|
|
3
|
+
* emitted `.ai.ts` files and reports them as VerifyErrors so the
|
|
4
|
+
* existing feedback runner re-emits real bodies.
|
|
5
|
+
*
|
|
6
|
+
* Why this exists:
|
|
7
|
+
* The tsc verifier catches code that DOESN'T COMPILE. It says nothing
|
|
8
|
+
* about code that compiles but ships no behavior — the dominant
|
|
9
|
+
* failure mode for smaller/open LLMs on per-owner emit:
|
|
10
|
+
* - Engine γ-stubs (LLM declined → fallback placeholder file)
|
|
11
|
+
* - LLM-emitted throw stubs ("not implemented", "TODO: ...")
|
|
12
|
+
* - LLM-emitted trivial returns (`return null as any`)
|
|
13
|
+
*
|
|
14
|
+
* Empirical at 2026-05-13:
|
|
15
|
+
* - idle-meta Ollama: 58% real-LLM fill, 80 tsc errors → 0 tsc
|
|
16
|
+
* errors looks clean but 42% of bodies are stubs.
|
|
17
|
+
* - idle-meta MarrBox: 69% real-LLM fill, 40 → ? tsc errors,
|
|
18
|
+
* 31% bodies still stubs.
|
|
19
|
+
*
|
|
20
|
+
* Reporting stubs as VerifyErrors lets the feedback runner re-emit
|
|
21
|
+
* them with a targeted prompt. The existing rollback machinery
|
|
22
|
+
* prevents regressions if the LLM can't do better.
|
|
23
|
+
*
|
|
24
|
+
* Design:
|
|
25
|
+
* - Regex-only — no TS compiler API import. The `.ai.ts` files have
|
|
26
|
+
* a narrow shape: top-level `export async function NAME(...):
|
|
27
|
+
* Promise<X> { ... }` declarations. Brace-balanced extraction with
|
|
28
|
+
* a single line scanner is enough.
|
|
29
|
+
* - Conservative: ONLY flags single-statement bodies that match
|
|
30
|
+
* stub patterns. A real function body with a stub-shaped throw
|
|
31
|
+
* inside a conditional is NOT flagged.
|
|
32
|
+
* - Severity `warning` not `error` — these don't break the build,
|
|
33
|
+
* but the feedback runner counts them as errors-to-fix.
|
|
34
|
+
*
|
|
35
|
+
* Initial release: `enabledByDefault: false` — opt in via
|
|
36
|
+
* `SPECVERSE_REALIZE_POST_VERIFY_ENABLE=stub-completeness`. Once the
|
|
37
|
+
* empirical hit-rate is measured we flip default-on.
|
|
38
|
+
*/
|
|
39
|
+
import { existsSync, readdirSync, readFileSync, statSync } from 'fs';
|
|
40
|
+
import { join, relative } from 'path';
|
|
41
|
+
/** Stub error codes — surfaced to the feedback prompt as the verifier
|
|
42
|
+
* code; the LLM doesn't see them directly but they appear in the
|
|
43
|
+
* audit sidecar + logs. */
|
|
44
|
+
export const STUB_CODES = {
|
|
45
|
+
GAMMA_FALLBACK: 'STUB001', // engine wrote the placeholder file
|
|
46
|
+
LLM_THROW: 'STUB002', // LLM emitted "throw not implemented"
|
|
47
|
+
TRIVIAL_RETURN: 'STUB003', // LLM emitted `return null|undefined|{}|[]`
|
|
48
|
+
EMPTY_BODY: 'STUB004', // body is whitespace/comments only
|
|
49
|
+
};
|
|
50
|
+
/** Resolve the behaviors directory tsc + this verifier scan. */
|
|
51
|
+
function resolveBehaviorsDir(ctx) {
|
|
52
|
+
const sub = ctx.subpath ?? 'backend';
|
|
53
|
+
return join(ctx.outputDir, sub, 'src', 'behaviors');
|
|
54
|
+
}
|
|
55
|
+
export function extractAsyncFunctions(source) {
|
|
56
|
+
const lines = source.split('\n');
|
|
57
|
+
const out = [];
|
|
58
|
+
// Pattern: line starts (after optional `export ` + `async `) with
|
|
59
|
+
// `async function NAME(`. We accept `export async function` (the
|
|
60
|
+
// canonical case) plus the alternate `async function NAME(...){...}`
|
|
61
|
+
// followed by `export { NAME as ... }` re-export form used for
|
|
62
|
+
// reserved-word action names in the engine γ-fallback file.
|
|
63
|
+
const declRe = /^(export\s+)?async\s+function\s+(\w+)\s*\(/;
|
|
64
|
+
for (let i = 0; i < lines.length; i++) {
|
|
65
|
+
const line = lines[i];
|
|
66
|
+
const m = declRe.exec(line);
|
|
67
|
+
if (!m)
|
|
68
|
+
continue;
|
|
69
|
+
const name = m[2];
|
|
70
|
+
// Walk forward to find the first `{` that opens the body. Skip
|
|
71
|
+
// anything inside the parameter list / return-type annotation.
|
|
72
|
+
let openIdx = -1;
|
|
73
|
+
let parenDepth = 0;
|
|
74
|
+
let lineCursor = i;
|
|
75
|
+
let colCursor = m.index + m[0].length; // just past `(`
|
|
76
|
+
// We've consumed up to the `(` of params; start at depth 1.
|
|
77
|
+
parenDepth = 1;
|
|
78
|
+
scanHeader: while (lineCursor < lines.length) {
|
|
79
|
+
const s = lines[lineCursor];
|
|
80
|
+
while (colCursor < s.length) {
|
|
81
|
+
const ch = s[colCursor];
|
|
82
|
+
if (parenDepth > 0) {
|
|
83
|
+
if (ch === '(')
|
|
84
|
+
parenDepth++;
|
|
85
|
+
else if (ch === ')')
|
|
86
|
+
parenDepth--;
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
// After params closed: look for `{`.
|
|
90
|
+
if (ch === '{') {
|
|
91
|
+
openIdx = colCursor;
|
|
92
|
+
break scanHeader;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
colCursor++;
|
|
96
|
+
}
|
|
97
|
+
lineCursor++;
|
|
98
|
+
colCursor = 0;
|
|
99
|
+
}
|
|
100
|
+
if (openIdx === -1)
|
|
101
|
+
continue;
|
|
102
|
+
// Now brace-count forward from just past `{` until we hit the
|
|
103
|
+
// matching `}`.
|
|
104
|
+
let depth = 1;
|
|
105
|
+
let bodyStartLineIdx = lineCursor;
|
|
106
|
+
let bodyStartColIdx = openIdx + 1;
|
|
107
|
+
let endLineIdx = -1;
|
|
108
|
+
let endColIdx = -1;
|
|
109
|
+
walkBody: for (let li = lineCursor; li < lines.length; li++) {
|
|
110
|
+
const s = lines[li];
|
|
111
|
+
const startCol = li === lineCursor ? openIdx + 1 : 0;
|
|
112
|
+
for (let ci = startCol; ci < s.length; ci++) {
|
|
113
|
+
const ch = s[ci];
|
|
114
|
+
if (ch === '{')
|
|
115
|
+
depth++;
|
|
116
|
+
else if (ch === '}') {
|
|
117
|
+
depth--;
|
|
118
|
+
if (depth === 0) {
|
|
119
|
+
endLineIdx = li;
|
|
120
|
+
endColIdx = ci;
|
|
121
|
+
break walkBody;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (endLineIdx === -1)
|
|
127
|
+
continue; // unbalanced; bail on this fn
|
|
128
|
+
// Slice the body content (exclusive of the outer braces).
|
|
129
|
+
let body;
|
|
130
|
+
if (bodyStartLineIdx === endLineIdx) {
|
|
131
|
+
body = lines[bodyStartLineIdx].slice(bodyStartColIdx, endColIdx);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
const first = lines[bodyStartLineIdx].slice(bodyStartColIdx);
|
|
135
|
+
const middle = lines.slice(bodyStartLineIdx + 1, endLineIdx).join('\n');
|
|
136
|
+
const last = lines[endLineIdx].slice(0, endColIdx);
|
|
137
|
+
body = [first, middle, last].filter((x) => x !== '').join('\n');
|
|
138
|
+
}
|
|
139
|
+
out.push({
|
|
140
|
+
name,
|
|
141
|
+
body,
|
|
142
|
+
declLine: i + 1,
|
|
143
|
+
bodyStartLine: bodyStartLineIdx + 1,
|
|
144
|
+
});
|
|
145
|
+
// Skip past the end so we don't re-scan content inside the body.
|
|
146
|
+
i = endLineIdx;
|
|
147
|
+
}
|
|
148
|
+
return out;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Strip line + block comments and blank lines, then trim.
|
|
152
|
+
* Used to normalize bodies before stub-pattern matching.
|
|
153
|
+
*/
|
|
154
|
+
export function stripCommentsAndBlanks(body) {
|
|
155
|
+
// Block comments first (greedy, multi-line capable).
|
|
156
|
+
let s = body.replace(/\/\*[\s\S]*?\*\//g, '');
|
|
157
|
+
// Line comments.
|
|
158
|
+
s = s.replace(/(^|\n)\s*\/\/[^\n]*/g, (_, p1) => p1 ?? '');
|
|
159
|
+
// Collapse multiple newlines + trim.
|
|
160
|
+
s = s.split('\n').map((l) => l.trimEnd()).filter((l) => l.trim() !== '').join('\n').trim();
|
|
161
|
+
return s;
|
|
162
|
+
}
|
|
163
|
+
// γ-fallback engine placeholders. Two producers:
|
|
164
|
+
// - per-owner-runner.renderFallbackPlaceholderFile → "(per-owner emit fell back)"
|
|
165
|
+
// - per-action-recovery.renderActionGammaStub → "(per-action recovery fell back)"
|
|
166
|
+
// Both are ENGINE placeholders (STUB001, auto-reemit-eligible), NOT the
|
|
167
|
+
// LLM's own "not implemented" throw (STUB002, surface-spec-gap).
|
|
168
|
+
const GAMMA_FALLBACK_RE = /^throw new Error\s*\(\s*["'`].*?not implemented \((?:per-owner emit|per-action recovery) fell back\).*?["'`]\s*\)\s*;?$/s;
|
|
169
|
+
const LLM_THROW_RE = /^throw new Error\s*\(\s*["'`][^"'`]*\b(not\s+implement\w*|not\s+yet|todo|placeholder|stub|requires|fallback|missing|unimplement\w*)\b[^"'`]*["'`]\s*\)\s*;?$/is;
|
|
170
|
+
const TRIVIAL_RETURN_RE = /^return\s+(?:null|undefined|\{\s*\}|\[\s*\])(\s+as\s+\w+)?\s*;?$/s;
|
|
171
|
+
/**
|
|
172
|
+
* Classify a function body as a stub (or not). Conservative: requires
|
|
173
|
+
* the body to be a single-statement match to avoid false positives on
|
|
174
|
+
* real bodies that happen to contain a throw deep inside a conditional.
|
|
175
|
+
*/
|
|
176
|
+
export function classifyBody(body) {
|
|
177
|
+
const stripped = stripCommentsAndBlanks(body);
|
|
178
|
+
if (stripped === '') {
|
|
179
|
+
return { kind: 'empty', code: STUB_CODES.EMPTY_BODY };
|
|
180
|
+
}
|
|
181
|
+
// Single-statement check: count semicolons + ensure no control-flow
|
|
182
|
+
// keywords at the top level. We don't try to detect every multi-
|
|
183
|
+
// statement function; instead, we use the simplest signal — if the
|
|
184
|
+
// stripped body matches a single-statement stub regex end-to-end,
|
|
185
|
+
// it's a stub.
|
|
186
|
+
if (GAMMA_FALLBACK_RE.test(stripped)) {
|
|
187
|
+
return { kind: 'gamma-fallback', code: STUB_CODES.GAMMA_FALLBACK };
|
|
188
|
+
}
|
|
189
|
+
if (LLM_THROW_RE.test(stripped)) {
|
|
190
|
+
return { kind: 'llm-throw', code: STUB_CODES.LLM_THROW };
|
|
191
|
+
}
|
|
192
|
+
if (TRIVIAL_RETURN_RE.test(stripped)) {
|
|
193
|
+
return { kind: 'trivial-return', code: STUB_CODES.TRIVIAL_RETURN };
|
|
194
|
+
}
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
/** Render a feedback-prompt-friendly message for a stub match. */
|
|
198
|
+
function messageFor(kind, fnName) {
|
|
199
|
+
switch (kind) {
|
|
200
|
+
case 'gamma-fallback':
|
|
201
|
+
return (`Function '${fnName}' is a γ-stub placeholder (per-owner emit fell back). ` +
|
|
202
|
+
`Emit a real implementation per the [PRE-BAKED] action contract in the spec.`);
|
|
203
|
+
case 'llm-throw':
|
|
204
|
+
return (`Function '${fnName}' has a placeholder body that throws 'not implemented' ` +
|
|
205
|
+
`(or similar). Emit a real implementation per the [PRE-BAKED] action contract.`);
|
|
206
|
+
case 'trivial-return':
|
|
207
|
+
return (`Function '${fnName}' returns a trivial placeholder (null/undefined/{}). ` +
|
|
208
|
+
`Emit a real implementation per the [PRE-BAKED] action contract.`);
|
|
209
|
+
case 'empty':
|
|
210
|
+
return (`Function '${fnName}' has an empty body. ` +
|
|
211
|
+
`Emit a real implementation per the [PRE-BAKED] action contract.`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
/** Recursively list `*.ai.ts` files under a directory. Defensive — the
|
|
215
|
+
* behaviors dir is normally flat but engines may add subdirs later. */
|
|
216
|
+
function listAiTsFiles(dir) {
|
|
217
|
+
if (!existsSync(dir))
|
|
218
|
+
return [];
|
|
219
|
+
const out = [];
|
|
220
|
+
for (const name of readdirSync(dir)) {
|
|
221
|
+
const p = join(dir, name);
|
|
222
|
+
let st;
|
|
223
|
+
try {
|
|
224
|
+
st = statSync(p);
|
|
225
|
+
}
|
|
226
|
+
catch {
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
if (st.isDirectory())
|
|
230
|
+
out.push(...listAiTsFiles(p));
|
|
231
|
+
else if (st.isFile() && p.endsWith('.ai.ts'))
|
|
232
|
+
out.push(p);
|
|
233
|
+
}
|
|
234
|
+
return out;
|
|
235
|
+
}
|
|
236
|
+
export const STUB_COMPLETENESS_VERIFIER = {
|
|
237
|
+
id: 'stub-completeness',
|
|
238
|
+
name: 'Stub Body Completeness',
|
|
239
|
+
// Default-on as of engines 6.56.0 (Phase 2 of
|
|
240
|
+
// 2026-05-13-VERIFIER-DIAGNOSTIC-TREATMENT-SPLIT). Safe to flip
|
|
241
|
+
// because the feedback runner's defaultTreatmentSelector routes
|
|
242
|
+
// STUB002 to surface-spec-gap (no reemit), preventing the cross-
|
|
243
|
+
// file regressions measured at engines 6.54.0 on idle-meta.
|
|
244
|
+
// STUB001/003/004 still auto-reemit (high-success on γ-fallback
|
|
245
|
+
// recovery, measured at engines 6.54.0 on nestjs-billing: 7/7 fixed).
|
|
246
|
+
enabledByDefault: true,
|
|
247
|
+
applies: (ctx) => {
|
|
248
|
+
if (ctx.targetLanguage && ctx.targetLanguage !== 'typescript')
|
|
249
|
+
return false;
|
|
250
|
+
const dir = resolveBehaviorsDir(ctx);
|
|
251
|
+
return existsSync(dir) && listAiTsFiles(dir).length > 0;
|
|
252
|
+
},
|
|
253
|
+
verify: async (ctx) => {
|
|
254
|
+
const start = Date.now();
|
|
255
|
+
const dir = resolveBehaviorsDir(ctx);
|
|
256
|
+
const files = listAiTsFiles(dir);
|
|
257
|
+
const errors = [];
|
|
258
|
+
const notes = [];
|
|
259
|
+
let totalFunctions = 0;
|
|
260
|
+
let totalStubs = 0;
|
|
261
|
+
for (const absFile of files) {
|
|
262
|
+
let source;
|
|
263
|
+
try {
|
|
264
|
+
source = readFileSync(absFile, 'utf8');
|
|
265
|
+
}
|
|
266
|
+
catch (e) {
|
|
267
|
+
notes.push(`could not read ${absFile}: ${e?.message ?? String(e)}`);
|
|
268
|
+
continue;
|
|
269
|
+
}
|
|
270
|
+
const fns = extractAsyncFunctions(source);
|
|
271
|
+
totalFunctions += fns.length;
|
|
272
|
+
for (const fn of fns) {
|
|
273
|
+
const match = classifyBody(fn.body);
|
|
274
|
+
if (!match)
|
|
275
|
+
continue;
|
|
276
|
+
totalStubs++;
|
|
277
|
+
errors.push({
|
|
278
|
+
file: relative(ctx.outputDir, absFile),
|
|
279
|
+
line: fn.declLine,
|
|
280
|
+
col: 1,
|
|
281
|
+
severity: 'warning',
|
|
282
|
+
code: match.code,
|
|
283
|
+
message: messageFor(match.kind, fn.name),
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
notes.push(`scanned ${files.length} .ai.ts file(s), ${totalFunctions} function(s); ` +
|
|
288
|
+
`flagged ${totalStubs} stub(s)`);
|
|
289
|
+
return {
|
|
290
|
+
verifierId: 'stub-completeness',
|
|
291
|
+
durationMs: Date.now() - start,
|
|
292
|
+
ok: true,
|
|
293
|
+
errors,
|
|
294
|
+
notes,
|
|
295
|
+
};
|
|
296
|
+
},
|
|
297
|
+
};
|
|
298
|
+
//# sourceMappingURL=stub-completeness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stub-completeness.js","sourceRoot":"","sources":["../../../../src/realize/post-emit-verify/verifiers/stub-completeness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AACrE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAQtC;;4BAE4B;AAC5B,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,cAAc,EAAE,SAAS,EAAG,oCAAoC;IAChE,SAAS,EAAE,SAAS,EAAQ,sCAAsC;IAClE,cAAc,EAAE,SAAS,EAAG,4CAA4C;IACxE,UAAU,EAAE,SAAS,EAAO,mCAAmC;CACvD,CAAC;AAEX,gEAAgE;AAChE,SAAS,mBAAmB,CAAC,GAAkB;IAC7C,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,IAAI,SAAS,CAAC;IACrC,OAAO,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;AACtD,CAAC;AAqBD,MAAM,UAAU,qBAAqB,CAAC,MAAc;IAClD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,GAAG,GAAwB,EAAE,CAAC;IACpC,kEAAkE;IAClE,iEAAiE;IACjE,qEAAqE;IACrE,+DAA+D;IAC/D,4DAA4D;IAC5D,MAAM,MAAM,GAAG,4CAA4C,CAAC;IAE5D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;QACvB,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,CAAC,CAAC;YAAE,SAAS;QACjB,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC;QAEnB,+DAA+D;QAC/D,+DAA+D;QAC/D,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC;QACjB,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,IAAI,SAAS,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAE,gBAAgB;QACxD,4DAA4D;QAC5D,UAAU,GAAG,CAAC,CAAC;QAEf,UAAU,EAAE,OAAO,UAAU,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;YAC7C,MAAM,CAAC,GAAG,KAAK,CAAC,UAAU,CAAE,CAAC;YAC7B,OAAO,SAAS,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC;gBAC5B,MAAM,EAAE,GAAG,CAAC,CAAC,SAAS,CAAE,CAAC;gBACzB,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;oBACnB,IAAI,EAAE,KAAK,GAAG;wBAAE,UAAU,EAAE,CAAC;yBACxB,IAAI,EAAE,KAAK,GAAG;wBAAE,UAAU,EAAE,CAAC;gBACpC,CAAC;qBAAM,CAAC;oBACN,qCAAqC;oBACrC,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;wBAAC,OAAO,GAAG,SAAS,CAAC;wBAAC,MAAM,UAAU,CAAC;oBAAC,CAAC;gBAC5D,CAAC;gBACD,SAAS,EAAE,CAAC;YACd,CAAC;YACD,UAAU,EAAE,CAAC;YACb,SAAS,GAAG,CAAC,CAAC;QAChB,CAAC;QACD,IAAI,OAAO,KAAK,CAAC,CAAC;YAAE,SAAS;QAE7B,8DAA8D;QAC9D,gBAAgB;QAChB,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,gBAAgB,GAAG,UAAU,CAAC;QAClC,IAAI,eAAe,GAAG,OAAO,GAAG,CAAC,CAAC;QAClC,IAAI,UAAU,GAAG,CAAC,CAAC,CAAC;QACpB,IAAI,SAAS,GAAG,CAAC,CAAC,CAAC;QAEnB,QAAQ,EAAE,KAAK,IAAI,EAAE,GAAG,UAAU,EAAE,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC;YAC5D,MAAM,CAAC,GAAG,KAAK,CAAC,EAAE,CAAE,CAAC;YACrB,MAAM,QAAQ,GAAG,EAAE,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACrD,KAAK,IAAI,EAAE,GAAG,QAAQ,EAAE,EAAE,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC;gBAC5C,MAAM,EAAE,GAAG,CAAC,CAAC,EAAE,CAAE,CAAC;gBAClB,IAAI,EAAE,KAAK,GAAG;oBAAE,KAAK,EAAE,CAAC;qBACnB,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;oBACpB,KAAK,EAAE,CAAC;oBACR,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;wBAAC,UAAU,GAAG,EAAE,CAAC;wBAAC,SAAS,GAAG,EAAE,CAAC;wBAAC,MAAM,QAAQ,CAAC;oBAAC,CAAC;gBACvE,CAAC;YACH,CAAC;QACH,CAAC;QACD,IAAI,UAAU,KAAK,CAAC,CAAC;YAAE,SAAS,CAAE,8BAA8B;QAEhE,0DAA0D;QAC1D,IAAI,IAAY,CAAC;QACjB,IAAI,gBAAgB,KAAK,UAAU,EAAE,CAAC;YACpC,IAAI,GAAG,KAAK,CAAC,gBAAgB,CAAE,CAAC,KAAK,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC;QACpE,CAAC;aAAM,CAAC;YACN,MAAM,KAAK,GAAG,KAAK,CAAC,gBAAgB,CAAE,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;YAC9D,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,gBAAgB,GAAG,CAAC,EAAE,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACxE,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,CAAE,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;YACpD,IAAI,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClE,CAAC;QAED,GAAG,CAAC,IAAI,CAAC;YACP,IAAI;YACJ,IAAI;YACJ,QAAQ,EAAE,CAAC,GAAG,CAAC;YACf,aAAa,EAAE,gBAAgB,GAAG,CAAC;SACpC,CAAC,CAAC;QAEH,iEAAiE;QACjE,CAAC,GAAG,UAAU,CAAC;IACjB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAY;IACjD,qDAAqD;IACrD,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;IAC9C,iBAAiB;IACjB,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3D,qCAAqC;IACrC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3F,OAAO,CAAC,CAAC;AACX,CAAC;AAED,iDAAiD;AACjD,oFAAoF;AACpF,yFAAyF;AACzF,wEAAwE;AACxE,iEAAiE;AACjE,MAAM,iBAAiB,GAAG,0HAA0H,CAAC;AAErJ,MAAM,YAAY,GAAG,gKAAgK,CAAC;AAEtL,MAAM,iBAAiB,GAAG,mEAAmE,CAAC;AAO9F;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,MAAM,QAAQ,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC;IAE9C,IAAI,QAAQ,KAAK,EAAE,EAAE,CAAC;QACpB,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,CAAC,UAAU,EAAE,CAAC;IACxD,CAAC;IAED,oEAAoE;IACpE,iEAAiE;IACjE,mEAAmE;IACnE,kEAAkE;IAClE,eAAe;IAEf,IAAI,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACrC,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,UAAU,CAAC,cAAc,EAAE,CAAC;IACrE,CAAC;IACD,IAAI,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAChC,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,CAAC,SAAS,EAAE,CAAC;IAC3D,CAAC;IACD,IAAI,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACrC,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,UAAU,CAAC,cAAc,EAAE,CAAC;IACrE,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,kEAAkE;AAClE,SAAS,UAAU,CAAC,IAAuB,EAAE,MAAc;IACzD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,gBAAgB;YACnB,OAAO,CACL,aAAa,MAAM,wDAAwD;gBAC3E,6EAA6E,CAC9E,CAAC;QACJ,KAAK,WAAW;YACd,OAAO,CACL,aAAa,MAAM,yDAAyD;gBAC5E,+EAA+E,CAChF,CAAC;QACJ,KAAK,gBAAgB;YACnB,OAAO,CACL,aAAa,MAAM,uDAAuD;gBAC1E,iEAAiE,CAClE,CAAC;QACJ,KAAK,OAAO;YACV,OAAO,CACL,aAAa,MAAM,uBAAuB;gBAC1C,iEAAiE,CAClE,CAAC;IACN,CAAC;AACH,CAAC;AAED;wEACwE;AACxE,SAAS,aAAa,CAAC,GAAW;IAChC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IAChC,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;QACpC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC1B,IAAI,EAAE,CAAC;QACP,IAAI,CAAC;YAAC,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC;YAAC,SAAS;QAAC,CAAC;QAC7C,IAAI,EAAE,CAAC,WAAW,EAAE;YAAE,GAAG,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;aAC/C,IAAI,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,CAAC,MAAM,0BAA0B,GAAqB;IAC1D,EAAE,EAAE,mBAAmB;IACvB,IAAI,EAAE,wBAAwB;IAC9B,8CAA8C;IAC9C,gEAAgE;IAChE,gEAAgE;IAChE,iEAAiE;IACjE,4DAA4D;IAC5D,gEAAgE;IAChE,sEAAsE;IACtE,gBAAgB,EAAE,IAAI;IAEtB,OAAO,EAAE,CAAC,GAAkB,EAAW,EAAE;QACvC,IAAI,GAAG,CAAC,cAAc,IAAI,GAAG,CAAC,cAAc,KAAK,YAAY;YAAE,OAAO,KAAK,CAAC;QAC5E,MAAM,GAAG,GAAG,mBAAmB,CAAC,GAAG,CAAC,CAAC;QACrC,OAAO,UAAU,CAAC,GAAG,CAAC,IAAI,aAAa,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,GAAkB,EAAyB,EAAE;QAC1D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,mBAAmB,CAAC,GAAG,CAAC,CAAC;QACrC,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,MAAM,GAAkB,EAAE,CAAC;QACjC,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,IAAI,cAAc,GAAG,CAAC,CAAC;QACvB,IAAI,UAAU,GAAG,CAAC,CAAC;QAEnB,KAAK,MAAM,OAAO,IAAI,KAAK,EAAE,CAAC;YAC5B,IAAI,MAAc,CAAC;YACnB,IAAI,CAAC;gBACH,MAAM,GAAG,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YACzC,CAAC;YAAC,OAAO,CAAM,EAAE,CAAC;gBAChB,KAAK,CAAC,IAAI,CAAC,kBAAkB,OAAO,KAAK,CAAC,EAAE,OAAO,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACpE,SAAS;YACX,CAAC;YAED,MAAM,GAAG,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;YAC1C,cAAc,IAAI,GAAG,CAAC,MAAM,CAAC;YAE7B,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;gBACrB,MAAM,KAAK,GAAG,YAAY,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;gBACpC,IAAI,CAAC,KAAK;oBAAE,SAAS;gBACrB,UAAU,EAAE,CAAC;gBACb,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC;oBACtC,IAAI,EAAE,EAAE,CAAC,QAAQ;oBACjB,GAAG,EAAE,CAAC;oBACN,QAAQ,EAAE,SAAS;oBACnB,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,OAAO,EAAE,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC;iBACzC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,KAAK,CAAC,IAAI,CACR,WAAW,KAAK,CAAC,MAAM,oBAAoB,cAAc,gBAAgB;YACzE,WAAW,UAAU,UAAU,CAChC,CAAC;QAEF,OAAO;YACL,UAAU,EAAE,mBAAmB;YAC/B,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;YAC9B,EAAE,EAAE,IAAI;YACR,MAAM;YACN,KAAK;SACN,CAAC;IACJ,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-owner realize-context snapshot.
|
|
3
|
+
*
|
|
4
|
+
* Phase 3 of 2026-05-13-VERIFIER-DIAGNOSTIC-TREATMENT-SPLIT.
|
|
5
|
+
*
|
|
6
|
+
* The per-owner emit prompt has TARGET RUNTIME, [PRE-BAKED] step bullets,
|
|
7
|
+
* cross-service operation signatures, available capabilities, library
|
|
8
|
+
* whitelist — everything the LLM needs to emit a real action body. The
|
|
9
|
+
* post-emit feedback runner's `buildLlmReemit` historically had NONE of
|
|
10
|
+
* this; the reemit prompt provided only the previous bad output + the
|
|
11
|
+
* verifier errors.
|
|
12
|
+
*
|
|
13
|
+
* Empirical consequence: sonnet still bridged the gap via inference;
|
|
14
|
+
* smaller models (Ollama qwen3-coder:30b, MarrBox) drifted further from
|
|
15
|
+
* the realize-emit skill's contract, introducing cross-file tsc
|
|
16
|
+
* regressions when asked to fix STUB002 stubs (measured 2026-05-13 at
|
|
17
|
+
* engines 6.54.0 on idle-meta).
|
|
18
|
+
*
|
|
19
|
+
* Phase 3 closes the gap by SNAPSHOTTING the per-owner context to disk
|
|
20
|
+
* at emit time and READING it at reemit time. The snapshot lives at
|
|
21
|
+
* `<outputDir>/.realize-context/<OwnerName>.md` and contains a compact
|
|
22
|
+
* markdown blob — directly embeddable in the reemit user prompt.
|
|
23
|
+
*
|
|
24
|
+
* Decoupling: the snapshot writer (called from per-owner-runner)
|
|
25
|
+
* doesn't know about reemit; the snapshot loader (called from reemit
|
|
26
|
+
* factory) doesn't know about per-owner-emit. They share only the
|
|
27
|
+
* file layout convention.
|
|
28
|
+
*/
|
|
29
|
+
/** Input data for snapshotting an owner's realize context. Mirrors the
|
|
30
|
+
* subset of PerOwnerEmitRequest that's directly useful for fixing
|
|
31
|
+
* bodies — TARGET RUNTIME + per-action [PRE-BAKED] scaffolding +
|
|
32
|
+
* cross-service signatures + available capabilities. */
|
|
33
|
+
export interface OwnerRealizeContext {
|
|
34
|
+
ownerName: string;
|
|
35
|
+
/** e.g. "Node.js (backend)" — short, structurally useful for choosing
|
|
36
|
+
* imports + identifying forbidden APIs. */
|
|
37
|
+
targetRuntime: string;
|
|
38
|
+
/** The full per-action scaffolding rendered by `buildPerActionScaffolding`
|
|
39
|
+
* — already formatted with `[PRE-BAKED] "<step>" → <snippet>` blocks
|
|
40
|
+
* and `[WRITE] "<step>"` markers. Reusing the same render keeps the
|
|
41
|
+
* reemit prompt aligned with the original per-owner prompt. */
|
|
42
|
+
perActionScaffolding: string;
|
|
43
|
+
/** AVAILABLE SPEC SURFACE — signatures of cross-service operations.
|
|
44
|
+
* Empty-fallback formatted by the per-owner-runner. */
|
|
45
|
+
availableSpecSurface: string;
|
|
46
|
+
/** AVAILABLE CAPABILITIES — clients / repos the LLM may call. */
|
|
47
|
+
availableCapabilities: string;
|
|
48
|
+
/** AVAILABLE CLIENTS — generated client classes the LLM may instantiate. */
|
|
49
|
+
availableClients: string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Render the context as a compact markdown blob suitable for direct
|
|
53
|
+
* embedding in the reemit prompt body. Mirrors the section headings
|
|
54
|
+
* used in the per-owner-emit prompt template so the LLM sees the same
|
|
55
|
+
* structural cues.
|
|
56
|
+
*/
|
|
57
|
+
export declare function formatContextSnapshot(ctx: OwnerRealizeContext): string;
|
|
58
|
+
/**
|
|
59
|
+
* Persist a context snapshot to disk. Best-effort — caller should
|
|
60
|
+
* never crash on snapshot failure (the reemit prompt degrades to the
|
|
61
|
+
* pre-Phase-3 behavior cleanly).
|
|
62
|
+
*/
|
|
63
|
+
export declare function writeContextSnapshot(outputDir: string, ctx: OwnerRealizeContext): void;
|
|
64
|
+
/**
|
|
65
|
+
* Load a previously-written snapshot. Returns the raw markdown blob,
|
|
66
|
+
* or `null` if no snapshot exists for the owner. Callers (the reemit
|
|
67
|
+
* factory) include the blob in the prompt body when present.
|
|
68
|
+
*/
|
|
69
|
+
export declare function loadContextSnapshot(outputDir: string, ownerName: string): string | null;
|
|
70
|
+
//# sourceMappingURL=realize-context-snapshot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"realize-context-snapshot.d.ts","sourceRoot":"","sources":["../../src/realize/realize-context-snapshot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAOH;;;yDAGyD;AACzD,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB;gDAC4C;IAC5C,aAAa,EAAE,MAAM,CAAC;IACtB;;;oEAGgE;IAChE,oBAAoB,EAAE,MAAM,CAAC;IAC7B;4DACwD;IACxD,oBAAoB,EAAE,MAAM,CAAC;IAC7B,iEAAiE;IACjE,qBAAqB,EAAE,MAAM,CAAC;IAC9B,4EAA4E;IAC5E,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,mBAAmB,GAAG,MAAM,CAmBtE;AAQD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,mBAAmB,GACvB,IAAI,CASN;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,MAAM,GAAG,IAAI,CAQf"}
|