opencode-swarm 7.121.1 → 7.121.3

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.
Files changed (34) hide show
  1. package/dist/cli/{curation-policy-re2kaysb.js → curation-policy-10wnhpwn.js} +2 -2
  2. package/dist/cli/{curator-tesgq6ye.js → curator-ed91r7rw.js} +10 -10
  3. package/dist/cli/{curator-llm-factory-jkbachdb.js → curator-llm-factory-q9veqj3h.js} +10 -10
  4. package/dist/cli/{evidence-summary-service-jtx5q3r6.js → evidence-summary-service-k14ykm03.js} +2 -2
  5. package/dist/cli/{guardrail-explain-hqz48re6.js → guardrail-explain-0vcaa7hj.js} +11 -11
  6. package/dist/cli/{hive-promoter-4vfe1rcs.js → hive-promoter-dg6fk563.js} +10 -10
  7. package/dist/cli/{index-rywkdacj.js → index-0f800qg7.js} +3 -3
  8. package/dist/cli/{index-nhgw7de8.js → index-35xyj7gn.js} +1 -1
  9. package/dist/cli/{index-69ms9ny1.js → index-5a3xsnzg.js} +1 -1
  10. package/dist/cli/{index-3366gs26.js → index-db82jxt7.js} +2 -2
  11. package/dist/cli/{index-j5xv8zbp.js → index-emkb0bbe.js} +1 -1
  12. package/dist/cli/{index-e7yqazk3.js → index-fs2q8jyf.js} +236 -229
  13. package/dist/cli/{index-0k4r8111.js → index-ft6jw816.js} +4 -4
  14. package/dist/cli/{index-k7gvykn4.js → index-g9eg7z93.js} +11 -11
  15. package/dist/cli/{index-0e1v02hq.js → index-j8349ac0.js} +1 -1
  16. package/dist/cli/{index-8cp19x15.js → index-qad0m9bz.js} +1 -1
  17. package/dist/cli/{index-0mbmfmt0.js → index-qt2yaghg.js} +2 -1
  18. package/dist/cli/{index-fndvr7fr.js → index-rbfq77sz.js} +1 -1
  19. package/dist/cli/{index-78b192v7.js → index-x4fwtd59.js} +3 -3
  20. package/dist/cli/index.js +10 -10
  21. package/dist/cli/{knowledge-escalator-0ejqs8c9.js → knowledge-escalator-8ajq1fhb.js} +3 -3
  22. package/dist/cli/{knowledge-events-wx9e37ba.js → knowledge-events-2sjy3aa7.js} +1 -1
  23. package/dist/cli/{knowledge-store-rnajx33a.js → knowledge-store-27cesthc.js} +1 -1
  24. package/dist/cli/{knowledge-validator-1f4mkzmc.js → knowledge-validator-9keh3p8j.js} +4 -4
  25. package/dist/cli/{scan-cursor-qapm0sxj.js → scan-cursor-qmsmmg1b.js} +2 -2
  26. package/dist/cli/{skill-generator-tkv7s12g.js → skill-generator-hkyxdc3j.js} +5 -5
  27. package/dist/commands/design-docs.d.ts +4 -0
  28. package/dist/commands/pr-feedback.d.ts +6 -6
  29. package/dist/config/plan-schema.d.ts +3 -0
  30. package/dist/hooks/delegation-gate.d.ts +115 -0
  31. package/dist/hooks/knowledge-curator.d.ts +4 -4
  32. package/dist/index.js +166 -156
  33. package/dist/tools/save-plan.d.ts +2 -0
  34. package/package.json +1 -1
@@ -6,13 +6,13 @@ import {
6
6
  resolveSwarmKnowledgePath,
7
7
  transactKnowledge,
8
8
  wordBigrams
9
- } from "./index-rywkdacj.js";
9
+ } from "./index-0f800qg7.js";
10
10
  import {
11
11
  countEntryContradictionsInWindow,
12
12
  countEntryViolationsInWindow,
13
13
  readKnowledgeEvents,
14
14
  recordKnowledgeEvent
15
- } from "./index-nhgw7de8.js";
15
+ } from "./index-35xyj7gn.js";
16
16
  import {
17
17
  isActiveStatus
18
18
  } from "./index-4rhcth7a.js";
@@ -188,11 +188,11 @@ async function maybeQuarantineOnContradiction(directory, entryId, threshold, win
188
188
  alreadyInactive: true
189
189
  };
