@cleocode/core 2026.10.17 → 2026.10.18

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 (188) hide show
  1. package/dist/audit-prune.d.ts +37 -8
  2. package/dist/audit-prune.d.ts.map +1 -1
  3. package/dist/audit-prune.js +46 -12
  4. package/dist/audit-prune.js.map +1 -1
  5. package/dist/build-provenance.json +2 -2
  6. package/dist/cloud/manifest-check.d.ts +21 -0
  7. package/dist/cloud/manifest-check.d.ts.map +1 -1
  8. package/dist/cloud/manifest-check.js +46 -1
  9. package/dist/cloud/manifest-check.js.map +1 -1
  10. package/dist/cloud/nexus-vault.d.ts +19 -0
  11. package/dist/cloud/nexus-vault.d.ts.map +1 -1
  12. package/dist/cloud/nexus-vault.js +134 -23
  13. package/dist/cloud/nexus-vault.js.map +1 -1
  14. package/dist/cloud/signing.d.ts.map +1 -1
  15. package/dist/cloud/signing.js +4 -0
  16. package/dist/cloud/signing.js.map +1 -1
  17. package/dist/doctor/row-identity.d.ts.map +1 -1
  18. package/dist/doctor/row-identity.js +2 -1
  19. package/dist/doctor/row-identity.js.map +1 -1
  20. package/dist/git/work-tree.d.ts +17 -0
  21. package/dist/git/work-tree.d.ts.map +1 -1
  22. package/dist/git/work-tree.js +30 -0
  23. package/dist/git/work-tree.js.map +1 -1
  24. package/dist/goal/close.d.ts +95 -0
  25. package/dist/goal/close.d.ts.map +1 -0
  26. package/dist/goal/close.js +497 -0
  27. package/dist/goal/close.js.map +1 -0
  28. package/dist/goal/draft.d.ts +81 -0
  29. package/dist/goal/draft.d.ts.map +1 -0
  30. package/dist/goal/draft.js +331 -0
  31. package/dist/goal/draft.js.map +1 -0
  32. package/dist/hooks/release-gate.d.ts +3 -0
  33. package/dist/hooks/release-gate.d.ts.map +1 -1
  34. package/dist/hooks/release-gate.js +4 -1
  35. package/dist/hooks/release-gate.js.map +1 -1
  36. package/dist/orchestration/lean-gain.d.ts +26 -0
  37. package/dist/orchestration/lean-gain.d.ts.map +1 -0
  38. package/dist/orchestration/lean-gain.js +61 -0
  39. package/dist/orchestration/lean-gain.js.map +1 -0
  40. package/dist/release/backfill.d.ts.map +1 -1
  41. package/dist/release/backfill.js +15 -5
  42. package/dist/release/backfill.js.map +1 -1
  43. package/dist/release/ci-evidence.d.ts +90 -5
  44. package/dist/release/ci-evidence.d.ts.map +1 -1
  45. package/dist/release/ci-evidence.js +277 -4
  46. package/dist/release/ci-evidence.js.map +1 -1
  47. package/dist/release/plan.d.ts +4 -1
  48. package/dist/release/plan.d.ts.map +1 -1
  49. package/dist/release/plan.js +10 -2
  50. package/dist/release/plan.js.map +1 -1
  51. package/dist/release/reconcile.d.ts +10 -0
  52. package/dist/release/reconcile.d.ts.map +1 -1
  53. package/dist/release/reconcile.js +42 -19
  54. package/dist/release/reconcile.js.map +1 -1
  55. package/dist/release/release-manifest.d.ts +2 -1
  56. package/dist/release/release-manifest.d.ts.map +1 -1
  57. package/dist/release/release-manifest.js +15 -1
  58. package/dist/release/release-manifest.js.map +1 -1
  59. package/dist/resources/admission-ledger.d.ts +21 -4
  60. package/dist/resources/admission-ledger.d.ts.map +1 -1
  61. package/dist/resources/admission-ledger.js +102 -19
  62. package/dist/resources/admission-ledger.js.map +1 -1
  63. package/dist/resources/run-class.d.ts +22 -0
  64. package/dist/resources/run-class.d.ts.map +1 -1
  65. package/dist/resources/run-class.js +81 -0
  66. package/dist/resources/run-class.js.map +1 -1
  67. package/dist/sessions/handoff.d.ts +2 -2
  68. package/dist/sessions/handoff.js +2 -2
  69. package/dist/store/audit-log-schema.d.ts +106 -39
  70. package/dist/store/audit-log-schema.d.ts.map +1 -1
  71. package/dist/store/audit-log-schema.js +6 -3
  72. package/dist/store/audit-log-schema.js.map +1 -1
  73. package/dist/store/row-identity-registry.d.ts +42 -6
  74. package/dist/store/row-identity-registry.d.ts.map +1 -1
  75. package/dist/store/row-identity-registry.js +256 -34
  76. package/dist/store/row-identity-registry.js.map +1 -1
  77. package/dist/store/row-identity.d.ts.map +1 -1
  78. package/dist/store/row-identity.js +16 -4
  79. package/dist/store/row-identity.js.map +1 -1
  80. package/dist/store/schema/cleo-global/nexus.d.ts +16 -0
  81. package/dist/store/schema/cleo-global/nexus.d.ts.map +1 -1
  82. package/dist/store/schema/cleo-global/nexus.js +4 -1
  83. package/dist/store/schema/cleo-global/nexus.js.map +1 -1
  84. package/dist/store/schema/cleo-project/audit.d.ts +48 -0
  85. package/dist/store/schema/cleo-project/audit.d.ts.map +1 -1
  86. package/dist/store/schema/cleo-project/audit.js +15 -1
  87. package/dist/store/schema/cleo-project/audit.js.map +1 -1
  88. package/dist/store/schema/cleo-project/lifecycle.d.ts +112 -0
  89. package/dist/store/schema/cleo-project/lifecycle.d.ts.map +1 -1
  90. package/dist/store/schema/cleo-project/lifecycle.js +36 -4
  91. package/dist/store/schema/cleo-project/lifecycle.js.map +1 -1
  92. package/dist/store/schema/cleo-project/provenance-commits.d.ts +48 -0
  93. package/dist/store/schema/cleo-project/provenance-commits.d.ts.map +1 -1
  94. package/dist/store/schema/cleo-project/provenance-commits.js +10 -1
  95. package/dist/store/schema/cleo-project/provenance-commits.js.map +1 -1
  96. package/dist/store/schema/cleo-project/provenance-rest.d.ts +128 -0
  97. package/dist/store/schema/cleo-project/provenance-rest.d.ts.map +1 -1
  98. package/dist/store/schema/cleo-project/provenance-rest.js +25 -1
  99. package/dist/store/schema/cleo-project/provenance-rest.js.map +1 -1
  100. package/dist/store/schema/cleo-project/tasks-core.d.ts +16 -0
  101. package/dist/store/schema/cleo-project/tasks-core.d.ts.map +1 -1
  102. package/dist/store/schema/cleo-project/tasks-core.js +6 -1
  103. package/dist/store/schema/cleo-project/tasks-core.js.map +1 -1
  104. package/dist/store/session-store.d.ts +5 -4
  105. package/dist/store/session-store.d.ts.map +1 -1
  106. package/dist/store/session-store.js +19 -5
  107. package/dist/store/session-store.js.map +1 -1
  108. package/dist/store/sync/apply/parent-delete.d.ts.map +1 -1
  109. package/dist/store/sync/apply/parent-delete.js +8 -0
  110. package/dist/store/sync/apply/parent-delete.js.map +1 -1
  111. package/dist/store/sync/apply/write-api.d.ts +3 -2
  112. package/dist/store/sync/apply/write-api.d.ts.map +1 -1
  113. package/dist/store/sync/apply/write-api.js +19 -0
  114. package/dist/store/sync/apply/write-api.js.map +1 -1
  115. package/dist/store/sync/capture.d.ts +11 -0
  116. package/dist/store/sync/capture.d.ts.map +1 -1
  117. package/dist/store/sync/capture.js +13 -3
  118. package/dist/store/sync/capture.js.map +1 -1
  119. package/dist/store/sync/flags.d.ts +10 -0
  120. package/dist/store/sync/flags.d.ts.map +1 -1
  121. package/dist/store/sync/flags.js +43 -5
  122. package/dist/store/sync/flags.js.map +1 -1
  123. package/dist/store/sync/timestamp-canon.d.ts.map +1 -1
  124. package/dist/store/sync/timestamp-canon.js +37 -0
  125. package/dist/store/sync/timestamp-canon.js.map +1 -1
  126. package/dist/store/tasks-schema.d.ts +1 -1
  127. package/dist/store/tasks-schema.d.ts.map +1 -1
  128. package/dist/store/tasks-schema.js +5 -1
  129. package/dist/store/tasks-schema.js.map +1 -1
  130. package/dist/store/twin-collapse.d.ts +2 -1
  131. package/dist/store/twin-collapse.d.ts.map +1 -1
  132. package/dist/store/twin-collapse.js +128 -104
  133. package/dist/store/twin-collapse.js.map +1 -1
  134. package/dist/store/validation-schemas.d.ts +390 -38
  135. package/dist/store/validation-schemas.d.ts.map +1 -1
  136. package/dist/store/vault-manifest.d.ts +9 -2
  137. package/dist/store/vault-manifest.d.ts.map +1 -1
  138. package/dist/store/vault-manifest.js +25 -4
  139. package/dist/store/vault-manifest.js.map +1 -1
  140. package/dist/system/health.d.ts.map +1 -1
  141. package/dist/system/health.js +3 -2
  142. package/dist/system/health.js.map +1 -1
  143. package/dist/tasks/affected-packages.d.ts +21 -2
  144. package/dist/tasks/affected-packages.d.ts.map +1 -1
  145. package/dist/tasks/affected-packages.js +96 -8
  146. package/dist/tasks/affected-packages.js.map +1 -1
  147. package/dist/tasks/affected-scope.d.ts +7 -2
  148. package/dist/tasks/affected-scope.d.ts.map +1 -1
  149. package/dist/tasks/affected-scope.js +158 -14
  150. package/dist/tasks/affected-scope.js.map +1 -1
  151. package/dist/tasks/change-set.d.ts +10 -0
  152. package/dist/tasks/change-set.d.ts.map +1 -1
  153. package/dist/tasks/change-set.js +70 -3
  154. package/dist/tasks/change-set.js.map +1 -1
  155. package/dist/tasks/done-plan.d.ts +11 -5
  156. package/dist/tasks/done-plan.d.ts.map +1 -1
  157. package/dist/tasks/done-plan.js +54 -10
  158. package/dist/tasks/done-plan.js.map +1 -1
  159. package/dist/tasks/done-record.d.ts.map +1 -1
  160. package/dist/tasks/done-record.js +25 -0
  161. package/dist/tasks/done-record.js.map +1 -1
  162. package/dist/tasks/evidence.d.ts.map +1 -1
  163. package/dist/tasks/evidence.js +22 -2
  164. package/dist/tasks/evidence.js.map +1 -1
  165. package/dist/tasks/gate-result-cache.d.ts.map +1 -1
  166. package/dist/tasks/gate-result-cache.js +24 -3
  167. package/dist/tasks/gate-result-cache.js.map +1 -1
  168. package/dist/tasks/gate-runner.d.ts +27 -3
  169. package/dist/tasks/gate-runner.d.ts.map +1 -1
  170. package/dist/tasks/gate-runner.js +77 -29
  171. package/dist/tasks/gate-runner.js.map +1 -1
  172. package/dist/tasks/qa-run-binding.d.ts +22 -3
  173. package/dist/tasks/qa-run-binding.d.ts.map +1 -1
  174. package/dist/tasks/qa-run-binding.js +46 -4
  175. package/dist/tasks/qa-run-binding.js.map +1 -1
  176. package/dist/tasks/test-run-binding.d.ts +21 -3
  177. package/dist/tasks/test-run-binding.d.ts.map +1 -1
  178. package/dist/tasks/test-run-binding.js +60 -14
  179. package/dist/tasks/test-run-binding.js.map +1 -1
  180. package/dist/tasks/tool-cache.d.ts.map +1 -1
  181. package/dist/tasks/tool-cache.js +24 -12
  182. package/dist/tasks/tool-cache.js.map +1 -1
  183. package/migrations/drizzle-cleo-global/20261016130000_t13777-nexus-audit-row-uids/migration.sql +18 -0
  184. package/migrations/drizzle-cleo-project/20261015100000_t12914-lifecycle-release-row-uids/migration.sql +88 -0
  185. package/migrations/drizzle-cleo-project/20261016130000_t13777-log-row-uids/migration.sql +42 -0
  186. package/migrations/drizzle-cleo-project/20261016140000_t13777-audit-collapse/migration.sql +31 -0
  187. package/package.json +18 -18
  188. package/templates/CLEO-REFERENCE.md +1 -1
