sequant 2.7.0 → 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.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +9 -1
- package/dist/bin/cli.d.ts +1 -1
- package/dist/bin/cli.js +10 -1
- package/dist/bin/preflight.d.ts +21 -0
- package/dist/bin/preflight.js +45 -0
- package/dist/marketplace/external_plugins/sequant/.claude-plugin/plugin.json +1 -1
- package/dist/marketplace/external_plugins/sequant/skills/_shared/references/force-push.md +34 -0
- package/dist/marketplace/external_plugins/sequant/skills/assess/SKILL.md +24 -7
- package/dist/marketplace/external_plugins/sequant/skills/exec/SKILL.md +29 -0
- package/dist/marketplace/external_plugins/sequant/skills/loop/SKILL.md +100 -2
- package/dist/marketplace/external_plugins/sequant/skills/qa/SKILL.md +24 -0
- package/dist/marketplace/external_plugins/sequant/skills/qa/references/anti-pattern-detection.md +285 -0
- package/dist/marketplace/external_plugins/sequant/skills/qa/references/call-site-review.md +202 -0
- package/dist/marketplace/external_plugins/sequant/skills/qa/references/quality-gates.md +287 -0
- package/dist/marketplace/external_plugins/sequant/skills/qa/references/test-quality-checklist.md +272 -0
- package/dist/marketplace/external_plugins/sequant/skills/qa/references/testing-requirements.md +40 -0
- package/dist/marketplace/external_plugins/sequant/skills/qa/scripts/quality-checks.sh +95 -11
- package/dist/marketplace/external_plugins/sequant/skills/references/shared/framework-gotchas.md +186 -0
- package/dist/marketplace/external_plugins/sequant/skills/release/SKILL.md +661 -0
- package/dist/marketplace/external_plugins/sequant/skills/test/references/browser-testing-patterns.md +423 -0
- package/dist/marketplace/external_plugins/sequant/skills/upstream/SKILL.md +419 -0
- package/dist/src/lib/errors.d.ts +85 -0
- package/dist/src/lib/errors.js +111 -0
- package/dist/src/lib/version-check.d.ts +19 -0
- package/dist/src/lib/version-check.js +44 -0
- package/dist/src/lib/workflow/batch-executor.js +61 -6
- package/dist/src/lib/workflow/drivers/agent-driver.d.ts +17 -0
- package/dist/src/lib/workflow/drivers/claude-code.d.ts +22 -0
- package/dist/src/lib/workflow/drivers/claude-code.js +111 -7
- package/dist/src/lib/workflow/log-writer.d.ts +1 -1
- package/dist/src/lib/workflow/phase-executor.d.ts +18 -0
- package/dist/src/lib/workflow/phase-executor.js +76 -14
- package/dist/src/lib/workflow/run-log-schema.d.ts +3 -0
- package/dist/src/lib/workflow/run-log-schema.js +7 -0
- package/dist/src/lib/workflow/state-manager.d.ts +1 -0
- package/dist/src/lib/workflow/state-manager.js +6 -0
- package/dist/src/lib/workflow/state-schema.d.ts +3 -0
- package/dist/src/lib/workflow/state-schema.js +7 -0
- package/dist/src/lib/workflow/types.d.ts +17 -0
- package/dist/src/ui/tui/theme.d.ts +18 -4
- package/dist/src/ui/tui/theme.js +18 -4
- package/package.json +4 -3
- package/templates/skills/_shared/references/force-push.md +34 -0
- package/templates/skills/assess/SKILL.md +24 -7
- package/templates/skills/exec/SKILL.md +29 -0
- package/templates/skills/loop/SKILL.md +100 -2
- package/templates/skills/qa/SKILL.md +24 -0
- package/templates/skills/qa/references/anti-pattern-detection.md +285 -0
- package/templates/skills/qa/references/call-site-review.md +202 -0
- package/templates/skills/qa/references/quality-gates.md +287 -0
- package/templates/skills/qa/references/test-quality-checklist.md +272 -0
- package/templates/skills/qa/references/testing-requirements.md +40 -0
- package/templates/skills/qa/scripts/quality-checks.sh +95 -11
- package/templates/skills/references/shared/framework-gotchas.md +186 -0
- package/templates/skills/release/SKILL.md +661 -0
- package/templates/skills/test/references/browser-testing-patterns.md +423 -0
- 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.
|
|
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.
|
|
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,12 @@ 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
|
+
|
|
19
25
|
### What's new in 2.7
|
|
20
26
|
|
|
21
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.)
|
|
@@ -99,7 +105,9 @@ SEQUANT WORKFLOW · #683
|
|
|
99
105
|
|
|
100
106
|
QA findings post back to the issue as comments, with each acceptance criterion re-checked independently.
|
|
101
107
|
|
|
102
|
-
>
|
|
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>
|
|
103
111
|
|
|
104
112
|
---
|
|
105
113
|
|
package/dist/bin/cli.d.ts
CHANGED
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
|
|
@@ -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.
|
|
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:
|
|
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
|
-
|
|
237
|
-
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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)
|