190
190
  }
191
- const { quarantineEntry } = await import("./knowledge-validator-1f4mkzmc.js");
191
+ const { quarantineEntry } = await import("./knowledge-validator-9keh3p8j.js");
192
192
  let policyConfig;
193
193
  try {
194
194
  const { KnowledgeConfigSchema } = await import("./schema-vwxpsk6j.js");
195
- const { loadPluginConfigWithMeta } = await import("./index-fndvr7fr.js");
195
+ const { loadPluginConfigWithMeta } = await import("./index-rbfq77sz.js");
196
196
  const { config: loadedConfig } = loadPluginConfigWithMeta(directory);
197
197
  policyConfig = KnowledgeConfigSchema.parse(loadedConfig.knowledge ?? {});
198
198
  } catch {
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  handleGuardrailExplain
4
- } from "./index-8cp19x15.js";
4
+ } from "./index-qad0m9bz.js";
5
5
  import {
6
6
  handleGuardrailLog
7
7
  } from "./index-zvae4m8g.js";
@@ -83,28 +83,28 @@ import {
83
83
  handleWriteRetroCommand,
84
84
  normalizeSwarmCommandInput,
85
85
  resolveCommand
86
- } from "./index-e7yqazk3.js";
86
+ } from "./index-fs2q8jyf.js";
87
87
  import"./index-kyvg2cmp.js";
88
88
  import"./index-vqcgmy4y.js";
89
- import"./index-j5xv8zbp.js";
89
+ import"./index-emkb0bbe.js";
90
90
  import"./index-4905hd2m.js";
91
91
  import"./index-nprawcc0.js";
92
- import"./index-78b192v7.js";
93
- import"./index-0k4r8111.js";
94
- import"./index-0e1v02hq.js";
92
+ import"./index-x4fwtd59.js";
93
+ import"./index-ft6jw816.js";
94
+ import"./index-j8349ac0.js";
95
95
  import"./index-vxv732ex.js";
96
96
  import"./index-c8s9a3zh.js";
97
97
  import"./index-816rkp4y.js";
98
98
  import"./index-22e127jw.js";
99
- import"./index-3366gs26.js";
100
- import"./index-69ms9ny1.js";
99
+ import"./index-db82jxt7.js";
100
+ import"./index-5a3xsnzg.js";
101
101
  import"./index-rtry5xyf.js";
102
- import"./index-rywkdacj.js";
103
- import"./index-nhgw7de8.js";
102
+ import"./index-0f800qg7.js";
103
+ import"./index-35xyj7gn.js";
104
104
  import"./index-ae75rja9.js";
105
105
  import"./index-3jvqw5hy.js";
106
106
  import"./index-9xpgytj9.js";
107
- import"./index-0mbmfmt0.js";
107
+ import"./index-qt2yaghg.js";
108
108
  import"./index-gnp9x6se.js";
109
109
  import {
110
110
  AGENT_TOOL_MAP,
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  readKnowledge,
4
4
  transactKnowledge
5
- } from "./index-rywkdacj.js";
5
+ } from "./index-0f800qg7.js";
6
6
  import {
7
7
  resolveKnowledgeStoreDir
8
8
  } from "./index-3jvqw5hy.js";
