@benjaminthomas/spec-driven-dev 1.6.0 → 1.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/README.md +35 -5
- package/bin/cli.mjs +30 -1
- package/package.json +1 -1
- package/skills/spec-create/SKILL.md +9 -0
- package/skills/spec-create/references/complexity-rubric.md +57 -0
- package/skills/spec-create/references/readme-template.md +6 -4
- package/skills/spec-create/references/task-template.md +6 -0
- package/skills/spec-implement/SKILL.md +30 -0
- package/skills/spec-investigate/SKILL.md +5 -0
- package/skills/spec-investigate/references/report-template.md +5 -0
- package/skills/spec-setup/SKILL.md +4 -1
- package/skills/spec-setup/references/config-template.yml +33 -0
package/README.md
CHANGED
|
@@ -93,6 +93,35 @@ words in quotes.
|
|
|
93
93
|
/spec-ship "ship it"
|
|
94
94
|
```
|
|
95
95
|
|
|
96
|
+
**The right model for each task.** `spec-create` rates every task **light**, **standard**, or
|
|
97
|
+
**deep**, based on how much it touches and how risky it is (data, security, concurrency, public
|
|
98
|
+
contracts, unclear requirements). `spec-implement` then runs each task on the model for its tier:
|
|
99
|
+
|
|
100
|
+
| Tier | Typical task | Claude Code | Codex CLI | Effort |
|
|
101
|
+
|---|---|---|---|---|
|
|
102
|
+
| light | copy change, config value, small UI tweak following an existing pattern | `haiku` | `gpt-6-luna` | low |
|
|
103
|
+
| standard | a normal feature slice: route + service + tests | `sonnet` | `gpt-6.1-sol` | medium |
|
|
104
|
+
| deep | migrations with backfills, auth/permissions, concurrency, cross-repo contracts | `opus` | `gpt-6.1-sol` | high |
|
|
105
|
+
| escalate | a deep task that still fails after a fix round | `fable` (asks first, as it may use usage credits) | (session model) | xhigh |
|
|
106
|
+
|
|
107
|
+
- **Reviews:** each batch's review runs on at least `standard`, and on the batch's highest tier.
|
|
108
|
+
- **Escalation:** a task that still fails after a fix round is retried one tier up. A deep task
|
|
109
|
+
that still fails goes to the `escalate` model.
|
|
110
|
+
- **Fallback:** if a model isn't available on your plan or provider, that task runs on your current
|
|
111
|
+
model and the report says so.
|
|
112
|
+
- **Where the defaults come from:** they were checked on 2026-11-06 against
|
|
113
|
+
[Claude Code's model docs](https://code.claude.com/docs/en/model-config) (on Bedrock, Google Cloud,
|
|
114
|
+
and Foundry, `sonnet`/`haiku` point to older versions),
|
|
115
|
+
[Anthropic's model overview](https://platform.claude.com/docs/en/about-claude/models/overview),
|
|
116
|
+
[Codex's config docs](https://developers.openai.com/codex/config-basic), and
|
|
117
|
+
[Cursor's model list](https://cursor.com/help/models-and-usage/available-models). Claude Code
|
|
118
|
+
uses family aliases, which always point to the newest model. Cursor's models depend on your plan,
|
|
119
|
+
so it uses your current model until you fill in the models you can see in its picker.
|
|
120
|
+
- **Tools that run one model per session** (Cursor, Codex) don't switch silently. Before a heavier
|
|
121
|
+
batch, they pause and tell you which model to switch to.
|
|
122
|
+
- **Changing the models:** edit the `models:` section of `.spec-driven.yml`, for example to use a
|
|
123
|
+
newer model for `deep`.
|
|
124
|
+
|
|
96
125
|
**Fewer stops:** after reviewing the spec, say **"approved, run it through"**. The workflow then
|
|
97
126
|
implements, verifies, and commits in one go. It stops at the first failure, and it always asks
|
|
98
127
|
before pushing or opening a PR. To make this the default after approval, choose `run-through` during
|
|
@@ -139,6 +168,7 @@ straight away, so you can fix it before moving on. Press Enter on an empty line
|
|
|
139
168
|
| Lint / typecheck / test / build / dev commands | `package.json` scripts and lockfile (per repo or package) | `pnpm run lint` |
|
|
140
169
|
| Where specs go | (you choose) | `specs/` |
|
|
141
170
|
| After you approve a spec | (you choose) | `stop` (wait at each stage) or `run-through` |
|
|
171
|
+
| Model and effort per task tier | written with the defaults above | edit `models:` / `effort:` later |
|
|
142
172
|
|
|
143
173
|
**Where the file lives, by layout:**
|
|
144
174
|
|
|
@@ -542,15 +572,15 @@ skips that step rather than failing.
|
|
|
542
572
|
|
|
543
573
|
| Skill | Stage | SKILL.md lines | Words | Supporting files |
|
|
544
574
|
|---|---|---:|---:|---:|
|
|
545
|
-
| `spec-setup` | 0 · configure |
|
|
546
|
-
| `spec-investigate` | 1 · understand |
|
|
547
|
-
| `spec-create` | 2 · plan |
|
|
548
|
-
| `spec-implement` | 3 · build |
|
|
575
|
+
| `spec-setup` | 0 · configure | 117 | 1,068 | 1 |
|
|
576
|
+
| `spec-investigate` | 1 · understand | 330 | 2,794 | 1 |
|
|
577
|
+
| `spec-create` | 2 · plan | 166 | 1,503 | 5 |
|
|
578
|
+
| `spec-implement` | 3 · build | 303 | 2,458 | 3 |
|
|
549
579
|
| `spec-verify` | 4 · prove | 155 | 1,492 | 1 |
|
|
550
580
|
| `spec-checkpoint` | 5 · commit | 108 | 795 | 0 |
|
|
551
581
|
| `spec-ship` | 6 · PR | 220 | 1,268 | 0 |
|
|
552
582
|
| `generative-seo` | standalone | 255 | 2,209 | 7 |
|
|
553
|
-
| **Total** | | **1,
|
|
583
|
+
| **Total** | | **1,654** | **13,587** | **18** |
|
|
554
584
|
|
|
555
585
|
- **8** skills: **1** setup + **6** workflow stages + **1** standalone
|
|
556
586
|
- **4** tools supported natively (Claude Code, Codex CLI, Cursor, Antigravity), plus an MCP fallback
|
package/bin/cli.mjs
CHANGED
|
@@ -235,11 +235,30 @@ function toYaml(c) {
|
|
|
235
235
|
out += `tracker:\n type: ${c.tracker.type}\n key: ${y(c.tracker.key)}\n url: ${y(c.tracker.url)}\n`;
|
|
236
236
|
out += `git:\n${cmds(c.git, " ")}\n`;
|
|
237
237
|
out += `commands:\n${cmds(c.commands, " ")}\n dev_url: ${y(c.devUrl)}\n`;
|
|
238
|
+
out += "models: # model per task tier; \"default\" = the session's model; escalate = last resort for repeat failures\n" + Object.entries(MODEL_DEFAULTS)
|
|
239
|
+
.map(([tool, m]) => ` ${tool}:\n` + MODEL_KEYS.map((t) => ` ${t}: ${m[t]}\n`).join("")).join("");
|
|
240
|
+
out += "effort: # effort / reasoning level per tier (Claude Code, Codex): low | medium | high | xhigh | max | default\n"
|
|
241
|
+
+ MODEL_KEYS.map((t) => ` ${t}: ${EFFORT_DEFAULTS[t]}\n`).join("");
|
|
238
242
|
out += `pipeline:\n after_approval: ${c.afterApproval || "stop"} # stop | run-through (implement → verify → checkpoint; ship always asks)\n`;
|
|
239
243
|
return out + `specs_dir: ${y(c.specsDir)}\n`;
|
|
240
244
|
}
|
|
241
245
|
|
|
242
246
|
const LAYOUTS = ["single", "monorepo", "multi-repo"];
|
|
247
|
+
const TIERS = ["light", "standard", "deep"];
|
|
248
|
+
const MODEL_KEYS = [...TIERS, "escalate"]; // escalate: optional last resort when a deep task keeps failing
|
|
249
|
+
const EFFORTS = ["low", "medium", "high", "xhigh", "max", "default"];
|
|
250
|
+
// Checked against the vendors' docs on 2026-11-06 (Claude Code model-config, OpenAI Codex config,
|
|
251
|
+
// Cursor models page). Claude Code aliases track the newest model per family on your provider.
|
|
252
|
+
// Cursor's models depend on your plan, so it defaults to the session's model.
|
|
253
|
+
// shortcut: model names go stale; refresh these defaults (and the README table) when vendors ship new lines.
|
|
254
|
+
const MODEL_DEFAULTS = {
|
|
255
|
+
claude: { light: "haiku", standard: "sonnet", deep: "opus", escalate: "fable" },
|
|
256
|
+
codex: { light: "gpt-6-luna", standard: "gpt-6.1-sol", deep: "gpt-6.1-sol", escalate: "default" },
|
|
257
|
+
cursor: { light: "default", standard: "default", deep: "default", escalate: "default" },
|
|
258
|
+
antigravity: { light: "default", standard: "default", deep: "default", escalate: "default" },
|
|
259
|
+
};
|
|
260
|
+
// Effort / reasoning level per tier, for tools that support it (Claude Code, Codex).
|
|
261
|
+
const EFFORT_DEFAULTS = { light: "low", standard: "medium", deep: "high", escalate: "xhigh" };
|
|
243
262
|
const splitList = (v) => (v || "").split(",").map((x) => x.trim()).filter(Boolean);
|
|
244
263
|
// Paths are stored relative to the config's folder when inside it, absolute otherwise.
|
|
245
264
|
const real = (p) => { try { return fs.realpathSync(p); } catch { return p; } }; // /var vs /private/var etc.
|
|
@@ -466,7 +485,8 @@ function parseYaml(text) {
|
|
|
466
485
|
}
|
|
467
486
|
const m = line.match(/^([\w-]+):\s*(.*)$/);
|
|
468
487
|
if (!m) continue;
|
|
469
|
-
const [, key,
|
|
488
|
+
const [, key, rawVal] = m;
|
|
489
|
+
const val = rawVal.replace(/(^|\s+)#.*$/, "").trim(); // `key: # comment` opens a block
|
|
470
490
|
if (val === "") {
|
|
471
491
|
const next = text.split("\n").slice(text.split("\n").indexOf(raw) + 1).find((l) => l.trim() && !l.trim().startsWith("#"));
|
|
472
492
|
parent[key] = next && next.trim().startsWith("- ") ? [] : {};
|
|
@@ -499,6 +519,15 @@ function doctor() {
|
|
|
499
519
|
if (!["single", "monorepo", "multi-repo"].includes(c.layout)) problems.push(`layout "${c.layout}" must be single, monorepo, or multi-repo`);
|
|
500
520
|
if (c.tracker && !["jira", "github", "linear", "none"].includes(c.tracker.type)) problems.push(`tracker.type "${c.tracker.type}" must be jira, github, linear, or none`);
|
|
501
521
|
if (c.git?.commit_style && !["conventional", "ticket", "freeform"].includes(c.git.commit_style)) problems.push(`git.commit_style "${c.git.commit_style}" must be conventional, ticket, or freeform`);
|
|
522
|
+
for (const [tool, m] of Object.entries(c.models || {})) {
|
|
523
|
+
if (typeof m !== "object") { problems.push(`models.${tool} must list light / standard / deep`); continue; }
|
|
524
|
+
for (const t of TIERS) if (!m[t]) problems.push(`models.${tool}.${t} is missing (use "default" for the session's model)`);
|
|
525
|
+
for (const k of Object.keys(m)) if (!MODEL_KEYS.includes(k)) problems.push(`models.${tool}.${k}: unknown tier (use light, standard, deep, escalate)`);
|
|
526
|
+
}
|
|
527
|
+
for (const [k, v] of Object.entries(c.effort || {})) {
|
|
528
|
+
if (!MODEL_KEYS.includes(k)) problems.push(`effort.${k}: unknown tier (use light, standard, deep, escalate)`);
|
|
529
|
+
else if (!EFFORTS.includes(v)) problems.push(`effort.${k} "${v}" must be one of ${EFFORTS.join(", ")}`);
|
|
530
|
+
}
|
|
502
531
|
if (c.pipeline?.after_approval && !["stop", "run-through"].includes(c.pipeline.after_approval)) problems.push(`pipeline.after_approval "${c.pipeline.after_approval}" must be stop or run-through`);
|
|
503
532
|
if (c.git?.branch_name && !/\{(ticket|slug)\}/.test(c.git.branch_name)) problems.push(`git.branch_name "${c.git.branch_name}" needs {ticket} or {slug}`);
|
|
504
533
|
const repos = c.layout === "single" ? [{ path: "." }] : Array.isArray(c.repos) ? c.repos : [];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@benjaminthomas/spec-driven-dev",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "Spec-driven AI development workflow (investigate → spec → implement → verify → ship) as Agent Skills for Claude Code, Cursor, Codex CLI and Antigravity.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -68,6 +68,11 @@ Think carefully about granularity. Too coarse and agents can't work in parallel.
|
|
|
68
68
|
|
|
69
69
|
Tests ship with the code they cover: fill in each task's **Tests** section (see the task template) instead of creating separate "write tests" tasks. Only add a standalone testing task for cross-cutting suites (e.g. a new E2E harness) or when the user asks for one.
|
|
70
70
|
|
|
71
|
+
**Rate each task's complexity.** Read `references/complexity-rubric.md` and give every task a tier
|
|
72
|
+
(`light`, `standard`, or `deep`) with the signals that justify it. `spec-implement` uses the tier to
|
|
73
|
+
pick the model for that task, so a risky task under-rated as `light` is the costly mistake. Round up
|
|
74
|
+
when unsure. If one task scores `deep` mainly because it's doing too much, split it first.
|
|
75
|
+
|
|
71
76
|
### Step 4: Build the Dependency Graph
|
|
72
77
|
|
|
73
78
|
For each task, identify:
|
|
@@ -130,6 +135,10 @@ Files created:
|
|
|
130
135
|
- action-required.md
|
|
131
136
|
- tasks/ ({T} task files)
|
|
132
137
|
|
|
138
|
+
Model plan: {n} light · {n} standard · {n} deep
|
|
139
|
+
(models from .spec-driven.yml → light: {model}, standard: {model}, deep: {model})
|
|
140
|
+
Deep tasks: {task-nn — main reason}
|
|
141
|
+
|
|
133
142
|
Batch breakdown:
|
|
134
143
|
- Batch 1: {count} tasks (parallel) — {brief description}
|
|
135
144
|
- Batch 2: {count} tasks (parallel) — {brief description}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Complexity Rubric
|
|
2
|
+
|
|
3
|
+
Use this to give every task a **tier**: `light`, `standard`, or `deep`. `spec-implement` runs the
|
|
4
|
+
task on the model mapped to that tier in `.spec-driven.yml` (`models:`). Rate from the evidence in
|
|
5
|
+
the task file and investigation, not from how long the description is.
|
|
6
|
+
|
|
7
|
+
## Contents
|
|
8
|
+
- Scoring
|
|
9
|
+
- Tier from score
|
|
10
|
+
- Overrides
|
|
11
|
+
- Examples
|
|
12
|
+
- What to write in the task file
|
|
13
|
+
|
|
14
|
+
## Scoring
|
|
15
|
+
|
|
16
|
+
Add one point for each signal that applies:
|
|
17
|
+
|
|
18
|
+
| Signal | Point when… |
|
|
19
|
+
|---|---|
|
|
20
|
+
| Spread | the task changes more than 3 files, or files in more than one module/package/repo |
|
|
21
|
+
| New design | there's no existing pattern in the repo to copy (new abstraction, algorithm, or integration) |
|
|
22
|
+
| Data | it changes a schema, migration, persisted format, or data backfill |
|
|
23
|
+
| Concurrency | it involves async ordering, queues, retries, locking, caching, or idempotency |
|
|
24
|
+
| Security | it touches auth, permissions, tenant isolation, secrets, payments, or untrusted input |
|
|
25
|
+
| Public contract | it changes an API, event, or interface that other code or other repos depend on |
|
|
26
|
+
| Ambiguity | acceptance criteria rely on judgement, or the investigation left UNKNOWNs in this area |
|
|
27
|
+
| Hard to verify | correctness can't be fully shown by the tests listed (timing, performance, UI feel) |
|
|
28
|
+
|
|
29
|
+
## Tier from score
|
|
30
|
+
|
|
31
|
+
| Score | Tier | Typical work |
|
|
32
|
+
|---|---|---|
|
|
33
|
+
| 0–1 | `light` | copy change, config value, small UI tweak, adding a field following an existing pattern |
|
|
34
|
+
| 2–3 | `standard` | a normal feature slice: a route + service + tests following existing patterns |
|
|
35
|
+
| 4+ | `deep` | cross-cutting design, migrations with backfills, auth/permission logic, concurrency fixes |
|
|
36
|
+
|
|
37
|
+
## Overrides
|
|
38
|
+
|
|
39
|
+
- **Security or Data alone make a task at least `standard`**, even if nothing else applies.
|
|
40
|
+
- **Security + Data, or Security + Concurrency, make it `deep`**, whatever the score.
|
|
41
|
+
- If the score is borderline, round up: a tier too high costs money, a tier too low costs rework.
|
|
42
|
+
|
|
43
|
+
## Examples
|
|
44
|
+
|
|
45
|
+
- "Rename the Export button to Download CSV" → 0 → `light`
|
|
46
|
+
- "Add `exported_at` column and show it on the orders page" → Data, Spread → 2 → `standard`
|
|
47
|
+
- "Make the CSV export stream rows instead of loading 10k into memory" → New design, Concurrency, Hard to verify → 3 → `standard`
|
|
48
|
+
- "Enforce tenant isolation on all export endpoints and backfill missing tenant IDs" → Security + Data → `deep`
|
|
49
|
+
|
|
50
|
+
## What to write in the task file
|
|
51
|
+
|
|
52
|
+
```markdown
|
|
53
|
+
## Complexity
|
|
54
|
+
|
|
55
|
+
**Tier:** standard
|
|
56
|
+
**Signals:** Data (adds `exported_at` migration), Spread (api + web)
|
|
57
|
+
```
|
|
@@ -29,10 +29,12 @@ graph TD
|
|
|
29
29
|
|
|
30
30
|
## Batches
|
|
31
31
|
|
|
32
|
-
| Batch | Tasks | Description |
|
|
33
|
-
|
|
34
|
-
| 1 | task-01, task-02 | {Brief description of what this batch accomplishes} |
|
|
35
|
-
| 2 | task-03 | {Brief description} |
|
|
32
|
+
| Batch | Tasks | Tiers | Description |
|
|
33
|
+
|------|-------|-------|-------------|
|
|
34
|
+
| 1 | task-01, task-02 | light, standard | {Brief description of what this batch accomplishes} |
|
|
35
|
+
| 2 | task-03 | deep | {Brief description} |
|
|
36
|
+
|
|
37
|
+
**Model plan:** {n} light · {n} standard · {n} deep. Deep tasks: {task-03 — reason}.
|
|
36
38
|
|
|
37
39
|
## Task Status
|
|
38
40
|
|
|
@@ -15,6 +15,11 @@ pending
|
|
|
15
15
|
|
|
16
16
|
{N}
|
|
17
17
|
|
|
18
|
+
## Complexity
|
|
19
|
+
|
|
20
|
+
**Tier:** {light | standard | deep}
|
|
21
|
+
**Signals:** {which rubric signals applied, with the evidence — or "none"}
|
|
22
|
+
|
|
18
23
|
## Description
|
|
19
24
|
|
|
20
25
|
{2-5 sentences describing what this task accomplishes and why it matters in the context of the overall feature. Include enough context that an agent unfamiliar with the planning conversation understands the purpose.}
|
|
@@ -82,5 +87,6 @@ pending
|
|
|
82
87
|
- The **Dependencies** section includes prose context (not just filenames) so the agent understands its inputs without reading other files. This is the most important part of making task files self-contained.
|
|
83
88
|
- **Files to Create** and **Files to Modify** make the task's scope explicit. Tasks in the same batch should not overlap on these lists.
|
|
84
89
|
- **Technical Details** captures everything from the planning conversation — CLI commands, schemas, code snippets, file paths, env vars, API endpoints. If it was discussed during planning and is relevant to this task, it belongs here.
|
|
90
|
+
- **Complexity** comes from `complexity-rubric.md`. `spec-implement` picks the coder's model from this tier, so rate honestly: under-rating a risky task is the expensive mistake.
|
|
85
91
|
- **Tests** names the tests the coder writes alongside the code. A behavioural acceptance criterion without a matching test is a gap — add the test or explain why it can only be checked by `spec-verify`.
|
|
86
92
|
- **Acceptance Criteria** should be specific enough that completion can be verified objectively (by a code review agent or a human).
|
|
@@ -108,6 +108,28 @@ Read `references/coder-prompt-template.md` and construct each agent's prompt by
|
|
|
108
108
|
|
|
109
109
|
The coder agents should NOT commit their changes — the orchestrator handles commits after review.
|
|
110
110
|
|
|
111
|
+
**Pick each coder's model and effort from the task's tier.** Read the task's `## Complexity` tier
|
|
112
|
+
(treat a missing tier as `standard`), then look up `.spec-driven.yml` → `models.<tool>.<tier>` and
|
|
113
|
+
`effort.<tier>`, where `<tool>` is the host you're running in (`claude`, `codex`, `cursor`,
|
|
114
|
+
`antigravity`). Without those sections, use these defaults: Claude Code `light → haiku/low`,
|
|
115
|
+
`standard → sonnet/medium`, `deep → opus/high`; other hosts use the session's model.
|
|
116
|
+
|
|
117
|
+
- **Host can set a model per agent** (e.g. Claude Code's Agent tool `model` and `effort`
|
|
118
|
+
parameters): dispatch each coder with its tier's model and effort.
|
|
119
|
+
- **Model not available** (not on your plan or provider, or rejected by the host): fall back to the
|
|
120
|
+
session's model, say which task fell back and why, and suggest fixing `models:`. Don't stop the
|
|
121
|
+
batch for this.
|
|
122
|
+
- **Host can't** (one model per session, as in Cursor or Codex): don't silently run deep tasks on a
|
|
123
|
+
light model. Before dispatching a batch, compare its highest tier with the model you're running
|
|
124
|
+
on. If the batch needs a stronger one, stop and say:
|
|
125
|
+
`Batch {N} has deep tasks ({task-nn: reason}). Switch to {models.<tool>.deep} for this batch, then
|
|
126
|
+
say "continue".` If the batch only has light tasks and you're on the deep model, mention that a
|
|
127
|
+
cheaper model would do, but carry on.
|
|
128
|
+
- If the mapped value is `default`, use whatever model the session already runs, without
|
|
129
|
+
recommending a switch.
|
|
130
|
+
|
|
131
|
+
Report the model used for each task in the batch summary.
|
|
132
|
+
|
|
111
133
|
**Isolate parallel coders in git worktrees when the host allows it.** Coders sharing one working
|
|
112
134
|
tree can clobber each other's edits and each other's lint/test runs. If your host can run an agent
|
|
113
135
|
in its own worktree (e.g. Claude Code's `isolation: "worktree"`), use it for every coder in a
|
|
@@ -143,6 +165,9 @@ Read `references/review-prompt-template.md` and construct the review prompt by f
|
|
|
143
165
|
- **{task_summaries}**: for each task in this batch, the task title and the coder agent's completion summary
|
|
144
166
|
- **{verification_commands}**: `commands.lint`/`typecheck`/`test` from `.spec-driven.yml` for each repo or package touched, or the project's own commands if there's no config (e.g., `pnpm lint && pnpm typecheck && pnpm test`)
|
|
145
167
|
|
|
168
|
+
Run the reviewer on the model for the **highest tier in the batch**, and never below `standard`: the
|
|
169
|
+
review is where deep mistakes get caught.
|
|
170
|
+
|
|
146
171
|
The review agent should:
|
|
147
172
|
1. Run lint, typecheck, and tests
|
|
148
173
|
2. Verify acceptance criteria and the tests named in each task file
|
|
@@ -160,6 +185,11 @@ If the review returns **FAIL**:
|
|
|
160
185
|
- **{issues}**: the specific issues for this task group
|
|
161
186
|
- **{task_content}**: the original task file for context
|
|
162
187
|
4. After fix agents complete, re-run the review (Step 6)
|
|
188
|
+
5. **Escalate on repeat failure.** If a task's issues survive a fix cycle, run its next fix one tier
|
|
189
|
+
higher (`light → standard → deep`). A `deep` task that still fails goes to `models.<tool>.escalate`
|
|
190
|
+
(e.g. `fable`) at `effort.escalate`, if it's set and not `default`. Ask first if that model can
|
|
191
|
+
bill to usage credits, as Fable can on some plans. Note every escalation in the batch report:
|
|
192
|
+
a task that needed escalating was probably under-rated, which is useful feedback for future specs.
|
|
163
193
|
|
|
164
194
|
**Cap at 3 review cycles per batch.** If the third review still fails, stop and report to the user:
|
|
165
195
|
|
|
@@ -288,6 +288,11 @@ gitignores `specs/`, matching whatever this repo already does there). Use the st
|
|
|
288
288
|
Every section should be specific and evidence-backed, or explicitly say "None found" /
|
|
289
289
|
"Not applicable to this ticket" rather than being left looking like an oversight.
|
|
290
290
|
|
|
291
|
+
**Complexity Estimate** uses the same signals and tiers `spec-create` will apply per task: spread,
|
|
292
|
+
new design, data, concurrency, security, public contract, ambiguity, hard to verify. Security plus
|
|
293
|
+
data, or security plus concurrency, means `deep`. Say which model is worth planning this on, since a
|
|
294
|
+
deep ticket deserves the strongest model for `spec-create` too.
|
|
295
|
+
|
|
291
296
|
**Recommended Implementation Direction** describes the technically-supported direction the
|
|
292
297
|
evidence points to — reusing existing patterns the investigation actually found, not a novel
|
|
293
298
|
architecture invented on the spot. It is not permission to start building; flag any business
|
|
@@ -48,6 +48,11 @@ Copy this structure into `specs/{feature-slug}/investigation.md`.
|
|
|
48
48
|
### Proposed Solutions Discussed
|
|
49
49
|
### Open Questions
|
|
50
50
|
### Conflicts / Discrepancies
|
|
51
|
+
## Complexity Estimate
|
|
52
|
+
- Overall tier: (light / standard / deep): the tier of the hardest part of the work
|
|
53
|
+
- Signals: (which of spread, new design, data, concurrency, security, public contract, ambiguity, hard to verify apply, each with its evidence)
|
|
54
|
+
- Suggested model for planning this: (`models.<tool>.deep` at `effort.deep` if the tier is deep, or the `escalate` model for very ambiguous, long-horizon work; otherwise the session's model is fine)
|
|
55
|
+
|
|
51
56
|
## Recommended Implementation Direction
|
|
52
57
|
## References
|
|
53
58
|
```
|
|
@@ -69,7 +69,10 @@ Read, don't guess. Collect a draft of every field in `references/config-template
|
|
|
69
69
|
steps (CI is often the most truthful source). Dev URL from the dev script, `.env.example`, or
|
|
70
70
|
framework defaults.
|
|
71
71
|
|
|
72
|
-
6. **
|
|
72
|
+
6. **Models per tier.** Write the `models:` block from the template. Ask which models the user
|
|
73
|
+
has for each tool they installed, only if they want to tune it: the Claude defaults (haiku /
|
|
74
|
+
sonnet / opus) work as-is, and `default` is safe for the rest.
|
|
75
|
+
7. **After approval.** Ask whether an approved spec should stop after each stage (`stop`), or
|
|
73
76
|
run implement → verify → checkpoint in one go (`run-through`), stopping at any failure and never
|
|
74
77
|
pushing. Store it as `pipeline.after_approval`.
|
|
75
78
|
|
|
@@ -42,6 +42,39 @@ commands:
|
|
|
42
42
|
dev: "" # how spec-verify starts the app
|
|
43
43
|
dev_url: "" # where it answers, e.g. http://localhost:3000
|
|
44
44
|
|
|
45
|
+
# Which model runs each task tier (spec-create rates every task light / standard / deep).
|
|
46
|
+
# Values are whatever your tool accepts; "default" means "whatever model the session is using".
|
|
47
|
+
# escalate = optional last resort when a deep task still fails review after a fix round.
|
|
48
|
+
# Defaults checked against vendor docs on 2026-11-06 — refresh when vendors ship new models.
|
|
49
|
+
models:
|
|
50
|
+
claude: # Claude Code aliases follow the newest model per family on your provider
|
|
51
|
+
light: haiku
|
|
52
|
+
standard: sonnet
|
|
53
|
+
deep: opus
|
|
54
|
+
escalate: fable # Fable: hardest/long-running work; may bill to usage credits on some plans
|
|
55
|
+
codex:
|
|
56
|
+
light: gpt-6-luna
|
|
57
|
+
standard: gpt-6.1-sol
|
|
58
|
+
deep: gpt-6.1-sol # same model, higher reasoning effort (see effort:)
|
|
59
|
+
escalate: default
|
|
60
|
+
cursor: # depends on your Cursor plan; set models you can see in the model picker
|
|
61
|
+
light: default
|
|
62
|
+
standard: default
|
|
63
|
+
deep: default
|
|
64
|
+
escalate: default
|
|
65
|
+
antigravity:
|
|
66
|
+
light: default
|
|
67
|
+
standard: default
|
|
68
|
+
deep: default
|
|
69
|
+
escalate: default
|
|
70
|
+
|
|
71
|
+
# Effort / reasoning level per tier, for tools that support it (Claude Code, Codex).
|
|
72
|
+
effort:
|
|
73
|
+
light: low
|
|
74
|
+
standard: medium
|
|
75
|
+
deep: high
|
|
76
|
+
escalate: xhigh
|
|
77
|
+
|
|
45
78
|
pipeline:
|
|
46
79
|
# stop — every stage waits for you (default)
|
|
47
80
|
# run-through — after you approve a spec: implement → verify → checkpoint in one go,
|