@@ -34,6 +34,11 @@
34
34
  * decided first-parent ancestor, i.e. the PR merged into a red main and
35
35
  * introduced no failure of its own. See {@link inheritedOnMerge}.
36
36
  *
37
+ * A third (T13809): a merge commit whose run FAILED only on the flaky-quarantine
38
+ * budget, with every test passing, failed no test of the PR's. See
39
+ * {@link nonTestFailuresOn}. The stand-in search also looks past later runs red
40
+ * for that reason alone, up to {@link CI_DESCENDANT_MAX_CANDIDATES} commits.
41
+ *
37
42
  * @task T12634
38
43
  */
39
44
  import type { EvidenceAtom, EvidenceValidationContext } from '@cleocode/contracts';
@@ -98,8 +103,9 @@ export interface EvaluateMergeCommitChecksOptions {
98
103
  */
99
104
  descendantSha?: string;
100
105
  /**
101
- * The merge commit's failures were all inherited from its base (T13453):
102
- * the descendant may stand in for a FAILED required check too.
106
+ * The merge commit's failures were not the PR's: all inherited from its
107
+ * base (T13453), or only the flaky-quarantine budget with every test passing
108
+ * (T13809). The descendant may stand in for a FAILED required check too.
103
109
  */
104
110
  inheritedFailures?: boolean;
105
111
  }