@@ -12,7 +12,7 @@ import {
12
12
  detectPosixWrites,
13
13
  detectWindowsWrites,
14
14
  resolveWriteTargets
15
- } from "./index-e7yqazk3.js";
15
+ } from "./index-fs2q8jyf.js";
16
16
  import {
17
17
  checkFileAuthority,
18
18
  classifyFile,
@@ -42,7 +42,8 @@ var TaskSchema = exports_external.object({
42
42
  acceptance: exports_external.string().optional(),
43
43
  files_touched: exports_external.array(exports_external.string()).default([]),
44
44
  evidence_path: exports_external.string().optional(),
45
- blocked_reason: exports_external.string().optional()
45
+ blocked_reason: exports_external.string().optional(),
46
+ fr_refs: exports_external.array(exports_external.string()).optional()
46
47
  });
47
48
  var PhaseSchema = exports_external.object({
48
49
  id: exports_external.number().int().min(1),
@@ -28,7 +28,7 @@ import {
28
28
  TaskSizeSchema,
29
29
  TaskStatusSchema,
30
30
  TestEvidenceSchema
31
- } from "./index-0mbmfmt0.js";
31
+ } from "./index-qt2yaghg.js";
32
32
  import {
33
33
  DeltaSpecSchema,
34
34
  ObligationSchema,
@@ -2,18 +2,18 @@
2
2
  import {
3
3
  ALLOWED_SKILL_PATH_PREFIXES,
4
4
  validateSkillPath
5
- } from "./index-3366gs26.js";
5
+ } from "./index-db82jxt7.js";
6
6
  import {
7
7
  computeOutcomeSignal,
8
8
  readKnowledge,
9
9
  resolveHiveKnowledgePath,
10
10
  resolveSwarmKnowledgePath,
11
11
  transactKnowledge
12
- } from "./index-rywkdacj.js";
12
+ } from "./index-0f800qg7.js";
13
13
  import {
14
14
  effectiveRetrievalOutcomes,
15
15
  readKnowledgeCounterRollups
16
- } from "./index-nhgw7de8.js";
16
+ } from "./index-35xyj7gn.js";
17
17
  import {
18
18
  isActiveStatus
19
19
  } from "./index-4rhcth7a.js";
package/dist/cli/index.js CHANGED
@@ -7,28 +7,28 @@ import {
7
7
  getPluginLockFilePaths,
8
8
  package_default,
9
9
  resolveCommand
10
- } from "./index-e7yqazk3.js";
10
+ } from "./index-fs2q8jyf.js";
11
11
  import"./index-kyvg2cmp.js";
12
12
  import"./index-vqcgmy4y.js";
13
- import"./index-j5xv8zbp.js";
13
+ import"./index-emkb0bbe.js";
14
14
  import"./index-4905hd2m.js";
15
15
  import"./index-nprawcc0.js";
16
- import"./index-78b192v7.js";
17
- import"./index-0k4r8111.js";
18
- import"./index-0e1v02hq.js";
16
+ import"./index-x4fwtd59.js";
17
+ import"./index-ft6jw816.js";
18
+ import"./index-j8349ac0.js";
19
19
  import"./index-vxv732ex.js";
20
20
  import"./index-c8s9a3zh.js";
21
21
  import"./index-816rkp4y.js";
22
22
  import"./index-22e127jw.js";
23
- import"./index-3366gs26.js";
24
- import"./index-69ms9ny1.js";
23
+ import"./index-db82jxt7.js";
24
+ import"./index-5a3xsnzg.js";
25
25
  import"./index-rtry5xyf.js";
26
- import"./index-rywkdacj.js";
27
- import"./index-nhgw7de8.js";
26
+ import"./index-0f800qg7.js";
27
+ import"./index-35xyj7gn.js";
28
28
  import"./index-ae75rja9.js";
29
29
  import"./index-3jvqw5hy.js";
30
30
  import"./index-9xpgytj9.js";
31
- import"./index-0mbmfmt0.js";
31
+ import"./index-qt2yaghg.js";
32
32
  import"./index-gnp9x6se.js";
33
33
  import {
34
34
  DEFAULT_AGENT_CONFIGS
@@ -8,9 +8,9 @@ import {
8
8
  maybeEscalateOnViolation,
9
9
  maybeQuarantineOnContradiction,
10
10
  readRecentEscalations
11
- } from "./index-0k4r8111.js";
12
- import"./index-rywkdacj.js";
13
- import"./index-nhgw7de8.js";
11
+ } from "./index-ft6jw816.js";
12
+ import"./index-0f800qg7.js";
13
+ import"./index-35xyj7gn.js";
14
14
  import"./index-ae75rja9.js";
15
15
  import"./index-3jvqw5hy.js";
16
16
  import"./index-4rhcth7a.js";
@@ -25,7 +25,7 @@ import {
25
25
  resolveKnowledgeCounterBaselinePath,
26
26
  resolveKnowledgeEventsPath,
27
27
  resolveLegacyApplicationLogPath
28
- } from "./index-nhgw7de8.js";
28
+ } from "./index-35xyj7gn.js";
29
29
  import"./index-ae75rja9.js";
30
30
  import"./index-3jvqw5hy.js";
31
31
  import"./index-zgwm4ryv.js";
@@ -40,7 +40,7 @@ import {
40
40
  transactKnowledge,
41
41
  transactKnowledgeWithCas,
42
42
  wordBigrams
43
- } from "./index-rywkdacj.js";
43
+ } from "./index-0f800qg7.js";
44
44
  import {
45
45
  resolveHiveDataDir
46
46
  } from "./index-ae75rja9.js";
