@deftai/directive-core 0.95.0 → 0.97.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.
Files changed (116) hide show
  1. package/dist/cache/archive.d.ts +134 -0
  2. package/dist/cache/archive.js +636 -0
  3. package/dist/cache/index.d.ts +1 -0
  4. package/dist/cache/index.js +1 -0
  5. package/dist/cache/main.js +298 -1
  6. package/dist/check/gate-lists.js +8 -0
  7. package/dist/consumer-check-contract/evaluate.d.ts +124 -0
  8. package/dist/consumer-check-contract/evaluate.js +699 -0
  9. package/dist/consumer-check-contract/index.d.ts +5 -0
  10. package/dist/consumer-check-contract/index.js +5 -0
  11. package/dist/content-contracts/skills/helpers.d.ts +1 -1
  12. package/dist/content-contracts/skills/helpers.js +1 -0
  13. package/dist/delivery-attempt/disk-begin.d.ts +51 -0
  14. package/dist/delivery-attempt/disk-begin.js +68 -0
  15. package/dist/delivery-attempt/evaluate.d.ts +26 -0
  16. package/dist/delivery-attempt/evaluate.js +443 -0
  17. package/dist/delivery-attempt/fingerprint.d.ts +32 -0
  18. package/dist/delivery-attempt/fingerprint.js +100 -0
  19. package/dist/delivery-attempt/handoff.d.ts +25 -0
  20. package/dist/delivery-attempt/handoff.js +102 -0
  21. package/dist/delivery-attempt/index.d.ts +17 -0
  22. package/dist/delivery-attempt/index.js +17 -0
  23. package/dist/delivery-attempt/ledger.d.ts +169 -0
  24. package/dist/delivery-attempt/ledger.js +758 -0
  25. package/dist/delivery-attempt/material-delta.d.ts +38 -0
  26. package/dist/delivery-attempt/material-delta.js +126 -0
  27. package/dist/delivery-attempt/types.d.ts +210 -0
  28. package/dist/delivery-attempt/types.js +77 -0
  29. package/dist/doctor/index.d.ts +1 -0
  30. package/dist/doctor/index.js +1 -0
  31. package/dist/doctor/main.js +12 -0
  32. package/dist/doctor/openclaw-soft-rebind.d.ts +26 -0
  33. package/dist/doctor/openclaw-soft-rebind.js +164 -0
  34. package/dist/hooks/dispatcher.d.ts +2 -1
  35. package/dist/hooks/dispatcher.js +63 -9
  36. package/dist/index.d.ts +5 -0
  37. package/dist/index.js +5 -0
  38. package/dist/init-deposit/gitignore.js +7 -0
  39. package/dist/init-deposit/hygiene.d.ts +1 -1
  40. package/dist/init-deposit/hygiene.js +16 -4
  41. package/dist/init-deposit/init-deposit.js +5 -0
  42. package/dist/init-deposit/refresh.js +3 -0
  43. package/dist/init-deposit/scaffold.js +6 -5
  44. package/dist/parent-turn-shape/evaluate.d.ts +84 -0
  45. package/dist/parent-turn-shape/evaluate.js +353 -0
  46. package/dist/parent-turn-shape/index.d.ts +8 -0
  47. package/dist/parent-turn-shape/index.js +8 -0
  48. package/dist/pr-merge-readiness/ci-gate.d.ts +29 -1
  49. package/dist/pr-merge-readiness/ci-gate.js +191 -24
  50. package/dist/pr-merge-readiness/compute.js +10 -1
  51. package/dist/pr-merge-readiness/index.d.ts +2 -1
  52. package/dist/pr-merge-readiness/index.js +2 -1
  53. package/dist/pr-merge-readiness/output.js +14 -0
  54. package/dist/pr-merge-readiness/platform-status.d.ts +29 -0
  55. package/dist/pr-merge-readiness/platform-status.js +49 -0
  56. package/dist/pr-watch/constants.d.ts +10 -0
  57. package/dist/pr-watch/constants.js +12 -1
  58. package/dist/pr-watch/main.js +16 -1
  59. package/dist/pr-watch/probe.js +13 -1
  60. package/dist/pr-watch/types.d.ts +3 -2
  61. package/dist/pr-watch/watch.js +14 -7
  62. package/dist/review-monitor/constants.js +3 -2
  63. package/dist/review-monitor/tier-detection.d.ts +7 -3
  64. package/dist/review-monitor/tier-detection.js +18 -1
  65. package/dist/review-monitor/verify.js +18 -0
  66. package/dist/scope/index.d.ts +2 -0
  67. package/dist/scope/index.js +2 -0
  68. package/dist/scope/main.d.ts +10 -0
  69. package/dist/scope/main.js +109 -24
  70. package/dist/scope/promote-from-issue.d.ts +49 -0
  71. package/dist/scope/promote-from-issue.js +367 -0
  72. package/dist/scope/promote-path.d.ts +39 -0
  73. package/dist/scope/promote-path.js +105 -0
  74. package/dist/scope-provenance/digest.d.ts +67 -0
  75. package/dist/scope-provenance/digest.js +188 -0
  76. package/dist/scope-provenance/evaluate.d.ts +82 -0
  77. package/dist/scope-provenance/evaluate.js +528 -0
  78. package/dist/scope-provenance/index.d.ts +6 -0
  79. package/dist/scope-provenance/index.js +6 -0
  80. package/dist/session/compact-ritual.d.ts +96 -0
  81. package/dist/session/compact-ritual.js +237 -0
  82. package/dist/session/compact-ritual.spec.d.ts +2 -0
  83. package/dist/session/compact-ritual.spec.js +21 -0
  84. package/dist/session/index.d.ts +2 -0
  85. package/dist/session/index.js +2 -0
  86. package/dist/session/openclaw-soft-rebind-deposit.d.ts +46 -0
  87. package/dist/session/openclaw-soft-rebind-deposit.js +165 -0
  88. package/dist/swarm/routing.d.ts +4 -2
  89. package/dist/swarm/routing.js +26 -4
  90. package/dist/test-boundary/evaluate.d.ts +54 -0
  91. package/dist/test-boundary/evaluate.js +368 -0
  92. package/dist/test-boundary/index.d.ts +6 -0
  93. package/dist/test-boundary/index.js +6 -0
  94. package/dist/test-boundary/policy.d.ts +52 -0
  95. package/dist/test-boundary/policy.js +182 -0
  96. package/dist/triage/actions/index.js +62 -2
  97. package/dist/triage/actions/types.d.ts +8 -1
  98. package/dist/triage/author-filter.d.ts +51 -0
  99. package/dist/triage/author-filter.js +152 -0
  100. package/dist/triage/bootstrap/gitignore.d.ts +1 -1
  101. package/dist/triage/bootstrap/gitignore.js +15 -1
  102. package/dist/triage/classify/index.d.ts +2 -2
  103. package/dist/triage/classify/index.js +2 -2
  104. package/dist/triage/classify/label-mirror.d.ts +68 -5
  105. package/dist/triage/classify/label-mirror.js +261 -31
  106. package/dist/triage/help/registry-data.d.ts +49 -38
  107. package/dist/triage/help/registry-data.js +115 -40
  108. package/dist/triage/index.d.ts +1 -0
  109. package/dist/triage/index.js +1 -0
  110. package/dist/triage/queue/index.d.ts +1 -0
  111. package/dist/triage/queue/index.js +1 -0
  112. package/dist/triage/queue/render.d.ts +2 -0
  113. package/dist/triage/queue/render.js +6 -0
  114. package/dist/vbrief-activate/activate.js +22 -6
  115. package/dist/xbrief/styles.js +33 -17
  116. package/package.json +11 -3
