@dougharness/cli 1.5.0 → 1.6.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 (33) hide show
  1. package/dist/generate/agents.js +4 -0
  2. package/dist/generate/agents.js.map +1 -1
  3. package/dist/generate/claude-md.js +1 -1
  4. package/dist/generate/claude-md.js.map +1 -1
  5. package/node_modules/@dougharness/flow/.claude-plugin/plugin.json +1 -1
  6. package/node_modules/@dougharness/flow/agents/coder.md +2 -0
  7. package/node_modules/@dougharness/flow/agents/implementer.md +2 -0
  8. package/node_modules/@dougharness/flow/agents/planner.md +1 -1
  9. package/node_modules/@dougharness/flow/agents/reviewer.md +2 -0
  10. package/node_modules/@dougharness/flow/agents/tester.md +2 -0
  11. package/node_modules/@dougharness/flow/lib/card-loop.mjs +16 -6
  12. package/node_modules/@dougharness/flow/lib/code-index.mjs +2 -2
  13. package/node_modules/@dougharness/flow/lib/coordinator.mjs +4 -2
  14. package/node_modules/@dougharness/flow/lib/decisions.mjs +2 -2
  15. package/node_modules/@dougharness/flow/lib/learn.mjs +11 -4
  16. package/node_modules/@dougharness/flow/lib/memory.mjs +46 -21
  17. package/node_modules/@dougharness/flow/package.json +1 -1
  18. package/node_modules/@dougharness/flow/scripts/autopilot.mjs +16 -0
  19. package/node_modules/@dougharness/flow/scripts/board.mjs +5 -1
  20. package/node_modules/@dougharness/flow/scripts/learn.mjs +3 -1
  21. package/node_modules/@dougharness/flow/scripts/memory.mjs +218 -9
  22. package/node_modules/@dougharness/flow/skills/doug-hand/SKILL.md +3 -1
  23. package/node_modules/@dougharness/flow/skills/doug-next/SKILL.md +2 -0
  24. package/node_modules/@dougharness/flow/skills/run-report/SKILL.md +6 -3
  25. package/node_modules/@dougharness/flow/workflows/card-queen.js +16 -6
  26. package/node_modules/@dougharness/gates/.claude-plugin/plugin.json +1 -1
  27. package/node_modules/@dougharness/gates/lib/block-ledger.mjs +1 -0
  28. package/node_modules/@dougharness/gates/lib/gate-lock.mjs +175 -4
  29. package/node_modules/@dougharness/gates/lib/test-totals.mjs +1 -1
  30. package/node_modules/@dougharness/gates/package.json +1 -1
  31. package/node_modules/@dougharness/gates/scripts/stop-gate.mjs +69 -99
  32. package/node_modules/@dougharness/gates/scripts/verify.mjs +27 -9
  33. package/package.json +3 -3
@@ -157,6 +157,7 @@ export function generateAgents(d, cfg) {
157
157
  "When a test contradicts the brief or the card's goal, do not change production code to fit the test; stop and report the conflict, quoting both, so the lead can send it back to the tester.",
158
158
  "Apply each mutation in a scratch copy or git worktree under `.doug/.state`, run the one test file there, and remove the copy.",
159
159
  "Scratch files go under `.doug/.state/scratch`; protect-paths keeps refusing the Claude Code session scratchpad, which is outside the project.",
160
+ "Run every other test command, a single test file or a mutation's test run in a scratch copy included, as `node <project root>/.doug/hooks/lib/gate-lock.mjs run -- <command>` with the Bash timeout set to 600000, so it waits on gate.lock instead of overlapping a gate; never wrap verify.mjs in gate-lock.mjs, since verify.mjs takes the lock itself. Put env vars right after `--` (`-- CI=1 <command>`) and quote a compound command as one argument (`-- 'cd dir && <command>'`).",
160
161
  timeoutRule,
161
162
  ],
162
163
  };
@@ -184,6 +185,7 @@ export function generateAgents(d, cfg) {
184
185
  "Severity blocker/major/minor with blocker meaning the change must not merge.",
185
186
  "Do not ask for work beyond the request.",
186
187
  "Apply each mutation in a scratch copy or git worktree under `.doug/.state`, run the one test file there, and remove the copy.",
188
+ "Run every other test command, a single test file or a mutation's test run in a scratch copy included, as `node <project root>/.doug/hooks/lib/gate-lock.mjs run -- <command>` with the Bash timeout set to 600000, so it waits on gate.lock instead of overlapping a gate; never wrap verify.mjs in gate-lock.mjs, since verify.mjs takes the lock itself. Put env vars right after `--` (`-- CI=1 <command>`) and quote a compound command as one argument (`-- 'cd dir && <command>'`).",
187
189
  timeoutRule,
188
190
  ],
189
191
  };
@@ -223,6 +225,8 @@ export function generateAgents(d, cfg) {
223
225
  "Report what ran.",
224
226
  'When your new tests are meant to stay red until the coder\'s change, end your final message with a JSON object {"tests_red_by_design": ["<test file>", ...]} naming every test file you left failing by its repository-relative path, report the red once, and do not rerun the suite to make a gate pass. Put that JSON line either as the last line of your final plain-text message or inside your hand-back message: the SubagentStop gate reads your last plain-text message first and, when that holds no claim, your last hand-back call.',
225
227
  "Scratch files go under `.doug/.state/scratch`; protect-paths keeps refusing the Claude Code session scratchpad, which is outside the project.",
228
+ "Run a full test suite only through `node .doug/hooks/scripts/verify.mjs`, never the gate's commands (the commands in `stopGate.commands`) directly, with or without CI=1: verify.mjs takes gate.lock, so your suite queues behind a running gate instead of overlapping it.",
229
+ "Run every other test command, a single test file or a mutation's test run in a scratch copy included, as `node <project root>/.doug/hooks/lib/gate-lock.mjs run -- <command>` with the Bash timeout set to 600000, so it waits on gate.lock instead of overlapping a gate; never wrap verify.mjs in gate-lock.mjs, since verify.mjs takes the lock itself. Put env vars right after `--` (`-- CI=1 <command>`) and quote a compound command as one argument (`-- 'cd dir && <command>'`).",
226
230
  timeoutRule,
227
231
  "On a tests-only card, run the brief's mutation list yourself in a scratch copy or git worktree under `.doug/.state`, run the one test file there, report each result, and remove the copy; never edit a production file in the live checkout.",
228
232
  ],