@@ -23,11 +23,11 @@ import {
23
23
  validateLesson,
24
24
  validateSkillCandidatePath,
25
25
  validateSkillPath
26
- } from "./index-3366gs26.js";
27
- import"./index-69ms9ny1.js";
26
+ } from "./index-db82jxt7.js";
27
+ import"./index-5a3xsnzg.js";
28
28
  import"./index-rtry5xyf.js";
29
- import"./index-rywkdacj.js";
30
- import"./index-nhgw7de8.js";
29
+ import"./index-0f800qg7.js";
30
+ import"./index-35xyj7gn.js";
31
31
  import"./index-ae75rja9.js";
32
32
  import"./index-3jvqw5hy.js";
33
33
  import"./index-4rhcth7a.js";
@@ -4,8 +4,8 @@ import {
4
4
  alreadyCuratedThisGeneration,
5
5
  claimNextScanBatch,
6
6
  getScanStatus
7
- } from "./index-0e1v02hq.js";
8
- import"./index-rywkdacj.js";
7
+ } from "./index-j8349ac0.js";
8
+ import"./index-0f800qg7.js";
9
9
  import"./index-ae75rja9.js";
10
10
  import"./index-3jvqw5hy.js";
11
11
  import"./index-4rhcth7a.js";
@@ -33,12 +33,12 @@ import {
33
33
  sanitizeSlug,
34
34
  selectCandidateEntries,
35
35
  writeEvalStub
36
- } from "./index-78b192v7.js";
37
- import"./index-3366gs26.js";
38
- import"./index-69ms9ny1.js";
36
+ } from "./index-x4fwtd59.js";
37
+ import"./index-db82jxt7.js";
38
+ import"./index-5a3xsnzg.js";
39
39
  import"./index-rtry5xyf.js";
40
- import"./index-rywkdacj.js";
41
- import"./index-nhgw7de8.js";
40
+ import"./index-0f800qg7.js";
41
+ import"./index-35xyj7gn.js";
42
42
  import"./index-ae75rja9.js";
43
43
  import"./index-3jvqw5hy.js";
44
44
  import"./index-4rhcth7a.js";
@@ -3,4 +3,8 @@
3
3
  * Sanitizes the description, parses flags, and emits a DESIGN_DOCS mode signal
4
4
  * that routes the architect into the design-doc generation/sync workflow.
5
5
  */
6
+ import { loadPluginConfigWithMeta } from '../config';
7
+ export declare const _internals: {
8
+ loadPluginConfigWithMeta: typeof loadPluginConfigWithMeta;
9
+ };
6
10
  export declare function handleDesignDocsCommand(directory: string, args: string[]): Promise<string>;