@@ -124,7 +130,7 @@ export interface MainCommit {
124
130
  parents: number;
125
131
  }
126
132
  /** Most later default-branch commits examined for a green stand-in run (T12742). */
127
- export declare const CI_DESCENDANT_MAX_CANDIDATES = 10;
133
+ export declare const CI_DESCENDANT_MAX_CANDIDATES = 20;
128
134
  /** Latest committer time after the merge commit a stand-in may have (T12742): 7 days. */
129
135
  export declare const CI_DESCENDANT_MAX_AGE_SECONDS: number;
130
136
  /** A `ci:` atom resolution: the validated atom, or the refusal. */
@@ -191,6 +197,11 @@ export interface ResolveCiEvidenceOptions {
191
197
  * `git log --first-parent -- <paths>`.
192
198
  */
193
199
  touchingCommits?: (from: string, to: string, paths: readonly string[], cwd: string) => MainCommit[] | null;
200
+ /**
201
+ * Plain-text log of one Actions job (a check-run id), or null when it cannot
202
+ * be read (T13809). Defaults to `gh api repos/{owner}/{repo}/actions/jobs/<id>/logs`.
203
+ */
204
+ fetchJobLog?: (jobId: number, cwd: string) => Promise<string | null>;
194
205
  }
195
206
  /**
196
207
  * Whether the project opted in to merge-commit CI as test/QA evidence
@@ -390,6 +401,70 @@ export declare function inheritedOnMerge(required: readonly string[], checks: re
390
401
  sha: string;
391
402
  checks: readonly CommitCheck[];
392
403
  }>, pins: Record<string, RequiredCheckPinSpec>): InheritedOnMergeResult;
404
+ /**
405
+ * Whether a unit-test job log shows a failure caused by the flaky-quarantine
406
+ * budget alone (T13809). `scripts/ci-flaky-quarantine.mjs` fails a main run
407
+ * whose quarantine is over budget right after the first test run, before it
408
+ * applies its own rule that a quarantined test's failure never blocks. So
409
+ * the log qualifies when the budget heading is present, no error escaped a
410
+ * test, and every failing test of that run is one the quarantine lists (no
411
+ * failure at all is the common case). Only the run's own summary block counts
412
+ * ({@link runSummary}), never a summary a test echoed. Any doubt is `false`:
413
+ * no summary block, a kill or crash marker, a failing test outside the
414
+ * quarantine, a file that failed to load, or counts that do not add up
415
+ * (per-file `(N tests | M failed)` lines included).
416
+ *
417
+ * @param log - The job's plain-text log (ANSI colour codes allowed).
418
+ * @returns Whether the job failed only on the quarantine budget.
419
+ * @task T13809
420
+ */
421
+ export declare function isQuarantineBudgetOnlyLog(log: string): boolean;
422
+ /** Result of {@link nonTestFailuresOn}. */
423
+ export type NonTestFailuresResult = {
424
+ ok: true;
425
+ jobs: Array<{
426
+ name: string;
427
+ mergeRunId: number;
428
+ }>;
429
+ } | {
430
+ ok: false;
431
+ reason: string;
432
+ };
433
+ /**
434
+ * Whether every failure on a commit's CI is a non-test failure (T13809): each
435
+ * failing job of a pinned workflow failed on the flaky-quarantine budget alone
436
+ * ({@link isQuarantineBudgetOnlyLog}) with every test passing. The required
437
+ * checks themselves (the aggregate job and its workflow run) only report the
438
+ * jobs they need, so their failure follows; any cancelled or timed-out job, a
439
+ * pending run, or an unreadable log refuses.
440
+ *
441
+ * @param checks - Checks fetched for `sha`.
442
+ * @param sha - The commit judged.
443
+ * @param required - Required check names.
444
+ * @param pins - Required-name to app/workflow pin.
445
+ * @param fetchJobLog - Plain-text log of one job.
446
+ * @param cwd - Repository work tree for `gh`.
447
+ * @returns The quarantine-only jobs, or why the commit failed for real.
448
+ * @task T13809
449
+ */
450
+ export declare function nonTestFailuresOn(checks: readonly CommitCheck[], sha: string, required: readonly string[], pins: Record<string, RequiredCheckPinSpec>, fetchJobLog: NonNullable<ResolveCiEvidenceOptions['fetchJobLog']>, cwd: string): Promise<NonTestFailuresResult>;
451
+ /**
452
+ * Whether a later commit's CI was cancelled rather than failed (T13809): its
453
+ * pinned workflow run concluded `cancelled` (a concurrency group stopped it)
454
+ * and every failing job's log is readable and names no failed test; a job a
455
+ * cancel interrupted often reports `failure` with nothing failed in its log. Such a run decides nothing, as a
456
+ * cancelled run never did (T12742).
457
+ *
458
+ * @param checks - Checks fetched for `sha`.
459
+ * @param sha - The later commit.
460
+ * @param required - Required check names.
461
+ * @param pins - Required-name to app/workflow pin.
462
+ * @param fetchJobLog - Plain-text log of one job.
463
+ * @param cwd - Repository work tree for `gh`.
464
+ * @returns Whether the run was cancelled with no test failing.
465
+ * @task T13809
466
+ */
467
+ export declare function cancelledWithoutTestFailure(checks: readonly CommitCheck[], sha: string, required: readonly string[], pins: Record<string, RequiredCheckPinSpec>, fetchJobLog: NonNullable<ResolveCiEvidenceOptions['fetchJobLog']>, cwd: string): Promise<boolean>;
393
468
  /** Inputs of {@link findGreenDescendant}. */
