@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.
@@ -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":"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"}
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":"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"}
@@ -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,EAMrB,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;AA+ID;;;;;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;AAmGD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,YAAY,EAAE,CAyD5D;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,YAAY,EAAE,CA4BnE"}
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"}