sequant 2.6.2 → 2.8.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 (62) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/README.md +13 -1
  4. package/dist/bin/cli.d.ts +1 -1
  5. package/dist/bin/cli.js +11 -1
  6. package/dist/bin/preflight.d.ts +21 -0
  7. package/dist/bin/preflight.js +45 -0
  8. package/dist/marketplace/external_plugins/sequant/.claude-plugin/plugin.json +1 -1
  9. package/dist/marketplace/external_plugins/sequant/skills/_shared/references/force-push.md +34 -0
  10. package/dist/marketplace/external_plugins/sequant/skills/assess/SKILL.md +24 -7
  11. package/dist/marketplace/external_plugins/sequant/skills/exec/SKILL.md +29 -0
  12. package/dist/marketplace/external_plugins/sequant/skills/loop/SKILL.md +100 -2
  13. package/dist/marketplace/external_plugins/sequant/skills/qa/SKILL.md +24 -0
  14. package/dist/marketplace/external_plugins/sequant/skills/qa/references/anti-pattern-detection.md +285 -0
  15. package/dist/marketplace/external_plugins/sequant/skills/qa/references/call-site-review.md +202 -0
  16. package/dist/marketplace/external_plugins/sequant/skills/qa/references/quality-gates.md +287 -0
  17. package/dist/marketplace/external_plugins/sequant/skills/qa/references/test-quality-checklist.md +272 -0
  18. package/dist/marketplace/external_plugins/sequant/skills/qa/references/testing-requirements.md +40 -0
  19. package/dist/marketplace/external_plugins/sequant/skills/qa/scripts/quality-checks.sh +95 -11
  20. package/dist/marketplace/external_plugins/sequant/skills/references/shared/framework-gotchas.md +186 -0
  21. package/dist/marketplace/external_plugins/sequant/skills/release/SKILL.md +661 -0
  22. package/dist/marketplace/external_plugins/sequant/skills/test/references/browser-testing-patterns.md +423 -0
  23. package/dist/marketplace/external_plugins/sequant/skills/upstream/SKILL.md +419 -0
  24. package/dist/src/commands/sync.d.ts +1 -0
  25. package/dist/src/commands/sync.js +56 -1
  26. package/dist/src/commands/update.js +7 -0
  27. package/dist/src/lib/errors.d.ts +85 -0
  28. package/dist/src/lib/errors.js +111 -0
  29. package/dist/src/lib/version-check.d.ts +19 -0
  30. package/dist/src/lib/version-check.js +44 -0
  31. package/dist/src/lib/workflow/batch-executor.js +61 -6
  32. package/dist/src/lib/workflow/drivers/agent-driver.d.ts +17 -0
  33. package/dist/src/lib/workflow/drivers/claude-code.d.ts +22 -0
  34. package/dist/src/lib/workflow/drivers/claude-code.js +111 -7
  35. package/dist/src/lib/workflow/log-writer.d.ts +1 -1
  36. package/dist/src/lib/workflow/phase-executor.d.ts +18 -0
  37. package/dist/src/lib/workflow/phase-executor.js +76 -14
  38. package/dist/src/lib/workflow/run-log-schema.d.ts +3 -0
  39. package/dist/src/lib/workflow/run-log-schema.js +7 -0
  40. package/dist/src/lib/workflow/state-manager.d.ts +1 -0
  41. package/dist/src/lib/workflow/state-manager.js +6 -0
  42. package/dist/src/lib/workflow/state-schema.d.ts +3 -0
  43. package/dist/src/lib/workflow/state-schema.js +7 -0
  44. package/dist/src/lib/workflow/types.d.ts +17 -0
  45. package/dist/src/ui/tui/theme.d.ts +18 -4
  46. package/dist/src/ui/tui/theme.js +18 -4
  47. package/package.json +4 -3
  48. package/templates/skills/_shared/references/force-push.md +34 -0
  49. package/templates/skills/assess/SKILL.md +24 -7
  50. package/templates/skills/exec/SKILL.md +29 -0
  51. package/templates/skills/loop/SKILL.md +100 -2
  52. package/templates/skills/qa/SKILL.md +24 -0
  53. package/templates/skills/qa/references/anti-pattern-detection.md +285 -0
  54. package/templates/skills/qa/references/call-site-review.md +202 -0
  55. package/templates/skills/qa/references/quality-gates.md +287 -0
  56. package/templates/skills/qa/references/test-quality-checklist.md +272 -0
  57. package/templates/skills/qa/references/testing-requirements.md +40 -0
  58. package/templates/skills/qa/scripts/quality-checks.sh +95 -11
  59. package/templates/skills/references/shared/framework-gotchas.md +186 -0
  60. package/templates/skills/release/SKILL.md +661 -0
  61. package/templates/skills/test/references/browser-testing-patterns.md +423 -0
  62. package/templates/skills/upstream/SKILL.md +419 -0
