@cat-factory/agents 0.72.3 → 0.73.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/agents/kinds/spec-blueprints.d.ts +6 -0
- package/dist/agents/kinds/spec-blueprints.d.ts.map +1 -1
- package/dist/agents/kinds/spec-blueprints.js +19 -5
- package/dist/agents/kinds/spec-blueprints.js.map +1 -1
- package/dist/agents/kinds/versions.d.ts +6 -1
- package/dist/agents/kinds/versions.d.ts.map +1 -1
- package/dist/agents/kinds/versions.js +10 -1
- package/dist/agents/kinds/versions.js.map +1 -1
- package/dist/agents/prompts/standard.d.ts.map +1 -1
- package/dist/agents/prompts/standard.js +1 -0
- package/dist/agents/prompts/standard.js.map +1 -1
- package/dist/agents/prompts/testing.d.ts.map +1 -1
- package/dist/agents/prompts/testing.js +24 -0
- package/dist/agents/prompts/testing.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -2
- package/dist/index.js.map +1 -1
- package/dist/repo-ops/builtin.d.ts +23 -0
- package/dist/repo-ops/builtin.d.ts.map +1 -1
- package/dist/repo-ops/builtin.js +186 -1
- package/dist/repo-ops/builtin.js.map +1 -1
- package/dist/repo-ops/readServiceSpec.d.ts +5 -0
- package/dist/repo-ops/readServiceSpec.d.ts.map +1 -0
- package/dist/repo-ops/readServiceSpec.js +174 -0
- package/dist/repo-ops/readServiceSpec.js.map +1 -0
- package/dist/repo-ops/render.d.ts +45 -0
- package/dist/repo-ops/render.d.ts.map +1 -1
- package/dist/repo-ops/render.js +145 -10
- package/dist/repo-ops/render.js.map +1 -1
- package/package.json +6 -5
package/dist/repo-ops/builtin.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { BLUEPRINT_DIR, BLUEPRINT_VERSION_PATH, SPEC_DIR, SPEC_FEATURES_DIR, SPEC_MODULES_DIR, } from '@cat-factory/contracts';
|
|
2
|
-
import { coerceBlueprintService, coerceSpecDoc, hashBlueprint, nextBlueprintVersion, renderBlueprintFiles, renderBlueprintVersionFile, renderSpecFeatureFiles, renderSpecFiles, } from './render.js';
|
|
2
|
+
import { asString, clearAspirationalTag, coerceBlueprintService, coerceSpecDoc, hashBlueprint, nextBlueprintVersion, promoteRequirementStates, renderBlueprintFiles, renderBlueprintVersionFile, renderSpecFeatureFiles, renderSpecFiles, } from './render.js';
|
|
3
|
+
import { readServiceSpec } from './readServiceSpec.js';
|
|
3
4
|
// ---------------------------------------------------------------------------
|
|
4
5
|
// BUILT-IN post-ops: the deterministic render + commit of the in-repo `blueprints/`
|
|
5
6
|
// (and, later, `spec/`) artifacts a migrated built-in agent produces.
|
|
@@ -208,4 +209,188 @@ export const specPostOp = async (ctx) => {
|
|
|
208
209
|
...(deletions.length > 0 ? { deletions } : {}),
|
|
209
210
|
});
|
|
210
211
|
};
|
|
212
|
+
// ---------------------------------------------------------------------------
|
|
213
|
+
// BUILT-IN post-op: tester-driven PROMOTION of the in-repo spec's implementation state.
|
|
214
|
+
//
|
|
215
|
+
// `spec/` is prescriptive — it says what must be TRUE — and `requirementItem.state` is what
|
|
216
|
+
// lets it also say what is true YET. A newly written requirement is `aspirational`; a first
|
|
217
|
+
// OBSERVED pass promotes it to `established`, which is what makes it standing behaviour for
|
|
218
|
+
// every later build and test prompt.
|
|
219
|
+
//
|
|
220
|
+
// SEAM CHOICE — this post-op, NOT the spec-writer's own update pass. The spec-writer runs
|
|
221
|
+
// near the front of every pipeline (0–1 steps behind the requirements gate) while the tester
|
|
222
|
+
// runs near the back, so by the time verdicts exist this run's writer has long finished:
|
|
223
|
+
// routing promotion through it would defer every promotion to the NEXT run (which may never
|
|
224
|
+
// come) and would hand a deterministic, evidence-backed state change to a model that cannot
|
|
225
|
+
// see the evidence. Promotion is mechanical, so it belongs in deterministic backend TS over
|
|
226
|
+
// the checkout-free RepoFiles port — the same shape `specPostOp` already uses.
|
|
227
|
+
//
|
|
228
|
+
// IDEMPOTENT BY CONTENT, which is the exact answer the durable driver needs: it re-reads the
|
|
229
|
+
// spec from the branch, recomputes the promoted tree and byte-compares. A REPLAY (or a re-test
|
|
230
|
+
// after a fixer round) reads an already-promoted spec, produces identical bytes and commits
|
|
231
|
+
// nothing. No marker row, no wall-clock guess.
|
|
232
|
+
// ---------------------------------------------------------------------------
|
|
233
|
+
/** The met requirement ids in a tester's structured report, or an empty set. */
|
|
234
|
+
function metRequirementIds(result) {
|
|
235
|
+
const report = result?.testReport;
|
|
236
|
+
if (!report || typeof report !== 'object')
|
|
237
|
+
return new Set();
|
|
238
|
+
const verdicts = report.requirementVerdicts;
|
|
239
|
+
if (!Array.isArray(verdicts))
|
|
240
|
+
return new Set();
|
|
241
|
+
const ids = new Set();
|
|
242
|
+
for (const raw of verdicts) {
|
|
243
|
+
if (!raw || typeof raw !== 'object')
|
|
244
|
+
continue;
|
|
245
|
+
const v = raw;
|
|
246
|
+
// ONLY `met` promotes. `not_covered` means nobody looked, and `not_met` means it does not
|
|
247
|
+
// hold — neither is evidence that the service honours the behaviour.
|
|
248
|
+
if (v.status !== 'met')
|
|
249
|
+
continue;
|
|
250
|
+
const id = asString(v.requirementId);
|
|
251
|
+
if (id)
|
|
252
|
+
ids.add(id);
|
|
253
|
+
}
|
|
254
|
+
return ids;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Whether a canonical path is a per-group JSON shard — `spec/modules/<module>/<group>.json`,
|
|
258
|
+
* the ONLY canonical file that stores requirements and rules. `_module.json` is the module's
|
|
259
|
+
* own identity, and `service.json` / `overview.md` are indexes.
|
|
260
|
+
*/
|
|
261
|
+
function isGroupShard(path) {
|
|
262
|
+
if (!path.startsWith(`${SPEC_MODULES_DIR}/`) || !path.endsWith('.json'))
|
|
263
|
+
return false;
|
|
264
|
+
const rest = path.slice(SPEC_MODULES_DIR.length + 1).split('/');
|
|
265
|
+
return rest.length === 2 && rest[1] !== '_module.json';
|
|
266
|
+
}
|
|
267
|
+
/** The requirement ids a RENDERED group shard carries (we produced it, so it always parses). */
|
|
268
|
+
function requirementIdsIn(content) {
|
|
269
|
+
const parsed = JSON.parse(content);
|
|
270
|
+
return (parsed.requirements ?? [])
|
|
271
|
+
.map((r) => asString(r?.id))
|
|
272
|
+
.filter((id) => id !== undefined);
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* The group shard whose data governs whether `path` may be rewritten: the shard itself, or —
|
|
276
|
+
* for the human-readable `spec/modules/<module>/<group>.md` render — the shard it is derived
|
|
277
|
+
* from. Null for files that carry no requirement data of their own.
|
|
278
|
+
*/
|
|
279
|
+
function governingGroupShard(path) {
|
|
280
|
+
if (isGroupShard(path))
|
|
281
|
+
return path;
|
|
282
|
+
if (path.startsWith(`${SPEC_MODULES_DIR}/`) && path.endsWith('.md')) {
|
|
283
|
+
const shard = `${path.slice(0, -'.md'.length)}.json`;
|
|
284
|
+
return isGroupShard(shard) ? shard : null;
|
|
285
|
+
}
|
|
286
|
+
return null;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* POST-OP for the tester kinds: promote every spec requirement the Tester OBSERVED to pass
|
|
290
|
+
* from `aspirational` to `established`, and commit the updated shards onto the run's branch.
|
|
291
|
+
*
|
|
292
|
+
* Reads the spec back from the branch (the tester's own result carries no spec), re-renders
|
|
293
|
+
* only the canonical shards, and surgically drops the now-stale `@aspirational` tag from the
|
|
294
|
+
* seed-once Gherkin files — never re-rendering those, so a pass-2 acceptance polish survives.
|
|
295
|
+
*
|
|
296
|
+
* NON-DESTRUCTIVE BY CONSTRUCTION. `readServiceSpec` is deliberately SALVAGING: a requirement
|
|
297
|
+
* or rule that fails validation (one field past a cap the lenient writer never enforced) is
|
|
298
|
+
* dropped so the rest of the tree survives the read. Re-rendering from that view would commit
|
|
299
|
+
* the drop — a state flip on one requirement silently deleting an unrelated one. So every
|
|
300
|
+
* GROUP SHARD is diffed against a BASELINE render taken BEFORE promotion: a shard whose
|
|
301
|
+
* committed bytes don't match its own baseline did not round-trip losslessly, so neither it,
|
|
302
|
+
* nor the markdown derived from it, nor the `@aspirational` tag of a requirement inside it is
|
|
303
|
+
* touched. A path the render would CREATE (a shifted collision suffix) is skipped rather than
|
|
304
|
+
* added beside the original — promotion never restructures the tree, it only flips a field.
|
|
305
|
+
*
|
|
306
|
+
* BEST-EFFORT: a throwing post-op fails its step, and promotion is bookkeeping — a spec that
|
|
307
|
+
* failed to promote must never turn a green tester run red. Every failure path is a silent
|
|
308
|
+
* no-op, exactly like the PR verification report's publish.
|
|
309
|
+
*/
|
|
310
|
+
export const specPromotionPostOp = async (ctx) => {
|
|
311
|
+
try {
|
|
312
|
+
const met = metRequirementIds(ctx.result);
|
|
313
|
+
if (met.size === 0)
|
|
314
|
+
return;
|
|
315
|
+
const view = await readServiceSpec(ctx.repo, ctx.branch);
|
|
316
|
+
if (!view.present || !view.spec)
|
|
317
|
+
return;
|
|
318
|
+
// Materialised BEFORE the in-place promotion below, so it captures the tree exactly as the
|
|
319
|
+
// read reconstructed it. A committed group shard that differs from this lost something on
|
|
320
|
+
// the way in, and must not be rewritten from it.
|
|
321
|
+
const baseline = new Map(renderSpecFiles(view.spec).map((f) => [f.path, f.content]));
|
|
322
|
+
const promoted = promoteRequirementStates(view.spec, met);
|
|
323
|
+
if (promoted.length === 0)
|
|
324
|
+
return;
|
|
325
|
+
// Re-render the canonical shards only. The seed-once feature files are NOT re-rendered
|
|
326
|
+
// (that would discard pass-2 polish); their stale tag is edited in place below.
|
|
327
|
+
const canonical = renderSpecFiles(view.spec);
|
|
328
|
+
const committed = new Map();
|
|
329
|
+
for (const f of canonical) {
|
|
330
|
+
const existing = await ctx.repo.getFile(f.path, ctx.branch);
|
|
331
|
+
committed.set(f.path, existing?.content ?? null);
|
|
332
|
+
}
|
|
333
|
+
// A group shard is SAFE when its committed bytes are either the pre-promotion baseline
|
|
334
|
+
// (it round-tripped losslessly) or the post-promotion render (a replay). Anything else
|
|
335
|
+
// means the read dropped or rewrote something, and neither that shard nor the markdown
|
|
336
|
+
// derived from it may be rewritten from the view.
|
|
337
|
+
const safeShards = new Set();
|
|
338
|
+
for (const f of canonical) {
|
|
339
|
+
if (!isGroupShard(f.path))
|
|
340
|
+
continue;
|
|
341
|
+
const existing = committed.get(f.path);
|
|
342
|
+
if (existing == null)
|
|
343
|
+
continue;
|
|
344
|
+
if (existing === baseline.get(f.path) || existing === f.content)
|
|
345
|
+
safeShards.add(f.path);
|
|
346
|
+
}
|
|
347
|
+
// The ids whose state change will actually LAND: those living in a safe shard. A
|
|
348
|
+
// requirement stranded in an unsafe one keeps both its `aspirational` shard entry and its
|
|
349
|
+
// `@aspirational` tag, so the two never disagree — clearing the tag alone would make a
|
|
350
|
+
// runner exercise a scenario the spec still calls unbuilt, the unsafe direction of the
|
|
351
|
+
// "a stale tag only ever costs a skip" trade.
|
|
352
|
+
const promotedSet = new Set(promoted);
|
|
353
|
+
const landed = new Set();
|
|
354
|
+
for (const f of canonical) {
|
|
355
|
+
if (!isGroupShard(f.path) || !safeShards.has(f.path))
|
|
356
|
+
continue;
|
|
357
|
+
for (const id of requirementIdsIn(f.content))
|
|
358
|
+
if (promotedSet.has(id))
|
|
359
|
+
landed.add(id);
|
|
360
|
+
}
|
|
361
|
+
if (landed.size === 0)
|
|
362
|
+
return;
|
|
363
|
+
const files = [];
|
|
364
|
+
for (const f of canonical) {
|
|
365
|
+
const existing = committed.get(f.path) ?? null;
|
|
366
|
+
// Absent ⇒ a path this render would CREATE; equal ⇒ already current (a replay).
|
|
367
|
+
if (existing === null || existing === f.content)
|
|
368
|
+
continue;
|
|
369
|
+
// Every other canonical file (`service.json`, `_module.json`, `overview.md`) is a pure
|
|
370
|
+
// index over data that lives in the shards, so rewriting it can lose nothing.
|
|
371
|
+
const shard = governingGroupShard(f.path);
|
|
372
|
+
if (shard && !safeShards.has(shard))
|
|
373
|
+
continue;
|
|
374
|
+
files.push(f);
|
|
375
|
+
}
|
|
376
|
+
// The feature files were already fetched by `readServiceSpec` — edit the content in hand
|
|
377
|
+
// rather than re-reading each one off the branch.
|
|
378
|
+
for (const feature of view.features) {
|
|
379
|
+
const updated = clearAspirationalTag(feature.content, landed);
|
|
380
|
+
if (updated !== feature.content)
|
|
381
|
+
files.push({ path: feature.path, content: updated });
|
|
382
|
+
}
|
|
383
|
+
// Nothing actually differs ⇒ a replay. Commit nothing.
|
|
384
|
+
if (files.length === 0)
|
|
385
|
+
return;
|
|
386
|
+
await ctx.repo.commitFiles({
|
|
387
|
+
branch: ctx.branch,
|
|
388
|
+
message: `Promote ${landed.size} verified requirement${landed.size === 1 ? '' : 's'} to established`,
|
|
389
|
+
files,
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
catch {
|
|
393
|
+
// Bookkeeping: never fail a tester step because the spec could not be promoted.
|
|
394
|
+
}
|
|
395
|
+
};
|
|
211
396
|
//# sourceMappingURL=builtin.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builtin.js","sourceRoot":"","sources":["../../src/repo-ops/builtin.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,sBAAsB,EAEtB,QAAQ,EACR,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,wBAAwB,CAAA;AAE/B,OAAO,EACL,sBAAsB,EACtB,aAAa,EACb,aAAa,EACb,oBAAoB,EAEpB,oBAAoB,EACpB,0BAA0B,EAC1B,sBAAsB,EACtB,eAAe,GAChB,MAAM,aAAa,CAAA;AAEpB,8EAA8E;AAC9E,oFAAoF;AACpF,sEAAsE;AACtE,EAAE;AACF,wFAAwF;AACxF,qFAAqF;AACrF,wFAAwF;AACxF,uFAAuF;AACvF,yFAAyF;AACzF,wFAAwF;AACxF,qFAAqF;AACrF,qEAAqE;AACrE,8EAA8E;AAE9E,wFAAwF;AACxF,SAAS,qBAAqB,CAAC,OAA2B;IACxD,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAA;IACzB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAA8B,CAAA;QAC/D,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAA;QACtF,OAAO;YACL,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,WAAW,EAAE,OAAO,MAAM,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE;YAC7E,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,OAAO,EAAE,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;SACjE,CAAA;IACH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,kBAAkB,CAAC,IAAe,EAAE,MAAc;IAC/D,MAAM,GAAG,GAAa,EAAE,CAAA;IACxB,KAAK,MAAM,KAAK,IAAI,MAAM,IAAI,CAAC,aAAa,CAAC,aAAa,EAAE,MAAM,CAAC,EAAE,CAAC;QACpE,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YACzB,KAAK,MAAM,GAAG,IAAI,MAAM,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;gBAC/D,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK;oBAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;YAC5C,CAAC;QACH,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QACtB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,eAAe,GAAW,KAAK,EAAE,GAAG,EAAE,EAAE;IACnD,mFAAmF;IACnF,yFAAyF;IACzF,2EAA2E;IAC3E,MAAM,OAAO,GAAG,sBAAsB,CAAC,GAAG,CAAC,MAAM,EAAE,gBAAgB,EAAE,EAAE,CAAC,CAAA;IACxE,IAAI,CAAC,OAAO;QAAE,OAAM;IAEpB,MAAM,QAAQ,GAAG,qBAAqB,CACpC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,sBAAsB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CACtE,CAAA;IACD,IAAI,QAAQ,IAAI,QAAQ,CAAC,IAAI,KAAK,CAAC,MAAM,aAAa,CAAC,OAAO,CAAC,CAAC;QAAE,OAAM;IAExE,MAAM,OAAO,GAAG,MAAM,oBAAoB,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC,CAAA;IACzE,MAAM,QAAQ,GAAG;QACf,GAAG,oBAAoB,CAAC,OAAO,CAAC;QAChC,MAAM,0BAA0B,CAAC,OAAO,EAAE,OAAO,CAAC;KACnD,CAAA;IACD,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;IACpD,MAAM,SAAS,GAAG,CAAC,MAAM,kBAAkB,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;IACjG,MAAM,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC;QACzB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,OAAO,EAAE,0BAA0B;QACnC,KAAK,EAAE,QAAQ;QACf,GAAG,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC/C,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,8EAA8E;AAC9E,0FAA0F;AAC1F,0FAA0F;AAC1F,6FAA6F;AAC7F,yFAAyF;AACzF,6FAA6F;AAC7F,8DAA8D;AAC9D,8EAA8E;AAE9E,gGAAgG;AAChG,MAAM,iBAAiB,GAAG;IACxB,GAAG,QAAQ,YAAY;IACvB,GAAG,QAAQ,WAAW;IACtB,GAAG,QAAQ,eAAe;CAC3B,CAAA;AAED;;;;;GAKG;AACH,KAAK,UAAU,mBAAmB,CAAC,IAAe,EAAE,MAAc;IAChE,MAAM,GAAG,GAAa,EAAE,CAAA;IACxB,KAAK,MAAM,KAAK,IAAI,MAAM,IAAI,CAAC,aAAa,CAAC,gBAAgB,EAAE,MAAM,CAAC,EAAE,CAAC;QACvE,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK;YAAE,SAAQ;QAClC,KAAK,MAAM,GAAG,IAAI,MAAM,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;YAC/D,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;gBACnF,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;YACpB,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,sBAAsB,CAAC,IAAe,EAAE,MAAc;IACnE,OAAO,CAAC,MAAM,IAAI,CAAC,aAAa,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;SACzD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;SAC9D,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;AACvB,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,UAAU,GAAW,KAAK,EAAE,GAAG,EAAE,EAAE;IAC9C,2EAA2E;IAC3E,mFAAmF;IACnF,wEAAwE;IACxE,IAAI,GAAG,CAAC,MAAM,EAAE,eAAe;QAAE,OAAM;IACvC,yFAAyF;IACzF,wFAAwF;IACxF,0FAA0F;IAC1F,2FAA2F;IAC3F,MAAM,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,CAAA;IAC/C,IAAI,CAAC,GAAG;QAAE,OAAM;IAEhB,MAAM,SAAS,GAAG,eAAe,CAAC,GAAG,CAAC,CAAA;IACtC,MAAM,QAAQ,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAA;IAE5C,6FAA6F;IAC7F,MAAM,cAAc,GAAmB,EAAE,CAAA;IACzC,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;YAAE,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC3E,CAAC;IAED,2FAA2F;IAC3F,6FAA6F;IAC7F,4FAA4F;IAC5F,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;IACrD,MAAM,OAAO,GAAG,CAAC,MAAM,mBAAmB,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;IAChG,MAAM,qBAAqB,GAAa,EAAE,CAAA;IAC1C,KAAK,MAAM,CAAC,IAAI,iBAAiB,EAAE,CAAC;QAClC,IAAI,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC;YAAE,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC1E,CAAC;IACD,MAAM,SAAS,GAAG;QAChB,GAAG,OAAO;QACV,GAAG,qBAAqB;QACxB,GAAG,CAAC,MAAM,sBAAsB,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;KACxD,CAAA;IAED,2FAA2F;IAC3F,wDAAwD;IACxD,IAAI,OAAO,GAAG,KAAK,CAAA;IACnB,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;QAC3D,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;YAChD,OAAO,GAAG,IAAI,CAAA;YACd,MAAK;QACP,CAAC;IACH,CAAC;IACD,IAAI,CAAC,OAAO,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAM;IAE7E,MAAM,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC;QACzB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,OAAO,EAAE,6BAA6B;QACtC,KAAK,EAAE,CAAC,GAAG,SAAS,EAAE,GAAG,cAAc,CAAC;QACxC,GAAG,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC/C,CAAC,CAAA;AACJ,CAAC,CAAA"}
|
|
1
|
+
{"version":3,"file":"builtin.js","sourceRoot":"","sources":["../../src/repo-ops/builtin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type ServiceSpecView } from '@cat-factory/contracts';
|
|
2
|
+
import type { RepoFiles } from '@cat-factory/kernel';
|
|
3
|
+
/** Read + reassemble the spec on `ref` (the repo default branch). Never throws. */
|
|
4
|
+
export declare function readServiceSpec(repo: RepoFiles, ref: string): Promise<ServiceSpecView>;
|
|
5
|
+
//# sourceMappingURL=readServiceSpec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readServiceSpec.d.ts","sourceRoot":"","sources":["../../src/repo-ops/readServiceSpec.ts"],"names":[],"mappings":"AAAA,OAAO,EAUL,KAAK,eAAe,EAIrB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,KAAK,EAAoB,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAmFtE,mFAAmF;AACnF,wBAAsB,eAAe,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAyF5F"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { EMPTY_SERVICE_SPEC_VIEW, SPEC_FEATURES_DIR, SPEC_MODULES_DIR, SPEC_SERVICE_PATH, safeParseDomainRule, safeParseRequirementGroup, safeParseRequirementItem, safeParseSpecModule, } from '@cat-factory/contracts';
|
|
2
|
+
import pMap from 'p-map';
|
|
3
|
+
// Reassemble the SHARDED `spec/` artifact into a single {@link ServiceSpecView} for the
|
|
4
|
+
// SPA, reading it checkout-free from the repo's default branch (main) via {@link RepoFiles}.
|
|
5
|
+
// The spec-writer harness writes the tree across many files (one canonical JSON shard per
|
|
6
|
+
// feature group, plus seeded Gherkin `.feature` files) so concurrent task branches merge
|
|
7
|
+
// cleanly; the slugs are filesystem-only (collision-suffixed, name-sorted), so the only way
|
|
8
|
+
// to recover the tree is to walk the directories — names live inside the shards, not the
|
|
9
|
+
// paths. This is the read-side mirror of the harness's `readExistingSpec`, over HTTP.
|
|
10
|
+
//
|
|
11
|
+
// Two resilience properties this reader guarantees, so the inspector never sees a 500 or a
|
|
12
|
+
// misleading "no spec" state:
|
|
13
|
+
// 1. Every repo read is total — a non-404 GitHub error (rate limit, 5xx, network) is
|
|
14
|
+
// treated as "missing" rather than thrown, so a flaky read degrades to a partial view
|
|
15
|
+
// instead of erroring the controller.
|
|
16
|
+
// 2. The tree is validated PER NODE, down to the individual requirement/rule — a malformed
|
|
17
|
+
// module shard is dropped without the rest of the tree, and a group shard is salvaged one
|
|
18
|
+
// requirement/rule at a time (so ONE field past a schema cap the lenient writer never
|
|
19
|
+
// enforced drops only that requirement, not the whole group with its valid siblings).
|
|
20
|
+
const EMPTY = EMPTY_SERVICE_SPEC_VIEW;
|
|
21
|
+
// Cap concurrent GitHub reads so a large spec doesn't fire a burst of dozens of parallel
|
|
22
|
+
// requests at once (GitHub flags high concurrency as secondary-rate-limit abuse). The reads
|
|
23
|
+
// are still parallel, just bounded.
|
|
24
|
+
const READ_CONCURRENCY = 12;
|
|
25
|
+
function parseJson(content) {
|
|
26
|
+
try {
|
|
27
|
+
return JSON.parse(content);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/** A trimmed non-empty string, else undefined — so a blank value falls back like a missing one. */
|
|
34
|
+
function nonEmptyString(value) {
|
|
35
|
+
return typeof value === 'string' && value.trim() !== '' ? value.trim() : undefined;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Parse one group shard, salvaging it PER REQUIREMENT/RULE. A strict whole-shard parse is
|
|
39
|
+
* tried first (the happy path). On failure — typically ONE field past a schema cap the
|
|
40
|
+
* lenient writer never enforces (e.g. a >120-char requirement title) — the group is rebuilt
|
|
41
|
+
* from its individually-validated requirements/rules, so one bad item drops only itself, not
|
|
42
|
+
* the whole group with its valid siblings. Returns undefined only when even the group's own
|
|
43
|
+
* identity (its name) is unrecoverable.
|
|
44
|
+
*/
|
|
45
|
+
function coerceGroupShard(value) {
|
|
46
|
+
const strict = safeParseRequirementGroup(value);
|
|
47
|
+
if (strict)
|
|
48
|
+
return strict;
|
|
49
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
50
|
+
return undefined;
|
|
51
|
+
const raw = value;
|
|
52
|
+
const requirements = (Array.isArray(raw.requirements) ? raw.requirements : [])
|
|
53
|
+
.map(safeParseRequirementItem)
|
|
54
|
+
.filter((r) => r !== undefined);
|
|
55
|
+
const rules = (Array.isArray(raw.rules) ? raw.rules : [])
|
|
56
|
+
.map(safeParseDomainRule)
|
|
57
|
+
.filter((r) => r !== undefined);
|
|
58
|
+
// Re-validate the rebuilt group: this enforces the group-level fields (name/summary) while
|
|
59
|
+
// the requirements/rules are already valid. A bad group name is unrecoverable ⇒ undefined.
|
|
60
|
+
return safeParseRequirementGroup({ ...raw, requirements, rules });
|
|
61
|
+
}
|
|
62
|
+
/** Read a file, treating ANY error (incl. non-404) as "missing" so the reader never throws. */
|
|
63
|
+
async function safeGetFile(repo, path, ref) {
|
|
64
|
+
try {
|
|
65
|
+
return await repo.getFile(path, ref);
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/** List a directory, treating ANY error as "empty" so the reader never throws. */
|
|
72
|
+
async function safeList(repo, path, ref) {
|
|
73
|
+
try {
|
|
74
|
+
return await repo.listDirectory(path, ref);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return [];
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/** Read + reassemble the spec on `ref` (the repo default branch). Never throws. */
|
|
81
|
+
export async function readServiceSpec(repo, ref) {
|
|
82
|
+
// The presence anchor: no readable object `spec/service.json` ⇒ no spec on this branch.
|
|
83
|
+
const serviceFile = await safeGetFile(repo, SPEC_SERVICE_PATH, ref);
|
|
84
|
+
if (!serviceFile)
|
|
85
|
+
return EMPTY;
|
|
86
|
+
const parsedService = parseJson(serviceFile.content);
|
|
87
|
+
// A non-object anchor (null / array / scalar) is a half-written or corrupt file — treat as
|
|
88
|
+
// "no spec" rather than reading garbage downstream.
|
|
89
|
+
if (!parsedService || typeof parsedService !== 'object' || Array.isArray(parsedService)) {
|
|
90
|
+
return EMPTY;
|
|
91
|
+
}
|
|
92
|
+
const service = parsedService;
|
|
93
|
+
// Walk `spec/modules/<moduleSlug>/` — each dir is one module, name-sorted by the writer.
|
|
94
|
+
const moduleDirs = (await safeList(repo, SPEC_MODULES_DIR, ref)).filter((e) => e.type === 'dir');
|
|
95
|
+
const moduleSlugToName = new Map();
|
|
96
|
+
const groupSlugToName = new Map();
|
|
97
|
+
// Phase A: per module, read its `_module.json` (for the display name) and list its shards.
|
|
98
|
+
const moduleInfos = await pMap(moduleDirs, async (dir) => {
|
|
99
|
+
const slug = dir.name;
|
|
100
|
+
const [meta, entries] = await Promise.all([
|
|
101
|
+
safeGetFile(repo, `${dir.path}/_module.json`, ref),
|
|
102
|
+
safeList(repo, dir.path, ref),
|
|
103
|
+
]);
|
|
104
|
+
const metaObj = (meta ? parseJson(meta.content) : undefined);
|
|
105
|
+
// Fall back to the slug for a blank name too (not only a missing one): `??` keeps `""`,
|
|
106
|
+
// which then fails the module schema and would silently drop the whole module + its
|
|
107
|
+
// valid groups. A corrupt/half-written `_module.json` should degrade to the slug instead.
|
|
108
|
+
const moduleName = nonEmptyString(metaObj?.name) ?? slug;
|
|
109
|
+
moduleSlugToName.set(slug, moduleName);
|
|
110
|
+
// Every `*.json` except `_module.json` is one canonical group shard.
|
|
111
|
+
const shards = entries.filter((e) => e.type === 'file' && e.name.endsWith('.json') && e.name !== '_module.json');
|
|
112
|
+
return { slug, moduleName, summary: metaObj?.summary ?? '', shards };
|
|
113
|
+
}, { concurrency: READ_CONCURRENCY });
|
|
114
|
+
// Phase B: read every group shard across all modules through one bounded queue (this is the
|
|
115
|
+
// largest fan-out), then validate PER SHARD so a malformed group is dropped, not the tree.
|
|
116
|
+
const shardRefs = moduleInfos.flatMap((m) => m.shards.map((entry) => ({
|
|
117
|
+
moduleSlug: m.slug,
|
|
118
|
+
groupSlug: entry.name.replace(/\.json$/, ''),
|
|
119
|
+
entry,
|
|
120
|
+
})));
|
|
121
|
+
const shardContents = await pMap(shardRefs, async (s) => ({ ref: s, file: await safeGetFile(repo, s.entry.path, ref) }), { concurrency: READ_CONCURRENCY });
|
|
122
|
+
const groupsByModule = new Map();
|
|
123
|
+
for (const { ref: s, file } of shardContents) {
|
|
124
|
+
const group = file ? coerceGroupShard(parseJson(file.content)) : undefined;
|
|
125
|
+
if (!group)
|
|
126
|
+
continue;
|
|
127
|
+
groupSlugToName.set(`${s.moduleSlug}/${s.groupSlug}`, group.name);
|
|
128
|
+
const list = groupsByModule.get(s.moduleSlug) ?? [];
|
|
129
|
+
list.push(group);
|
|
130
|
+
groupsByModule.set(s.moduleSlug, list);
|
|
131
|
+
}
|
|
132
|
+
const modules = moduleInfos
|
|
133
|
+
.map((m) => safeParseSpecModule({
|
|
134
|
+
name: m.moduleName,
|
|
135
|
+
summary: m.summary,
|
|
136
|
+
groups: groupsByModule.get(m.slug) ?? [],
|
|
137
|
+
}))
|
|
138
|
+
.filter((m) => m !== undefined);
|
|
139
|
+
// Build the doc from the per-node-validated pieces directly, so a missing/empty service
|
|
140
|
+
// name (the SPA falls back to the block title) degrades to showing the modules rather than
|
|
141
|
+
// blanking the whole view.
|
|
142
|
+
const spec = {
|
|
143
|
+
service: typeof service.service === 'string' ? service.service : '',
|
|
144
|
+
summary: typeof service.summary === 'string' ? service.summary : '',
|
|
145
|
+
modules,
|
|
146
|
+
};
|
|
147
|
+
const features = await readFeatureFiles(repo, ref, moduleSlugToName, groupSlugToName);
|
|
148
|
+
return { present: true, spec, features };
|
|
149
|
+
}
|
|
150
|
+
/** Read the seeded Gherkin `.feature` files under `spec/features/<module>/<group>.feature`. */
|
|
151
|
+
async function readFeatureFiles(repo, ref, moduleSlugToName, groupSlugToName) {
|
|
152
|
+
const moduleDirs = (await safeList(repo, SPEC_FEATURES_DIR, ref)).filter((e) => e.type === 'dir');
|
|
153
|
+
const perModule = await pMap(moduleDirs, async (dir) => {
|
|
154
|
+
const entries = await safeList(repo, dir.path, ref);
|
|
155
|
+
return entries
|
|
156
|
+
.filter((e) => e.type === 'file' && e.name.endsWith('.feature'))
|
|
157
|
+
.map((entry) => ({ slug: dir.name, entry }));
|
|
158
|
+
}, { concurrency: READ_CONCURRENCY });
|
|
159
|
+
const featureRefs = perModule.flat();
|
|
160
|
+
const read = await pMap(featureRefs, async (fr) => {
|
|
161
|
+
const file = await safeGetFile(repo, fr.entry.path, ref);
|
|
162
|
+
if (!file)
|
|
163
|
+
return null;
|
|
164
|
+
const groupSlug = fr.entry.name.replace(/\.feature$/, '');
|
|
165
|
+
return {
|
|
166
|
+
module: moduleSlugToName.get(fr.slug) ?? fr.slug,
|
|
167
|
+
group: groupSlugToName.get(`${fr.slug}/${groupSlug}`) ?? groupSlug,
|
|
168
|
+
path: fr.entry.path,
|
|
169
|
+
content: file.content,
|
|
170
|
+
};
|
|
171
|
+
}, { concurrency: READ_CONCURRENCY });
|
|
172
|
+
return read.filter((x) => x !== null);
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=readServiceSpec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readServiceSpec.js","sourceRoot":"","sources":["../../src/repo-ops/readServiceSpec.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,yBAAyB,EACzB,wBAAwB,EACxB,mBAAmB,GAMpB,MAAM,wBAAwB,CAAA;AAE/B,OAAO,IAAI,MAAM,OAAO,CAAA;AAExB,wFAAwF;AACxF,6FAA6F;AAC7F,0FAA0F;AAC1F,yFAAyF;AACzF,4FAA4F;AAC5F,yFAAyF;AACzF,sFAAsF;AACtF,EAAE;AACF,2FAA2F;AAC3F,8BAA8B;AAC9B,uFAAuF;AACvF,2FAA2F;AAC3F,2CAA2C;AAC3C,6FAA6F;AAC7F,+FAA+F;AAC/F,2FAA2F;AAC3F,2FAA2F;AAE3F,MAAM,KAAK,GAAG,uBAAuB,CAAA;AAErC,yFAAyF;AACzF,4FAA4F;AAC5F,oCAAoC;AACpC,MAAM,gBAAgB,GAAG,EAAE,CAAA;AAE3B,SAAS,SAAS,CAAC,OAAe;IAChC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC;AAED,mGAAmG;AACnG,SAAS,cAAc,CAAC,KAAc;IACpC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAA;AACpF,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,gBAAgB,CAAC,KAAc;IACtC,MAAM,MAAM,GAAG,yBAAyB,CAAC,KAAK,CAAC,CAAA;IAC/C,IAAI,MAAM;QAAE,OAAO,MAAM,CAAA;IACzB,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAA;IACjF,MAAM,GAAG,GAAG,KAAoD,CAAA;IAChE,MAAM,YAAY,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;SAC3E,GAAG,CAAC,wBAAwB,CAAC;SAC7B,MAAM,CAAC,CAAC,CAAC,EAA8B,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CAAA;IAC7D,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;SACtD,GAAG,CAAC,mBAAmB,CAAC;SACxB,MAAM,CAAC,CAAC,CAAC,EAA8B,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CAAA;IAC7D,2FAA2F;IAC3F,2FAA2F;IAC3F,OAAO,yBAAyB,CAAC,EAAE,GAAG,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAA;AACnE,CAAC;AAED,+FAA+F;AAC/F,KAAK,UAAU,WAAW,CAAC,IAAe,EAAE,IAAY,EAAE,GAAW;IACnE,IAAI,CAAC;QACH,OAAO,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED,kFAAkF;AAClF,KAAK,UAAU,QAAQ,CAAC,IAAe,EAAE,IAAY,EAAE,GAAW;IAChE,IAAI,CAAC;QACH,OAAO,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAA;IACX,CAAC;AACH,CAAC;AAED,mFAAmF;AACnF,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAAe,EAAE,GAAW;IAChE,wFAAwF;IACxF,MAAM,WAAW,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,iBAAiB,EAAE,GAAG,CAAC,CAAA;IACnE,IAAI,CAAC,WAAW;QAAE,OAAO,KAAK,CAAA;IAC9B,MAAM,aAAa,GAAG,SAAS,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;IACpD,2FAA2F;IAC3F,oDAAoD;IACpD,IAAI,CAAC,aAAa,IAAI,OAAO,aAAa,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;QACxF,OAAO,KAAK,CAAA;IACd,CAAC;IACD,MAAM,OAAO,GAAG,aAAuD,CAAA;IAEvE,yFAAyF;IACzF,MAAM,UAAU,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,gBAAgB,EAAE,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,CAAA;IAChG,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAkB,CAAA;IAClD,MAAM,eAAe,GAAG,IAAI,GAAG,EAAkB,CAAA;IAEjD,2FAA2F;IAC3F,MAAM,WAAW,GAAG,MAAM,IAAI,CAC5B,UAAU,EACV,KAAK,EAAE,GAAG,EAAE,EAAE;QACZ,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAA;QACrB,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YACxC,WAAW,CAAC,IAAI,EAAE,GAAG,GAAG,CAAC,IAAI,eAAe,EAAE,GAAG,CAAC;YAClD,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC;SAC9B,CAAC,CAAA;QACF,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAE9C,CAAA;QACb,wFAAwF;QACxF,oFAAoF;QACpF,0FAA0F;QAC1F,MAAM,UAAU,GAAG,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,IAAI,CAAA;QACxD,gBAAgB,CAAC,GAAG,CAAC,IAAI,EAAE,UAAU,CAAC,CAAA;QACtC,qEAAqE;QACrE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAC3B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,cAAc,CAClF,CAAA;QACD,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,IAAI,EAAE,EAAE,MAAM,EAAE,CAAA;IACtE,CAAC,EACD,EAAE,WAAW,EAAE,gBAAgB,EAAE,CAClC,CAAA;IAED,4FAA4F;IAC5F,2FAA2F;IAC3F,MAAM,SAAS,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAC1C,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACvB,UAAU,EAAE,CAAC,CAAC,IAAI;QAClB,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;QAC5C,KAAK;KACN,CAAC,CAAC,CACJ,CAAA;IACD,MAAM,aAAa,GAAG,MAAM,IAAI,CAC9B,SAAS,EACT,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,EAC3E,EAAE,WAAW,EAAE,gBAAgB,EAAE,CAClC,CAAA;IACD,MAAM,cAAc,GAAG,IAAI,GAAG,EAA8B,CAAA;IAC5D,KAAK,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,aAAa,EAAE,CAAC;QAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;QAC1E,IAAI,CAAC,KAAK;YAAE,SAAQ;QACpB,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;QACjE,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,CAAA;QACnD,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAChB,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,EAAE,IAAI,CAAC,CAAA;IACxC,CAAC;IAED,MAAM,OAAO,GAAG,WAAW;SACxB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACT,mBAAmB,CAAC;QAClB,IAAI,EAAE,CAAC,CAAC,UAAU;QAClB,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,MAAM,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE;KACzC,CAAC,CACH;SACA,MAAM,CAAC,CAAC,CAAC,EAAmB,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CAAA;IAElD,wFAAwF;IACxF,2FAA2F;IAC3F,2BAA2B;IAC3B,MAAM,IAAI,GAAY;QACpB,OAAO,EAAE,OAAO,OAAO,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;QACnE,OAAO,EAAE,OAAO,OAAO,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;QACnE,OAAO;KACR,CAAA;IAED,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,IAAI,EAAE,GAAG,EAAE,gBAAgB,EAAE,eAAe,CAAC,CAAA;IAErF,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAA;AAC1C,CAAC;AAED,+FAA+F;AAC/F,KAAK,UAAU,gBAAgB,CAC7B,IAAe,EACf,GAAW,EACX,gBAAqC,EACrC,eAAoC;IAEpC,MAAM,UAAU,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,iBAAiB,EAAE,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,CAAA;IACjG,MAAM,SAAS,GAAG,MAAM,IAAI,CAC1B,UAAU,EACV,KAAK,EAAE,GAAG,EAAE,EAAE;QACZ,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QACnD,OAAO,OAAO;aACX,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;aAC/D,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAA;IAChD,CAAC,EACD,EAAE,WAAW,EAAE,gBAAgB,EAAE,CAClC,CAAA;IACD,MAAM,WAAW,GAAG,SAAS,CAAC,IAAI,EAAE,CAAA;IACpC,MAAM,IAAI,GAAG,MAAM,IAAI,CACrB,WAAW,EACX,KAAK,EAAE,EAAE,EAAmC,EAAE;QAC5C,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QACxD,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAA;QACtB,MAAM,SAAS,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAA;QACzD,OAAO;YACL,MAAM,EAAE,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI;YAChD,KAAK,EAAE,eAAe,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,SAAS,EAAE,CAAC,IAAI,SAAS;YAClE,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI;YACnB,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAA;IACH,CAAC,EACD,EAAE,WAAW,EAAE,gBAAgB,EAAE,CAClC,CAAA;IACD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAwB,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAA;AAC7D,CAAC"}
|
|
@@ -58,6 +58,35 @@ export declare function dedupeSpecIds(doc: SpecDoc): void;
|
|
|
58
58
|
* for old on-disk specs). The strict `parseSpecDoc` re-validates the returned doc.
|
|
59
59
|
*/
|
|
60
60
|
export declare function coerceSpecDoc(parsed: unknown, fallbackName: string): SpecDoc | null;
|
|
61
|
+
/**
|
|
62
|
+
* Flip every requirement whose id is in `metIds` from `aspirational` to `established`, in
|
|
63
|
+
* place, and return the ids actually promoted (already-`established` ones are NOT re-reported,
|
|
64
|
+
* so a caller can tell a no-op replay from real work).
|
|
65
|
+
*
|
|
66
|
+
* Promotion is ONE-WAY here on purpose. A tester that did not exercise a requirement this run
|
|
67
|
+
* reports `not_covered`, and a run whose blast radius never touched a behaviour must not
|
|
68
|
+
* demote it — otherwise every unrelated PR would silently strip the service's standing
|
|
69
|
+
* behaviour back to nothing. A genuine regression is a `not_met` on an ESTABLISHED
|
|
70
|
+
* requirement, which is a failing test the run has to answer for, not a spec edit.
|
|
71
|
+
*/
|
|
72
|
+
export declare function promoteRequirementStates(doc: SpecDoc, metIds: Iterable<string>): string[];
|
|
73
|
+
/**
|
|
74
|
+
* Drop the `@aspirational` tag from the scenarios of `promotedIds` in one already-committed
|
|
75
|
+
* `.feature` file, returning the new content (or the input unchanged when nothing matched).
|
|
76
|
+
*
|
|
77
|
+
* A SURGICAL edit rather than a re-render, because feature files are SEED-ONCE: the spec
|
|
78
|
+
* post-op writes one only when absent, so a later pass-2 acceptance polish survives a re-run.
|
|
79
|
+
* Re-rendering to refresh a tag would throw that polish away. Anchored on the
|
|
80
|
+
* `# requirement: <id>` comment the render emits directly ABOVE each scenario's tag line
|
|
81
|
+
* (see {@link renderSpecFeatureFiles} for why the comment leads rather than sits between the
|
|
82
|
+
* tags and the `Scenario:` keyword).
|
|
83
|
+
*
|
|
84
|
+
* Degrades to a no-op when a polished file no longer carries the anchor comment or the tag
|
|
85
|
+
* line: the JSON shard stays the single source of truth for state, and the tag is a runner
|
|
86
|
+
* convenience — a stale tag makes a runner skip a scenario it could have run, which is
|
|
87
|
+
* strictly safer than the reverse.
|
|
88
|
+
*/
|
|
89
|
+
export declare function clearAspirationalTag(content: string, promotedIds: Iterable<string>): string;
|
|
61
90
|
/**
|
|
62
91
|
* Deterministically SHARD a spec doc into the in-repo artifact files: a tiny
|
|
63
92
|
* `service.json`, an `overview.md` index (modules → features with links), a
|
|
@@ -73,6 +102,22 @@ export declare function renderSpecFiles(doc: SpecDoc): RenderedFile[];
|
|
|
73
102
|
* requirement's scenarios are tagged `@must`. The `acceptance` agent later polishes
|
|
74
103
|
* these (pass 2). Groups with no acceptance criteria produce no feature file. The caller
|
|
75
104
|
* seeds these once (writes only when absent) so pass-2 polish survives a re-run.
|
|
105
|
+
*
|
|
106
|
+
* Two machine-readable anchors ride each scenario:
|
|
107
|
+
* - `@aspirational` tags a scenario whose requirement is NOT yet observed to hold, so a
|
|
108
|
+
* runner can skip it (`--tags 'not @aspirational'`) instead of reporting a not-yet-built
|
|
109
|
+
* behaviour as a failure on every unrelated run.
|
|
110
|
+
* - A `# requirement: <id>` comment carries the SPEC REQUIREMENT ID — the key the Tester
|
|
111
|
+
* reports its per-requirement verdicts under, and the join key the PR verification report
|
|
112
|
+
* uses to pair a criterion with its evidence. It is a comment rather than a tag because a
|
|
113
|
+
* Gherkin tag is a bare word: an arbitrary requirement id (dots, colons, slashes from a
|
|
114
|
+
* model-supplied `id`) is not safely expressible as one, and a mangled tag would silently
|
|
115
|
+
* break the join.
|
|
116
|
+
*
|
|
117
|
+
* The comment LEADS the tag line rather than sitting between the tags and `Scenario:`. Tags
|
|
118
|
+
* attach to the keyword that follows them, and parsers differ on whether a comment may
|
|
119
|
+
* interrupt that pair; leading it keeps the tag line adjacent to its scenario under every
|
|
120
|
+
* Gherkin dialect. {@link clearAspirationalTag} depends on this order.
|
|
76
121
|
*/
|
|
77
122
|
export declare function renderSpecFeatureFiles(doc: SpecDoc): RenderedFile[];
|
|
78
123
|
//# sourceMappingURL=render.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/repo-ops/render.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/repo-ops/render.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EAOrB,KAAK,OAAO,EAUb,MAAM,wBAAwB,CAAA;AAkB/B,4DAA4D;AAC5D,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,gGAAgG;AAChG,wBAAsB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAG9D;AAED,gFAAgF;AAChF,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAE3D;AA+CD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,OAAO,EACf,YAAY,EAAE,MAAM,GACnB,gBAAgB,GAAG,IAAI,CAqBzB;AAED,qFAAqF;AACrF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM/C;AAED,+EAA+E;AAC/E,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,CAExE;AAED,oFAAoF;AACpF,wBAAgB,aAAa,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAExE;AAED,oEAAoE;AACpE,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE,gBAAgB,EACzB,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAC7C,OAAO,CAAC,YAAY,CAAC,CAQvB;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,gBAAgB,GAAG,IAAI,EACjC,GAAG,EAAE,IAAI,GACR,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CAKnD;AAOD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,gBAAgB,GAAG,YAAY,EAAE,CAqC9E;AAwJD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAkBhD;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CA0BnF;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE,CAezF;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM,CAyB3F;AAsID;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,YAAY,EAAE,CAyD5D;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,YAAY,EAAE,CAkCnE"}
|