portable-agent-layer 0.114.0-canary.8 → 0.114.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 (154) hide show
  1. package/README.md +22 -15
  2. package/assets/plugins/dark-factory/README.md +62 -5
  3. package/assets/plugins/dark-factory/agents/coach.md +21 -0
  4. package/assets/plugins/dark-factory/agents/code-writer.md +2 -2
  5. package/assets/plugins/dark-factory/agents/debugger.md +5 -2
  6. package/assets/plugins/dark-factory/agents/reviewer.md +3 -1
  7. package/assets/plugins/dark-factory/agents/test-writer.md +1 -1
  8. package/assets/plugins/dark-factory/scripts/build.mjs +557 -0
  9. package/assets/plugins/dark-factory/scripts/coach.mjs +473 -0
  10. package/assets/plugins/dark-factory/scripts/corrections.mjs +108 -0
  11. package/assets/plugins/dark-factory/scripts/coverage.mjs +61 -0
  12. package/assets/plugins/dark-factory/scripts/findings.mjs +288 -0
  13. package/assets/plugins/dark-factory/scripts/gate.mjs +4 -3
  14. package/assets/plugins/dark-factory/scripts/instructions.mjs +94 -0
  15. package/assets/plugins/dark-factory/scripts/lib.mjs +84 -4
  16. package/assets/plugins/dark-factory/scripts/role.mjs +188 -24
  17. package/assets/plugins/dark-factory/scripts/roles.mjs +175 -10
  18. package/assets/plugins/dark-factory/scripts/ship.mjs +72 -22
  19. package/assets/plugins/dark-factory/scripts/stats.mjs +42 -0
  20. package/assets/plugins/dark-factory/scripts/task.mjs +75 -17
  21. package/assets/plugins/dark-factory/skills/po/SKILL.md +16 -2
  22. package/assets/schema/pal-settings.schema.json +4 -17
  23. package/assets/skills/pal-analyze/SKILL.md +4 -4
  24. package/assets/skills/projects/SKILL.md +2 -3
  25. package/assets/templates/AGENTS.md.template +1 -2
  26. package/assets/templates/PAL/ALGORITHM.md +10 -81
  27. package/assets/templates/PAL/MEMORY_SYSTEM.md +12 -27
  28. package/assets/templates/PAL/PROJECT_LIFECYCLE.md +1 -2
  29. package/assets/templates/PAL/README.md +8 -16
  30. package/assets/templates/PAL/SYSTEM_ARCHITECTURE.md +37 -89
  31. package/assets/templates/pal-settings.json +0 -8
  32. package/assets/templates/rules.codex.rules +4 -12
  33. package/assets/templates/settings.antigravity.json +1 -5
  34. package/assets/templates/settings.claude.json +12 -6
  35. package/package.json +10 -10
  36. package/src/cli/builtin-tools.ts +0 -10
  37. package/src/cli/dependencies.ts +6 -1
  38. package/src/cli/index.ts +37 -17
  39. package/src/cli/leftovers.ts +115 -2
  40. package/src/cli/migrate.ts +180 -1
  41. package/src/cli/progress.ts +21 -0
  42. package/src/cli/tree.ts +5 -1
  43. package/src/cli/update-flow.ts +40 -11
  44. package/src/hooks/CompactRecover.ts +0 -1
  45. package/src/hooks/LoadContext.ts +2 -3
  46. package/src/hooks/PreCompactPersist.ts +1 -3
  47. package/src/hooks/RtkWrap.ts +4 -4
  48. package/src/hooks/SecurityValidator.ts +1 -4
  49. package/src/hooks/StopOrchestrator.ts +2 -9
  50. package/src/hooks/handlers/agenda.ts +1 -60
  51. package/src/hooks/handlers/inject-retrieval.ts +5 -31
  52. package/src/hooks/handlers/persist-last-exchange.ts +5 -165
  53. package/src/hooks/handlers/project-touch.ts +2 -12
  54. package/src/hooks/handlers/rating.ts +5 -41
  55. package/src/hooks/handlers/session-intelligence.ts +13 -66
  56. package/src/hooks/handlers/session-name.ts +0 -6
  57. package/src/hooks/handlers/synthesis.ts +0 -1
  58. package/src/hooks/handlers/tab.ts +0 -1
  59. package/src/hooks/handlers/update-check.ts +22 -5
  60. package/src/hooks/lib/capture-store.ts +13 -27
  61. package/src/hooks/lib/claim-check.ts +4 -10
  62. package/src/hooks/lib/claim-log.ts +11 -2
  63. package/src/hooks/lib/claude-md.ts +5 -14
  64. package/src/hooks/lib/context.ts +5 -161
  65. package/src/hooks/lib/daily-nudge.ts +0 -2
  66. package/src/hooks/lib/graduation.ts +16 -47
  67. package/src/hooks/lib/import-merge.ts +1 -1
  68. package/src/hooks/lib/learning-store.ts +1 -68
  69. package/src/hooks/lib/models.ts +1 -5
  70. package/src/hooks/lib/paths.ts +0 -5
  71. package/src/hooks/lib/post-tool.ts +2 -0
  72. package/src/hooks/lib/progress-tree-context.ts +6 -4
  73. package/src/hooks/lib/progress-tree-factory.ts +124 -0
  74. package/src/hooks/lib/progress-tree-git.ts +19 -4
  75. package/src/hooks/lib/progress-tree-prs.ts +214 -0
  76. package/src/hooks/lib/progress-tree-render.ts +83 -13
  77. package/src/hooks/lib/progress-tree-session-end.ts +61 -0
  78. package/src/hooks/lib/progress-tree-session-node.ts +11 -4
  79. package/src/hooks/lib/progress-tree-stop.ts +14 -0
  80. package/src/hooks/lib/progress-tree-tidy.ts +112 -0
  81. package/src/hooks/lib/progress-tree-tool.ts +174 -0
  82. package/src/hooks/lib/progress-tree.ts +113 -6
  83. package/src/hooks/lib/projects.ts +3 -7
  84. package/src/hooks/lib/prompt-text.ts +7 -3
  85. package/src/hooks/lib/rtk-worktree.ts +18 -0
  86. package/src/hooks/lib/security.ts +51 -7
  87. package/src/hooks/lib/semi-static.ts +1 -82
  88. package/src/hooks/lib/session-context.ts +1 -6
  89. package/src/hooks/lib/settings.ts +2 -0
  90. package/src/hooks/lib/stop.ts +2 -49
  91. package/src/hooks/lib/text-similarity.ts +2 -3
  92. package/src/hooks/lib/time.ts +0 -15
  93. package/src/hooks/lib/tool-events.ts +3 -3
  94. package/src/hooks/lib/transcript.ts +20 -1
  95. package/src/targets/claude/install.ts +0 -6
  96. package/src/targets/claude/uninstall.ts +0 -7
  97. package/src/targets/codex/install.ts +0 -6
  98. package/src/targets/codex/uninstall.ts +0 -5
  99. package/src/targets/copilot/install.ts +2 -10
  100. package/src/targets/copilot/uninstall.ts +0 -6
  101. package/src/targets/cursor/install.ts +0 -5
  102. package/src/targets/cursor/uninstall.ts +0 -6
  103. package/src/targets/lib.ts +2 -3
  104. package/src/targets/opencode/install.ts +0 -5
  105. package/src/targets/opencode/plugin.ts +17 -17
  106. package/src/targets/opencode/uninstall.ts +0 -5
  107. package/src/tools/agent/analyze.ts +3 -3
  108. package/src/tools/agent/project.ts +0 -12
  109. package/src/tools/agent/synthesize.ts +9 -53
  110. package/src/tools/control-room/attention.ts +13 -23
  111. package/src/tools/control-room/data.ts +9 -73
  112. package/src/tools/control-room/detail.ts +3 -24
  113. package/src/tools/control-room/matrix.ts +10 -11
  114. package/src/tools/control-room/server.ts +4 -3
  115. package/src/tools/control-room/ui/dist/assets/{index-D0pEd7Ln.js → index-Ci0Zp32V.js} +1 -1
  116. package/src/tools/control-room/ui/dist/index.html +1 -1
  117. package/src/tools/control-room/ui/parts.tsx +19 -15
  118. package/src/tools/control-room/ui/screens/project-detail.tsx +6 -15
  119. package/src/tools/control-room/ui/screens/settings.tsx +1 -1
  120. package/src/tools/control-room/ui/screens/today.tsx +20 -17
  121. package/src/tools/control-room/work.ts +82 -0
  122. package/src/tools/dark-factory/stamp.ts +12 -8
  123. package/src/tools/lib/analyze-report.ts +2 -5
  124. package/src/tools/lib/thread.ts +7 -75
  125. package/assets/plugins/dark-factory/workflows/build.js +0 -235
  126. package/assets/skills/opinion/SKILL.md +0 -95
  127. package/assets/skills/opinion/tools/opinion.ts +0 -237
  128. package/assets/skills/pal-reflect/SKILL.md +0 -62
  129. package/assets/templates/PAL/OPINION_TRACKING.md +0 -3
  130. package/src/hooks/handlers/auto-graduate.ts +0 -177
  131. package/src/hooks/handlers/failure-principle.ts +0 -91
  132. package/src/hooks/handlers/failure.ts +0 -75
  133. package/src/hooks/handlers/reflect-trigger.ts +0 -99
  134. package/src/hooks/handlers/self-model-trigger.ts +0 -26
  135. package/src/hooks/lib/decision-label.ts +0 -70
  136. package/src/hooks/lib/failure-principle.ts +0 -98
  137. package/src/hooks/lib/handoff-context.ts +0 -112
  138. package/src/hooks/lib/learning-category.ts +0 -14
  139. package/src/hooks/lib/opinions.ts +0 -209
  140. package/src/hooks/lib/progress-tree-gate.ts +0 -117
  141. package/src/hooks/lib/relationship.ts +0 -137
  142. package/src/hooks/lib/retrieval-index.ts +0 -260
  143. package/src/hooks/lib/retrieval.ts +0 -176
  144. package/src/hooks/lib/wisdom.ts +0 -202
  145. package/src/tools/agent/handoff-note.ts +0 -86
  146. package/src/tools/agent/relationship-note.ts +0 -77
  147. package/src/tools/agent/relationship-reflect.ts +0 -103
  148. package/src/tools/agent/thread.ts +0 -87
  149. package/src/tools/agent/wisdom-frame.ts +0 -248
  150. package/src/tools/lib/handoff-note.ts +0 -102
  151. package/src/tools/lib/note-flags.ts +0 -59
  152. package/src/tools/lib/relationship-reflect.ts +0 -402
  153. package/src/tools/lib/self-model.ts +0 -499
  154. package/src/tools/self-model.ts +0 -177