@@ -8,7 +8,7 @@
8
8
  {
9
9
  "name": "sequant",
10
10
  "description": "AI coding agent orchestrator for Claude Code — resolve GitHub issues end-to-end with isolated git worktrees, quality gates, and an MCP server. Includes 17 skills, workflow MCP tools, and pre/post-tool hooks.",
11
- "version": "2.6.2",
11
+ "version": "2.8.0",
12
12
  "author": {
13
13
  "name": "sequant-io",
14
14
  "email": "hello@sequant.io"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "sequant",
3
3
  "description": "AI coding agent orchestrator for Claude Code — resolve GitHub issues end-to-end with isolated git worktrees and quality gates, through spec → exec → qa phases.",
4
- "version": "2.6.2",
4
+ "version": "2.8.0",
5
5
  "author": {
6
6
  "name": "sequant-io",
7
7
  "email": "hello@sequant.io"
package/README.md CHANGED
@@ -16,6 +16,16 @@ AI coding agents write code well, but leave you to run the workflow around it
16
16
 
17
17
  See the [CHANGELOG](CHANGELOG.md) for release notes, or the [migration guide](CHANGELOG.md#migration-from-v1x) if upgrading from v1.x.
18
18
 
19
+ ### What's new in 2.8
20
+
21
+ - **Clearer failures when an agent stops early** — phases that hit a turn cap now preserve their partial work and halt cleanly for resume instead of discarding it (#739, #733), and rate-limit/out-of-credits failures are named for what they are (with reset time and credit-purchase hints) rather than buried under generic retry noise (#732).
22
+ - **Runtime Node-version guard** — `sequant` checks the running Node against its `engines.node` floor (`>=22.12.0`) at startup and exits with a friendly upgrade message instead of crashing later on a Node-22-only API (#734).
23
+ - **`/assess` avoids npx version skew** — it now emits `sequant run …` when a global install is on `PATH` (and the unchanged `npx sequant run …` otherwise), so copy-pasted commands don't silently run a stale binary (#740).
24
+
25
+ ### What's new in 2.7
26
+
27
+ - **Trustworthy `--dry-run` previews for `sync` and `update`** — `sequant sync --dry-run` (`-d`) previews the exact set the apply would write (`new` + `modified` + `local-override`) and mutates nothing. Both `sync --dry-run` and `update --dry-run` now exit non-zero when work is pending, so a CI/automation job can gate on the exit code instead of parsing stdout. (`update` is the interactive command; `sync` is the documented non-interactive/CI surface.)
28
+
19
29
  ### What's new in 2.6
20
30
 
21
31
  - **Boxed Ink TUI is the default for `sequant run`** — on a TTY, `run` now renders the boxed dashboard by default (matching `sequant ready`). Opt out with `--no-tui` (line renderer) or `-s`/`--quiet` (heartbeat-only); non-TTY output auto-degrades.
@@ -95,7 +105,9 @@ SEQUANT WORKFLOW · #683
95
105
 
96
106
  QA findings post back to the issue as comments, with each acceptance criterion re-checked independently.
97
107
 
98
- > 📹 A recorded demo GIF of the live run grid is coming — tracked in [#695](https://github.com/sequant-io/sequant/issues/695).
108
+ <p align="center">
109
+ <img src="https://raw.githubusercontent.com/sequant-io/sequant/main/docs/assets/run-grid.gif" alt="Sequant run grid: the live boxed TUI driving issue #64 through spec, exec, and qa to a green success rollup" width="760">
110
+ </p>
99
111
 
100
112
  ---
101
113
 
package/dist/bin/cli.d.ts CHANGED
@@ -4,4 +4,4 @@
4
4
  *
5
5
  * Sequential AI phases with quality gates for any codebase.
6
6
  */
7
- export {};
7
+ import "./preflight.js";
package/dist/bin/cli.js CHANGED
@@ -4,6 +4,12 @@
4
4
  *
5
5
  * Sequential AI phases with quality gates for any codebase.
6
6
  */
7
+ // MUST stay first (#734): the Node-version preflight guard. ESM evaluates a
8
+ // module's imports depth-first in source order before the importer's body, so
9
+ // this side-effecting import runs the guard before commander / chalk / the
10
+ // agent SDK / command modules are evaluated — closing the import-time crash
11
+ // window on an old Node below the engines floor. See bin/preflight.ts.
12
+ import "./preflight.js";
7
13
  import { Command, InvalidArgumentError, Option } from "commander";
8
14
  import chalk from "chalk";
9
15
  import { fileURLToPath } from "url";
@@ -15,7 +21,9 @@ import { configureUI, banner } from "../src/lib/cli-ui.js";
15
21
  import { isCI, isStdoutTTY } from "../src/lib/tty.js";
16
22
  import { detectPackageManagerSync, getPackageManagerCommands, } from "../src/lib/stacks.js";
17
23
  // Read version from package.json dynamically
18
- // Works from both source (bin/) and compiled (dist/bin/) locations
24
+ // Works from both source (bin/) and compiled (dist/bin/) locations.
25
+ // Note: the engines.node floor is read separately in bin/preflight.ts, which
26
+ // must run before this module's imports — see the side-effecting import above.
19
27
  function getVersion() {
20
28
  const __dirname = dirname(fileURLToPath(import.meta.url));
21
29
  let dir = __dirname;
@@ -88,6 +96,7 @@ configureUI({
88
96
  isCI: isCI(),
89
97
  minimal: process.env.SEQUANT_MINIMAL === "1",
90
98
  });
99
+ // (Node-version preflight guard runs at import time — see bin/preflight.ts.)
91
100
  // Warn if running from a problematic install location.
92
101
  // The home-stray case ($HOME/node_modules/sequant) gets a distinct warning
93
102
  // because it pollutes resolution for every subdirectory of $HOME, which the
@@ -135,6 +144,7 @@ program
135
144
  .description("Sync skills and templates from the Sequant package (non-interactive)")
136
145
  .option("-f, --force", "Sync even if versions match")
137
146
  .option("-q, --quiet", "Suppress output")
147
+ .option("-d, --dry-run", "Show what sync would write without making changes (exits non-zero if work is pending)")
138
148
  .action(syncCommand);
139
149
  program
140
150
  .command("doctor")
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Runtime Node-version preflight (#734).
4
+ *
5
+ * This module is imported FIRST in `bin/cli.ts`, ahead of every third-party
6
+ * import (commander, chalk, the agent SDK) and every command module. ESM
7
+ * evaluates a module's dependencies depth-first in source order before the
8
+ * importer's body runs, so this module's top-level guard executes before any
9
+ * of those heavier modules are evaluated. That closes the import-time crash
10
+ * window: if a dependency tripped a Node-22-only API at module-load time on an
11
+ * old Node, the user would otherwise get an opaque stack trace from the import
12
+ * itself — before the in-body guard at `cli.ts` ever ran.
13
+ *
14
+ * The only modules evaluated before this guard are Node built-ins plus the
15
+ * first-party `version-check.ts` chain (→ `stacks.ts` → `fs.ts`), which import
16
+ * built-ins only and are therefore safe on the old Node this guard rejects.
17
+ *
18
+ * The pure comparison logic lives in `src/lib/version-check.ts` (AC-6); this
19
+ * file is just the early entry point that reads the floor and invokes it.
20
+ */
21
+ export {};
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Runtime Node-version preflight (#734).
4
+ *
5
+ * This module is imported FIRST in `bin/cli.ts`, ahead of every third-party
6
+ * import (commander, chalk, the agent SDK) and every command module. ESM
7
+ * evaluates a module's dependencies depth-first in source order before the
8
+ * importer's body runs, so this module's top-level guard executes before any
9
+ * of those heavier modules are evaluated. That closes the import-time crash
10
+ * window: if a dependency tripped a Node-22-only API at module-load time on an
11
+ * old Node, the user would otherwise get an opaque stack trace from the import
12
+ * itself — before the in-body guard at `cli.ts` ever ran.
13
+ *
14
+ * The only modules evaluated before this guard are Node built-ins plus the
15
+ * first-party `version-check.ts` chain (→ `stacks.ts` → `fs.ts`), which import
16
+ * built-ins only and are therefore safe on the old Node this guard rejects.
17
+ *
18
+ * The pure comparison logic lives in `src/lib/version-check.ts` (AC-6); this
19
+ * file is just the early entry point that reads the floor and invokes it.
20
+ */
21
+ import { readFileSync } from "fs";
22
+ import { fileURLToPath } from "url";
23
+ import { dirname, resolve } from "path";
24
+ import { assertNodeVersion } from "../src/lib/version-check.js";
25
+ // Derive the engines floor from package.json (single source of truth, AC-3),
26
+ // using the same walk-up read as getVersion() in cli.ts. Built-in globals only,
27
+ // so this runs — rather than crashes — on the old Node it is meant to reject.
28
+ function readEngineFloor() {
29
+ let dir = dirname(fileURLToPath(import.meta.url));
30
+ while (dir !== dirname(dir)) {
31
+ const candidate = resolve(dir, "package.json");
32
+ try {
33
+ const pkg = JSON.parse(readFileSync(candidate, "utf-8"));
34
+ if (pkg.name === "sequant") {
35
+ return pkg.engines?.node ?? null;
36
+ }
37
+ }
38
+ catch {
39
+ // Not found at this level, keep walking up.
40
+ }
41
+ dir = dirname(dir);
42
+ }
43
+ return null; // Fallback — assertNodeVersion treats a null floor as "skip".
44
+ }
45
+ assertNodeVersion(readEngineFloor());
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "sequant",
3
3
  "description": "AI coding agent orchestrator for Claude Code — resolve GitHub issues end-to-end with isolated git worktrees and quality gates, through spec → exec → qa phases.",
4
- "version": "2.6.2",
4
+ "version": "2.8.0",
5
5
  "author": {
6
6
  "name": "sequant-io",
7
7
  "email": "hello@sequant.io"
@@ -0,0 +1,34 @@
1
+ # Force-push handoff pattern
2
+
3
+ When you encounter `HOOK_BLOCKED: Force push` from `.claude/hooks/pre-tool.sh:106-111`, **do not attempt to bypass the hook**. The block is intentional — force-pushing rewrites history and can destroy work for others sharing the branch.
4
+
5
+ ## The pattern: hand the command to the user
6
+
7
+ When a force push is genuinely required (e.g., cleaning contamination off a feature branch after a clean rebase), present the exact command to the user prefixed with `!` so they execute it in-session:
8
+
9
+ ```
10
+ ! git push --force-with-lease origin feature/<branch>
11
+ ```
12
+
13
+ The user pastes that into the prompt; the `!` runs it in their shell, output streams back into the conversation, and you continue from there.
14
+
15
+ **Always prefer `--force-with-lease` over raw `--force`.** `--force-with-lease` refuses to overwrite the remote ref if someone else pushed in the meantime, turning a silent stomp into a clean error.
16
+
17
+ ## Why bypass attempts fail
18
+
19
+ `CLAUDE_HOOKS_DISABLED=true git push --force ...` does **not** work. The hook reads `CLAUDE_HOOKS_DISABLED` at the harness level *before* Bash executes the command, so prefixing the env var inside the command line has no effect. Setting it via `export` in a prior tool call doesn't help either — each Bash tool call is a fresh subprocess.
20
+
21
+ ## When force push is legitimate vs. not
22
+
23
+ | Legitimate | Not legitimate |
24
+ |------------|----------------|
25
+ | Cleaning rebase contamination off your own feature branch before PR | Rewriting history on `main`/`master` |
26
+ | Removing accidentally-committed secrets after rotation | "Squashing for cleanliness" on a shared branch |
27
+ | Recovering from a mistakenly-pushed merge commit | Force-pushing over someone else's work |
28
+
29
+ For shared branches, prefer `git revert` over force push.
30
+
31
+ ## Reference
32
+
33
+ - Block definition: `.claude/hooks/pre-tool.sh:106-111`
34
+ - Regex: `git push.*(--force| -f($| ))` — note this can also match the literal strings inside quoted `gh issue/pr` bodies (workaround: write the body to a file first)
@@ -69,6 +69,20 @@ If the output is non-empty, paste every line verbatim above the dashboard table
69
69
 
70
70
  The orchestrator/MCP mode (`SEQUANT_ORCHESTRATOR` set) returns no output, so the call is safe to make unconditionally.
71
71
 
72
+ **Command prefix (#740, read-only):**
73
+
74
+ Probe once here for a global/PATH `sequant`, and reuse the result for every emitted run command below. `npx sequant` is the invocation most prone to version skew (a dual node prefix plus npx cache reuse can silently run a *stale* binary while a directly-installed `sequant` on PATH is current), so prefer a resolvable global install when one exists.
75
+
76
+ ```bash
77
+ # Resolve CMD_PREFIX once here; reuse it for every emitted run command below.
78
+ command -v sequant >/dev/null 2>&1 && CMD_PREFIX="sequant" || CMD_PREFIX="npx sequant"
79
+ ```
80
+
81
+ - Global install on PATH → `CMD_PREFIX="sequant"` → emit `sequant run …`
82
+ - No global install (npx-only) → `CMD_PREFIX="npx sequant"` → emit `npx sequant run …` (unchanged default — zero behavior change for npx-only users)
83
+
84
+ The probe is read-only and side-effect-free, so it runs unconditionally, including in orchestrator/MCP mode (`SEQUANT_ORCHESTRATOR` set).
85
+
72
86
  **From GitHub (parallel for all issues):**
73
87
 
74
88
  ```bash
@@ -182,7 +196,7 @@ Triggers (any one):
182
196
  - Issue body or comments mention `"depends on #N"`, `"blocked by #N"`, or `"after #N"`
183
197
  - One issue's described output is another issue's input (e.g., A changes a function signature that B consumes)
184
198
 
185
- Format: `Chain: npx sequant run <N1> <N2> --chain --qa-gate -Q <phases> # alternative — <one-line reason>`
199
+ Format: `Chain: <CMD_PREFIX> run <N1> <N2> --chain --qa-gate -Q <phases> # alternative — <one-line reason>` (`<CMD_PREFIX>` resolved in Step 1)
186
200
 
187
201
  Flag references:
188
202
  - `--chain` chains issues (each branches from previous; implies `--sequential`)
@@ -233,15 +247,15 @@ False-positive guards and tunables (excluded paths, the path regex, the slash-co
233
247
  ...
234
248
  ────────────────────────────────────────────────────────────────
235
249
  Commands:
236
- npx sequant run <N1> <N2> <flags>
237
- npx sequant run <N3> <flags> # resume
250
+ <CMD_PREFIX> run <N1> <N2> <flags>
251
+ <CMD_PREFIX> run <N3> <flags> # resume
238
252
  ────────────────────────────────────────────────────────────────
239
253
  Order: <N> → <N> (<dependency reason>)
240
254
 
241
255
  ⚠ #<N> <warning>
242
256
  ⚠ #<N> <warning>
243
257
 
244
- Chain: npx sequant run <N1> <N2> --chain --qa-gate -Q <phases> # alternative — <reason>
258
+ Chain: <CMD_PREFIX> run <N1> <N2> --chain --qa-gate -Q <phases> # alternative — <reason>
245
259
 
246
260
  Flags:
247
261
  <flag> <one-line reason>
@@ -286,6 +300,7 @@ The commands block is headed by `Commands:` — no box-drawing, no character cou
286
300
  6. If ALL issues share the same workflow, emit a single command
287
301
  7. **Line splitting:** When a single command would contain more than 6 issue numbers, split into multiple commands of at most 6 issues each, grouped by compatible workflow. Example: 11 issues → two commands (6 + 5)
288
302
  8. **Minimal flags:** Omit `--phases` when the resulting workflow equals the CLI default (registered at `bin/cli.ts:186`, defined as `DEFAULT_PHASES` in `src/lib/workflow/types.ts`). Prefer additive flags over restating phases — additive flags: `--testgen` and `--security-review` (`bin/cli.ts:208-209`). Use `--testgen` instead of `--phases spec,testgen,exec,qa` (or `…,testgen,…,test,qa` for ui-labelled issues, since `phase-mapper.determinePhasesForIssue` auto-adds `test` from the ui label). Use `--security-review` instead of `--phases spec,security-review,exec,qa`. The posted marker (`<!-- assess:phases=… -->`) records the full resolved workflow regardless — markers are machine-readable, displayed commands are human shorthand. This intentional divergence is fine: parsers consume markers, humans copy commands.
303
+ 9. **Command prefix:** Substitute the Step-1 `CMD_PREFIX` for **every** emitted `sequant run` command — the Commands block, the `Chain:` line, and both single-issue detail-mode commands (PROCEED and the REWRITE "fresh start"). `Cleanup:` commands are `git`/`gh`, not `sequant`, so they are unaffected. A resolvable global `sequant` on PATH yields `sequant run …`; npx-only yields `npx sequant run …` (the default). Never mix prefixes within a single assessment.
289
304
 
290
305
  #### Annotation Rules
291
306
 
@@ -303,7 +318,7 @@ Emit annotations in this order between the separators that follow `Commands:`:
303
318
  - `⚠ #412 bug + auth labels — domain label (auth) takes priority over bug`
304
319
 
305
320
  - **`Chain:`** — Only when 2+ PROCEED issues have a detected dependency (see "Chain detection" in Step 4). Suggests an alternative execution topology. Does not replace the default per-issue commands. Format:
306
- `Chain: npx sequant run <N1> <N2> --chain --qa-gate -Q <phases> # alternative — <one-line reason>`
321
+ `Chain: <CMD_PREFIX> run <N1> <N2> --chain --qa-gate -Q <phases> # alternative — <one-line reason>` (`<CMD_PREFIX>` resolved in Step 1)
307
322
 
308
323
  - **`Flags:`** — Only when non-default flags appear in the commands and the reason isn't obvious. One line per **distinct** flag used across all commands. Omit entire section when `-Q` is the only non-default flag AND its reason is obvious (e.g., all issues are enhancements). Format:
309
324
  ```
@@ -321,6 +336,8 @@ Emit annotations in this order between the separators that follow `Commands:`:
321
336
 
322
337
  Not all issues have explicit `- [ ]` checkboxes, so the `ACs` column is omitted.
323
338
 
339
+ > **Prefix in examples:** The worked examples in this doc show the `npx sequant` default (the zero-install path). When the Step-1 probe resolves a global `sequant` on PATH, `CMD_PREFIX="sequant"` and every emitted command uses `sequant run …` instead — consistently within one assessment (see Commands Block Rule #9).
340
+
324
341
  ```
325
342
  # Action Reason Run
326
343
  462 PARK Manual measurement task ‖
@@ -485,7 +502,7 @@ More context since you're focused on one issue. Separators between every section
485
502
  → PROCEED — <one-line reason>
486
503
 
487
504
  Commands:
488
- npx sequant run <N> <flags>
505
+ <CMD_PREFIX> run <N> <flags>
489
506
 
490
507
  <phases> · <N> ACs
491
508
 
@@ -617,7 +634,7 @@ Need: <specific information required>
617
634
  → REWRITE — <reason>
618
635
 
619
636
  Commands:
620
- npx sequant run <N> <flags> # fresh start
637
+ <CMD_PREFIX> run <N> <flags> # fresh start
621
638
 
622
639
  <phases> · <N> ACs
623
640
  ────────────────────────────────────────────────────────────────
@@ -1657,6 +1657,35 @@ Parse the agent's output text for these patterns to detect failures:
1657
1657
  | `blocked by hook` | Operation was blocked by pre-tool hook |
1658
1658
  | `I'm unable to` | Agent hit a blocking constraint |
1659
1659
 
1660
+ ### 4b2. Detecting Turn-Capped Implementers (Incomplete, not Failed)
1661
+
1662
+ Every spawned implementer runs under a `maxTurns` cap (live since #484). Hitting the cap is **not** a failure — the agent did real, partial work before running out of turns, and that work is preserved (driver returns it flagged `capped: true` and warns rather than erroring, #733). Treat a capped implementer as **incomplete**, distinct from the hook-block failures in Section 4b.
1663
+
1664
+ **Turn-cap detection keywords** (parse the agent's output text):
1665
+
1666
+ | Pattern | Meaning |
1667
+ |---------|---------|
1668
+ | `error_max_turns` | Agent hit its turn cap |
1669
+ | `turn cap` / `Returning partial results` | Driver-emitted turn-cap warning |
1670
+ | Output ends mid-task with no completion report | Likely capped |
1671
+
1672
+ **How to handle a capped implementer:**
1673
+
1674
+ - Do **not** discard its changes or roll back the group — keep the partial work it committed.
1675
+ - Record, per task, **which tasks finished vs. which were capped**. A capped task is incomplete, not done.
1676
+ - Continue with the remaining (non-capped) tasks normally; one cap does not abort the whole `/exec` run.
1677
+ - The next `/exec` iteration (or a resumed session) picks up the capped task to finish it — note it explicitly so it is not mistaken for complete.
1678
+ - Reflect capped tasks honestly in the AC verification table (⚠️ Partial) and the progress update, rather than reporting the AC as fully satisfied.
1679
+
1680
+ ```markdown
1681
+ ### Parallel Group Results
1682
+
1683
+ | Task | Status |
1684
+ |------|--------|
1685
+ | Create types/metrics.ts | ✅ Finished |
1686
+ | Refactor batch-executor | ⚠️ Capped (incomplete — resume next iteration) |
1687
+ ```
1688
+
1660
1689
  ### 4c. Prompt Templates for Sub-Agents
1661
1690
 
1662
1691
  When spawning sub-agents for implementation tasks, use task-specific prompt templates for better results. See [prompt-templates.md](../_shared/references/prompt-templates.md) for the full reference.
@@ -42,6 +42,30 @@ When invoked as `/loop <issue-number>`, your job is to:
42
42
  4. Re-run validation until quality gates pass
43
43
  5. Exit when `READY_FOR_MERGE` or max iterations reached
44
44
 
45
+ ## Orchestration Context
46
+
47
+ When running as part of an orchestrated workflow (e.g., `sequant run` or `/fullsolve`), this skill receives environment variables that indicate the orchestration context:
48
+
49
+ | Environment Variable | Description | Example Value |
50
+ |---------------------|-------------|---------------|
51
+ | `SEQUANT_ORCHESTRATOR` | The orchestrator invoking this skill | `sequant-run` |
52
+ | `SEQUANT_PHASE` | Current phase in the workflow | `loop` |
53
+ | `SEQUANT_ISSUE` | Issue number being processed | `123` |
54
+ | `SEQUANT_WORKTREE` | Path to the feature worktree | `/path/to/worktrees/feature/...` |
55
+
56
+ **Behavior when orchestrated (SEQUANT_ORCHESTRATOR is set):**
57
+
58
+ 1. **Use provided worktree** - Work in `SEQUANT_WORKTREE` path directly
59
+ 2. **Use `SEQUANT_ISSUE`** - Skip issue number parsing from invocation
60
+ 3. **Reduce GitHub comment frequency** - Defer updates to orchestrator
61
+ 4. **Trust issue context** - Orchestrator has already validated issue
62
+
63
+ **Behavior when standalone (SEQUANT_ORCHESTRATOR is NOT set):**
64
+
65
+ - Locate worktree from issue number
66
+ - Post progress comments to GitHub
67
+ - Fetch issue context if needed
68
+
45
69
  ## Invocation
46
70
 
47
71
  - `/loop 123` - Parse log for issue #123, fix issues, re-validate
@@ -50,12 +74,66 @@ When invoked as `/loop <issue-number>`, your job is to:
50
74
 
51
75
  ### Step 1: Read Previous Phase Output
52
76
 
77
+ **The source of findings depends on whether you're running in orchestrated or standalone mode.**
78
+
79
+ #### Step 1A: Orchestrated Mode (SEQUANT_ORCHESTRATOR is set)
80
+
81
+ When `SEQUANT_ORCHESTRATOR` is set, read QA findings from the GitHub issue comments instead of a log file:
82
+
83
+ ```bash
84
+ # Check if we're in orchestrated mode
85
+ if [[ -n "$SEQUANT_ORCHESTRATOR" ]]; then
86
+ echo "Orchestrated mode detected (orchestrator: $SEQUANT_ORCHESTRATOR)"
87
+
88
+ # Use SEQUANT_ISSUE if provided, otherwise parse from invocation
89
+ ISSUE_NUMBER="${SEQUANT_ISSUE:-<issue-number>}"
90
+
91
+ # Fetch QA findings from issue comments (use startswith to avoid matching comments that reference QA format)
92
+ gh issue view "$ISSUE_NUMBER" --json comments -q '.comments[] | select(.body | startswith("## QA Review for Issue")) | .body' | tail -1
93
+ fi
94
+ ```
95
+
96
+ **How to identify QA comments:**
97
+
98
+ | Pattern | Meaning |
99
+ |---------|---------|
100
+ | `## QA Review for Issue #N` | QA phase comment header |
101
+ | `### Verdict:` | Contains AC_NOT_MET, AC_MET_BUT_NOT_A_PLUS, etc. |
102
+ | `### AC Coverage` | Table with MET/NOT_MET/PARTIALLY_MET statuses |
103
+ | `### Required Fixes` or `### Recommendations` | Actionable items to fix |
104
+
105
+ **Parsing QA comment:**
106
+ ```bash
107
+ # Extract verdict from QA comment
108
+ verdict=$(echo "$qa_comment" | grep -oE "Verdict:\s*\w+" | head -1 | awk '{print $2}' || true)
109
+
110
+ # Extract NOT_MET AC items
111
+ not_met_acs=$(echo "$qa_comment" | grep -E "NOT_MET|PARTIALLY_MET" || true)
112
+
113
+ # Extract recommendations section
114
+ recommendations=$(echo "$qa_comment" | sed -n '/### Required Fixes/,/###/p' | head -n -1)
115
+ ```
116
+
117
+ **If no QA comment found in orchestrated mode:**
118
+ 1. Log a clear error: `"Warning: No QA comment found in issue #N"`
119
+ 2. Fall back to Step 1B (log file) as a recovery mechanism
120
+ 3. If log file also doesn't exist, exit with error
121
+
122
+ #### Step 1B: Standalone Mode (no SEQUANT_ORCHESTRATOR)
123
+
124
+ When running standalone (interactive `/loop` invocation), read from the log file:
125
+
53
126
  Use the Read tool to read the log file for this issue:
54
127
  ```
55
128
  Read(file_path="/tmp/claude-issue-<issue-number>.log")
56
129
  ```
57
130
 
58
- Parse the log to find:
131
+ **If log file doesn't exist:**
132
+ - Error: `"Log file not found at /tmp/claude-issue-<N>.log. Please run /spec, /exec, /test, or /qa first."`
133
+
134
+ #### Parsing Findings (Both Modes)
135
+
136
+ Parse the output (from comment or log file) to find:
59
137
  - **Last phase executed:** `/test` or `/qa`
60
138
  - **Verdict:** `READY_FOR_MERGE`, `AC_MET_BUT_NOT_A_PLUS`, `NEEDS_VERIFICATION`,
61
139
  or `AC_NOT_MET`
@@ -102,6 +180,12 @@ Extract:
102
180
 
103
181
  ### Step 4: Locate Feature Worktree
104
182
 
183
+ **If orchestrated (SEQUANT_WORKTREE is set):**
184
+ - Use the provided worktree path directly: `cd $SEQUANT_WORKTREE`
185
+ - Skip the lookup steps below
186
+
187
+ **If standalone:**
188
+
105
189
  Find the worktree for this issue:
106
190
  ```bash
107
191
  git worktree list | grep -E "feature.*<issue-number>" || true
@@ -365,7 +449,21 @@ For each iteration, output:
365
449
 
366
450
  ## Error Handling
367
451
 
368
- **If log file doesn't exist:**
452
+ **If orchestrated but no QA comment found:**
453
+ ```
454
+ Warning: No QA comment found in issue #<N>
455
+ Attempting fallback to log file...
456
+ ```
457
+
458
+ If fallback also fails:
459
+ ```
460
+ Error: No QA findings available.
461
+ - No QA comment found in issue #<N>
462
+ - Log file not found at /tmp/claude-issue-<N>.log
463
+ Please run /qa <N> first.
464
+ ```
465
+
466
+ **If log file doesn't exist (standalone mode):**
369
467
  ```
370
468
  Error: Log file not found at /tmp/claude-issue-<N>.log
371
469
  Please run /spec, /exec, /test, or /qa first.
@@ -1085,6 +1085,30 @@ skill_modified=$(git diff main...HEAD --name-only | grep -E "^\.(claude/skills|s
1085
1085
  ```
1086
1086
  If skill files are modified, the quality-checks.sh script automatically runs the three-directory sync check (section 12). If divergence is detected, this blocks `READY_FOR_MERGE` — verdict becomes `AC_MET_BUT_NOT_A_PLUS` with a note to run `npx tsx scripts/check-skill-sync.ts --fix`.
1087
1087
 
1088
+ #### Turn-Capped Checks → Inconclusive (not a phase failure)
1089
+
1090
+ A spawned quality-check sub-agent runs under a `maxTurns` cap (live on every agent since #484). When an agent hits that cap, its work is **partial**, not failed — the driver returns it flagged `capped: true` and warns rather than erroring (#733).
1091
+
1092
+ **How to recognize a turn-capped check:** the sub-agent's reported output is truncated mid-analysis, ends without a verdict, or explicitly notes it ran out of turns (look for `error_max_turns`, "turn cap", or "Returning partial results" in its output).
1093
+
1094
+ **How to handle it — do NOT fail the whole QA phase on a cap alone:**
1095
+
1096
+ - Mark that single check **⚠️ Inconclusive** in the QA summary, with a one-line reason (`hit turn cap — partial analysis`).
1097
+ - Use whatever partial findings the capped agent *did* surface; do not discard them.
1098
+ - Let the **other** checks proceed and contribute to the verdict normally.
1099
+ - If a capped check leaves an AC genuinely unverified, the verdict is `NEEDS_VERIFICATION` for that AC — never a hard `AC_NOT_MET` justified solely by the cap.
1100
+ - Surface inconclusive checks prominently so a human can re-run that check (e.g. with a higher cap) rather than silently treating the cap as a pass.
1101
+
1102
+ ```markdown
1103
+ ### Quality Checks
1104
+
1105
+ | Check | Status | Notes |
1106
+ |-------|--------|-------|
1107
+ | Type safety | ✅ Pass | 0 issues |
1108
+ | Scope/size | ⚠️ Inconclusive | hit turn cap — partial analysis, re-run recommended |
1109
+ | Security | ✅ Pass | 0 critical |
1110
+ ```
1111
+
1088
1112
  See [quality-gates.md](references/quality-gates.md) for detailed verdict synthesis.
1089
1113
 
1090
1114
  ### Using MCP Tools (Optional)