@@ -1,22 +1,22 @@
1
1
  /**
2
2
  * Handle /swarm pr-feedback command.
3
3
  *
4
- * Triggers the architect to enter MODE: PR_FEEDBACK — the swarm workflow for
4
+ * Triggers the architect to enter MODE: PR_FEEDBACK the swarm workflow for
5
5
  * ingesting and closing KNOWN pull-request feedback (review comments, requested
6
6
  * changes, CI failures, merge conflicts, stale branches, pasted notes). This is
7
7
  * distinct from /swarm pr-review, which discovers NEW findings.
8
8
  *
9
9
  * Input contract (PR reference is optional):
10
- * /swarm pr-feedback 155 → feedback pass on PR 155
11
- * /swarm pr-feedback 155 also fix the lint errors → PR 155 + extra instructions
10
+ * /swarm pr-feedback 155 feedback pass on PR 155
11
+ * /swarm pr-feedback 155 also fix the lint errors PR 155 + extra instructions
12
12
  * /swarm pr-feedback 155 continue from .swarm/pr-review/<run_id>/feedback-handoff.md
13
13
  * -> PR 155 + handoff path instructions
14
- * /swarm pr-feedback owner/repo#155 → shorthand
14
+ * /swarm pr-feedback owner/repo#155 shorthand
15
15
  * /swarm pr-feedback https://github.com/.../pull/155
16
- * /swarm pr-feedback → bare signal; architect builds
16
+ * /swarm pr-feedback bare signal; architect builds
17
17
  * the ledger from current PR/branch
18
18
  * /swarm pr-feedback address the review notes about error handling
19
- * → no parseable PR ref ⇒ the whole
19
+ * no parseable PR ref the whole
20
20
  * input is forwarded as instructions
21
21
  *
22
22
  * PR-reference parsing and injection-hardening are shared with /swarm pr-review
@@ -69,6 +69,7 @@ export declare const TaskSchema: z.ZodObject<{
69
69
  files_touched: z.ZodDefault<z.ZodArray<z.ZodString>>;
70
70
  evidence_path: z.ZodOptional<z.ZodString>;
71
71
  blocked_reason: z.ZodOptional<z.ZodString>;
72
+ fr_refs: z.ZodOptional<z.ZodArray<z.ZodString>>;
72
73
  }, z.core.$strip>;
73
74
  export type Task = z.infer<typeof TaskSchema>;
74
75
  export declare const PhaseSchema: z.ZodObject<{
@@ -103,6 +104,7 @@ export declare const PhaseSchema: z.ZodObject<{
103
104
  files_touched: z.ZodDefault<z.ZodArray<z.ZodString>>;
104
105
  evidence_path: z.ZodOptional<z.ZodString>;
105
106
  blocked_reason: z.ZodOptional<z.ZodString>;
107
+ fr_refs: z.ZodOptional<z.ZodArray<z.ZodString>>;
106
108
  }, z.core.$strip>>>;
107
109
  type: z.ZodOptional<z.ZodEnum<{
108
110
  code: "code";
@@ -148,6 +150,7 @@ export declare const PlanSchema: z.ZodObject<{
148
150
  files_touched: z.ZodDefault<z.ZodArray<z.ZodString>>;
149
151
  evidence_path: z.ZodOptional<z.ZodString>;
150
152
  blocked_reason: z.ZodOptional<z.ZodString>;
153
+ fr_refs: z.ZodOptional<z.ZodArray<z.ZodString>>;
151
154
  }, z.core.$strip>>>;
152
155
  type: z.ZodOptional<z.ZodEnum<{
153
156
  code: "code";
@@ -66,6 +66,20 @@ interface ValidationContext {
66
66
  /**
67
67
  * Validates a DelegationEnvelope against the current plan and agent list.
68
68
  * Returns { valid: true } on success, or { valid: false; reason: string } on failure.
69
+ *
70
+ * NOTE (#1687, kept SEPARATE from {@link validateCoderReviewerAcceptanceField}):
71
+ * this validator operates on a *structured* `DelegationEnvelope` object recovered
72
+ * from the OLD `KEY:VALUE` envelope format (`taskId:`/`targetAgent:`/`action:`/
73
+ * `commandType:`/`files:`/`acceptanceCriteria:`) and is consumed ADVISORY-ONLY,
74
+ * POST-execution via {@link appendDelegationEnvelopeAdvisory} in `toolAfter` (it
75
+ * never throws). The free-text coder/reviewer format
76
+ * (`TASK:`/`FILE:`/`ACCEPTANCE:`) does NOT parse into this shape
77
+ * (`parseDelegationEnvelope` returns `null`), so this path never fires on a real
78
+ * coder/reviewer dispatch. The pre-dispatch, BLOCKING acceptance-field gate for
79
+ * the free-text format lives in {@link validateCoderReviewerAcceptanceField};
80
+ * the two are intentionally not merged (advisory-vs-blocking, structured-vs-
81
+ * free-text are different contracts). Do not delete this function — it retains a
82
+ * real purpose for the old envelope format and other delegation types.
69
83
  */
70
84
  export declare function validateDelegationEnvelope(envelope: unknown, context: ValidationContext): EnvelopeValidationResult;
71
85
  /**
@@ -87,6 +101,107 @@ export declare function validateDelegationEnvelope(envelope: unknown, context: V
87
101
  * the side effect (advisory push) is the production purpose.
88
102
  */
89
103
  export declare function appendDelegationEnvelopeAdvisory(session: AgentSessionState, promptText: string, context: ValidationContext): EnvelopeValidationResult | null;
