sequant 2.8.0 → 2.10.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 (211) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/README.md +23 -4
  4. package/dist/bin/cli.js +99 -18
  5. package/dist/marketplace/external_plugins/sequant/.claude-plugin/plugin.json +1 -1
  6. package/dist/marketplace/external_plugins/sequant/.mcp.json +1 -1
  7. package/dist/marketplace/external_plugins/sequant/README.md +58 -2
  8. package/dist/marketplace/external_plugins/sequant/hooks/parallel-marker.sh +50 -0
  9. package/dist/marketplace/external_plugins/sequant/hooks/post-tool.sh +38 -10
  10. package/dist/marketplace/external_plugins/sequant/hooks/pre-tool.sh +405 -67
  11. package/dist/marketplace/external_plugins/sequant/skills/_shared/references/trust-model.md +18 -0
  12. package/dist/marketplace/external_plugins/sequant/skills/assess/SKILL.md +250 -344
  13. package/dist/marketplace/external_plugins/sequant/skills/assess/references/predicted-collision-detection.md +10 -7
  14. package/dist/marketplace/external_plugins/sequant/skills/docs/SKILL.md +4 -4
  15. package/dist/marketplace/external_plugins/sequant/skills/exec/SKILL.md +26 -6
  16. package/dist/marketplace/external_plugins/sequant/skills/fullsolve/SKILL.md +4 -2
  17. package/dist/marketplace/external_plugins/sequant/skills/loop/SKILL.md +38 -2
  18. package/dist/marketplace/external_plugins/sequant/skills/merger/SKILL.md +2 -2
  19. package/dist/marketplace/external_plugins/sequant/skills/qa/SKILL.md +337 -57
  20. package/dist/marketplace/external_plugins/sequant/skills/qa/references/anti-pattern-detection.md +6 -6
  21. package/dist/marketplace/external_plugins/sequant/skills/qa/references/call-site-review.md +2 -2
  22. package/dist/marketplace/external_plugins/sequant/skills/qa/references/code-review-checklist.md +2 -2
  23. package/dist/marketplace/external_plugins/sequant/skills/qa/references/fixtures/injection-issue-body.md +36 -0
  24. package/dist/marketplace/external_plugins/sequant/skills/qa/references/quality-gates.md +21 -7
  25. package/dist/marketplace/external_plugins/sequant/skills/qa/references/testing-requirements.md +1 -1
  26. package/dist/marketplace/external_plugins/sequant/skills/qa/scripts/quality-checks.sh +11 -11
  27. package/dist/marketplace/external_plugins/sequant/skills/reflect/SKILL.md +27 -13
  28. package/dist/marketplace/external_plugins/sequant/skills/reflect/references/documentation-tiers.md +80 -68
  29. package/dist/marketplace/external_plugins/sequant/skills/reflect/references/phase-reflection.md +31 -15
  30. package/dist/marketplace/external_plugins/sequant/skills/release/SKILL.md +11 -3
  31. package/dist/marketplace/external_plugins/sequant/skills/setup/SKILL.md +5 -5
  32. package/dist/marketplace/external_plugins/sequant/skills/spec/SKILL.md +2 -0
  33. package/dist/marketplace/external_plugins/sequant/skills/spec/references/verification-criteria.md +1 -1
  34. package/dist/marketplace/external_plugins/sequant/skills/test/SKILL.md +1 -1
  35. package/dist/src/commands/assess-render.d.ts +23 -0
  36. package/dist/src/commands/assess-render.js +60 -0
  37. package/dist/src/commands/doctor.js +8 -13
  38. package/dist/src/commands/init.js +13 -1
  39. package/dist/src/commands/locks.js +2 -0
  40. package/dist/src/commands/logs.js +20 -6
  41. package/dist/src/commands/merge.js +154 -2
  42. package/dist/src/commands/ready-tui-adapter.js +6 -1
  43. package/dist/src/commands/ready.d.ts +25 -3
  44. package/dist/src/commands/ready.js +39 -13
  45. package/dist/src/commands/resume.d.ts +113 -0
  46. package/dist/src/commands/resume.js +193 -0
  47. package/dist/src/commands/run-display.d.ts +20 -0
  48. package/dist/src/commands/run-display.js +117 -5
  49. package/dist/src/commands/run-flags.d.ts +42 -1
  50. package/dist/src/commands/run-flags.js +53 -1
  51. package/dist/src/commands/run-progress.js +26 -1
  52. package/dist/src/commands/run.js +11 -10
  53. package/dist/src/commands/state.js +7 -0
  54. package/dist/src/commands/stats.js +47 -0
  55. package/dist/src/commands/status.d.ts +9 -0
  56. package/dist/src/commands/status.js +24 -1
  57. package/dist/src/commands/sync.js +90 -19
  58. package/dist/src/commands/update.js +28 -5
  59. package/dist/src/lib/ac-parser.d.ts +14 -0
  60. package/dist/src/lib/ac-parser.js +99 -5
  61. package/dist/src/lib/assess/index.d.ts +10 -0
  62. package/dist/src/lib/assess/index.js +9 -0
  63. package/dist/src/lib/assess/renderer.d.ts +64 -0
  64. package/dist/src/lib/assess/renderer.js +481 -0
  65. package/dist/src/lib/assess/types.d.ts +224 -0
  66. package/dist/src/lib/assess/types.js +241 -0
  67. package/dist/src/lib/assess-collision-detect.d.ts +19 -2
  68. package/dist/src/lib/assess-collision-detect.js +68 -4
  69. package/dist/src/lib/ci/outputs.d.ts +15 -2
  70. package/dist/src/lib/ci/outputs.js +17 -5
  71. package/dist/src/lib/cli-flags.d.ts +33 -0
  72. package/dist/src/lib/cli-flags.js +46 -0
  73. package/dist/src/lib/cli-ui/run-renderer-types.d.ts +21 -7
  74. package/dist/src/lib/cli-ui/run-renderer.d.ts +10 -0
  75. package/dist/src/lib/cli-ui/run-renderer.js +79 -9
  76. package/dist/src/lib/errors.d.ts +84 -6
  77. package/dist/src/lib/errors.js +142 -17
  78. package/dist/src/lib/locks/index.d.ts +3 -3
  79. package/dist/src/lib/locks/index.js +2 -2
  80. package/dist/src/lib/locks/lock-manager.d.ts +20 -2
  81. package/dist/src/lib/locks/lock-manager.js +47 -3
  82. package/dist/src/lib/locks/types.d.ts +34 -3
  83. package/dist/src/lib/locks/types.js +16 -0
  84. package/dist/src/lib/manifest.js +1 -17
  85. package/dist/src/lib/mcp-config.d.ts +45 -0
  86. package/dist/src/lib/mcp-config.js +77 -1
  87. package/dist/src/lib/merge-check/combined-branch-test.d.ts +21 -2
  88. package/dist/src/lib/merge-check/combined-branch-test.js +233 -110
  89. package/dist/src/lib/merge-check/command-result.d.ts +36 -0
  90. package/dist/src/lib/merge-check/command-result.js +56 -0
  91. package/dist/src/lib/merge-check/index.d.ts +4 -0
  92. package/dist/src/lib/merge-check/index.js +1 -1
  93. package/dist/src/lib/merge-check/report.js +5 -1
  94. package/dist/src/lib/merge-check/types.d.ts +9 -0
  95. package/dist/src/lib/merge-check/watch.d.ts +121 -0
  96. package/dist/src/lib/merge-check/watch.js +215 -0
  97. package/dist/src/lib/qa/infra-blocked-ci.d.ts +90 -0
  98. package/dist/src/lib/qa/infra-blocked-ci.js +80 -0
  99. package/dist/src/lib/settings.d.ts +14 -0
  100. package/dist/src/lib/settings.js +61 -8
  101. package/dist/src/lib/shutdown.d.ts +42 -2
  102. package/dist/src/lib/shutdown.js +75 -5
  103. package/dist/src/lib/skills-check.d.ts +26 -0
  104. package/dist/src/lib/skills-check.js +31 -0
  105. package/dist/src/lib/stacks.d.ts +110 -1
  106. package/dist/src/lib/stacks.js +244 -5
  107. package/dist/src/lib/templates.d.ts +74 -0
  108. package/dist/src/lib/templates.js +171 -16
  109. package/dist/src/lib/test-tautology-detector.d.ts +9 -2
  110. package/dist/src/lib/test-tautology-detector.js +153 -12
  111. package/dist/src/lib/version-check.d.ts +31 -0
  112. package/dist/src/lib/version-check.js +46 -7
  113. package/dist/src/lib/workflow/batch-executor.d.ts +138 -6
  114. package/dist/src/lib/workflow/batch-executor.js +550 -54
  115. package/dist/src/lib/workflow/chain-preflight.d.ts +89 -0
  116. package/dist/src/lib/workflow/chain-preflight.js +199 -0
  117. package/dist/src/lib/workflow/chain-resume.d.ts +118 -0
  118. package/dist/src/lib/workflow/chain-resume.js +170 -0
  119. package/dist/src/lib/workflow/completed-status.d.ts +52 -0
  120. package/dist/src/lib/workflow/completed-status.js +57 -0
  121. package/dist/src/lib/workflow/config-resolver.d.ts +26 -0
  122. package/dist/src/lib/workflow/config-resolver.js +54 -2
  123. package/dist/src/lib/workflow/dependency-markers.d.ts +29 -0
  124. package/dist/src/lib/workflow/dependency-markers.js +79 -0
  125. package/dist/src/lib/workflow/drivers/agent-driver.d.ts +7 -0
  126. package/dist/src/lib/workflow/drivers/aider.d.ts +2 -0
  127. package/dist/src/lib/workflow/drivers/aider.js +2 -0
  128. package/dist/src/lib/workflow/drivers/claude-code.d.ts +21 -0
  129. package/dist/src/lib/workflow/drivers/claude-code.js +50 -8
  130. package/dist/src/lib/workflow/error-classifier.d.ts +9 -2
  131. package/dist/src/lib/workflow/error-classifier.js +14 -1
  132. package/dist/src/lib/workflow/git-diff-utils.d.ts +35 -3
  133. package/dist/src/lib/workflow/git-diff-utils.js +77 -4
  134. package/dist/src/lib/workflow/heartbeat.d.ts +38 -0
  135. package/dist/src/lib/workflow/heartbeat.js +90 -0
  136. package/dist/src/lib/workflow/log-writer.d.ts +44 -1
  137. package/dist/src/lib/workflow/log-writer.js +81 -14
  138. package/dist/src/lib/workflow/metrics-schema.d.ts +42 -3
  139. package/dist/src/lib/workflow/metrics-schema.js +16 -0
  140. package/dist/src/lib/workflow/metrics-writer.d.ts +2 -1
  141. package/dist/src/lib/workflow/phase-executor.d.ts +234 -13
  142. package/dist/src/lib/workflow/phase-executor.js +533 -56
  143. package/dist/src/lib/workflow/phase-registry.js +2 -1
  144. package/dist/src/lib/workflow/platforms/github.d.ts +64 -0
  145. package/dist/src/lib/workflow/platforms/github.js +152 -0
  146. package/dist/src/lib/workflow/qa-cache.d.ts +6 -1
  147. package/dist/src/lib/workflow/qa-cache.js +22 -9
  148. package/dist/src/lib/workflow/ready-gate.d.ts +17 -4
  149. package/dist/src/lib/workflow/ready-gate.js +25 -9
  150. package/dist/src/lib/workflow/run-log-schema.d.ts +37 -0
  151. package/dist/src/lib/workflow/run-log-schema.js +92 -2
  152. package/dist/src/lib/workflow/run-orchestrator.d.ts +33 -0
  153. package/dist/src/lib/workflow/run-orchestrator.js +429 -47
  154. package/dist/src/lib/workflow/skills-preflight.d.ts +89 -0
  155. package/dist/src/lib/workflow/skills-preflight.js +112 -0
  156. package/dist/src/lib/workflow/state-cleanup.js +9 -2
  157. package/dist/src/lib/workflow/state-manager.d.ts +33 -0
  158. package/dist/src/lib/workflow/state-manager.js +83 -0
  159. package/dist/src/lib/workflow/state-schema.d.ts +26 -0
  160. package/dist/src/lib/workflow/state-schema.js +47 -0
  161. package/dist/src/lib/workflow/status-derivation.d.ts +30 -0
  162. package/dist/src/lib/workflow/status-derivation.js +27 -0
  163. package/dist/src/lib/workflow/types.d.ts +149 -4
  164. package/dist/src/lib/workflow/types.js +1 -0
  165. package/dist/src/lib/workflow/worktree-manager.d.ts +70 -2
  166. package/dist/src/lib/workflow/worktree-manager.js +201 -52
  167. package/dist/src/mcp/tools/run.d.ts +11 -1
  168. package/dist/src/mcp/tools/run.js +22 -1
  169. package/dist/src/mcp/tools/status.js +6 -0
  170. package/dist/src/ui/tui/ElapsedTimer.d.ts +12 -3
  171. package/dist/src/ui/tui/ElapsedTimer.js +12 -10
  172. package/dist/src/ui/tui/IssueBox.js +10 -2
  173. package/dist/src/ui/tui/row-cap.js +2 -1
  174. package/dist/src/ui/tui/theme.d.ts +7 -0
  175. package/dist/src/ui/tui/theme.js +9 -0
  176. package/package.json +9 -10
  177. package/templates/hooks/parallel-marker.sh +50 -0
  178. package/templates/hooks/post-tool.sh +38 -10
  179. package/templates/hooks/pre-tool.sh +405 -67
  180. package/templates/scripts/cleanup-worktree.sh +282 -30
  181. package/templates/scripts/new-feature.sh +264 -16
  182. package/templates/skills/_shared/references/trust-model.md +18 -0
  183. package/templates/skills/assess/SKILL.md +250 -344
  184. package/templates/skills/assess/references/predicted-collision-detection.md +10 -7
  185. package/templates/skills/docs/SKILL.md +4 -4
  186. package/templates/skills/exec/SKILL.md +26 -6
  187. package/templates/skills/fullsolve/SKILL.md +4 -2
  188. package/templates/skills/loop/SKILL.md +38 -2
  189. package/templates/skills/merger/SKILL.md +2 -2
  190. package/templates/skills/qa/SKILL.md +337 -57
  191. package/templates/skills/qa/references/anti-pattern-detection.md +6 -6
  192. package/templates/skills/qa/references/call-site-review.md +2 -2
  193. package/templates/skills/qa/references/code-review-checklist.md +2 -2
  194. package/templates/skills/qa/references/fixtures/injection-issue-body.md +36 -0
  195. package/templates/skills/qa/references/quality-gates.md +21 -7
  196. package/templates/skills/qa/references/testing-requirements.md +1 -1
  197. package/templates/skills/qa/scripts/quality-checks.sh +11 -11
  198. package/templates/skills/reflect/SKILL.md +27 -13
  199. package/templates/skills/reflect/references/documentation-tiers.md +80 -68
  200. package/templates/skills/reflect/references/phase-reflection.md +31 -15
  201. package/templates/skills/release/SKILL.md +11 -3
  202. package/templates/skills/setup/SKILL.md +5 -5
  203. package/templates/skills/spec/SKILL.md +2 -0
  204. package/templates/skills/spec/references/verification-criteria.md +1 -1
  205. package/templates/skills/test/SKILL.md +1 -1
  206. package/dist/src/lib/phase-spinner.d.ts +0 -146
  207. package/dist/src/lib/phase-spinner.js +0 -255
  208. package/dist/src/lib/workflow/pr-operations.d.ts +0 -86
  209. package/dist/src/lib/workflow/pr-operations.js +0 -326
  210. package/dist/src/lib/workflow/run-summary.d.ts +0 -36
  211. package/dist/src/lib/workflow/run-summary.js +0 -142