394
469
  export interface FindGreenDescendantInput {
395
470
  /** Required check names. */
@@ -430,6 +505,8 @@ export interface FindGreenDescendantInput {
430
505
  isAncestor: NonNullable<ResolveCiEvidenceOptions['isAncestor']>;
431
506
  /** First parent of a commit (T13453: the inherited-failure walk); absent = never inherit. */
432
507
  firstParentOf?: NonNullable<ResolveCiEvidenceOptions['firstParentOf']>;
508
+ /** Log of one job (T13809: the quarantine-budget check); absent = never classify. */
509
+ fetchJobLog?: NonNullable<ResolveCiEvidenceOptions['fetchJobLog']>;
433
510
  }
434
511
  /** Result of {@link findGreenDescendant}. */
435
512
  export type FindGreenDescendantResult = {
@@ -447,6 +524,11 @@ export type FindGreenDescendantResult = {
447
524
  prHeadSha?: string;
448
525
  /** The merge commit's inherited failures, when it FAILED rather than being superseded (T13453). */
449
526
  inherited?: InheritedFailure[];
527
+ /** The merge commit's jobs that failed on the flaky-quarantine budget alone (T13809). */
528
+ nonTest?: Array<{
529
+ name: string;
530
+ mergeRunId: number;
531
+ }>;
450
532
  } | {
451
533
  ok: false;
452
534
  reason: string;
@@ -457,7 +539,9 @@ export type FindGreenDescendantResult = {
457
539
  *
458
540
  * The stand-in's CI tested the DESCENDANT's tree, not the merge tree. It is
459
541
  * accepted only when that difference cannot matter to the PR:
460
- * - the merge commit must be superseded, not failed ({@link supersededOnMerge});
542
+ * - the merge commit must be superseded, not failed ({@link supersededOnMerge}),
543
+ * unless its failures were inherited from main ({@link inheritedOnMerge}) or
544
+ * were only the flaky-quarantine budget ({@link nonTestFailuresOn}, T13809);
461
545
  * - the PR's own final head (`prHeadSha`) must have a green latest
462
546
  * `pull_request` run for every superseded check — a later fix on main
463
547
  * never rescues a broken PR;
@@ -473,7 +557,8 @@ export type FindGreenDescendantResult = {
473
557
  * failed job of a pinned workflow) refuses, and a PENDING run refuses with
474
558
  * "wait for <sha>" — a later green run is never shopped for past one that
475
559
  * is red or may still go red. Only cancelled, skipped and missing
476
- * (never-started) runs move on to the next candidate.
560
+ * (never-started) runs, and a run red only for the flaky-quarantine budget
561
+ * (T13809), move on to the next candidate.
477
562
  *
478
563
  * @param input - Merge-commit checks, pins, changed paths, PR head and injected I/O.
479
564
  * @returns The stand-in SHA, its checks and proven range, or the refusal reason.
@@ -1 +1 @@
1
- {"version":3,"file":"ci-evidence.d.ts","sourceRoot":"","sources":["../../src/release/ci-evidence.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ci-evidence.d.ts","sourceRoot":"","sources":["../../src/release/ci-evidence.ts"],"names":[],"mappings":"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"}
@@ -34,6 +34,11 @@
34
34
  * decided first-parent ancestor, i.e. the PR merged into a red main and
35
35
  * introduced no failure of its own. See {@link inheritedOnMerge}.
36
36
  *
37
+ * A third (T13809): a merge commit whose run FAILED only on the flaky-quarantine
38
+ * budget, with every test passing, failed no test of the PR's. See
39
+ * {@link nonTestFailuresOn}. The stand-in search also looks past later runs red
40
+ * for that reason alone, up to {@link CI_DESCENDANT_MAX_CANDIDATES} commits.
41
+ *
37
42
  * @task T12634
38
43
  */
39
44
  import { execFileSync } from 'node:child_process';
@@ -46,7 +51,7 @@ import { describeRequiredWorkflowsSource, readRequiredCheckPins, resolvePrEviden
46
51
  /** First-parent ancestors searched for a decided base verdict of a failing job (T13453). */
47
52
  export const CI_INHERITED_MAX_ANCESTORS = 10;
48
53
  /** Most later default-branch commits examined for a green stand-in run (T12742). */
49
- export const CI_DESCENDANT_MAX_CANDIDATES = 10;
54
+ export const CI_DESCENDANT_MAX_CANDIDATES = 20;
50
55
  /** Latest committer time after the merge commit a stand-in may have (T12742): 7 days. */
51
56
  export const CI_DESCENDANT_MAX_AGE_SECONDS = 7 * 24 * 60 * 60;
52
57
  /** Merge-commit verdicts a later green main run may stand in for (T12742). */
@@ -601,6 +606,204 @@ export function inheritedOnMerge(required, checks, mergeCommitSha, ancestors, pi
601
606
  const names = required.filter((name) => !judgeOnSha(checks.filter((c) => c.name === name && pinMatches(c, pins[name])), mergeCommitSha).ok);
602
607
  return { ok: true, names, inherited };
603
608
  }
609
+ /**
610
+ * The heading `scripts/ci-flaky-quarantine.mjs` prints when it fails a main
611
+ * run because the open quarantine exceeds its budget (T13145). It returns
612
+ * right after the first test run, whatever that run's outcome.
613
+ */
614
+ const QUARANTINE_BUDGET_HEADING = '### Flaky quarantine over budget';
615
+ /** Test-title form shared by vitest's ` > `-joined names and the quarantine list. */
616
+ const normTitle = (title) => title
617
+ .replace(/\s*>\s*/g, ' ')
618
+ .replace(/\s+/g, ' ')
619
+ .trim();
620
+ /** The failed count in one vitest summary line (0 when it names none). */
621
+ const failedIn = (line) => Number(/(\d+) failed/.exec(line)?.[1] ?? 0);
622
+ /**
623
+ * The run's own vitest summary block in `text` (T13809): the LAST `Test Files`
624
+ * line, preceded by a blank or test-result line and followed within four lines
625
+ * by its `Tests`, `Start at` and `Duration` lines, with no test result or test
626
+ * output after it. A killed run has no block of its own; a block a test echoed
627
+ * (even a full one) is followed by more test output, or follows a child's
628
+ * unprefixed output. Null when there is none.
629
+ */
630
+ /** A vitest per-file result, a test's captured output, or a failure line. */
631
+ const TEST_RESULT_LINE = /^\S*\s+(?:[✓❯×✗↓]\s|stdout \||stderr \|)|\bFAIL\s{2,}/;
632
+ /** What vitest prints right before its summary: a blank (timestamp-only) or result line. */
633
+ const BEFORE_SUMMARY_LINE = /^(?:\d{4}-\d\d-\d\dT\S+Z)?\s*$|^\S*\s+[✓❯×✗↓]\s|\bFAIL\s{2,}/;
634
+ function runSummary(text) {
635
+ const lines = text.split('\n');
636
+ for (let i = lines.length - 1; i >= 0; i--) {
637
+ if (!/\bTest Files\s{2,}\d/.test(lines[i] ?? ''))
638
+ continue;
639
+ // A child vitest's echoed block may follow its unprefixed output (inherited stdio).
640
+ if (i > 0 && !BEFORE_SUMMARY_LINE.test(lines[i - 1] ?? ''))
641
+ return null;
642
+ const block = lines.slice(i + 1, i + 5);
643
+ const tests = block.find((l) => /\bTests\s{2,}\d/.test(l));
644
+ if (!tests || !block.some((l) => /\bStart at\s{2,}/.test(l)))
645
+ return null;
646
+ const duration = block.findIndex((l) => /\bDuration\s{2,}/.test(l));
647
+ if (duration < 0)
648
+ return null;
649
+ // The run's own summary is its LAST vitest output: a test result or test
650
+ // output after it means this block was echoed by a test, and the run itself
651
+ // died before printing its own (an OOM-killed run prints no marker).
652
+ if (lines.slice(i + 2 + duration).some((l) => TEST_RESULT_LINE.test(l)))
653
+ return null;
654
+ return { failedFiles: failedIn(lines[i] ?? ''), failedTests: failedIn(tests) };
655
+ }
656
+ return null;
657
+ }
658
+ /**
659
+ * vitest's own report that a worker died or ran out of memory. A test's child
660
+ * processes print `Killed` and signal names as ordinary output, so those are
661
+ * not markers; a killed vitest leaves no summary block ({@link runSummary}).
662
+ */
663
+ const RUN_DIED = /Worker exited unexpectedly|Worker terminated due to reaching memory limit|JavaScript heap out of memory/;
664
+ /**
665
+ * Whether a unit-test job log shows a failure caused by the flaky-quarantine
666
+ * budget alone (T13809). `scripts/ci-flaky-quarantine.mjs` fails a main run
667
+ * whose quarantine is over budget right after the first test run, before it
668
+ * applies its own rule that a quarantined test's failure never blocks. So
669
+ * the log qualifies when the budget heading is present, no error escaped a
670
+ * test, and every failing test of that run is one the quarantine lists (no
671
+ * failure at all is the common case). Only the run's own summary block counts
672
+ * ({@link runSummary}), never a summary a test echoed. Any doubt is `false`:
673
+ * no summary block, a kill or crash marker, a failing test outside the
674
+ * quarantine, a file that failed to load, or counts that do not add up
675
+ * (per-file `(N tests | M failed)` lines included).
676
+ *
677
+ * @param log - The job's plain-text log (ANSI colour codes allowed).
678
+ * @returns Whether the job failed only on the quarantine budget.
679
+ * @task T13809
680
+ */
681
+ export function isQuarantineBudgetOnlyLog(log) {
682
+ const text = log.replace(/\u001b\[[0-9;]*m/g, '');
683
+ // The script's own verdict is the last heading, with its count line under it
684
+ // (a test's fixture output may carry the heading too).
685
+ const heading = text.lastIndexOf(QUARANTINE_BUDGET_HEADING);
686
+ if (heading < 0)
687
+ return false;
688
+ if (!/^[^\n]*\n(?:[^\n]*\n)?[^\n]*\d+ tests are quarantined \(most \d+\)/.test(text.slice(heading))) {
689
+ return false;
690
+ }
691
+ const run = text.slice(0, heading);
692
+ if (/Unhandled (Errors?|Rejection)|\bErrors\s{2,}\d/.test(run) || RUN_DIED.test(run))
693
+ return false;
694
+ // Only the run's own summary counts; a summary a test echoed never stands in.
695
+ const summary = runSummary(run);
696
+ if (summary === null)
697
+ return false;
698
+ const { failedFiles, failedTests } = summary;
699
+ const testPath = String.raw `\S+\.(?:test|spec)\.[cm]?[jt]sx?`;
700
+ // Every per-file `(N tests | M failed)` line must agree with the summary.
701
+ const perFile = [
702
+ ...run.matchAll(new RegExp(`❯\\s+(?:\\S+\\s+)?(${testPath})\\s+\\([^)]*?(\\d+) failed`, 'gm')),
703
+ ].map((m) => ({ file: m[1] ?? '', failed: Number(m[2] ?? 0) }));
704
+ if (perFile.reduce((a, f) => a + f.failed, 0) !== failedTests)
705
+ return false;
706
+ if (failedFiles === 0 && failedTests === 0)
707
+ return true;
708
+ const quarantined = [
709
+ ...text.slice(heading).matchAll(new RegExp(`- \`(${testPath})\` > (.+)$`, 'gm')),
710
+ ].map((m) => ({ file: m[1] ?? '', title: normTitle(m[2] ?? '') }));
711
+ const failing = new Map();
712
+ for (const m of run.matchAll(new RegExp(`\\bFAIL\\s{2,}(?:\\S+\\s+)?(${testPath}) > (.+)$`, 'gm'))) {
713
+ const entry = { file: m[1] ?? '', title: normTitle(m[2] ?? '') };
714
+ failing.set(`${entry.file}\u0000${entry.title}`, entry);
715
+ }
716
+ if (failing.size !== failedTests)
717
+ return false;
718
+ if (new Set([...failing.values()].map((f) => f.file)).size !== failedFiles)
719
+ return false;
720
+ if (!perFile.every((p) => [...failing.values()].some((f) => f.file === p.file)))
721
+ return false;
722
+ return [...failing.values()].every((f) => quarantined.some((q) => q.title === f.title && q.file.endsWith(f.file)));
723
+ }
724
+ /**
725
+ * Whether every failure on a commit's CI is a non-test failure (T13809): each
726
+ * failing job of a pinned workflow failed on the flaky-quarantine budget alone
727
+ * ({@link isQuarantineBudgetOnlyLog}) with every test passing. The required
728
+ * checks themselves (the aggregate job and its workflow run) only report the
729
+ * jobs they need, so their failure follows; any cancelled or timed-out job, a
730
+ * pending run, or an unreadable log refuses.
731
+ *
732
+ * @param checks - Checks fetched for `sha`.
733
+ * @param sha - The commit judged.
734
+ * @param required - Required check names.
735
+ * @param pins - Required-name to app/workflow pin.
736
+ * @param fetchJobLog - Plain-text log of one job.
737
+ * @param cwd - Repository work tree for `gh`.
738
+ * @returns The quarantine-only jobs, or why the commit failed for real.
739
+ * @task T13809
740
+ */
741
+ export async function nonTestFailuresOn(checks, sha, required, pins, fetchJobLog, cwd) {
742
+ const latest = latestRuns(checks, sha, pinnedScope(required, pins));
743
+ const jobs = [];
744
+ for (const c of latest) {
745
+ if (c.status !== 'completed') {
746
+ return { ok: false, reason: `${c.name}: pending on ${sha.slice(0, 12)}` };
747
+ }
748
+ if (c.conclusion === 'success' || c.conclusion === 'skipped')
749
+ continue;
750
+ // The required checks (the aggregate job and its workflow run) follow the jobs they need.
751
+ if (c.source === 'workflow-run' || required.includes(c.name))
752
+ continue;
753
+ const log = c.conclusion === 'failure' ? await fetchJobLog(c.id, cwd) : null;
754
+ if (log === null || !isQuarantineBudgetOnlyLog(log)) {
755
+ return {
756
+ ok: false,
757
+ reason: `${c.name}: ${c.conclusion} on ${sha.slice(0, 12)}${log === null && c.conclusion === 'failure' ? ' (its log could not be read)' : ''} — not the flaky-quarantine budget alone`,
758
+ };
759
+ }
760
+ jobs.push({ name: c.name, mergeRunId: c.id });
761
+ }
762
+ return jobs.length > 0
763
+ ? { ok: true, jobs }
764
+ : { ok: false, reason: `no job failed on ${sha.slice(0, 12)} for the quarantine budget` };
765
+ }
766
+ /**
767
+ * Whether a later commit's CI was cancelled rather than failed (T13809): its
768
+ * pinned workflow run concluded `cancelled` (a concurrency group stopped it)
769
+ * and every failing job's log is readable and names no failed test; a job a
770
+ * cancel interrupted often reports `failure` with nothing failed in its log. Such a run decides nothing, as a
771
+ * cancelled run never did (T12742).
772
+ *
773
+ * @param checks - Checks fetched for `sha`.
774
+ * @param sha - The later commit.
775
+ * @param required - Required check names.
776
+ * @param pins - Required-name to app/workflow pin.
777
+ * @param fetchJobLog - Plain-text log of one job.
778
+ * @param cwd - Repository work tree for `gh`.
779
+ * @returns Whether the run was cancelled with no test failing.
780
+ * @task T13809
781
+ */
782
+ export async function cancelledWithoutTestFailure(checks, sha, required, pins, fetchJobLog, cwd) {
783
+ const latest = latestRuns(checks, sha, pinnedScope(required, pins));
784
+ const runs = latest.filter((c) => c.source === 'workflow-run');
785
+ if (!runs.some((r) => r.conclusion === 'cancelled'))
786
+ return false;
787
+ if (runs.some((r) => r.conclusion !== 'cancelled' && r.conclusion !== 'success'))
788
+ return false;
789
+ for (const c of latest) {
790
+ if (c.source === 'workflow-run' || required.includes(c.name))
791
+ continue;
792
+ if (c.status !== 'completed')
793
+ return false;
794
+ if (HARMLESS_CONCLUSIONS.has(c.conclusion ?? ''))
795
+ continue;
796
+ const log = await fetchJobLog(c.id, cwd);
797
+ // An unreadable log proves nothing about the job: never skip past it.
798
+ if (log === null)
799
+ return false;
800
+ const text = log.replace(/\u001b\[[0-9;]*m/g, '');
801
+ if (/\bFAIL\s{2,}|\d+ failed/.test(text) || RUN_DIED.test(text)) {
802
+ return false;
803
+ }
804
+ }
805
+ return true;
806
+ }
604
807
  /**
605
808
  * CI-definition paths no commit in a descendant range may touch (T12742): the
606
809
  * pinned workflow file of every required check, local composite actions, and
@@ -620,7 +823,9 @@ function ciDefinitionPaths(required, pins) {
620
823
  *
621
824
  * The stand-in's CI tested the DESCENDANT's tree, not the merge tree. It is
622
825
  * accepted only when that difference cannot matter to the PR:
623
- * - the merge commit must be superseded, not failed ({@link supersededOnMerge});
826
+ * - the merge commit must be superseded, not failed ({@link supersededOnMerge}),
827
+ * unless its failures were inherited from main ({@link inheritedOnMerge}) or
828
+ * were only the flaky-quarantine budget ({@link nonTestFailuresOn}, T13809);
624
829
  * - the PR's own final head (`prHeadSha`) must have a green latest
625
830
  * `pull_request` run for every superseded check — a later fix on main
626
831
  * never rescues a broken PR;
@@ -636,7 +841,8 @@ function ciDefinitionPaths(required, pins) {
636
841
  * failed job of a pinned workflow) refuses, and a PENDING run refuses with
637
842
  * "wait for <sha>" — a later green run is never shopped for past one that
638
843
  * is red or may still go red. Only cancelled, skipped and missing
639
- * (never-started) runs move on to the next candidate.
844
+ * (never-started) runs, and a run red only for the flaky-quarantine budget
845
+ * (T13809), move on to the next candidate.
640
846
  *
641
847
  * @param input - Merge-commit checks, pins, changed paths, PR head and injected I/O.
642
848
  * @returns The stand-in SHA, its checks and proven range, or the refusal reason.
@@ -649,6 +855,19 @@ export async function findGreenDescendant(input) {
649
855
  pins,
650
856
  });
651
857
  let inherited;
858
+ let nonTest;
859
+ if (!superseded.ok && input.fetchJobLog) {
860
+ // T13809: a merge-commit run red only because main's flaky quarantine was
861
+ // over budget (every test passed) failed no test of the PR's.
862
+ const result = await nonTestFailuresOn(input.checks, merge, required, pins, input.fetchJobLog, cwd);
863
+ if (result.ok) {
864
+ nonTest = result.jobs;
865
+ superseded = {
866
+ ok: true,
867
+ names: required.filter((name) => !judgeOnSha(input.checks.filter((c) => c.name === name && pinMatches(c, pins[name])), merge).ok),
868
+ };
869
+ }
870
+ }
652
871
  if (!superseded.ok && input.firstParentOf) {
653
872
  // T13453: a real failure may still be main's, inherited by a PR that
654
873
  // merged into a red main. Walk the first-parent ancestors for each
@@ -736,6 +955,17 @@ export async function findGreenDescendant(input) {
736
955
  if (!fetched.ok)
737
956
  return { ok: false, reason: fetched.reason };
738
957
  const failedJob = firstRealFailure(fetched.checks, sha, scope);
958
+ if (failedJob && input.fetchJobLog) {
959
+ // T13809: a later run red only for the quarantine budget, or cancelled
960
+ // with no test failing, decides nothing; look on. Any other failure still
961
+ // refuses: a green run is never shopped for past a real one.
962
+ const quarantineOnly = await nonTestFailuresOn(fetched.checks, sha, required, pins, input.fetchJobLog, cwd);
963
+ if (quarantineOnly.ok)
964
+ continue;
965
+ if (await cancelledWithoutTestFailure(fetched.checks, sha, required, pins, input.fetchJobLog, cwd)) {
966
+ continue;
967
+ }
968
+ }
739
969
  if (failedJob) {
740
970
  return {
741
971
  ok: false,
@@ -771,6 +1001,7 @@ export async function findGreenDescendant(input) {
771
1001
  range: `${merge}..${sha}`,
772
1002
  ...(head ? { prHeadSha: head } : {}),
773
1003
  ...(inherited ? { inherited } : {}),
1004
+ ...(nonTest ? { nonTest } : {}),
774
1005
  };
775
1006
  }
776
1007
  }
@@ -926,6 +1157,29 @@ function ghApi(path, cwd) {
926
1157
  return null;
927
1158
  }
928
1159
  }
1160
+ /** Default {@link ResolveCiEvidenceOptions.fetchJobLog}: the job's plain-text log via `gh` (T13809). */
1161
+ async function defaultFetchJobLog(jobId, cwd) {
1162
+ if (!isGitWorkTree(cwd) || !isGhCliAvailable())
1163
+ return null;
1164
+ try {
1165
+ // Job logs carry ANSI colour; gh refuses to print them without the flag.
1166
+ const args = [
1167
+ 'api',
1168
+ '--allow-escape-sequences',
1169
+ `repos/{owner}/{repo}/actions/jobs/${jobId}/logs`,
1170
+ ];
1171
+ return execFileSync('gh', args, {
1172
+ cwd,
1173
+ encoding: 'utf-8',
1174
+ stdio: ['ignore', 'pipe', 'pipe'],
1175
+ maxBuffer: 64 * 1024 * 1024,
1176
+ timeout: ghQueryTimeoutMs(),
1177
+ });
1178
+ }
1179
+ catch {
1180
+ return null;
1181
+ }
1182
+ }
929
1183
  /**
930
1184
  * Drop runs a schedule started from every fetch (T13623). A nightly run that
931
1185
  * happens to land on a merge commit tests main at that hour, not the merge:
@@ -1294,6 +1548,7 @@ export async function resolveCiEvidenceAtom(prNumber, roots, opts = {}) {
1294
1548
  touchingCommits: opts.touchingCommits ?? listPathTouchingMainCommits,
1295
1549
  isAncestor: opts.isAncestor ?? defaultIsAncestor,
1296
1550
  firstParentOf: opts.firstParentOf ?? defaultFirstParentOf,
1551
+ fetchJobLog: opts.fetchJobLog ?? defaultFetchJobLog,
1297
1552
  });
1298
1553
  if (found.ok) {
1299
1554
  const withDescendant = [...checks, ...found.checks];
@@ -1301,7 +1556,7 @@ export async function resolveCiEvidenceAtom(prNumber, roots, opts = {}) {
1301
1556
  ...(treeEqualHead ? { treeEquivalentSha: treeEqualHead } : {}),
1302
1557
  pins,
1303
1558
  descendantSha: found.sha,
1304
- ...(found.inherited ? { inheritedFailures: true } : {}),
1559
+ ...(found.inherited || found.nonTest ? { inheritedFailures: true } : {}),
1305
1560
  });
1306
1561
  if (rejudged.ok) {
1307
1562
  checks = withDescendant;
@@ -1311,6 +1566,7 @@ export async function resolveCiEvidenceAtom(prNumber, roots, opts = {}) {
1311
1566
  range: found.range,
1312
1567
  ...(found.prHeadSha ? { prHeadSha: found.prHeadSha } : {}),
1313
1568
  ...(found.inherited ? { inherited: found.inherited } : {}),
1569
+ ...(found.nonTest ? { nonTest: found.nonTest } : {}),
1314
1570
  };
1315
1571
  }
1316
1572
  else {
@@ -1348,6 +1604,8 @@ export async function resolveCiEvidenceAtom(prNumber, roots, opts = {}) {
1348
1604
  const docsOnlyDiff = pr.changedPaths.length > 0 && pr.changedPaths.every(isCiDocumentPath);
1349
1605
  const isCode = !docsOnlyDiff;
1350
1606
  const jobsByGate = {};
1607
+ const fetchJobLog = opts.fetchJobLog ?? defaultFetchJobLog;
1608
+ let mergeNonTest;
1351
1609
  if (isCode) {
1352
1610
  for (const g of gateLists) {
1353
1611
  const globs = readCiChecks(roots.storeRoot).jobs?.[g.key];
@@ -1370,6 +1628,20 @@ export async function resolveCiEvidenceAtom(prNumber, roots, opts = {}) {
1370
1628
  }
1371
1629
  const scope = { ...(app !== undefined ? { app } : {}), workflows: scopeWorkflows };
1372
1630
  let judgedJobs = evaluateJobs(globs, checks, pr.mergeCommitSha, scope);
1631
+ if (!judgedJobs.ok) {
1632
+ // T13809: a job red only on the quarantine budget ran every test and
1633
+ // they all passed; for this gate it ran and succeeded.
1634
+ mergeNonTest ??= descendant?.nonTest
1635
+ ? { ok: true, jobs: descendant.nonTest }
1636
+ : await nonTestFailuresOn(checks, pr.mergeCommitSha, required.workflows, pins, fetchJobLog, cwd);
1637
+ if (mergeNonTest.ok) {
1638
+ const passed = new Set(mergeNonTest.jobs.map((j) => j.mergeRunId));
1639
+ const asRun = checks.map((c) => (passed.has(c.id) ? { ...c, conclusion: 'success' } : c));
1640
+ const onMerge = evaluateJobs(globs, asRun, pr.mergeCommitSha, scope);
1641
+ if (onMerge.ok)
1642
+ judgedJobs = onMerge;
1643
+ }
1644
+ }
1373
1645
  if (!judgedJobs.ok && treeEqualHead && !mainOnly) {
1374
1646
  const onHead = evaluateJobs(globs, checks, treeEqualHead, scope, 'pull_request');
1375
1647
  if (onHead.ok)
@@ -1431,6 +1703,7 @@ export async function resolveCiEvidenceAtom(prNumber, roots, opts = {}) {
1431
1703
  descendantRange: descendant.range,
1432
1704
  ...(descendant.prHeadSha ? { descendantPrHeadSha: descendant.prHeadSha } : {}),
1433
1705
  ...(descendant.inherited ? { inheritedFailures: descendant.inherited } : {}),
1706
+ ...(descendant.nonTest ? { nonTestFailures: descendant.nonTest } : {}),
1434
1707
  }
1435
1708
  : {}),
1436
1709
  ...(mainOnly ? { mainOnly: true } : {}),