@@ -0,0 +1,353 @@
1
+ /**
2
+ * Parent turn-shape hard-stop for text-repetition hang (FC14 / #3131).
3
+ *
4
+ * Soft skill prose (#2943) alone is insufficient: parents still burn the full
5
+ * output budget on identical progress sentences with zero tool_use after leaf
6
+ * announce. This pure library is the Directive-side machine-checkable gate.
7
+ *
8
+ * Hosts (OpenClaw, swarm parents, review monitors) SHOULD evaluate the parent
9
+ * turn stream mid-generation and hard-stop when `ok` is false.
10
+ *
11
+ * Illegal shape (MUST NOT):
12
+ * N > maxIdenticalWithoutTool (default 2) near-identical assistant sentences
13
+ * (or streaming text chunks) in one turn with no tool_use and no yield.
14
+ *
15
+ * Legal post-announce shapes:
16
+ * 1. Tool batch (ground-truth) then one consolidate
17
+ * 2. sessions_yield / wait without filler
18
+ * 3. One short user answer that is NOT a repeated progress line
19
+ */
20
+ /** Canonical fail class for the hang (#3131 / soft FC14 recurrence of #2943). */
21
+ export const PARENT_TURN_FAIL_FC14 = "FC14";
22
+ /** Default max identical text units without tool/yield (N>2 is illegal). */
23
+ export const DEFAULT_MAX_IDENTICAL_WITHOUT_TOOL = 2;
24
+ /** Minimum length (chars) for a text unit to count toward repetition. */
25
+ const MIN_UNIT_LEN = 12;
26
+ /** Word Jaccard threshold for near-identical (after normalize). */
27
+ const JACCARD_NEAR = 0.9;
28
+ /** Progress-ish tokens that mark filler narration after announce. */
29
+ const PROGRESS_HINT_RE = /\b(checking|checking\s+worktrees|open\s+prs?|next|unfinished|implementing|looking\s+at|will\s+(check|inspect|verify|spawn)|status\s+next|monitor(?:ing)?)\b/i;
30
+ /**
31
+ * Normalize assistant text for identity comparison.
32
+ * Collapses whitespace, lowercases, strips common trailing punctuation.
33
+ */
34
+ export function normalizeTurnText(text) {
35
+ return text
36
+ .normalize("NFKC")
37
+ .toLowerCase()
38
+ .replace(/\s+/g, " ")
39
+ .replace(/^[\s"'`]+|[\s"'`]+$/g, "")
40
+ .replace(/[.!?…,:;]+$/g, "")
41
+ .trim();
42
+ }
43
+ /** Split a blob into sentence-like units (periods, newlines, ellipsis). */
44
+ export function splitTextUnits(text) {
45
+ const raw = text.replace(/\r\n/g, "\n");
46
+ // Include single newlines so block-formatted repeated progress lines still
47
+ // unitize (FC14 hang class often streams one line per newline, no period).
48
+ // Optional closing quotes after terminal punctuation, with or without space:
49
+ // `"Hello." "Hello."` and `"Hello.""Hello."`.
50
+ const parts = raw
51
+ .split(/(?:\n+|(?<=[.!?…])["']+\s*|(?<=[.!?…])\s+|(?<=\.\.\.)\s+)/)
52
+ .map((p) => p.trim())
53
+ .filter((p) => p.length > 0);
54
+ if (parts.length === 0 && raw.trim().length > 0) {
55
+ return [raw.trim()];
56
+ }
57
+ return parts;
58
+ }
59
+ function wordSet(normalized) {
60
+ const words = normalized.split(/[^a-z0-9_]+/).filter((w) => w.length > 0);
61
+ return new Set(words);
62
+ }
63
+ /**
64
+ * True when two normalized strings are near-identical (exact, containment with
65
+ * high length ratio, or high word Jaccard). Short units never match.
66
+ */
67
+ export function isNearIdentical(a, b) {
68
+ const na = normalizeTurnText(a);
69
+ const nb = normalizeTurnText(b);
70
+ if (na.length < MIN_UNIT_LEN || nb.length < MIN_UNIT_LEN)
71
+ return false;
72
+ if (na === nb)
73
+ return true;
74
+ const shorter = na.length <= nb.length ? na : nb;
75
+ const longer = na.length <= nb.length ? nb : na;
76
+ if (longer.includes(shorter) && shorter.length / longer.length >= 0.85) {
77
+ return true;
78
+ }
79
+ const sa = wordSet(na);
80
+ const sb = wordSet(nb);
81
+ if (sa.size === 0 || sb.size === 0)
82
+ return false;
83
+ let inter = 0;
84
+ for (const w of sa) {
85
+ if (sb.has(w))
86
+ inter += 1;
87
+ }
88
+ const union = sa.size + sb.size - inter;
89
+ if (union === 0)
90
+ return false;
91
+ return inter / union >= JACCARD_NEAR;
92
+ }
93
+ /**
94
+ * Collect assistant text units from turn events.
95
+ *
96
+ * Streaming hosts often emit word/chunk deltas as separate `assistant_text`
97
+ * events. Coalesce consecutive text events into one blob so fragmented
98
+ * progress sentences reconstruct before split/identity checks (P1 / #3131).
99
+ * Non-text events (tool_use / yield) flush the coalesce buffer.
100
+ */
101
+ function collectAssistantUnits(events) {
102
+ const units = [];
103
+ const pushUnitsFrom = (text) => {
104
+ for (const u of splitTextUnits(text)) {
105
+ const t = u.trim();
106
+ if (t.length >= MIN_UNIT_LEN)
107
+ units.push(t);
108
+ }
109
+ };
110
+ let run = "";
111
+ for (const ev of events) {
112
+ if (ev.kind === "assistant_text") {
113
+ const text = typeof ev.text === "string" ? ev.text : "";
114
+ if (!text)
115
+ continue;
116
+ // Sentence-boundary deltas often omit whitespace after `.!?` before the
117
+ // next capital letter. Insert space only at sentence ends — never between
118
+ // arbitrary alnum chunks (subword streams like workt+rees must not gain
119
+ // a false space).
120
+ if (run.length > 0 && /[.!?…]["']?\s*$/.test(run) && !/^\s/.test(text) && !/\s$/.test(run)) {
121
+ run += " ";
122
+ }
123
+ run += text;
124
+ continue;
125
+ }
126
+ // Non-text event ends the coalesce run (tool/yield boundaries).
127
+ if (run.trim().length > 0)
128
+ pushUnitsFrom(run);
129
+ run = "";
130
+ }
131
+ if (run.trim().length > 0)
132
+ pushUnitsFrom(run);
133
+ return units;
134
+ }
135
+ /**
136
+ * Max connected-component size under near-identity edges (union-find).
137
+ * Captures non-transitive chains of incrementally varied progress lines
138
+ * (A≈B≈C even when A≉C) so FC14 cannot be bypassed by wording drift.
139
+ */
140
+ function maxNearIdentityComponent(units) {
141
+ const n = units.length;
142
+ if (n === 0)
143
+ return 0;
144
+ // Precompute normalize + word sets once (avoid O(n²) re-normalize/Set alloc).
145
+ const norms = units.map((u) => normalizeTurnText(u));
146
+ const sets = norms.map((n) => wordSet(n));
147
+ const near = (i, j) => {
148
+ const na = norms[i] ?? "";
149
+ const nb = norms[j] ?? "";
150
+ if (na.length < MIN_UNIT_LEN || nb.length < MIN_UNIT_LEN)
151
+ return false;
152
+ if (na === nb)
153
+ return true;
154
+ const shorter = na.length <= nb.length ? na : nb;
155
+ const longer = na.length <= nb.length ? nb : na;
156
+ if (longer.includes(shorter) && shorter.length / longer.length >= 0.85)
157
+ return true;
158
+ const sa = sets[i] ?? new Set();
159
+ const sb = sets[j] ?? new Set();
160
+ if (sa.size === 0 || sb.size === 0)
161
+ return false;
162
+ let inter = 0;
163
+ for (const w of sa) {
164
+ if (sb.has(w))
165
+ inter += 1;
166
+ }
167
+ const union = sa.size + sb.size - inter;
168
+ return union > 0 && inter / union >= JACCARD_NEAR;
169
+ };
170
+ const parent = Array.from({ length: n }, (_, i) => i);
171
+ const find = (i) => {
172
+ let x = i;
173
+ while (parent[x] !== x) {
174
+ parent[x] = parent[parent[x] ?? x] ?? x;
175
+ x = parent[x] ?? x;
176
+ }
177
+ return x;
178
+ };
179
+ const unite = (a, b) => {
180
+ const ra = find(a);
181
+ const rb = find(b);
182
+ if (ra !== rb)
183
+ parent[ra] = rb;
184
+ };
185
+ for (let i = 0; i < n; i++) {
186
+ for (let j = i + 1; j < n; j++) {
187
+ if (near(i, j))
188
+ unite(i, j);
189
+ }
190
+ }
191
+ const sizes = new Map();
192
+ let max = 1;
193
+ for (let i = 0; i < n; i++) {
194
+ const r = find(i);
195
+ const next = (sizes.get(r) ?? 0) + 1;
196
+ sizes.set(r, next);
197
+ if (next > max)
198
+ max = next;
199
+ }
200
+ return max;
201
+ }
202
+ /**
203
+ * Max count of any single near-identical cluster among units.
204
+ * Consecutive runs + exact-normalized frequency (O(n)); for small unit counts
205
+ * also union-find near-identity components so non-consecutive / chain variants
206
+ * cannot bypass FC14 (P1 / #3131).
207
+ */
208
+ function maxIdenticalCluster(units) {
209
+ if (units.length === 0)
210
+ return 0;
211
+ const norms = units.map((u) => normalizeTurnText(u));
212
+ let maxRun = 1;
213
+ let run = 1;
214
+ for (let i = 1; i < units.length; i++) {
215
+ if (isNearIdentical(units[i] ?? "", units[i - 1] ?? "")) {
216
+ run += 1;
217
+ if (run > maxRun)
218
+ maxRun = run;
219
+ }
220
+ else {
221
+ run = 1;
222
+ }
223
+ }
224
+ // Frequency by exact normalized form (O(n)).
225
+ const freq = new Map();
226
+ let maxFreq = 1;
227
+ for (const n of norms) {
228
+ if (n.length < MIN_UNIT_LEN)
229
+ continue;
230
+ const next = (freq.get(n) ?? 0) + 1;
231
+ freq.set(n, next);
232
+ if (next > maxFreq)
233
+ maxFreq = next;
234
+ }
235
+ // Always cluster near-identity components. Input size is bounded by the
236
+ // zero-tool character hard-stop above, so O(n²) stays finite.
237
+ const maxComponent = maxNearIdentityComponent(units);
238
+ return Math.max(maxRun, maxFreq, maxComponent);
239
+ }
240
+ /**
241
+ * Detect when a single blob itself embeds the same sentence many times
242
+ * (model streams one giant assistant message of repeated lines).
243
+ */
244
+ export function countRepeatedUnitsInBlob(text) {
245
+ const units = splitTextUnits(text).filter((u) => u.trim().length >= MIN_UNIT_LEN);
246
+ return maxIdenticalCluster(units);
247
+ }
248
+ function looksLikeProgressOnly(units) {
249
+ if (units.length < 2)
250
+ return false;
251
+ let progressHits = 0;
252
+ for (const u of units) {
253
+ if (PROGRESS_HINT_RE.test(u))
254
+ progressHits += 1;
255
+ }
256
+ // Majority of multi-sentence text is progress narration.
257
+ return progressHits >= Math.ceil(units.length / 2);
258
+ }
259
+ /**
260
+ * Evaluate whether a parent turn shape is legal under the FC14 hard-stop.
261
+ * Pure / side-effect free — safe for mid-stream host gates and unit tests.
262
+ */
263
+ export function evaluateParentTurnShape(input) {
264
+ const events = input.events ?? [];
265
+ const maxAllowed = input.maxIdenticalWithoutTool ?? DEFAULT_MAX_IDENTICAL_WITHOUT_TOOL;
266
+ let hasToolUse = false;
267
+ let hasYield = false;
268
+ for (const ev of events) {
269
+ if (ev.kind === "tool_use")
270
+ hasToolUse = true;
271
+ if (ev.kind === "yield")
272
+ hasYield = true;
273
+ }
274
+ // Tool or yield greases the turn: repetition hard-stop does not fire.
275
+ if (hasToolUse || hasYield) {
276
+ return {
277
+ ok: true,
278
+ failClass: "none",
279
+ reasons: [],
280
+ maxIdenticalCount: 0,
281
+ hasToolUse,
282
+ hasYield,
283
+ };
284
+ }
285
+ // Fail closed on unbounded zero-tool text (output-budget burn / DoS class).
286
+ const ZERO_TOOL_CHAR_CAP = 50_000;
287
+ let zeroToolChars = 0;
288
+ for (const ev of events) {
289
+ if (ev.kind === "assistant_text" && typeof ev.text === "string") {
290
+ zeroToolChars += ev.text.length;
291
+ }
292
+ }
293
+ if (zeroToolChars > ZERO_TOOL_CHAR_CAP) {
294
+ return {
295
+ ok: false,
296
+ failClass: "FC14",
297
+ reasons: [
298
+ `FC14 text-repetition-hang: zero-tool assistant text exceeds ${ZERO_TOOL_CHAR_CAP} chars ` +
299
+ `(${zeroToolChars}) without tool_use/yield — hard-stop budget burn. Refs #3131 / #2943.`,
300
+ ],
301
+ maxIdenticalCount: Math.ceil(zeroToolChars / MIN_UNIT_LEN),
302
+ hasToolUse,
303
+ hasYield,
304
+ };
305
+ }
306
+ const units = collectAssistantUnits(events);
307
+ // Also fold in whole-blob repetition for single giant text events.
308
+ let maxIdenticalCount = maxIdenticalCluster(units);
309
+ for (const ev of events) {
310
+ if (ev.kind === "assistant_text" && typeof ev.text === "string") {
311
+ maxIdenticalCount = Math.max(maxIdenticalCount, countRepeatedUnitsInBlob(ev.text));
312
+ }
313
+ }
314
+ const reasons = [];
315
+ let failClass = "none";
316
+ if (maxIdenticalCount > maxAllowed) {
317
+ failClass = "FC14";
318
+ reasons.push(`FC14 text-repetition-hang: ${maxIdenticalCount} near-identical assistant text units ` +
319
+ `with zero tool_use/yield (max allowed ${maxAllowed}; N>${maxAllowed} is illegal). ` +
320
+ `After subagent announce, emit a tool-first ground-truth batch, sessions_yield, ` +
321
+ `or one short non-repeated answer — not repeated progress lines. Refs #3131 / #2943.`);
322
+ }
323
+ // Post-announce: multi-sentence progress-only with zero tools is also illegal
324
+ // even when sentences are not exact clones (soft-only #2943 recurrence class).
325
+ // Threshold is >=2 units (N>1 multi-sentence) — exactly two progress lines
326
+ // must not bypass the gate.
327
+ if (input.afterSubagentAnnounce &&
328
+ units.length >= 2 &&
329
+ looksLikeProgressOnly(units) &&
330
+ failClass === "none") {
331
+ failClass = "progress-only-no-tool";
332
+ reasons.push(`progress-only-no-tool: post-subagent-announce turn has ${units.length} assistant ` +
333
+ `text units with progress narration and zero tool_use/yield. MUST tool-first or yield. Refs #3131 / #2943.`);
334
+ }
335
+ // Alias surface: FC14 and text-repetition-hang name the same hang class.
336
+ if (failClass === "FC14") {
337
+ // Keep failClass as FC14; callers may also match text-repetition-hang via reasons.
338
+ }
339
+ return {
340
+ ok: failClass === "none",
341
+ failClass,
342
+ reasons,
343
+ maxIdenticalCount,
344
+ hasToolUse,
345
+ hasYield,
346
+ };
347
+ }
348
+ /** Convenience: true when the turn is an illegal text-repetition hang. */
349
+ export function isTextRepetitionHang(input) {
350
+ const r = evaluateParentTurnShape(input);
351
+ return r.failClass === "FC14" || r.failClass === "text-repetition-hang";
352
+ }
353
+ //# sourceMappingURL=evaluate.js.map
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Parent turn-shape hard-stop (FC14 / #3131).
3
+ *
4
+ * Machine-checkable gate so soft skill prose is not the sole mitigation for
5
+ * the OpenClaw parent text-repetition hang after leaf announce.
6
+ */
7
+ export { countRepeatedUnitsInBlob, DEFAULT_MAX_IDENTICAL_WITHOUT_TOOL, evaluateParentTurnShape, isNearIdentical, isTextRepetitionHang, normalizeTurnText, PARENT_TURN_FAIL_FC14, type ParentTurnEvent, type ParentTurnFailClass, type ParentTurnShapeInput, type ParentTurnShapeResult, splitTextUnits, } from "./evaluate.js";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Parent turn-shape hard-stop (FC14 / #3131).
3
+ *
4
+ * Machine-checkable gate so soft skill prose is not the sole mitigation for
5
+ * the OpenClaw parent text-repetition hang after leaf announce.
6
+ */
7
+ export { countRepeatedUnitsInBlob, DEFAULT_MAX_IDENTICAL_WITHOUT_TOOL, evaluateParentTurnShape, isNearIdentical, isTextRepetitionHang, normalizeTurnText, PARENT_TURN_FAIL_FC14, splitTextUnits, } from "./evaluate.js";
8
+ //# sourceMappingURL=index.js.map
@@ -1,5 +1,21 @@
1
1
  import type { CheckRunRecord } from "./gh.js";
2
- export type CiReadyState = "ready" | "blocked" | "not_ready_yet" | "runner_capacity_stall" | "skipped";
2
+ /**
3
+ * Bot-reviewer check-runs are not CI workflow jobs. Presence of only these
4
+ * (or empty check-runs) is the `ci_never_scheduled` weather signal (#3167).
5
+ */
6
+ export declare function isBotReviewCheck(name: string): boolean;
7
+ /**
8
+ * Suite family for cancelled↔green sibling matching (#3167 / Greptile P1).
9
+ * Unrelated greens (CodeQL, Socket, …) must not clear a cancelled TypeScript/Go lane.
10
+ * Returns null when the check is not a TS/Go CI suite job.
11
+ */
12
+ export declare function suiteFamilyOf(name: string): "typescript" | "go" | null;
13
+ /**
14
+ * Branch-protection SoT aggregators only (#3168 map). Primary/failover lanes are
15
+ * not authoritative: a green primary must not clear a cancelled aggregator.
16
+ */
17
+ export declare function isAuthoritativeSuiteAggregator(name: string): boolean;
18
+ export type CiReadyState = "ready" | "blocked" | "ci_failures" | "not_ready_yet" | "runner_capacity_stall" | "ci_never_scheduled" | "ci_cancelled_no_failover" | "skipped";
3
19
  export interface CiGateOptions {
4
20
  readonly skipCi?: boolean;
5
21
  readonly ignoreCheckNames?: readonly string[];
@@ -23,6 +39,8 @@ export interface CiGateSummary {
23
39
  readonly pending_required: readonly string[];
24
40
  /** Required checks classified as capacity-stalled (#2672). */
25
41
  readonly capacity_stalled_required: readonly string[];
42
+ /** Required checks cancelled without a green failover sibling (#3167). */
43
+ readonly cancelled_required: readonly string[];
26
44
  readonly conclusions: readonly CiCheckConclusion[];
27
45
  }
28
46
  export interface CiGateResult {
@@ -30,5 +48,15 @@ export interface CiGateResult {
30
48
  readonly summary: CiGateSummary;
31
49
  }
32
50
  export declare function buildCiSummaryLine(summary: CiGateSummary): string;
51
+ /**
52
+ * Classify required CI weather for a HEAD check-run list (#2169 / #2672 / #3167).
53
+ *
54
+ * Distinct ready_state codes:
55
+ * - `ci_never_scheduled` — no CI workflow check-runs (bots alone / empty)
56
+ * - `runner_capacity_stall` — queued past budget, no runner claimed
57
+ * - `ci_failures` — completed failure / timed_out with product evidence
58
+ * - `ci_cancelled_no_failover` — only cancelled failures; no green failover
59
+ * - `not_ready_yet` / `ready` / `blocked` / `skipped` — legacy + residual
60
+ */
33
61
  export declare function evaluateCiGate(checkRuns: readonly CheckRunRecord[], options?: CiGateOptions): CiGateResult;
34
62
  //# sourceMappingURL=ci-gate.d.ts.map