104
+ /**
105
+ * FR-003 / SC-003 / SC-004 (issue #1687): pre-dispatch acceptance-criteria
106
+ * enforcement for **coder and reviewer** delegations, operating on the REAL
107
+ * free-text delegation prompt (`TASK:`/`FILE:`/`INPUT:`/`OUTPUT:`/`CONSTRAINT:`/
108
+ * `ACCEPTANCE:`/`SKILLS:`) the architect actually sends via the native Task tool.
109
+ *
110
+ * Deliberately kept SEPARATE from {@link validateDelegationEnvelope} (see the
111
+ * sibling note there), NOT a rename/reuse of it, because the semantics differ on
112
+ * two axes: this function parses the FREE-TEXT `ACCEPTANCE:` line (not a
113
+ * structured envelope object) and is consumed as a BLOCKING, PRE-execution
114
+ * (`toolBefore`) gate (not the advisory, post-execution `toolAfter` path that
115
+ * `validateDelegationEnvelope` feeds via {@link appendDelegationEnvelopeAdvisory}).
116
+ * The two formats never overlap — `parseDelegationEnvelope` returns `null` for
117
+ * the free-text coder/reviewer format — so merging them would conflate
118
+ * advisory-vs-blocking and structured-vs-free-text contracts. M15's advisory
119
+ * mechanism is left fully intact for the old envelope format and other
120
+ * delegation types.
121
+ *
122
+ * A dispatch passes when an `ACCEPTANCE:` line exists AND the field carries
123
+ * non-empty, non-whitespace content — either INLINE on the header line (the
124
+ * architect-instructed same-line format) OR on the lines that FOLLOW a bare
125
+ * `ACCEPTANCE:` header, up to (but excluding) the next INPUT-FORMAT field header
126
+ * (`^[A-Z][A-Z0-9_]*:`, e.g. `SKILLS:`) or end of input. The multi-line form is
127
+ * a plausible way to paste a verbatim FR/SC body that spans lines (PR #1864
128
+ * review feedback), so treating a bare header + following content as EMPTY would
129
+ * false-block a good-faith copy. The next-field-header terminator ensures
130
+ * content belonging to the NEXT field (e.g. `SKILLS: none`) is never miscounted
131
+ * as ACCEPTANCE content — an empty `ACCEPTANCE:` immediately followed by another
132
+ * field is still correctly rejected as empty. Prompts are split on `\r?\n` so a
133
+ * trailing `\r` (CRLF-authored prompts) never leaks into the captured content.
134
+ *
135
+ * Only NON-EMPTINESS is enforced here; verbatim-coverage of the mapped FR/SC
136
+ * bodies is a SEPARATE, later check ({@link checkAcceptanceCoversFrRefs}) that
137
+ * already newline-normalizes the whole prompt, so multi-line ACCEPTANCE content
138
+ * is visible to it regardless.
139
+ *
140
+ * @param promptText the assembled delegation prompt (all text-bearing Task args
141
+ * joined).
142
+ * @returns `{ valid: true }` when the ACCEPTANCE field is present and non-empty;
143
+ * otherwise `{ valid: false, reason }` with a diagnosable reason the caller
144
+ * turns into a blocking, pre-dispatch error.
145
+ */
146
+ export declare function validateCoderReviewerAcceptanceField(promptText: string): {
147
+ valid: boolean;
148
+ reason?: 'acceptance_field_missing' | 'acceptance_field_empty';
149
+ };
150
+ /**
151
+ * FR-001/FR-002/FR-005/SC-001/SC-002/SC-006 (issue #1687): pull the verbatim
152
+ * requirement BODY for a single spec id (`FR-###` / `SC-###`) out of `spec.md`.
153
+ *
154
+ * spec.md requirements are bold-prefixed bullets, one per (possibly wrapped)
155
+ * bullet, e.g.
156
+ * `- **FR-000 — Structured task-to-FR mapping.** The plan task model SHALL ...`
157
+ * `- **SC-000 (FR-000).** Given a plan ..., then ...`
158
+ * The requirement BODY is the text AFTER the FIRST closing `**` of the leading
159
+ * bold span — i.e. everything past the `**...**` id/title prefix. Handles both
160
+ * FR-### and SC-### uniformly (no special-casing) and stitches on any
161
+ * immediately-following continuation lines of a wrapped bullet until the next
162
+ * bullet / next FR-|SC- bullet / a blank line / a markdown heading.
163
+ *
164
+ * @returns the raw (untrimmed) body string, or `null` when the id is not present
165
+ * in the spec (unknown/typo/renamed) — the caller treats null as fail-open skip.
166
+ */
167
+ export declare function extractSpecRequirementBodyById(specText: string, id: string): string | null;
168
+ /**
169
+ * FR-001/FR-002 (issue #1687): symmetric normalization applied identically to
170
+ * BOTH the extracted spec body AND the ACCEPTANCE prompt text before the
171
+ * substring-coverage compare. Asymmetric normalization would false-block, so this
172
+ * is deliberately the single shared normalizer. Strips markdown emphasis/code
173
+ * markers and leading list markers, folds punctuation the architect's LLM copy
174
+ * routinely substitutes (dash-width, curly-vs-straight quotes) so a good-faith
175
+ * verbatim copy is not false-blocked on a `—`→`--` or `'`→`'` swap, collapses
176
+ * ALL whitespace (incl. newlines) to single spaces, trims, and lowercases. Every
177
+ * fold is symmetric (both sides go through this one function), so it can only
178
+ * REDUCE false-blocks — it never opens a bypass, since covered/uncovered still
179
+ * differ by whole words, not punctuation.
180
+ */
181
+ export declare function normalizeAcceptanceText(s: string): string;
182
+ /**
183
+ * FR-001/FR-002/FR-005/SC-001/SC-002/SC-006 (issue #1687): mechanical coverage
184
+ * check that the ACCEPTANCE text CONTAINS the verbatim requirement body for each
185
+ * mapped spec id. Fail-open by construction:
186
+ * - an id not present in spec.md (unknown/typo/renamed) is SKIPPED, never blocked;
187
+ * - an id whose body normalizes to empty is SKIPPED (neither trivially covered
188
+ * nor a miss);
189
+ * - each id is checked INDEPENDENTLY (per-id substring), because the architect
190
+ * concatenates multiple requirement bodies with an UNSPECIFIED separator — a
191
+ * whole-string equality compare would false-block multi-FR tasks.
192
+ *
193
+ * @returns `{ covered: true }` when every id is present-and-covered or skipped;
194
+ * `{ covered: false, missingId }` naming the FIRST id whose body is not a
195
+ * substring of the ACCEPTANCE text.
196
+ */
197
+ export declare function checkAcceptanceCoversFrRefs(params: {
198
+ acceptanceText: string;
199
+ frRefs: string[];
200
+ specText: string;
201
+ }): {
202
+ covered: boolean;
203
+ missingId?: string;
204
+ };
90
205
  interface MessageInfo {
91
206
  role: string;
92
207
  agent?: string;
@@ -55,7 +55,7 @@ export interface EnrichmentQuotaOptions {
55
55
  * One retry on schema failure (with a RETRY message naming the missing
56
56
  * fields). Quota-gated per call via the dedicated knowledge-enrichment quota.
57
57
  * Returns null when
58
- * enrichment is unavailable (quota exhausted) or fails twice — the caller
58
+ * enrichment is unavailable (quota exhausted) or fails twice the caller
59
59
  * quarantines the entry. Never throws.
60
60
  */
61
61
  export declare function enrichLessonToV3(params: {
@@ -106,15 +106,15 @@ export declare function runAutoPromotion(directory: string, config: KnowledgeCon
106
106
  /**
107
107
  * G7 (#1716): Auto-demote swarm entries that have sustained a net-negative
108
108
  * outcome signal over consecutive phase EVALUATIONS (i.e. consecutive
109
- * `runAutoDemotion` invocations with distinct phase numbers — a skipped phase
110
- * in between still counts, matching the issue's "≥3 consecutive" intent as
109
+ * `runAutoDemotion` invocations with distinct phase numbers a skipped phase
110
+ * in between still counts, matching the issue's "3 consecutive" intent as
111
111
  * implemented against evaluation cadence, not wall-clock phase contiguity).
112
112
  *
113
113
  * Companion to {@link runAutoPromotion}. For each `promoted` entry:
114
114
  * 1. Dedupe by phase: if `entry.last_demotion_phase === phaseNumber`, this
115
115
  * entry has already been processed for this phase (handles the case where
116
116
  * `curateAndStoreSwarm` is invoked multiple times in the same logical
117
- * phase — e.g. phase-complete + close). Skip the counter update.
117
+ * phase e.g. phase-complete + close). Skip the counter update.
118
118
  * 2. Otherwise compute the outcome signal. If at/below
119
119
  * `config.promoted_demotion_signal_threshold`, increment
120
120
  * `recent_negative_phase_count`; else reset it to 0.