@@ -1 +1 @@
1
- {"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/generate/agents.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/generate/agents.ts"],"names":[],"mappings":"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"}
@@ -82,7 +82,7 @@ export function generateClaudeMd(d, cfg) {
82
82
  lines.push("");
83
83
  lines.push("## Gotchas");
84
84
  lines.push("");
85
- lines.push("<!-- Add project-specific pitfalls here, one line each. Keep this file under 60 lines. -->");
85
+ lines.push("<!-- Add project-specific pitfalls here, one line each. Keep this file to 200 lines or fewer. -->");
86
86
  lines.push("");
87
87
  lines.push(...MODELS_SECTION);
88
88
  return lines.join("\n");
@@ -1 +1 @@
1
- {"version":3,"file":"claude-md.js","sourceRoot":"","sources":["../../src/generate/claude-md.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"claude-md.js","sourceRoot":"","sources":["../../src/generate/claude-md.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "doug-flow",
3
3
  "displayName": "Doug Flow",
4
- "version": "1.5.0",
4
+ "version": "1.6.0",
5
5
  "description": "Plan, approve, implement one task per worktree, verify, review. A deterministic Workflow-tool template plus planner, implementer, verifier, and reviewer subagents. The plan is a file; nothing is implemented until you approve it.",
6
6
  "author": {
7
7
  "name": "Doug contributors"
@@ -21,3 +21,5 @@ You implement the change the brief asks for. The brief carries the repository fa
21
21
  8. Apply each mutation in a scratch copy or git worktree under `.doug/.state`, run the one test file there, and remove the copy.
22
22
  9. Scratch files go under `.doug/.state/scratch`; protect-paths keeps refusing the Claude Code session scratchpad, which is outside the project.
23
23
  10. Run any command that can take over 120 s with the Bash timeout set to 600000, and hand back only after it exits.
24
+ 11. Run a full test suite only through `node .doug/hooks/scripts/verify.mjs`, never the gate's commands (the commands in `stopGate.commands`) directly, with or without CI=1: verify.mjs takes gate.lock, so your suite queues behind a running gate instead of overlapping it.
25
+ 12. Run every other test command, a single test file or a mutation's test run in a scratch copy included, as `node <the worktree>/.doug/hooks/lib/gate-lock.mjs run -- <command>` with the Bash timeout set to 600000, so it waits on gate.lock instead of overlapping a gate; never wrap verify.mjs in gate-lock.mjs, since verify.mjs takes the lock itself. Put env vars right after `--` (`-- CI=1 pnpm exec vitest run <file>`) and quote a compound command as one argument (`-- 'cd dir && vitest run x'`).
@@ -19,5 +19,7 @@ You implement one task. You get a spec, a list of files you own, and a verificat
19
19
  5. Commit on your branch with a message starting `<id>: `. Commit messages carry no attribution trailers: no Co-Authored-By line and no Claude-Session line, whatever your defaults say. A commit with either is a finding and the plan cannot land. Get `filesTouched` from `git diff --name-only <base>...HEAD`, not from memory. In a card loop, only the commit seat commits: when your brief names you the gate seat or any seat other than commit, never run git add or git commit.
20
20
  6. If verification fails and you cannot fix it within the owned files, return `blocked: true` and say exactly what fails and what you need - the file, the symbol or interface, or the decision - so a swarm lead can re-brief you once on it. Do not report success you have not seen.
21
21
  7. Return `partial: true` only after a hook told you `[doug] Worker context at <pct>% of <window> tokens`: stop at a boundary (finish the file you are on and its named test, then commit) and include a handoff (`completed`, `remaining`, `next`, `verify`). Never claim partial to escape a hard task: without that notice, a partial claim is refused at your stop.
22
+ 8. Run a full test suite only through `node .doug/hooks/scripts/verify.mjs`, never the gate's commands (the commands in `stopGate.commands`) directly, with or without CI=1: verify.mjs takes gate.lock, so your suite queues behind a running gate instead of overlapping it. The exception is the task's own verification command (usually `pnpm test:unit`): run it as written, as rule 3 says.
23
+ 9. Run every other test command, a single test file or a mutation's test run in a scratch copy included, as `node <the worktree>/.doug/hooks/lib/gate-lock.mjs run -- <command>` with the Bash timeout set to 600000, so it waits on gate.lock instead of overlapping a gate; never wrap verify.mjs in gate-lock.mjs, since verify.mjs takes the lock itself. Put env vars right after `--` (`-- CI=1 pnpm exec vitest run <file>`) and quote a compound command as one argument (`-- 'cd dir && vitest run x'`).
22
24
 
23
25
  Your final output is the structured result, not a message to a person.
@@ -12,7 +12,7 @@ You are the planner. You produce a plan, not code. The plan is a file that a hum
12
12
 
13
13
  ## What you do
14
14
 
15
- 1. Read the request. Read the parts of the repository it touches: entry points, the files that will change, their tests, the build and test commands (CLAUDE.md and .doug/config.json list them). Before deciding tasks, run `node "<scripts>/memory.mjs" recall "<the request in one line>" --k 8`, where `<scripts>` is the directory the prompt names after `Scripts:`, else `$CLAUDE_PLUGIN_ROOT/scripts` when that variable is set and non-empty, else skip the command and say so. Use the `Scripts:` directory as given, even when it lies under `~/.claude/plugins/cache` (a marketplace install's does). Never search the filesystem for another copy (no `find /`), and never pick a version under `~/.claude/plugins/cache` yourself; a subagent may not have `CLAUDE_PLUGIN_ROOT` set. When the command runs, treat each returned lesson as a constraint the plan must respect, citing the lesson id in the task spec it shaped; when the command prints keyword-only or no lessons, say nothing and go on. When `.doug/config.json` has `memory.index.enabled` true, also run `node "<scripts>/memory.mjs" index search "<the request in one line>" --k 8` (same `<scripts>` directory as above) and read the files it names before deciding tasks; when the index is off, the header says keyword-only with no chunks, or it prints nothing, say nothing and go on.
15
+ 1. Read the request. Read the parts of the repository it touches: entry points, the files that will change, their tests, the build and test commands (CLAUDE.md and .doug/config.json list them). Before deciding tasks, run `node "<scripts>/memory.mjs" recall "<the request in one line>" --k 8`, where `<scripts>` is the directory the prompt names after `Scripts:`, else `$CLAUDE_PLUGIN_ROOT/scripts` when that variable is set and non-empty, else skip the command and say so. Use the `Scripts:` directory as given, even when it lies under `~/.claude/plugins/cache` (a marketplace install's does). Run these from the project root (a directory with `.doug/`), never from the scripts directory; a directory with no `.doug/` is refused. Never search the filesystem for another copy (no `find /`), and never pick a version under `~/.claude/plugins/cache` yourself; a subagent may not have `CLAUDE_PLUGIN_ROOT` set. When the command runs, treat each returned lesson as a constraint the plan must respect, citing the lesson id in the task spec it shaped; when the command prints keyword-only or no lessons, say nothing and go on. When `.doug/config.json` has `memory.index.enabled` true, also run `node "<scripts>/memory.mjs" index search "<the request in one line>" --k 8` (same `<scripts>` directory as above) and read the files it names before deciding tasks; when the index is off, the header says keyword-only with no chunks, or it prints nothing, say nothing and go on.
16
16
  2. Decide the smallest set of tasks that achieves the goal. One task for single-file work. Three to five only for a real feature. Never more than eight: `plan.mjs validate` warns past five and past eight, and the user sees the warning at approval; split the work into two cards instead.
17
17
  3. For each task, list the files it owns. Two tasks may not own the same file unless one depends on the other. Tests belong to the task that changes the behavior they test.
18
18
  4. Order consumers after producers. A task whose spec or acceptance names a file, route, or subcommand another task owns or introduces (a page that PUTs to a server route, docs that name a CLI subcommand, a test that runs another task's file) must list that task in `dependsOn`, so it lands in a later level. The adversary judges a task branch against the whole plan goal, and a consumer in the same level as its producer is judged before the producer's work exists on its branch: on board-reorder (2026-09-07) that blocked four runs in a row. `plan.mjs validate` reports the pair when a spec or verify command names a file another task owns with no dependency between them; routes and subcommands it cannot see, so check those yourself.
@@ -26,3 +26,5 @@ Review the diff, not the description of the diff. Get it with `git diff <base>..
26
26
  Severity: `blocker` fails the review; `major` should be fixed before merge but does not fail it alone; `minor` is advisory. `approve` is true only with no blockers, `specCompliant` true, and `inScope` true. Do not ask for work beyond the task.
27
27
 
28
28
  Budget your turns: you have at most 40 tool calls (maxTurns). Read the diff and run the checks your prompt names first, then any deeper probes; stop with at least 5 calls to spare and return your review with what you found: a capped run returns a partial review, never an empty one.
29
+
30
+ Test runs: Run a full test suite only through `node .doug/hooks/scripts/verify.mjs`, never the gate's commands (the commands in `stopGate.commands`) directly, with or without CI=1: verify.mjs takes gate.lock, so your suite queues behind a running gate instead of overlapping it. Run every other test command, a single test file or a mutation's test run in a scratch copy included, as `node <the worktree>/.doug/hooks/lib/gate-lock.mjs run -- <command>` with the Bash timeout set to 600000, so it waits on gate.lock instead of overlapping a gate; never wrap verify.mjs in gate-lock.mjs, since verify.mjs takes the lock itself. Put env vars right after `--` (`-- CI=1 pnpm exec vitest run <file>`) and quote a compound command as one argument (`-- 'cd dir && vitest run x'`).
@@ -19,3 +19,5 @@ You write the tests for the behavior the brief names. The brief carries the repo
19
19
  6. Scratch files go under `.doug/.state/scratch`; protect-paths keeps refusing the Claude Code session scratchpad, which is outside the project.
20
20
  7. Run any command that can take over 120 s with the Bash timeout set to 600000, and hand back only after it exits.
21
21
  8. On a tests-only card, run the brief's mutation list yourself in a scratch copy or git worktree under `.doug/.state`, run the one test file there, report each result, and remove the copy; never edit a production file in the live checkout.
22
+ 9. Run a full test suite only through `node .doug/hooks/scripts/verify.mjs`, never the gate's commands (the commands in `stopGate.commands`) directly, with or without CI=1: verify.mjs takes gate.lock, so your suite queues behind a running gate instead of overlapping it.
23
+ 10. Run every other test command, a single test file or a mutation's test run in a scratch copy included, as `node <the worktree>/.doug/hooks/lib/gate-lock.mjs run -- <command>` with the Bash timeout set to 600000, so it waits on gate.lock instead of overlapping a gate; never wrap verify.mjs in gate-lock.mjs, since verify.mjs takes the lock itself. Put env vars right after `--` (`-- CI=1 pnpm exec vitest run <file>`) and quote a compound command as one argument (`-- 'cd dir && vitest run x'`).
@@ -102,6 +102,14 @@ export const BRIEF_RULES = {
102
102
  seats: ["coder", "reviewer", "tester"],
103
103
  when: "mutations",
104
104
  },
105
+ "suites-through-verify": {
106
+ text: "Run a full test suite only through `node .doug/hooks/scripts/verify.mjs`, never the gate's commands (the commands in `stopGate.commands`) directly, with or without CI=1: verify.mjs takes gate.lock, so your suite queues behind a running gate instead of overlapping it.",
107
+ seats: ["tester", "coder", "reviewer", "gate"],
108
+ },
109
+ "tests-take-gate-lock": {
110
+ text: "Run every other test command, a single test file or a mutation's test run in a scratch copy included, as `node <card worktree>/.doug/hooks/lib/gate-lock.mjs run -- <command>` with the Bash timeout set to 600000, so it waits on gate.lock instead of overlapping a gate; never wrap verify.mjs in gate-lock.mjs, since verify.mjs takes the lock itself. Put env vars right after `--` (`-- CI=1 pnpm exec vitest run <file>`) and quote a compound command as one argument (`-- 'cd dir && vitest run x'`).",
111
+ seats: ["tester", "coder", "reviewer"],
112
+ },
105
113
  "reviewer-reruns-mutations": {
106
114
  text: "Rerun every listed mutation yourself and add your own (own: true); read the diff only after running them.",
107
115
  seats: ["reviewer"],
@@ -854,15 +862,17 @@ export function next(state, handBack) {
854
862
  // An evidenced major gets the same one fix pass; a major without evidence and a minor stay advisory.
855
863
  const majors = findings.filter((f) => f.severity === "major" && nonBlank(f.evidence));
856
864
  if (blockers.length === 0 && majors.length === 0) return advance(s, "gate", "ok", { acc });
857
- // A reviewer round that carried a user answer and still has an open finding gets one extra coder round.
858
- const answered = (s.answers || []).some(
859
- (a) => a.seat === "reviewer" && (a.round ?? 1) <= (s.seatRuns.reviewer || 0),
860
- );
861
- if (s.counters.fixPasses >= 1 && answered && !s.answerCoderUsed) {
865
+ // Each user answer to a reviewer stop gets one coder round when the reviewer that carried it still has an open finding.
866
+ const given = s.answerCoderRounds || [];
867
+ const fresh = (s.answers || [])
868
+ .filter((a) => a.seat === "reviewer" && (a.round ?? 1) <= (s.seatRuns.reviewer || 0))
869
+ .map((a) => a.round ?? 1)
870
+ .filter((r) => !given.includes(r));
871
+ if (s.counters.fixPasses >= 1 && fresh.length > 0) {
862
872
  return advance(s, buildSeat(s), "blockers", {
863
873
  acc,
864
874
  fixFor: "review",
865
- answerCoderUsed: true,
875
+ answerCoderRounds: [...given, ...fresh],
866
876
  lastFindings: findings.filter((f) => f.severity !== "minor"),
867
877
  });
868
878
  }
@@ -305,7 +305,7 @@ export async function buildIndex(m, dir, opts = {}) {
305
305
  .map((r) => r.id);
306
306
  const indexedAt = toIsoTimestamp(now);
307
307
 
308
- m.exec("BEGIN");
308
+ m.exec("BEGIN IMMEDIATE");
309
309
  try {
310
310
  for (const id of existingIds) {
311
311
  if (newIds.has(id)) continue;
@@ -352,7 +352,7 @@ export async function buildIndex(m, dir, opts = {}) {
352
352
  .prepare("SELECT id FROM code_chunks WHERE path = ?")
353
353
  .all(path)
354
354
  .map((r) => r.id);
355
- m.exec("BEGIN");
355
+ m.exec("BEGIN IMMEDIATE");
356
356
  try {
357
357
  for (const id of ids) {
358
358
  m.prepare("DELETE FROM code_chunks WHERE id = ?").run(id);
@@ -260,7 +260,7 @@ export function queenKind(card) {
260
260
 
261
261
  // Which ready cards to start now. A flow card without a plan comes back as needsPlan (its owned files are
262
262
  // unknown until a planner runs); with a plan it is checked like any card. A card is launched when it conflicts
263
- // with nothing in flight and nothing launched before it; otherwise it is held against what it met first.
263
+ // with nothing in flight and nothing launched or waiting for a plan before it; otherwise it is held against what it met first.
264
264
  // needsPlan and launch together never exceed `slots`; a held card takes no slot.
265
265
  export function pickCards(arg) {
266
266
  const { ready = [], inFlight = [], slots = 0, plans = {}, roots } = arg && typeof arg === "object" ? arg : {};
@@ -270,6 +270,7 @@ export function pickCards(arg) {
270
270
  const withPlan = (c) => (c.track === "flow" && planOf(c) ? { ...c, plan: planOf(c) } : c);
271
271
  const running = (inFlight || []).filter((c) => c && typeof c === "object").map(withPlan);
272
272
  const launched = [];
273
+ const pending = [];
273
274
  let blocked = false;
274
275
  for (const raw of ready || []) {
275
276
  if (!raw || typeof raw !== "object") continue;
@@ -284,11 +285,12 @@ export function pickCards(arg) {
284
285
  if (out.launch.length + out.needsPlan.length >= slots) continue;
285
286
  if (raw.track === "flow" && !planOf(raw)) {
286
287
  out.needsPlan.push(raw.id);
288
+ pending.push(raw);
287
289
  continue;
288
290
  }
289
291
  const card = withPlan(raw);
290
292
  let met = null;
291
- for (const other of [...running, ...launched]) {
293
+ for (const other of [...running, ...launched, ...pending]) {
292
294
  met = cardConflict(card, other, opts);
293
295
  if (met) break;
294
296
  }
@@ -10,7 +10,7 @@
10
10
  // when a matching file is read. Source: https://code.claude.com/docs/en/memory.md#path-specific-rules
11
11
  import { existsSync, readFileSync, readdirSync } from "node:fs";
12
12
  import { join } from "node:path";
13
- import { unifiedDiff, writeProposals, countLines, insertBulletUnderHeading, removeExactLine, renderRule } from "./learn.mjs";
13
+ import { unifiedDiff, writeProposals, countLines, CLAUDE_MD_MAX_LINES, exceedsClaudeMdLimit, insertBulletUnderHeading, removeExactLine, renderRule } from "./learn.mjs";
14
14
 
15
15
  const DECISIONS_RELDIR = "docs/decisions";
16
16
  const RULES_RELDIR = ".claude/rules";
@@ -295,7 +295,7 @@ export function proposeClaudeMd({ dir, edits, now = new Date(), dryRun = false }
295
295
  return { ok: false, reason: "this edit would change the fenced Commands block, which is not editable here" };
296
296
  }
297
297
  const after = countLines(newText);
298
- if (after > 60) return { ok: false, reason: `CLAUDE.md would be ${after} lines, over its 60-line limit` };
298
+ if (exceedsClaudeMdLimit(newText)) return { ok: false, reason: `CLAUDE.md would be ${after} lines, over its ${CLAUDE_MD_MAX_LINES}-line limit` };
299
299
 
300
300
  const diffResult = diffOrRefuse(CLAUDE_MD_RELPATH, oldText, newText);
301
301
  if (!diffResult.ok) return diffResult;
@@ -325,12 +325,19 @@ function normalize(s) {
325
325
  }
326
326
 
327
327
  // wc -l semantics: the count of newline-terminated lines, not split("\n").length (which counts one extra empty
328
- // element for a file ending in "\n"). CLAUDE.md's own header says "Keep it under 60 lines" against this count.
328
+ // element for a file ending in "\n"). CLAUDE.md's own header says "Keep it to 200 lines or fewer" against this count.
329
329
  export function countLines(text) {
330
330
  if (text === "") return 0;
331
331
  return text.endsWith("\n") ? text.split("\n").length - 1 : text.split("\n").length;
332
332
  }
333
333
 
334
+ // The one CLAUDE.md size limit, shared by learn.mjs and decisions.mjs: 200 lines are allowed, 201 are over. 200 is
335
+ // Anthropic's documented target per CLAUDE.md file, not a measured threshold.
336
+ export const CLAUDE_MD_MAX_LINES = 200;
337
+ export function exceedsClaudeMdLimit(text) {
338
+ return countLines(text) > CLAUDE_MD_MAX_LINES;
339
+ }
340
+
334
341
  function findSection(lines, heading) {
335
342
  const start = lines.findIndex((l) => l.trim() === heading);
336
343
  if (start === -1) return null;
@@ -532,7 +539,7 @@ export function proposeChanges(signals, { dir, claudeMd, config, skills = [] } =
532
539
 
533
540
  // promote: a pitfall cited by RULE_MIN_CARDS distinct cards over RULE_MIN_SESSIONS distinct sessions (card
534
541
  // memory-failure-lessons, ADR 0019 line 60). With known files it becomes a path-scoped .claude/rules file; with none, a
535
- // CLAUDE.md Gotchas bullet (refused at the 60-line cap). Feedback lessons have no trigger.
542
+ // CLAUDE.md Gotchas bullet (refused over the 200-line limit). Feedback lessons have no trigger.
536
543
  for (const r of signals.lessons.pitfalls ?? []) {
537
544
  if (r.cards.length < RULE_MIN_CARDS || r.sessions.length < RULE_MIN_SESSIONS) continue;
538
545
  const evidence = { id: r.id, cards: r.cards, sessions: r.sessions, citations: r.citations, files: r.files };
@@ -553,8 +560,8 @@ export function proposeChanges(signals, { dir, claudeMd, config, skills = [] } =
553
560
  proposals.push({ id: nextId(), kind: "promote", target: "CLAUDE.md", reason: `${reason}, but CLAUDE.md has no "${heading}" section`, evidence, diff: null });
554
561
  continue;
555
562
  }
556
- if (countLines(updated) >= 60) {
557
- proposals.push({ id: nextId(), kind: "promote", target: "CLAUDE.md", reason: `${reason}, but CLAUDE.md is at its 60-line limit (would be ${countLines(updated)})`, evidence, diff: null });
563
+ if (exceedsClaudeMdLimit(updated)) {
564
+ proposals.push({ id: nextId(), kind: "promote", target: "CLAUDE.md", reason: `${reason}, but CLAUDE.md is over its ${CLAUDE_MD_MAX_LINES}-line limit (would be ${countLines(updated)})`, evidence, diff: null });
558
565
  continue;
559
566
  }
560
567
  proposals.push({ id: nextId(), kind: "promote", target: "CLAUDE.md", reason, evidence, diff: unifiedDiff("CLAUDE.md", claudeMd, updated) });
@@ -275,7 +275,7 @@ const V1_OUTCOME_COLUMNS = [
275
275
  ];
276
276
 
277
277
  function migrateV1ToV2(db) {
278
- db.exec("BEGIN");
278
+ db.exec("BEGIN IMMEDIATE");
279
279
  try {
280
280
  db.exec(`CREATE TABLE outcomes_v2 (${OUTCOMES_COLUMNS_SQL});`);
281
281
  db.exec(
@@ -300,7 +300,7 @@ const V2_LESSON_COLUMNS = [
300
300
  ];
301
301
 
302
302
  function migrateV2ToV3(db) {
303
- db.exec("BEGIN");
303
+ db.exec("BEGIN IMMEDIATE");
304
304
  try {
305
305
  db.exec(`CREATE TABLE lessons_v3 (${LESSONS_COLUMNS_SQL});`);
306
306
  db.exec(
@@ -320,7 +320,7 @@ function migrateV2ToV3(db) {
320
320
  // v3 had no reflections table. Unlike v1->v2 and v2->v3, nothing existing is rebuilt: adding a table needs no
321
321
  // rebuild-under-a-temp-name dance, just the CREATE plus the version bump, in the same transactional pattern.
322
322
  function migrateV3ToV4(db) {
323
- db.exec("BEGIN");
323
+ db.exec("BEGIN IMMEDIATE");
324
324
  try {
325
325
  db.exec(`CREATE TABLE reflections (${REFLECTIONS_COLUMNS_SQL});`);
326
326
  db.exec("PRAGMA user_version = 4");
@@ -338,7 +338,7 @@ function migrateV3ToV4(db) {
338
338
  // this guard makes the step a no-op there instead of a duplicate-column error, while still doing the ALTER for a
339
339
  // genuine v4 store that only ever had the v4 columns.
340
340
  function migrateV4ToV5(db) {
341
- db.exec("BEGIN");
341
+ db.exec("BEGIN IMMEDIATE");
342
342
  try {
343
343
  const cols = db.prepare("PRAGMA table_info(outcomes)").all().map((c) => c.name);
344
344
  if (!cols.includes("partial")) db.exec("ALTER TABLE outcomes ADD COLUMN partial INTEGER;");
@@ -354,7 +354,7 @@ function migrateV4ToV5(db) {
354
354
  // the four CREATEs and the version bump. No add-only trigger is added for these tables — the code index is a
355
355
  // cache, never add-only.
356
356
  function migrateV5ToV6(db) {
357
- db.exec("BEGIN");
357
+ db.exec("BEGIN IMMEDIATE");
358
358
  try {
359
359
  db.exec(CODE_INDEX_SCHEMA_SQL);
360
360
  db.exec("PRAGMA user_version = 6");
@@ -381,7 +381,7 @@ const V7_CONDITION_COLUMNS = [
381
381
  ];
382
382
 
383
383
  function migrateV6ToV7(db) {
384
- db.exec("BEGIN");
384
+ db.exec("BEGIN IMMEDIATE");
385
385
  try {
386
386
  const cols = db.prepare("PRAGMA table_info(outcomes)").all().map((c) => c.name);
387
387
  for (const [name, type] of V7_CONDITION_COLUMNS) {
@@ -403,7 +403,7 @@ function migrateV6ToV7(db) {
403
403
  const V8_CODEX_COLUMNS = [["codex_usd", "REAL"]];
404
404
 
405
405
  function migrateV7ToV8(db) {
406
- db.exec("BEGIN");
406
+ db.exec("BEGIN IMMEDIATE");
407
407
  try {
408
408
  const cols = db.prepare("PRAGMA table_info(outcomes)").all().map((c) => c.name);
409
409
  for (const [name, type] of V8_CODEX_COLUMNS) {
@@ -424,7 +424,7 @@ function migrateV7ToV8(db) {
424
424
  const V9_STOP_COLUMNS = [["stop_class", "TEXT"]];
425
425
 
426
426
  function migrateV8ToV9(db) {
427
- db.exec("BEGIN");
427
+ db.exec("BEGIN IMMEDIATE");
428
428
  try {
429
429
  const cols = db.prepare("PRAGMA table_info(outcomes)").all().map((c) => c.name);
430
430
  for (const [name, type] of V9_STOP_COLUMNS) {
@@ -445,7 +445,7 @@ function migrateV8ToV9(db) {
445
445
  const V10_MEMORY_COLUMNS = [["memory_config", "TEXT"]];
446
446
 
447
447
  function migrateV9ToV10(db) {
448
- db.exec("BEGIN");
448
+ db.exec("BEGIN IMMEDIATE");
449
449
  try {
450
450
  const cols = db.prepare("PRAGMA table_info(outcomes)").all().map((c) => c.name);
451
451
  for (const [name, type] of V10_MEMORY_COLUMNS) {
@@ -463,7 +463,7 @@ function migrateV9ToV10(db) {
463
463
  // proposal a repeat of the lesson. One guarded ALTER (LESSONS_COLUMNS_SQL already carries seen for a rebuilt
464
464
  // store), then the version bump. seen is not in the no-rewrite trigger's column list.
465
465
  function migrateV10ToV11(db) {
466
- db.exec("BEGIN");
466
+ db.exec("BEGIN IMMEDIATE");
467
467
  try {
468
468
  const cols = db.prepare("PRAGMA table_info(lessons)").all().map((c) => c.name);
469
469
  if (!cols.includes("seen")) db.exec("ALTER TABLE lessons ADD COLUMN seen INTEGER NOT NULL DEFAULT 0;");
@@ -480,7 +480,7 @@ function migrateV10ToV11(db) {
480
480
  // carries both for a rebuilt store), then the version bump. Neither is in the no-rewrite trigger's column list,
481
481
  // and the no-delete trigger is unchanged: an archived row is kept.
482
482
  function migrateV11ToV12(db) {
483
- db.exec("BEGIN");
483
+ db.exec("BEGIN IMMEDIATE");
484
484
  try {
485
485
  const cols = db.prepare("PRAGMA table_info(lessons)").all().map((c) => c.name);
486
486
  if (!cols.includes("archived")) db.exec("ALTER TABLE lessons ADD COLUMN archived TEXT;");
@@ -493,10 +493,14 @@ function migrateV11ToV12(db) {
493
493
  }
494
494
  }
495
495
 
496
+ // Bounded wait for another process's write lock; well under the 5 s SessionStart hook timeout.
497
+ export const MEMORY_BUSY_TIMEOUT_MS = 2000;
498
+
496
499
  export function openMemory(dir) {
497
500
  const file = memoryPath(dir);
498
501
  mkdirSync(dirname(file), { recursive: true });
499
- const db = new DatabaseSync(file);
502
+ const db = new DatabaseSync(file, { timeout: MEMORY_BUSY_TIMEOUT_MS });
503
+ db.exec(`PRAGMA busy_timeout = ${MEMORY_BUSY_TIMEOUT_MS}`);
500
504
  db.exec("PRAGMA foreign_keys = ON");
501
505
  const version = db.prepare("PRAGMA user_version").get().user_version;
502
506
  if (version === 0) {
@@ -620,7 +624,8 @@ export function inspectMemory(dir) {
620
624
  out.exists = true;
621
625
  let db;
622
626
  try {
623
- db = new DatabaseSync(file, { readOnly: true });
627
+ db = new DatabaseSync(file, { readOnly: true, timeout: MEMORY_BUSY_TIMEOUT_MS });
628
+ db.exec(`PRAGMA busy_timeout = ${MEMORY_BUSY_TIMEOUT_MS}`);
624
629
  out.userVersion = db.prepare("PRAGMA user_version").get().user_version;
625
630
  out.quickCheck = String(db.prepare("PRAGMA quick_check").get().quick_check);
626
631
  } catch (err) {
@@ -688,7 +693,7 @@ export function addLesson(m, opts) {
688
693
  commit_sha: commit,
689
694
  created,
690
695
  };
691
- m.exec("BEGIN");
696
+ m.exec("BEGIN IMMEDIATE");
692
697
  try {
693
698
  m.prepare(
694
699
  `INSERT INTO lessons (id, text, kind, scope, citation, source_agent, source_model, task, card, commit_sha, created)
@@ -2193,7 +2198,7 @@ const ROUND_COLUMNS = new Set(["passes", "fix_passes"]);
2193
2198
  export function recordOutcomes(m, rows) {
2194
2199
  let inserted = 0;
2195
2200
  let updated = 0;
2196
- m.exec("BEGIN");
2201
+ m.exec("BEGIN IMMEDIATE");
2197
2202
  try {
2198
2203
  for (const row of rows) {
2199
2204
  const existing = m.prepare("SELECT id FROM outcomes WHERE run = ? AND task = ?").get(row.run, row.task);
@@ -2813,7 +2818,7 @@ export async function runReflect(m, report, opts = {}) {
2813
2818
  if (dryRun) {
2814
2819
  counters = computeReflectCounters(m, blocks, report, { apply: false, harmfulIds });
2815
2820
  } else {
2816
- m.exec("BEGIN");
2821
+ m.exec("BEGIN IMMEDIATE");
2817
2822
  try {
2818
2823
  counters = computeReflectCounters(m, blocks, report, { apply: true, harmfulIds });
2819
2824
  for (const id of counters.harmful) {
@@ -3147,6 +3152,8 @@ export function failureSlice(dir, card, { session = null } = {}) {
3147
3152
  card: cardName,
3148
3153
  run,
3149
3154
  line: i + 1,
3155
+ class: kind === "block" ? v.class : null,
3156
+ files: kind === "block" && Array.isArray(v.files) ? v.files.filter((f) => typeof f === "string" && f !== "") : [],
3150
3157
  session: sessionOf(v) ?? runSession ?? (typeof session === "string" && session !== "" ? session : null),
3151
3158
  text: failureItemText(kind, body, e.text),
3152
3159
  });
@@ -3179,12 +3186,12 @@ export function readPitfallOccurrences(dir) {
3179
3186
  }
3180
3187
 
3181
3188
  export function recordPitfallOccurrence(dir, occ) {
3182
- const { lesson, citation, card = null, run = null, session = null, at = nowIso() } = occ ?? {};
3189
+ const { lesson, citation, card = null, run = null, session = null, at = nowIso(), via, class: cls = null, files = [] } = occ ?? {};
3183
3190
  if (typeof lesson !== "string" || typeof citation !== "string") throw new Error("recordPitfallOccurrence needs a lesson and a citation");
3184
3191
  if (readPitfallOccurrences(dir).some((o) => o.lesson === lesson && o.citation === citation)) return { written: false };
3185
3192
  const path = join(dir, PITFALL_LEDGER_RELPATH);
3186
3193
  mkdirSync(dirname(path), { recursive: true });
3187
- appendFileSync(path, JSON.stringify({ lesson, citation, card, run, session, at }) + "\n", "utf8");
3194
+ appendFileSync(path, JSON.stringify({ lesson, citation, card, run, session, at, ...(via ? { via } : {}), class: typeof cls === "string" ? cls : null, files: Array.isArray(files) ? files : [] }) + "\n", "utf8");
3188
3195
  return { written: true };
3189
3196
  }
3190
3197
 
@@ -3252,6 +3259,24 @@ export async function runFailureReflect(m, opts = {}) {
3252
3259
  const existing = m.prepare("SELECT * FROM reflections WHERE report_hash = ?").get(key);
3253
3260
  if (existing) return { alreadyReflected: true, ...base, row: reflectionRowToObject(existing) };
3254
3261
 
3262
+ // Code-side repeats (ADR 0019 line 60): a real block with the same class on a file a live pitfall's recorded
3263
+ // occurrence also names is another occurrence of that pitfall. Empty files never match.
3264
+ const fileRepeated = [];
3265
+ const sharesFile = (a, b) => Array.isArray(a) && Array.isArray(b) && a.some((f) => b.includes(f));
3266
+ for (const item of slice.items) {
3267
+ if (item.kind !== "block" || !item.files.length) continue;
3268
+ for (const o of readPitfallOccurrences(dir)) {
3269
+ if (o.class !== item.class || !sharesFile(o.files, item.files)) continue;
3270
+ const target = getLesson(m, o.lesson);
3271
+ if (!target || target.kind !== "pitfall" || target.superseded_by) continue;
3272
+ // List the pitfall only when this match is new: a block already recorded (a card's second stop re-reads it) adds nothing.
3273
+ const isNew = dryRun
3274
+ ? !readPitfallOccurrences(dir).some((x) => x.lesson === target.id && x.citation === item.ref)
3275
+ : recordPitfallOccurrence(dir, { lesson: target.id, citation: item.ref, card: item.card, run: item.run, session: item.session, at: now, via: "file", class: item.class, files: item.files }).written;
3276
+ if (isNew && !fileRepeated.includes(target.id)) fileRepeated.push(target.id);
3277
+ }
3278
+ }
3279
+
3255
3280
  const prompt = buildFailureReflectPrompt(slice, { existingLessons: listLessons(m) });
3256
3281
  // A dry run with no propose makes no model call: it returns the prompt it would send and spends nothing.
3257
3282
  if (dryRun && typeof propose !== "function") {
@@ -3268,10 +3293,10 @@ export async function runFailureReflect(m, opts = {}) {
3268
3293
  const byRef = new Map(slice.items.map((i) => [i.ref, i]));
3269
3294
  const appended = [];
3270
3295
  const appendedIds = new Set();
3271
- const repeated = [];
3296
+ const repeated = [...fileRepeated];
3272
3297
  const rejected = [];
3273
3298
  const occur = (lesson, item) => {
3274
- if (!dryRun) recordPitfallOccurrence(dir, { lesson, citation: item.ref, card: item.card, run: item.run, session: item.session, at: now });
3299
+ if (!dryRun) recordPitfallOccurrence(dir, { lesson, citation: item.ref, card: item.card, run: item.run, session: item.session, at: now, class: item.class, files: item.files });
3275
3300
  if (!repeated.includes(lesson)) repeated.push(lesson);
3276
3301
  };
3277
3302
  for (const p of result.lessons) {
@@ -3338,7 +3363,7 @@ export async function runFailureReflect(m, opts = {}) {
3338
3363
  });
3339
3364
  appended.push(row.id);
3340
3365
  appendedIds.add(row.id);
3341
- recordPitfallOccurrence(dir, { lesson: row.id, citation: item.ref, card: item.card, run: item.run, session: item.session, at: now });
3366
+ recordPitfallOccurrence(dir, { lesson: row.id, citation: item.ref, card: item.card, run: item.run, session: item.session, at: now, class: item.class, files: item.files });
3342
3367
  }
3343
3368
 
3344
3369
  const sessionId = result.sessionId || null;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dougharness/flow",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "private": true,
5
5
  "description": "Plan, approve, implement one task per worktree, verify, review: a Workflow-tool template and subagents for Claude Code.",
6
6
  "type": "module",
@@ -37,6 +37,20 @@ import { SEATS } from "../lib/card-loop.mjs";
37
37
  import { planFor, reportPathFor } from "../lib/plan.mjs";
38
38
  import { readMemoryConfig, readMemoryStaleDays } from "../lib/embeddings.mjs";
39
39
 
40
+ // Card memory-failures-wiring (user decision, 2026-10-28): a stopped card starts `memory.mjs reflect --failures
41
+ // <card> --max-usd 0.5 --detach` (job failures-<card>, cheap row), after its run history is written. The queue
42
+ // approval is the approval. A start that fails (a live job holds the name) warns and never fails the report.
43
+ function startFailuresReflect(dir, id) {
44
+ try {
45
+ execFileSync(process.execPath, [join(dirname(fileURLToPath(import.meta.url)), "memory.mjs"), "reflect", "--failures", id, dir, "--max-usd", "0.5", "--detach"], {
46
+ stdio: ["ignore", "ignore", "pipe"],
47
+ env: process.env,
48
+ });
49
+ } catch (e) {
50
+ process.stderr.write(`autopilot: warning: cannot start reflect --failures for ${id}: ${String(e.stderr || e.message || e).trim().split("\n")[0]}\n`);
51
+ }
52
+ }
53
+
40
54
  const argv = process.argv.slice(2);
41
55
  const opts = {};
42
56
  const pos = [];
@@ -566,6 +580,7 @@ switch (cmd) {
566
580
  process.stderr.write(`autopilot: warning: cannot write the run history for ${c.id}: ${e.message || e}\n`);
567
581
  }
568
582
  }
583
+ if (kind === "hand" && parsed !== null && (parsed.report ?? parsed)?.outcome === "stopped") startFailuresReflect(dir, c.id);
569
584
  if (kind === "flow" && parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) && parsed.ok === false && !parsed.paused) {
570
585
  try {
571
586
  const mem = await import("../lib/memory.mjs");
@@ -645,6 +660,7 @@ switch (cmd) {
645
660
  process.stderr.write(`autopilot: warning: cannot write the run history for ${c.id}: ${e.message || e}\n`);
646
661
  }
647
662
  }
663
+ if (kind === "flow" && parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) && parsed.ok === false && !parsed.paused) startFailuresReflect(dir, c.id);
648
664
  const v = classifyNotification(kind, { status: "completed", result: parsed === null ? text : parsed });
649
665
  if (v.action === "ask") {
650
666
  let answered = false;
@@ -145,7 +145,11 @@ function unknownFlagFor(cmd, opts) {
145
145
  }
146
146
 
147
147
  function dirFrom(args, n) {
148
- return resolve(process.env.CLAUDE_PROJECT_DIR || args[n] || process.cwd());
148
+ const d = resolve(process.env.CLAUDE_PROJECT_DIR || args[n] || process.cwd());
149
+ if (!existsSync(join(d, ".doug")) && !existsSync(join(d, "docs", "board.json"))) {
150
+ fail(`not a Doug project: ${d} has no .doug/`, 1);
151
+ }
152
+ return d;
149
153
  }
150
154
 
151
155
  if (cmd === "epic" || cmd === "milestone") {
@@ -43,7 +43,9 @@ for (const a of argv) {
43
43
  const [cmd, ...rest] = positional;
44
44
 
45
45
  function dirFrom(args, n) {
46
- return resolve(process.env.CLAUDE_PROJECT_DIR || args[n] || process.cwd());
46
+ const d = resolve(process.env.CLAUDE_PROJECT_DIR || args[n] || process.cwd());
47
+ if (!existsSync(join(d, ".doug"))) fail(`not a Doug project: ${d} has no .doug/`, 1);
48
+ return d;
47
49
  }
48
50
 
49
51
  function readClaudeMd(dir) {