@@ -79,13 +79,19 @@ export const ErrorContextSchema = z.object({
79
79
  stdoutTail: z.array(z.string()),
80
80
  /** Process exit code */
81
81
  exitCode: z.number().int().optional(),
82
- /** Classified error category (legacy, kept for backwards compatibility) */
82
+ /**
83
+ * Classified error category (legacy, kept for backwards compatibility).
84
+ * Keep in sync with `ERROR_CATEGORIES` in `error-classifier.ts` —
85
+ * `rate_limit` / `billing` added by #761 AC-6.
86
+ */
83
87
  category: z.enum([
84
88
  "context_overflow",
85
89
  "api_error",
86
90
  "hook_failure",
87
91
  "build_error",
88
92
  "timeout",
93
+ "rate_limit",
94
+ "billing",
89
95
  "unknown",
90
96
  ]),
91
97
  /** Typed error class name (AC-8), e.g. "ApiError", "BuildError" */
@@ -174,6 +180,20 @@ export const IssueLogSchema = z.object({
174
180
  phases: z.array(PhaseLogSchema),
175
181
  /** Total execution time in seconds */
176
182
  totalDurationSeconds: z.number().nonnegative(),
183
+ /**
184
+ * Set when this issue never finished because the run was terminated from
185
+ * outside (#856). Reuses the `"failure"` status — additive boolean rather
186
+ * than a new `IssueStatus` enum value, matching the `capped` precedent
187
+ * above, so the persisted-log schema stays stable at `version: 1`.
188
+ *
189
+ * Without this, a run killed mid-flight persisted as `success`: `startIssue`
190
+ * seeds `status: "success"` and only `logPhase` ever revises it, so an issue
191
+ * whose first phase never completed was written out as a pass with an empty
192
+ * `phases[]`.
193
+ */
194
+ aborted: z.boolean().optional(),
195
+ /** Human-readable cause of the abort (e.g. `terminated by SIGTERM`). */
196
+ abortReason: z.string().optional(),
177
197
  /** PR number if created after successful QA */
178
198
  prNumber: z.number().int().positive().optional(),
179
199
  /** PR URL if created after successful QA */
@@ -206,6 +226,21 @@ export const RunSummarySchema = z.object({
206
226
  passed: z.number().int().nonnegative(),
207
227
  /** Number of issues that failed */
208
228
  failed: z.number().int().nonnegative(),
229
+ /**
230
+ * Number of issues that ended `partial` — timed out with no genuine failure
231
+ * and no recovery (#766). Given its own bucket so an all-partial run no longer
232
+ * vanishes from both `passed` and `failed` (the `0 passed · 0 failed` bug).
233
+ * `.default(0)` keeps logs written before this field parseable.
234
+ */
235
+ partial: z.number().int().nonnegative().default(0),
236
+ /**
237
+ * Number of issues cut short by an external signal (#856). A sub-count of
238
+ * `failed`, not a fourth disjoint bucket — aborted issues carry
239
+ * `status: "failure"` so existing consumers keep working, and this field
240
+ * says whether the failure was the run's own or something killing it.
241
+ * `.default(0)` keeps logs written before this field parseable.
242
+ */
243
+ aborted: z.number().int().nonnegative().default(0),
209
244
  /** Total execution time in seconds */
210
245
  totalDurationSeconds: z.number().nonnegative(),
211
246
  });
@@ -233,6 +268,11 @@ export const RunLogSchema = z.object({
233
268
  startCommit: z.string().optional(),
234
269
  /** Git commit SHA at run end (AC-2) */
235
270
  endCommit: z.string().optional(),
271
+ /**
272
+ * Signal that terminated the run, when it ended by external signal rather
273
+ * than by finishing (#856). Present iff at least one issue is `aborted`.
274
+ */
275
+ abortedBy: z.string().optional(),
236
276
  });
237
277
  /**
238
278
  * Default log directory paths
@@ -263,7 +303,9 @@ export function generateLogFilename(runId, startTime) {
263
303
  */
264
304
  export function createEmptyRunLog(config, options) {
265
305
  const runId = randomUUID();
266
- const startTime = new Date().toISOString();
306
+ // #867: use the caller-supplied run origin when provided so the log's wall
307
+ // clock shares the orchestrator's start; fall back to now for standalone use.
308
+ const startTime = (options?.startTime ?? new Date()).toISOString();
267
309
  return {
268
310
  version: 1,
269
311
  runId,
@@ -274,6 +316,8 @@ export function createEmptyRunLog(config, options) {
274
316
  totalIssues: 0,
275
317
  passed: 0,
276
318
  failed: 0,
319
+ partial: 0,
320
+ aborted: 0,
277
321
  totalDurationSeconds: 0,
278
322
  },
279
323
  startCommit: options?.startCommit,
@@ -326,6 +370,14 @@ export function finalizeRunLog(runLog, options) {
326
370
  const totalDurationSeconds = (endTime.getTime() - startTime.getTime()) / 1000;
327
371
  const passed = runLog.issues.filter((i) => i.status === "success").length;
328
372
  const failed = runLog.issues.filter((i) => i.status === "failure").length;
373
+ // #766: `partial` gets its own bucket so an all-partial run isn't counted as
374
+ // `0 passed · 0 failed` — it landed in neither before.
375
+ const partial = runLog.issues.filter((i) => i.status === "partial").length;
376
+ // #856: aborted issues are also counted in `failed` (they carry
377
+ // `status: "failure"`); this is the sub-count that says *why* they failed,
378
+ // so a run killed from outside is distinguishable from one whose phases
379
+ // genuinely failed.
380
+ const aborted = runLog.issues.filter((i) => i.aborted).length;
329
381
  return {
330
382
  ...runLog,
331
383
  endTime: endTime.toISOString(),
@@ -333,8 +385,46 @@ export function finalizeRunLog(runLog, options) {
333
385
  totalIssues: runLog.issues.length,
334
386
  passed,
335
387
  failed,
388
+ partial,
389
+ aborted,
336
390
  totalDurationSeconds,
337
391
  },
338
392
  endCommit: options?.endCommit ?? runLog.endCommit,
393
+ ...((options?.abortedBy ?? runLog.abortedBy) && {
394
+ abortedBy: options?.abortedBy ?? runLog.abortedBy,
395
+ }),
339
396
  };
340
397
  }
398
+ /**
399
+ * Derive an issue's overall log status from its phase log entries (#766).
400
+ *
401
+ * Phases are appended in execution order, so the last entry for a given phase
402
+ * name is its latest attempt — that attempt wins. This lets a `timeout`/
403
+ * `failure` that a later quality-loop iteration recovers from de-escalate to
404
+ * `success`, keeping the JSON log consistent with the live card and summary
405
+ * table (AC-3/AC-5). `loop` is auxiliary recovery and never determines the
406
+ * verdict (mirrors the live-card rule); an unrecovered failure still leaves a
407
+ * non-loop phase failed. Priority among latest attempts: failure > timeout >
408
+ * success.
409
+ *
410
+ * An issue with no phase entries is a `failure`, not a `success` (#856). The
411
+ * only way to reach that state is for `startIssue` to have run while no phase
412
+ * ever completed — i.e. the run was cut short. Returning `success` there is
413
+ * what let a SIGTERM'd run persist as a pass with an empty `phases[]`.
414
+ */
415
+ export function deriveIssueLogStatus(phases) {
416
+ const latest = new Map();
417
+ for (const p of phases) {
418
+ if (p.phase === "loop")
419
+ continue;
420
+ latest.set(p.phase, p.status);
421
+ }
422
+ const statuses = [...latest.values()];
423
+ if (statuses.length === 0)
424
+ return "failure";
425
+ if (statuses.some((s) => s === "failure"))
426
+ return "failure";
427
+ if (statuses.some((s) => s === "timeout"))
428
+ return "partial";
429
+ return "success";
430
+ }
@@ -13,6 +13,7 @@ import { LogWriter } from "./log-writer.js";
13
13
  import { StateManager } from "./state-manager.js";
14
14
  import { ShutdownManager } from "../shutdown.js";
15
15
  import type { LockFile } from "../locks/index.js";
16
+ import { type ChainResumePlan } from "./chain-resume.js";
16
17
  import { WorkflowEventEmitter } from "./event-emitter.js";
17
18
  import type { SequantSettings } from "../settings.js";
18
19
  /**
@@ -55,6 +56,12 @@ export interface OrchestratorConfig {
55
56
  packageManager?: string;
56
57
  /** Base branch for rebase/PR targets */
57
58
  baseBranch?: string;
59
+ /**
60
+ * Chain resume plan (#760). Present only when re-running a `--chain` batch
61
+ * whose completed prefix is being skipped. Drives the first active link's
62
+ * rebase onto the last completed link's committed tip in `executeSequential`.
63
+ */
64
+ chainResume?: ChainResumePlan;
58
65
  /** Per-phase progress callback (parallel mode) */
59
66
  onProgress?: ProgressCallback;
60
67
  /** #672 AC-2: phase-plan callback forwarded into per-issue contexts. */
@@ -112,6 +119,13 @@ export interface ResolvedRun {
112
119
  config: ExecutionConfig;
113
120
  /** Parsed + dep-sorted issue numbers (pre-state-guard) */
114
121
  issueNumbers: number[];
122
+ /**
123
+ * Raw CLI issue order BEFORE `sortByDependencies` reorders it (#762).
124
+ * The chain content pre-flight must compare against this order — comparing
125
+ * against the dep-sorted `issueNumbers` would make the dependency-order and
126
+ * file-overlap-order checks dead code, since the sorter already fixed them.
127
+ */
128
+ rawIssueOrder: number[];
115
129
  /** Resolved batches if --batch specified, else null */
116
130
  batches: number[][] | null;
117
131
  /** Resolved base branch (CLI → settings → auto-detect → "main") */
@@ -150,6 +164,13 @@ export interface RunResult {
150
164
  mergedOptions: RunOptions;
151
165
  /** Log writer (for reflection access) */
152
166
  logWriter: LogWriter | null;
167
+ /**
168
+ * Run wall-clock duration in seconds, computed once by the orchestrator from
169
+ * the run's start and end (#867). The post-run summary reads THIS value rather
170
+ * than re-summing per-issue durations — under `--parallel` that sum
171
+ * double-counts overlapping issues and over-reports by ~the concurrency factor.
172
+ */
173
+ wallClockDurationSeconds: number;
153
174
  }
154
175
  /**
155
176
  * CLI-free workflow execution engine.
@@ -174,6 +195,18 @@ export declare class RunOrchestrator {
174
195
  * listening (#504, AC-3).
175
196
  */
176
197
  getEmitter(): WorkflowEventEmitter;
198
+ /**
199
+ * The wrapped progress sink handed to the batch executor — every phase
200
+ * lifecycle event enters the orchestrator through here.
201
+ *
202
+ * @internal Exported for testing only. `applyProgressEvent` is private and
203
+ * depends on `issueStates`/`phaseStartTimes`/`emitter`, so there is no way
204
+ * to exercise its branches short of a full `run()`. Without this seam the
205
+ * #804 `waiting` branch would be untestable — and an untested `waiting`
206
+ * branch is not cosmetic: falling through to the complete/failed handler
207
+ * marks a merely-paused phase `failed` and emits `phase_failed`.
208
+ */
209
+ getProgressCallback(): ProgressCallback;
177
210
  /**
178
211
  * Point-in-time view of the entire run.
179
212
  *