package/README.md CHANGED
@@ -1,10 +1,16 @@
1
1
  # Portable Agent Layer (PAL)
2
2
 
3
- A cross-platform, cross-agent layer for portable AI workflows, memory, and accumulated knowledge.
3
+ [![PAL: stop re-explaining yourself to every AI tool](https://raw.githubusercontent.com/kovrichard/portable-agent-layer/main/docs/images/pal-banner.png)](https://pal.konvert7.com)
4
+
5
+ [![npm version](https://img.shields.io/npm/v/portable-agent-layer)](https://www.npmjs.com/package/portable-agent-layer) [![npm downloads](https://img.shields.io/npm/dm/portable-agent-layer)](https://www.npmjs.com/package/portable-agent-layer) [![License: MIT](https://img.shields.io/npm/l/portable-agent-layer)](LICENSE)
6
+
7
+ **Your AI forgets you. PAL doesn't.** Free, open-source memory, skills and rules shared by Claude Code, opencode, Cursor, GitHub Copilot, Codex and Antigravity CLI. Install it once, and every agent starts the next session knowing who you are, what you're working on and where you left off.
8
+
9
+ **Website:** [pal.konvert7.com](https://pal.konvert7.com)
4
10
 
5
11
  PAL lets you carry your agent context across **Windows**, **macOS**, and **Linux**, and work across different agent runtimes and interfaces such as **Claude Code**, **opencode**, **Cursor**, **GitHub Copilot**, **Codex**, and **Antigravity CLI**. Its core idea is simple: your knowledge and workflows should belong to **you**, not to a single machine, tool, or vendor.
6
12
 
7
- > Inspired in part by [Daniel Miessler](https://danielmiessler.com)'s work on [Personal AI Infrastructure](https://github.com/danielmiessler/Personal_AI_Infrastructure). PAL is an independent open-source implementation focused on portability across platforms and agents. It is not affiliated with or endorsed by Daniel Miessler.
13
+ > Inspired in part by [Daniel Miessler](https://danielmiessler.com)'s work on [LifeOS](https://github.com/danielmiessler/LifeOS). PAL is an independent open-source implementation focused on portability across platforms and agents. It is not affiliated with or endorsed by Daniel Miessler.
8
14
 
9
15
  ---
10
16
 
@@ -77,7 +83,7 @@ pal cli status # check your setup
77
83
  | `pal cli init` | Scaffold PAL home directory and install hooks |
78
84
  | `pal cli install` | Register hooks/skills for targets |
79
85
  | `pal cli uninstall` | Remove hooks/skills for targets |
80
- | `pal cli update` | Update PAL (git pull or npm update) and reinstall hooks. Install asks once whether to do this on its own: when a session closes PAL checks for a release (at most hourly) and installs it, so opening PAL is never slowed. A failed update waits a day before retrying. The switch lives in the control room under Settings → Updates. On a repo install an update waits while the clone has uncommitted changes. `--canary` installs the latest prerelease from the `canary` branch instead; auto-update always follows the stable release |
86
+ | `pal cli update` | Update PAL (git pull or npm update) and reinstall hooks. Install asks once whether to do this on its own: when a session closes PAL checks for a release (at most hourly) and installs it, so opening PAL is never slowed. A failed update waits a day before retrying. The switch lives in the control room under Settings → Updates. On a repo install an update waits while the clone has uncommitted changes. `--canary` switches a package install to the `canary` prerelease channel; from then on plain `pal cli update`, auto-update and the update notice follow canary until `--stable` switches back. Neither ever installs an older version than the one you have |
81
87
  | `pal cli export` | Export user state (telos, memory) to a zip |
82
88
  | `pal cli import` | Import user state from a zip |
83
89
  | `pal cli status` | Show current PAL configuration |
@@ -88,7 +94,7 @@ pal cli status # check your setup
88
94
  | `pal cli cost` | What each month was paid against its API-equivalent cost, per agent |
89
95
  | `pal cli wrapped [--year <yyyy>]` | A year of your work in numbers, read from the event log |
90
96
  | `pal cli patterns` | How you work across projects, read from the event log |
91
- | `pal cli progress [show\|list\|open\|enter\|park\|wait\|done\|stopped\|decide\|attach\|follow-up]` | The progress tree: what you are on in this project, where it stopped, what is parked or waiting, and the decisions and artifacts on each node. Detours are child nodes and `done` returns to the parent. With `dynamicContext.workTree` opted into, the active node rides along in every session and prompt, and your own commits attach to it at turn end |
97
+ | `pal cli progress [show\|list\|open\|enter\|park\|wait\|done\|stopped\|decide\|attach\|follow-up]` | The progress tree: what you are on in this project, where it stopped, what is parked or waiting, and the decisions and artifacts on each node. Detours are child nodes and `done` returns to the parent. The active node rides along in every session and prompt, and your own commits attach to it at turn end |
92
98
  | `pal cli content preserve` | Copy every Claude Code transcript, gzipped, into `memory/content/` before Claude Code deletes it (30 days by default). Runs on its own whenever a session closes; the content store never leaves the machine, so `export` skips it |
93
99
  | `pal cli events discord-nag <sent\|answered>` | For a bot outside PAL: record a nag it sent (`--kind <kind>`), or the answer to one and how long it took (`--after-sec <n>`), in the local event log |
94
100
  | `pal cli infer` | One model call for scripts and bots, on the active agent's route: prompt on stdin, reply on stdout. `--tier small\|medium\|large\|flagship` (on Claude: Haiku, Sonnet, Opus, Fable; on Codex: Luna, Sol, Sol at high effort, Astra; on Antigravity: Flash at low, medium and high effort, and no flagship; an agent without the tier asked refuses it), `--system <file>`, `--schema <file>` for a JSON reply checked against it, `--timeout <seconds>`. The call loads no PAL hooks or context; exits 1 with the reason when no route answers |
@@ -131,7 +137,7 @@ pal cli install # all available (default)
131
137
  | Codex | Full | Yes | Yes | Yes | Yes | `codex exec` |
132
138
  | Antigravity CLI | Full | Yes | Yes (plugin) | Yes (via the plugin's `rules/`) | Yes | `agy` |
133
139
 
134
- PAL's background inference (session naming, summaries, failure capture, etc.) runs through whichever subscription CLI is active — no API key required by default.
140
+ PAL's background inference (session naming, summaries, correction checks, etc.) runs through whichever subscription CLI is active — no API key required by default.
135
141
 
136
142
  ---
137
143
 
@@ -208,9 +214,7 @@ PAL ships with built-in skills that extend your agent's capabilities:
208
214
  | `fyzz-chat-api` | Query Fyzz Chat conversations via API |
209
215
  | `humanize` | Rewrite text to strip AI tells and read as human |
210
216
  | `onboarding` | Interview the user to fill empty TELOS topics and the timezone, one topic at a time |
211
- | `opinion` | Confirm or contradict tracked opinions (confidence-weighted) |
212
217
  | `pal-analyze` | Surface rating trends, failure patterns, and graduation candidates |
213
- | `pal-reflect` | Promote recurring observations into tracked opinions |
214
218
  | `playwright` | Screenshot a page for a visual check |
215
219
  | `presentation` | Build branded slide decks from outlines |
216
220
  | `projects` | Look up, resume, register, or manage tracked projects |
@@ -245,14 +249,17 @@ Your setup should be able to travel with you.
245
249
 
246
250
  ## Features
247
251
 
248
- - **Cross-platform**: works on Windows, macOS, and Linux
249
- - **Cross-agent**: full support for Claude Code, opencode, Cursor, GitHub Copilot, Codex, and Antigravity CLI
250
- - **Subscription-first inference**: background inference routes through whichever subscription CLI is active — no API key needed by default
251
- - **Portable knowledge**: export and import accumulated knowledge
252
- - **A morning screen, not a dashboard**: `pal cli server` ranks your projects *and* your written goals in one urgent/important grid. Urgency is read off the files — blockers, an unfinished handoff, a date in a next step, an important thing gone quiet. Importance comes from one fact per project: whether it serves a goal you wrote down, is a way the work could pay, or is kept for its own sake. PAL guesses that once at session stop; you correct it on the page or with `project.ts serves <name> goal|revenue|fun`, and the correction survives every later guess
253
- - **TypeScript-first**: built in TypeScript from day one
254
- - **Open source**: hackable, inspectable, extensible
255
- - **Composable**: intended to fit into real developer workflows
252
+ - **Memory across sessions**: when a session starts, PAL loads who you are, your active projects and where your last session's work stopped. When it ends, PAL saves a summary and any corrections for next time
253
+ - **Learns from your corrections**: tell an agent it got something wrong and PAL labels the mistake, drafts a rule and asks you once. Approve it with `pal cli rule approve` and every agent follows it from the next session
254
+ - **Done means checked**: real work runs through five phases (observe, plan, execute, verify, learn), and nothing is done until each criterion has evidence
255
+ - **Built-in skills**: research, PDFs, slide decks, frontend design, humanizing text and more. See [Skills](#skills)
256
+ - **Cross-agent**: one memory shared by Claude Code, opencode, Cursor, GitHub Copilot, Codex and Antigravity CLI
257
+ - **Cross-platform**: works on Windows, macOS and Linux
258
+ - **No API key needed**: background work like session summaries runs through the CLI of the agent you're using, on the subscription you already pay for
259
+ - **Guardrails**: a hook checks every command before it runs and blocks the destructive ones, like a recursive delete of your home directory, a disk format or a download piped into a shell
260
+ - **A morning screen**: `pal cli server start` runs a local page that shows three moves for today and ranks every project and goal by urgency and importance
261
+ - **Portable plain files**: your memory lives in `~/.pal` as plain files. `pal cli export` packs it into one zip and `pal cli import` restores it on another machine
262
+ - **Open source**: MIT licensed, so you can read and change every line
256
263
 
257
264
  ---
258
265
 
@@ -11,7 +11,7 @@ Without PAL:
11
11
  /plugin install dark-factory@pal
12
12
  ```
13
13
 
14
- With PAL, it is installed for you.
14
+ With PAL, the marketplace is registered but the plugin starts disabled; turn it on with `/plugin enable dark-factory@pal`.
15
15
 
16
16
  ## Requirements
17
17
 
@@ -19,6 +19,7 @@ With PAL, it is installed for you.
19
19
  - `git`: worktrees, branches and pushes.
20
20
  - `gh`, signed in with `gh auth login`: opens the pull request and reads its CI checks.
21
21
  - `bash`: runs the gate and the notify commands. On Windows it comes with Git for Windows.
22
+ - `claude`, signed in: every role runs as a headless `claude -p` session.
22
23
 
23
24
  The PO checks for these before it takes a request, and every build checks again before it starts.
24
25
 
@@ -26,6 +27,21 @@ The PO checks for these before it takes a request, and every build checks again
26
27
 
27
28
  Run `/dark-factory:po` and say what you want. The PO writes a spec with acceptance criteria, shows it to you, and starts the build once you say go. You hear back when the pull request is ready, or when the factory needs an answer only you can give.
28
29
 
30
+ The build is a plain Node program, `scripts/build.mjs`, that the PO starts in the background. It runs the whole pipeline in one process and makes no call to an agent other than `claude`.
31
+
32
+ ### From a terminal or cron
33
+
34
+ ```
35
+ node <plugin folder>/scripts/build.mjs <task-id>
36
+ ```
37
+
38
+ Inside Claude Code the plugin folder is `${CLAUDE_PLUGIN_ROOT}`.
39
+
40
+ - It needs `claude` and `gh` signed in. Set `DARK_FACTORY_HOME` when the default `~/.dark-factory` isn't the home.
41
+ - It prints one JSON line, `{task, status, message, pr}`.
42
+ - It exits 0 for ready, 1 for stuck and 3 for waiting.
43
+ - A rerun after an answer goes in the spec's **Decisions** section, and the rerun continues the task.
44
+
29
45
  ## Roles
30
46
 
31
47
  | Role | Model | Job |
@@ -38,6 +54,7 @@ Run `/dark-factory:po` and say what you want. The PO writes a spec with acceptan
38
54
  | Debugger | Opus | Reproduces bugs, fixes what the code writer could not |
39
55
  | Reviewer | Sonnet | Reviews the diff against the spec |
40
56
  | Tester | Sonnet | Checks the criteria in the running app |
57
+ | Coach | Opus | Studies every ready or stuck run and proposes general rules for the role prompts |
41
58
  | Gate | code | Runs your checks; its exit code is the verdict |
42
59
 
43
60
  Not every task runs every role. The PO picks a category, and code maps it to roles:
@@ -72,24 +89,64 @@ Each repository the factory works on has a `.dark-factory.json` at its root:
72
89
  }
73
90
  ```
74
91
 
92
+ The categories with a test writer (`bug`, `feature` and `big-feature`) need a gate check named exactly `tests`. The build runs it right after the test writer, and the task is stuck when no test fails.
93
+
75
94
  ## Notifications
76
95
 
77
96
  Set `DARK_FACTORY_NOTIFY` to a shell command. It receives the message on stdin, with `DARK_FACTORY_TASK` and `DARK_FACTORY_KIND` (`ready`, `waiting` or `stuck`) in its environment.
78
97
 
79
98
  ## Measuring
80
99
 
81
- The factory keeps its tasks, worktrees and event log in `$DARK_FACTORY_HOME`, which defaults to `~/.dark-factory` on every machine. `pal cli export` does not carry them: a factory task cannot continue on another machine, so its history stays where it ran.
100
+ The factory keeps its tasks, worktrees and event log in `$DARK_FACTORY_HOME`, which defaults to `~/.dark-factory` on every machine. A factory task cannot continue on another machine, so its history stays where it ran.
101
+
102
+ Every step appends one event to `$DARK_FACTORY_HOME/events.jsonl`, and the events of a task are also appended to `tasks/<task>/events.jsonl`, with its `run_finished` line. A role's `role_finished` event carries its `sessionId`, the name of its transcript. `node scripts/stats.mjs` counts, from those events alone: tasks by category, outcomes, gate failures by check and by role, the code writer's first-try pass rate, escalations, CI results, review rounds, questions to you, and roles added by the diff check.
103
+
104
+ Every role run appends `role_finished` with its cost and tokens, and the red-test proof appends `tests_red` with the exit code and the failing count. Every build appends `run_finished` with the outcome, the total `costUsd`, the total tokens, the number of role runs and `wallMs`. `node scripts/task.mjs show <id>` prints the task with its latest step.
105
+
106
+ ## Coach
107
+
108
+ After a run ends `ready` or `stuck`, the build starts the coach in a detached process, so nothing waits on it. It writes `coach_started`, then `coach_finished` or `coach_failed`.
109
+
110
+ The coach reads the spec, the artifacts, the task's events, the diff of the run, the transcripts named by `role_finished`'s `transcriptPath`, and the commits you pushed to a merged PR after the factory's last push (`pushed` carries `head`).
111
+
112
+ Its findings live in `$DARK_FACTORY_HOME/coach/findings.jsonl`. Each finding has an `id`, a `role`, a `class`, a `rule`, a `severity`, a `metric`, its `evidence` and a `status`: `pending`, `rejected`, or `approved` once a task is created for it.
113
+
114
+ The coach's result has a `reviewed` list with one verdict per transcript and per correction commit: its `source` (the transcript path or the commit sha), a `verdict` of `finding` or `clean`, the `class` for a finding, and a one-sentence `reason`. `coach.mjs` checks coverage in code: an input with no item, or a `finding` whose class is neither among the run's findings nor the class of a pending finding, is missing. Missing inputs make it resume the same session once (`--resume`), listing them, and the second result's verdicts and findings are merged with the first's. Inputs still missing are recorded as `coach_incomplete`; the findings returned are stored anyway, and a correction without a verdict is not marked given, so the next run gets it again. `coach_finished` carries `reviewed` and `expected`: the number of inputs with a verdict, and the number of inputs.
115
+
116
+ A deterministic generality check drops a rule that names a path, basename or identifier the run's diff changed, and records it as `coach_rule_rejected`. An added function or variable name only counts when it is camelCase, contains `_` or a digit, and has at least 3 characters; a plain lowercase name such as `parse` or `slug` passes, because it would match ordinary words in a rule.
117
+
118
+ The coach runs with `--add-dir` for the factory home, the transcripts folder and the plugin directory, so it can read the transcripts and the role prompts. Concurrent coach runs take a lock on `coach/findings.lock` while they update the findings, and a task whose merged PR has no later commits is recorded as `coach_checked` and not queried again.
119
+
120
+ `node scripts/coach.mjs` has these commands:
121
+
122
+ - `run <task-id>` runs the coach by hand.
123
+ - `list` lists pending findings by role; `list --applied` reports each merged rule's metric before and after its merge.
124
+ - `show <id>` prints one finding.
125
+ - `reject <id> "<reason>"` rejects a finding; its class does not come back.
126
+ - `approve <id> [--repo <path>]` creates a `small` task for the plugin repo with a generated spec. Set `coach.repo` in `config.json` to skip `--repo`.
127
+
128
+ Approving only creates the task. Your go builds it, and the rule lands through a PR.
129
+
130
+ ## Instructions
131
+
132
+ Every role gets your instructions appended to its system prompt: first the user's `~/.claude/CLAUDE.md`, then the repo's `CLAUDE.md`, each headed by its path. An `@path` line in either file imports that file, as Claude Code does: the path is relative to the file that contains the line, `~/` is your home folder, imports nest up to 5 levels, and lines inside code blocks are never imports. A file that doesn't exist is skipped. An import that can't be read stays as written in the instructions and is logged as an `instructions_import_missing` event.
133
+
134
+ The repo's `CLAUDE.md` is read from your checkout when the task starts, so a role that edits it in the worktree doesn't change what the later roles are told.
135
+
136
+ - `"repoInstructions": false` in `.dark-factory.json` leaves out the repo's `CLAUDE.md`.
137
+ - `"userInstructions": false` in `$DARK_FACTORY_HOME/config.json` (`~/.dark-factory/config.json`, optional; a missing file means both parts are on) leaves out your `~/.claude/CLAUDE.md`.
82
138
 
83
- Every step appends one event to `$DARK_FACTORY_HOME/events.jsonl`. `node scripts/stats.mjs` counts, from those events alone: tasks by category, outcomes, gate failures by check and by role, the code writer's first-try pass rate, escalations, CI results, review rounds, questions to you, and roles added by the diff check.
139
+ Hooks never run in a role, and neither do your settings or MCP servers.
84
140
 
85
141
  ## Permissions
86
142
 
87
- The build runs git, gh and your gate commands without you watching. Allow them before the first run, for example in `.claude/settings.json`:
143
+ - Roles run isolated: `--setting-sources ""`, the plugin from `--plugin-dir`, and their own tool policy from `roles.mjs`, so user hooks and settings don't reach them; only the CLAUDE.md instructions above do.
144
+ - The PO session only needs `"Bash(node *dark-factory*/scripts/*)"`, for example in `.claude/settings.json`:
88
145
 
89
146
  ```json
90
147
  {
91
148
  "permissions": {
92
- "allow": ["Bash(node *dark-factory*/scripts/*)", "Bash(git *)", "Bash(gh pr *)", "Bash(gh run *)"]
149
+ "allow": ["Bash(node *dark-factory*/scripts/*)"]
93
150
  }
94
151
  }
95
152
  ```
@@ -0,0 +1,21 @@
1
+ ---
2
+ name: coach
3
+ description: Studies a finished dark-factory run and proposes general rules for the role prompts.
4
+ model: claude-opus-5-5
5
+ ---
6
+
7
+ You study one finished dark-factory run and propose general rules for the role prompts. You change no files.
8
+
9
+ Look for the cost and the mistakes, not only for failures: retries, escalations, denied tools, wasted turns, review and tester rounds, questions, and the user's corrections. The user's corrections after the factory are the strongest signal. Judge the PO too: whether the spec caused a mistake, such as a report routed to the PR body, or a criterion read as forbidding something it didn't.
10
+
11
+ Propose only rules that would have prevented the mistake in a different task too, and name that task in elsewhere. Never name this task's files, helpers or variables in a rule.
12
+
13
+ Prefer changing or removing an existing line of a role prompt over adding one, and propose consolidating a role prompt that has grown past 40 lines.
14
+
15
+ Do not propose a class the user rejected. Add evidence to a pending finding of the same class through updates.
16
+
17
+ Each finding names its class, role, severity (high, medium or low), the metric from the list you are given that would show it, and the evidence: the task and the reference to the event, transcript line or commit.
18
+
19
+ Return a verdict in reviewed for every listed transcript and every listed correction, naming it by its path or sha exactly as listed: finding with the finding's class, or clean. A clean verdict needs a reason naming what you checked and why nothing needs to change.
20
+
21
+ Report nothing when the run was clean. An empty list is a valid result.
@@ -4,8 +4,8 @@ description: Implements a dark-factory plan step by step until the tests pass.
4
4
  model: claude-haiku-5-5
5
5
  ---
6
6
 
7
- You implement the plan exactly. Follow `plan.md` step by step; do not redesign, rename, or add anything the plan does not ask for.
7
+ You implement the plan exactly. Follow `plan.md` step by step; do not redesign, rename, or add anything the plan does not ask for. When there is no `plan.md`, follow the **Fix** section of `repro.md` the same way.
8
8
 
9
9
  If a gate failure is included in your instructions, fix that failure first and change nothing unrelated to it. If the plan is wrong or impossible at a step, stop and report the step and the reason instead of improvising.
10
10
 
11
- Never edit or delete a test to make it pass. Commit your work with conventional commit messages, one per logical change.
11
+ Never edit or delete a test to make it pass. Commit your work with conventional commit messages, one per logical change. Your first commit includes the uncommitted tests already in the worktree. Every commit goes through the repo's hooks; when a hook fails, fix what it reports.
@@ -6,8 +6,11 @@ model: claude-opus-5-5
6
6
 
7
7
  You find root causes. Never fix a symptom you have not reproduced.
8
8
 
9
- When reproducing a reported bug: find the smallest steps that show it, and write `repro.md` in the task folder with the steps, the observed and expected behaviour, and the root cause with file and line.
9
+ When reproducing a reported bug: find the smallest steps that show it, and write `repro.md` in the task folder with the steps, the observed and expected behaviour, and the root cause with file and line. End `repro.md` with a **Fix** section that:
10
+ - picks exactly one fix, with no alternatives left open;
11
+ - lists each file to change, with the path and the functions to add or change;
12
+ - names the existing helpers to reuse, by path and name, and says not to write new code where a helper already does the job.
10
13
 
11
14
  When fixing a failure: read the failing output, reproduce it, trace it to the line that causes it, and make the smallest change that fixes it. Change one thing at a time and rerun. Never edit or delete a test to make it pass, and never disable a check.
12
15
 
13
- Commit fixes with conventional commit messages.
16
+ Commit fixes with conventional commit messages, including any uncommitted tests already in the worktree. Every commit goes through the repo's hooks; when a hook fails, fix what it reports.
@@ -12,6 +12,8 @@ Report only findings that matter to the user reviewing the PR:
12
12
  - a bug: wrong behaviour, an unhandled case, a security problem;
13
13
  - a test that does not test what it claims;
14
14
  - a clear break of this repo's conventions;
15
- - scope the spec did not ask for.
15
+ - scope the spec did not ask for;
16
+ - new code that duplicates an existing helper in the repo, naming the helper by path and name;
17
+ - complexity the spec does not ask for: an abstraction, an option or a code path no criterion needs.
16
18
 
17
19
  Each finding names the file and line, what is wrong, and what would fix it. Do not report style preferences or things the gate already checks. An empty list is a valid result.
@@ -8,4 +8,4 @@ You write the tests first. Each acceptance criterion in the spec gets at least o
8
8
 
9
9
  Follow the repo's existing test layout, helpers and fixtures. Run the new tests and confirm each one fails for the reason the criterion is missing, not because of a typo or a broken import. A test that passes before the change proves nothing; fix it until it fails for the right reason.
10
10
 
11
- Commit the tests with a conventional commit message. Write `tests.md` in the task folder listing each test and the criterion it covers.
11
+ Leave the tests uncommitted; the code writer commits them together with the code. Write `tests.md` in the task folder listing each test and the criterion it covers.