@gavin-hu/my-pi-agent 0.17.0 → 0.19.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 (274) hide show
  1. package/README.md +61 -45
  2. package/README.zh-CN.md +54 -42
  3. package/docs/extensions/README.md +34 -0
  4. package/docs/extensions/board.md +344 -0
  5. package/{extensions/bytefly/README.md → docs/extensions/bytefly.md} +465 -416
  6. package/{extensions/check/README.md → docs/extensions/check.md} +83 -68
  7. package/{extensions/context/README.md → docs/extensions/context.md} +40 -23
  8. package/docs/extensions/file-browse.md +554 -0
  9. package/{extensions/file-open/README.md → docs/extensions/file-open.md} +31 -23
  10. package/{extensions/file-read/README.md → docs/extensions/file-read.md} +47 -55
  11. package/{extensions/goal/README.md → docs/extensions/goal.md} +115 -131
  12. package/{extensions/job/README.md → docs/extensions/job.md} +66 -53
  13. package/{extensions/memory/README.md → docs/extensions/memory.md} +74 -63
  14. package/docs/extensions/plan.md +976 -0
  15. package/{extensions/question/README.md → docs/extensions/question.md} +54 -28
  16. package/{extensions/rewind/README.md → docs/extensions/rewind.md} +115 -122
  17. package/docs/extensions/session-bus.md +285 -0
  18. package/{extensions/subagent/README.md → docs/extensions/subagent.md} +166 -119
  19. package/docs/extensions/team.md +226 -0
  20. package/{extensions/todo/README.md → docs/extensions/todo.md} +85 -88
  21. package/{extensions/watch/README.md → docs/extensions/watch.md} +60 -38
  22. package/{extensions/web-access/README.md → docs/extensions/web-access.md} +93 -50
  23. package/{extensions/wechat/README.md → docs/extensions/wechat.md} +275 -192
  24. package/{extensions/worktree/README.md → docs/extensions/worktree.md} +115 -72
  25. package/extensions/board/commands.ts +87 -0
  26. package/extensions/board/config.ts +36 -0
  27. package/extensions/board/format.ts +72 -0
  28. package/extensions/board/index.ts +40 -0
  29. package/extensions/board/input.ts +54 -0
  30. package/extensions/board/join.ts +42 -0
  31. package/extensions/board/page.ts +312 -0
  32. package/extensions/board/result.ts +99 -0
  33. package/extensions/board/rows.ts +48 -0
  34. package/extensions/board/schema.ts +75 -0
  35. package/extensions/board/seat.ts +29 -0
  36. package/extensions/board/snapshot.ts +41 -0
  37. package/extensions/board/tools.ts +279 -0
  38. package/extensions/board/transport/router.ts +172 -0
  39. package/extensions/board/transport/server.ts +149 -0
  40. package/extensions/board/types.ts +54 -0
  41. package/extensions/board/view/actions.ts +306 -0
  42. package/extensions/board/view/client.ts +41 -0
  43. package/extensions/board/view/keys.ts +121 -0
  44. package/extensions/board/view/live.ts +397 -0
  45. package/extensions/board/view/page.ts +158 -0
  46. package/extensions/board/view/render.ts +496 -0
  47. package/extensions/board/view/styles.ts +211 -0
  48. package/extensions/board/view/team.ts +305 -0
  49. package/extensions/board/writes.ts +99 -0
  50. package/extensions/bytefly/notify/types.ts +1 -1
  51. package/extensions/bytefly/panel/commands.ts +40 -7
  52. package/extensions/bytefly/panel/settings-runtime.ts +0 -6
  53. package/extensions/bytefly/panel/settings.ts +11 -21
  54. package/extensions/bytefly/panel/tui/settings-view.ts +1 -1
  55. package/extensions/bytefly/picker/discovery.ts +0 -2
  56. package/extensions/bytefly/picker/types.ts +0 -2
  57. package/extensions/bytefly/update/check.ts +39 -0
  58. package/extensions/bytefly/update/format.ts +15 -0
  59. package/extensions/bytefly/update/register.ts +73 -34
  60. package/extensions/bytefly/update/state.ts +6 -3
  61. package/extensions/context/tui.ts +1 -1
  62. package/extensions/file-browse/{config.ts → config/config.ts} +13 -4
  63. package/extensions/file-browse/{files.ts → files/files.ts} +1 -14
  64. package/extensions/file-browse/{paths.ts → files/paths.ts} +1 -1
  65. package/extensions/file-browse/{git.ts → git/git.ts} +10 -3
  66. package/extensions/file-browse/index.ts +4 -4
  67. package/extensions/file-browse/{live.ts → live/live.ts} +54 -82
  68. package/extensions/file-browse/live/rev.ts +42 -0
  69. package/extensions/file-browse/{router.ts → transport/router.ts} +44 -17
  70. package/extensions/file-browse/transport/server.ts +110 -0
  71. package/extensions/file-browse/view/chrome.ts +83 -0
  72. package/extensions/file-browse/{client.ts → view/client.ts} +63 -1
  73. package/extensions/file-browse/view/diff-html.ts +94 -0
  74. package/extensions/file-browse/{html.ts → view/html.ts} +32 -158
  75. package/extensions/file-browse/{icons.ts → view/icons.ts} +1 -1
  76. package/extensions/file-browse/{live-client.ts → view/live-client.ts} +47 -1
  77. package/extensions/file-browse/{markdown.ts → view/markdown.ts} +7 -7
  78. package/extensions/file-browse/{raw-html.ts → view/raw-html.ts} +1 -1
  79. package/extensions/file-browse/{styles.ts → view/styles.ts} +31 -5
  80. package/extensions/file-browse/{tree.ts → view/tree.ts} +1 -1
  81. package/extensions/file-browse/{urls.ts → view/urls.ts} +1 -1
  82. package/extensions/file-read/schema.ts +2 -1
  83. package/extensions/goal/plan-route.ts +8 -2
  84. package/extensions/job/index.ts +15 -7
  85. package/extensions/memory/store.ts +12 -5
  86. package/extensions/plan/blocks.ts +23 -2
  87. package/extensions/plan/commands.ts +77 -21
  88. package/extensions/plan/feedback.ts +409 -63
  89. package/extensions/plan/index.ts +7 -5
  90. package/extensions/plan/plan-index.ts +44 -10
  91. package/extensions/plan/plan-text.ts +51 -24
  92. package/extensions/plan/plans.ts +162 -57
  93. package/extensions/plan/policy.ts +20 -12
  94. package/extensions/plan/review-prompt.ts +93 -0
  95. package/extensions/plan/review.ts +51 -95
  96. package/extensions/plan/runtime.ts +22 -10
  97. package/extensions/plan/sections.ts +112 -0
  98. package/extensions/plan/steps.ts +63 -95
  99. package/extensions/plan/tools/enter.ts +8 -3
  100. package/extensions/plan/tools/exit.ts +13 -19
  101. package/extensions/plan/tools/write.ts +8 -3
  102. package/extensions/plan/tools.ts +1 -1
  103. package/extensions/plan/tui.ts +29 -15
  104. package/extensions/plan/types.ts +29 -3
  105. package/extensions/plan/web-chrome.ts +2 -1
  106. package/extensions/plan/web-client.ts +122 -178
  107. package/extensions/plan/web-collab.ts +207 -0
  108. package/extensions/plan/web-comments.ts +269 -0
  109. package/extensions/plan/web-page.ts +96 -17
  110. package/extensions/plan/web-router.ts +109 -47
  111. package/extensions/plan/web-share-session.ts +191 -0
  112. package/extensions/plan/web-share.ts +169 -0
  113. package/extensions/plan/web-streams.ts +124 -0
  114. package/extensions/plan/web-tokens.ts +63 -0
  115. package/extensions/plan/web.ts +245 -151
  116. package/extensions/question/dialogs.ts +91 -1
  117. package/extensions/question/tools.ts +2 -1
  118. package/extensions/rewind/{commands.ts → commands/commands.ts} +5 -5
  119. package/extensions/rewind/{review.ts → commands/review.ts} +13 -13
  120. package/extensions/rewind/{rewind.ts → commands/rewind.ts} +6 -6
  121. package/extensions/rewind/{config.ts → config/config.ts} +1 -1
  122. package/extensions/rewind/index.ts +3 -3
  123. package/extensions/rewind/{policy.ts → state/policy.ts} +4 -4
  124. package/extensions/rewind/{runtime.ts → state/runtime.ts} +11 -11
  125. package/extensions/rewind/{snapshot-run.ts → state/snapshot-run.ts} +1 -1
  126. package/extensions/rewind/{timeline.ts → state/timeline.ts} +2 -2
  127. package/extensions/rewind/{format.ts → text/format.ts} +3 -3
  128. package/extensions/rewind/{git.ts → transport/git.ts} +2 -2
  129. package/extensions/rewind/{restore.ts → transport/restore.ts} +2 -2
  130. package/extensions/rewind/{snapshot.ts → transport/snapshot.ts} +1 -1
  131. package/extensions/rewind/{store.ts → transport/store.ts} +1 -1
  132. package/extensions/rewind/{checklist.ts → view/checklist.ts} +6 -6
  133. package/extensions/rewind/{hunk-picker.ts → view/hunk-picker.ts} +8 -8
  134. package/extensions/rewind/{path-picker.ts → view/path-picker.ts} +7 -7
  135. package/extensions/rewind/{review-tui.ts → view/review-tui.ts} +11 -11
  136. package/extensions/rewind/{rewind-tui.ts → view/rewind-tui.ts} +17 -11
  137. package/extensions/rewind/{status.ts → view/status.ts} +4 -4
  138. package/extensions/session-bus/commands.ts +113 -0
  139. package/extensions/session-bus/format.ts +101 -0
  140. package/extensions/session-bus/index.ts +75 -0
  141. package/extensions/session-bus/join-request.ts +40 -0
  142. package/extensions/session-bus/mail-watch.ts +134 -0
  143. package/extensions/session-bus/notice.ts +86 -0
  144. package/extensions/session-bus/overlap.ts +36 -0
  145. package/extensions/session-bus/protocol.ts +104 -0
  146. package/extensions/session-bus/resolve.ts +67 -0
  147. package/extensions/session-bus/result.ts +208 -0
  148. package/extensions/session-bus/rows.ts +171 -0
  149. package/extensions/session-bus/runtime.ts +466 -0
  150. package/extensions/session-bus/store.ts +365 -0
  151. package/extensions/session-bus/tools.ts +192 -0
  152. package/extensions/session-bus/tui.ts +394 -0
  153. package/extensions/session-bus/types.ts +98 -0
  154. package/extensions/subagent/agents.ts +9 -8
  155. package/extensions/subagent/invocation.ts +4 -2
  156. package/extensions/team/commands.ts +112 -0
  157. package/extensions/team/dispatch.ts +133 -0
  158. package/extensions/team/format.ts +105 -0
  159. package/extensions/team/index.ts +33 -0
  160. package/extensions/team/schema.ts +29 -0
  161. package/extensions/team/tools.ts +246 -0
  162. package/extensions/team/types.ts +48 -0
  163. package/extensions/watch/index.ts +15 -9
  164. package/extensions/web-access/fetch/page.ts +4 -1
  165. package/extensions/web-access/fetch/structured.ts +447 -0
  166. package/extensions/web-access/fetch/tool.ts +2 -1
  167. package/extensions/web-access/search/tool.ts +2 -1
  168. package/extensions/wechat/bridge.ts +76 -92
  169. package/extensions/wechat/{commands.ts → commands/commands.ts} +26 -18
  170. package/extensions/wechat/{doctor.ts → commands/doctor.ts} +5 -5
  171. package/extensions/wechat/{history.ts → commands/history.ts} +1 -1
  172. package/extensions/wechat/{login.ts → commands/login.ts} +3 -3
  173. package/extensions/wechat/{slash.ts → commands/slash.ts} +38 -2
  174. package/extensions/wechat/dialog/channels.ts +136 -0
  175. package/extensions/wechat/{interaction.ts → dialog/interaction.ts} +66 -51
  176. package/extensions/wechat/{prompt.ts → dialog/prompt.ts} +40 -25
  177. package/extensions/wechat/{remote-ui.ts → dialog/remote-ui.ts} +1 -1
  178. package/extensions/wechat/index.ts +10 -10
  179. package/extensions/wechat/{admission.ts → peer/admission.ts} +2 -2
  180. package/extensions/wechat/{peer-session.ts → peer/peer-session.ts} +2 -2
  181. package/extensions/wechat/{peer-worker.ts → peer/peer-worker.ts} +119 -56
  182. package/extensions/wechat/{presence.ts → peer/presence.ts} +11 -11
  183. package/extensions/wechat/{reply-pipeline.ts → peer/reply-pipeline.ts} +13 -5
  184. package/extensions/wechat/{credentials.ts → state/credentials.ts} +2 -2
  185. package/extensions/wechat/{state.ts → state/state.ts} +14 -2
  186. package/extensions/wechat/{format.ts → text/format.ts} +3 -3
  187. package/extensions/wechat/{notices.ts → text/notices.ts} +15 -7
  188. package/extensions/wechat/tools.ts +29 -12
  189. package/extensions/wechat/{client.ts → transport/client.ts} +26 -2
  190. package/extensions/wechat/{deliver.ts → transport/deliver.ts} +104 -40
  191. package/extensions/wechat/{inbound.ts → transport/inbound.ts} +5 -5
  192. package/extensions/wechat/{media.ts → transport/media.ts} +11 -5
  193. package/extensions/wechat/transport/outbound.ts +142 -0
  194. package/extensions/wechat/{poll.ts → transport/poll.ts} +3 -3
  195. package/extensions/wechat/types.ts +10 -1
  196. package/extensions/wechat/{login-screen.ts → view/login-screen.ts} +4 -4
  197. package/extensions/wechat/{status-screen.ts → view/status-screen.ts} +31 -26
  198. package/extensions/worktree/git.ts +5 -0
  199. package/extensions/worktree/guard.ts +3 -5
  200. package/extensions/worktree/registry.ts +11 -5
  201. package/extensions/worktree/status.ts +1 -3
  202. package/lib/README.md +12 -6
  203. package/lib/board/card.ts +290 -0
  204. package/lib/board/links.ts +117 -0
  205. package/lib/board/page-pointer.ts +256 -0
  206. package/lib/board/round-text.ts +72 -0
  207. package/lib/board/round.ts +89 -0
  208. package/lib/board/rules.ts +304 -0
  209. package/lib/board/session.ts +105 -0
  210. package/lib/board/store.ts +310 -0
  211. package/lib/board/view.ts +150 -0
  212. package/lib/errors.ts +12 -4
  213. package/lib/format.ts +13 -0
  214. package/lib/http/guard.ts +112 -0
  215. package/lib/http/index.ts +16 -5
  216. package/lib/http/router.ts +40 -13
  217. package/lib/http/serve.ts +234 -0
  218. package/lib/http/server.ts +29 -13
  219. package/lib/http/sink.ts +110 -0
  220. package/lib/http/token.ts +38 -0
  221. package/lib/interaction.ts +10 -0
  222. package/lib/notice.ts +29 -2
  223. package/lib/plan-entry.ts +7 -2
  224. package/lib/policy.ts +12 -2
  225. package/lib/qr.ts +64 -0
  226. package/lib/repo-key.ts +74 -0
  227. package/lib/report.ts +52 -33
  228. package/lib/requirements.ts +7 -9
  229. package/lib/session-label.ts +64 -0
  230. package/lib/session-roster.ts +130 -0
  231. package/lib/session-tool.ts +184 -0
  232. package/lib/tool-names.ts +25 -2
  233. package/lib/tui/README.md +16 -2
  234. package/lib/tui/dock-screen.ts +85 -17
  235. package/lib/tui/glyphs.ts +2 -0
  236. package/lib/tui/line-pane.ts +15 -4
  237. package/lib/tui/tool.ts +23 -4
  238. package/lib/web/README.md +5 -2
  239. package/lib/web/components.ts +6 -1
  240. package/lib/web/runtime.ts +7 -1
  241. package/lib/web/tokens.ts +25 -2
  242. package/package.json +27 -14
  243. package/skills/init/SKILL.md +80 -45
  244. package/skills/init/references/agents-md-quality.md +26 -2
  245. package/skills/init/references/interview-questions.md +36 -14
  246. package/skills/next/SKILL.md +77 -51
  247. package/skills/project-docs/SKILL.md +133 -0
  248. package/skills/project-docs/references/audit.md +131 -0
  249. package/skills/project-docs/references/changelog.md +105 -0
  250. package/skills/project-docs/references/discovery.md +127 -0
  251. package/skills/project-docs/references/readme.md +80 -0
  252. package/skills/project-docs/references/release.md +84 -0
  253. package/skills/project-docs/references/roadmap.md +93 -0
  254. package/skills/project-docs/scripts/state.ts +316 -0
  255. package/skills/refactor/SKILL.md +100 -125
  256. package/skills/refactor/references/handoff.md +35 -0
  257. package/skills/refactor/references/signals.md +54 -0
  258. package/skills/refactor/scripts/inventory.ts +587 -0
  259. package/extensions/file-browse/README.md +0 -467
  260. package/extensions/file-browse/server.ts +0 -134
  261. package/extensions/plan/README.md +0 -709
  262. package/extensions/plan/config.ts +0 -27
  263. package/extensions/wechat/outbound.ts +0 -100
  264. package/extensions/wechat/qrcode.ts +0 -46
  265. package/skills/changelog/SKILL.md +0 -148
  266. /package/extensions/file-browse/{diff.ts → text/diff.ts} +0 -0
  267. /package/extensions/file-browse/{fuzzy.ts → text/fuzzy.ts} +0 -0
  268. /package/extensions/file-browse/{palette.ts → view/palette.ts} +0 -0
  269. /package/extensions/rewind/{patch.ts → text/patch.ts} +0 -0
  270. /package/extensions/rewind/{paths.ts → text/paths.ts} +0 -0
  271. /package/extensions/rewind/{queue.ts → transport/queue.ts} +0 -0
  272. /package/extensions/rewind/{temp-index.ts → transport/temp-index.ts} +0 -0
  273. /package/extensions/wechat/{lock.ts → state/lock.ts} +0 -0
  274. /package/extensions/wechat/{channel.ts → text/channel.ts} +0 -0
@@ -1,18 +1,23 @@
1
1
  ---
2
2
  name: next
3
- description: "Decide what to do next from a project's real state, or from the current conversation: loose work in the tree, commits since the last tag, unreleased changelog entries, roadmap or plan items still open, and the project's check command. Returns a short ranked list with the evidence for each item and the command that starts it; read-only, it never edits, commits, or begins the work. Use when asked what to do next, where to pick up, what is left, or what to work on now."
3
+ description: "Decide what to do next from the current conversation when it has work in it, or from the project's real state when it is empty: loose work, commits since the last tag, unreleased changelog entries, roadmap or plan items still open, and the project's check command. Returns a short list of suggested next todos in priority order, with the evidence for each and the command that starts it; read-only, it never edits, commits, or begins the work. Use when asked what to do next, where to pick up, what is left, or what to work on now."
4
4
  ---
5
5
 
6
- # Decide what to do next
6
+ # Suggest the next todos, by priority
7
7
 
8
- This is a triage, not a work session. The deliverable is a short ranked list with
9
- evidence; do not edit, commit, tag, or start the top item. The skill is
10
- model-invoked when a request matches the description; `/skill:next` is the
11
- explicit fallback. Read the project's own instructions first; where they disagree
12
- with this skill, the project wins.
8
+ This is a triage, not a work session. The deliverable is a short list of
9
+ suggested next todos in priority order, each with the evidence for it; do not
10
+ edit, commit, tag, or start the first one. The skill is model-invoked when a
11
+ request matches the description; `/skill:next` is the explicit fallback. Read the
12
+ project's own instructions first; where they disagree with this skill, the
13
+ project wins.
13
14
 
14
- Two sibling skills own a narrower question: an audit of *where to refactor* is
15
- `refactor`, and *what the last tag owes the changelog* is `changelog`. When the
15
+ The conversation decides where the candidates come from (section 3); the request
16
+ decides only what to ask and where to look.
17
+
18
+ Two sibling skills, where they are installed, own a narrower question: an audit
19
+ of *where to refactor* is `refactor`, and *whether a document still tells the
20
+ truth* — the changelog, the roadmap, the front door — is `project-docs`. When the
16
21
  request is already scoped to one of those, name the skill that answers it and
17
22
  hand over, instead of returning a generic list.
18
23
 
@@ -24,15 +29,12 @@ its list survives the conversation that produced it.
24
29
 
25
30
  The host appends the text after the command to these instructions as the request.
26
31
  It is `<prompt>` in `/skill:next <prompt>`, it comes before any reading, and it
27
- carries up to three parts:
32
+ carries up to two parts:
28
33
 
29
34
  ```text
30
- /skill:next [session] [what you want] [@path ...]
35
+ /skill:next [what you want] [@path ...]
31
36
  ```
32
37
 
33
- - **`session`, first word** — session mode (section 3). The rest of the prompt
34
- keeps its own meaning: `/skill:next session what is left?` is session mode with
35
- a filter, not a filter of `session`.
36
38
  - **What you want** — a question, a goal, or a topic: "what is left before
37
39
  0.17?", "plan file outline". It chooses what the shortlist is about and keeps
38
40
  only the sources that can answer it; say which ones you kept. A named release,
@@ -48,7 +50,9 @@ carries up to three parts:
48
50
  - **An imperative** — "fix the failing test" names one piece of work, and the
49
51
  prompt is not approval for it. Answer with that item alone — evidence, starting
50
52
  command, effort — and ask before starting, instead of producing a list.
51
- - **No prompt** — triage of the current project.
53
+ - **No prompt** — the source rule in section 3 still decides: an empty
54
+ conversation is triaged from the project, and one that has done work is read
55
+ for what it left open.
52
56
  - **Anything unreadable** — triage anyway, and say in one clause how you read the
53
57
  prompt, so a misreading is visible in the report rather than silently narrowing
54
58
  the list.
@@ -66,40 +70,56 @@ With the request read, find:
66
70
  - the release path: what a tag, a version bump, or an unreleased entry owes;
67
71
  - the VCS, its branch model, and the last tag if there is one.
68
72
 
69
- State the profile in one or two lines. Do not invent a source the project does
70
- not have; a project with no roadmap is triaged from git and the check alone.
73
+ Do not invent a source the project does not have; a project with no roadmap is
74
+ triaged from version control and the check alone. These profile facts decide
75
+ which evidence rows apply, and section 7's report states them.
76
+
77
+ ## 3. Choose the source
78
+
79
+ There are two sources, and the conversation picks one:
80
+
81
+ - **This conversation** — the source once it has done work. Read its own record:
82
+ the todo list, the goal, the approved plan and its ticked steps, what subagents
83
+ and jobs returned, the paths it recorded, and the diff it produced. The
84
+ candidates are the loose ends it left: uncommitted files, an unapproved plan, a
85
+ check that was never run, a documented behavior that changed without a doc or
86
+ changelog edit.
87
+ - **The project's real state** — only when the conversation is empty. Read git,
88
+ the changelog, the roadmap or issues, and the plans directory; the candidates
89
+ are the project's loose work, broken promises, and unfinished ones.
71
90
 
72
- ## 3. Choose the mode
91
+ Empty means the conversation has done no work yet, not that it has no messages:
92
+ there is no todo list, no goal, no approved plan or ticked step, no subagent or
93
+ job result, no path it recorded, and no edit or commit from this session. The
94
+ request itself never counts, or `/skill:next` could never reach the tree.
73
95
 
74
- - **Triage** — what the tree says. Use git, the changelog, the roadmap or issues,
75
- and the plans directory. This is the default.
76
- - **Session** — what this conversation left open. Read the conversation's own
77
- record: the todo list, the goal, the approved plan and its ticked steps, what
78
- subagents and jobs returned, and the diff this session produced. Then list the
79
- loose ends it left: uncommitted files, an unapproved plan, a claim that was
80
- never run, a documented behavior that changed without a doc or changelog edit.
81
- - When both apply, run triage and read the session for context; the tree wins,
82
- because it is where the work actually is.
96
+ The tree is evidence in both sources. Verify every candidate against the code
97
+ before recommending it, and read the tree's status, the session's diff, the
98
+ changelog's unreleased section where the project has one, and the last check
99
+ result whichever source chose the candidates. A conversation that ended cleanly
100
+ has an empty list; do not fall back to the tree to fill it.
83
101
 
84
- Mode and scope are independent: session mode still honours a path, and triage
85
- with a path reads the whole tree's evidence before narrowing. State the mode, the
86
- scope, and the prompt as read, at the top of the report.
102
+ Scope is independent of the source: a path narrows either one, and a topic keeps
103
+ only the sources that can answer it. State the source, the scope, and the prompt
104
+ as read, at the top of the report.
87
105
 
88
106
  ## 4. Gather evidence
89
107
 
90
108
  Read only; nothing in this stage writes. Follow the project's own tool
91
- discipline, and say what you could not read.
109
+ discipline, and say what you could not read. The commands below are git's — use
110
+ the project's VCS for a project that is not on git — and read the rows its
111
+ profile says exist.
92
112
 
93
113
  | Source | What it proves |
94
114
  |---|---|
95
115
  | `git status --short`, `git diff --stat` | Work in flight, and whose it is |
96
- | `git log --oneline <last-tag>..HEAD` | What has landed unreleased |
116
+ | `git log --oneline <last-tag>..HEAD` | What has landed unreleased, if the project tags |
97
117
  | `git worktree list`, `git branch --no-merged` | An isolated tree left behind, a branch never merged |
98
- | The changelog's `[Unreleased]` | Whether a landed change is recorded, and whether the window is empty |
118
+ | The changelog's unreleased section (`[Unreleased]` under Keep a Changelog) | Whether a landed change is recorded, and whether the window is empty |
99
119
  | The roadmap, issue tracker, or `TODO` docs | The project's stated priorities, and which are already done |
100
- | The plans directory (`.pi/plans` or the project's equivalent) | An approved plan whose steps remain |
120
+ | The plan files the host's plan tool records (`~/.pi/agent/plans/<repo-key>` here) | An approved plan whose steps remain |
101
121
  | The todo list, the goal, job and subagent results | What the session promised and did not finish |
102
- | The check command | Whether the tree is green — cite the last known result, and make running it the item's starting command rather than running it here |
122
+ | The check command | Whether the tree is green — cite the session's last result, and make running it the item's starting command rather than running it here |
103
123
 
104
124
  A roadmap, a changelog, and a plan all lag the tree. Verify a candidate against
105
125
  the code before recommending it, and drop one that is already done.
@@ -116,12 +136,14 @@ cannot point at it, drop it.
116
136
  - Prefer the candidate with a fast verification command.
117
137
  - Never invent work to fill the list. An empty list is a valid answer.
118
138
 
119
- ## 6. Rank by cost of loss
139
+ ## 6. Rank by priority
120
140
 
121
- Order by what it would cost to lose, cheapest loss first:
141
+ Priority is what it would cost to lose the work, cheapest loss first, so the
142
+ order is the suggestion: the first item is the one to start, and a later item is
143
+ not an alternative to an earlier one. Order by that cost:
122
144
 
123
145
  - **Loose work** — a dirty tree, an unapproved plan, a check that has not been
124
- run, an unmerged branch, a worktree left behind, a stopped job.
146
+ run, an unmerged branch, a scratch tree or branch left behind, a stopped job.
125
147
  - **A broken promise** — a README, roadmap, or doc claim the code no longer
126
148
  meets, a released behavior with no test.
127
149
  - **An unfinished promise** — a stated roadmap item, the remaining steps of an
@@ -130,8 +152,8 @@ Order by what it would cost to lose, cheapest loss first:
130
152
  - **New reach** — a capability nobody has asked for comes last, and only when the
131
153
  three above are empty.
132
154
 
133
- Label each item with the ceremony it needs. The label is not a second ordering:
134
- cost of loss decides the order, and the label says how much work the item takes.
155
+ Label each item with the ceremony it needs. The label says how much work the item
156
+ takes, not where it ranks: the priority ladder decides the order.
135
157
 
136
158
  - **Do next** — cheap, safe, and unblocks the rest.
137
159
  - **Worth planning** — high value, but it spans files, changes a public surface,
@@ -139,17 +161,20 @@ cost of loss decides the order, and the label says how much work the item takes.
139
161
  - **Later** — real, but not now.
140
162
 
141
163
  Cap the list at three to five items, and let a tier be empty. A roadmap restated
142
- as ten suggestions is not a triage. Do not invent a numeric score; the reason
143
- must be readable.
164
+ as ten suggestions is not a triage. Number the items: the number is the priority.
165
+ Do not invent a score beyond that; the reason must be readable.
144
166
 
145
167
  ## 7. Report
146
168
 
147
- - **State** — one paragraph: the mode, the scope and how the prompt was read,
148
- the branch or worktree, what is dirty, what is unreleased, and whether the
149
- check passes. Name anything you could not read.
150
- - **The shortlist** — each item with its label, the action, the evidence at
151
- `path:line` or the command output that proves it, the command that starts it,
152
- and effort (S/M/L). Link the file the item lives in.
169
+ - **State** — one paragraph: the source and why it was chosen (a conversation
170
+ with work in it, or an empty one), the scope and how the prompt was read, the
171
+ branch or tree, what is dirty, what is unreleased, whether the check passes,
172
+ and the profile facts the list rests on — VCS, check command, and where work
173
+ is tracked. Name anything you could not read.
174
+ - **The list** — the suggested next todos, numbered in priority order, each with
175
+ its label, the action, the evidence at `path:line` or the command output that
176
+ proves it, the command that starts it, and effort (S/M/L). Link the file the
177
+ item lives in.
153
178
  - **Rejected or stale** — one line each, with the reason the roadmap, changelog,
154
179
  or plan entry no longer applies.
155
180
  - **Next step** — ask which item to start. Do not start it, and do not open with
@@ -174,11 +199,12 @@ When the user picks an item, the audit is over:
174
199
  - Nothing worth doing: say so, with what was checked, instead of inventing work.
175
200
  - The tree is mid-rebase, mid-merge, mid-bisect, or has a conflict: reconciling it
176
201
  is the only next item; nothing else is safe to suggest.
177
- - The project has no work tracking: say the list is derived from git and the check
178
- only, and suggest recording the plan or roadmap the project is missing.
202
+ - The project has no work tracking: say the list is derived from version control
203
+ and the check only, and suggest recording the plan or roadmap the project is
204
+ missing.
179
205
  - A candidate needs a destructive command (a branch delete, a worktree prune, a
180
206
  history rewrite) to start: name it as a decision for the user, not as a step.
181
207
 
182
- The triage is done when the mode is stated, every item has evidence and a
208
+ The triage is done when the source is stated, every item has evidence and a
183
209
  starting command, the list is capped, rejected candidates are explained, and no
184
210
  file was modified.
@@ -0,0 +1,133 @@
1
+ ---
2
+ name: project-docs
3
+ description: "Keep a project's documents true to its tree: a read-only audit of the front door, the roadmap, the contributor path, and the changelog against the code and against each other, then one mode per act that writes — record a changelog bullet in the same commit as the change, curate a release section from the project's own rules, delete a shipped roadmap item and renumber, and sync the README front door. Use when a doc claim looks stale, before a release, or when a change lands owing an entry; prioritisation stays with `next` and structure with `refactor`."
4
+ compatibility: "Bun for scripts/state.ts; git for the roadmap and the audit."
5
+ ---
6
+
7
+ # Keep the docs true to the tree
8
+
9
+ Goal: the documents a reader trusts — the front door, the plan of record, the record
10
+ of what shipped, and the contributor path — so a claim the tree no longer meets is
11
+ found, and each act that needs writing has one owner. This is a procedure, not a
12
+ second policy: the project's instructions and release document win, and where they
13
+ are silent this file says ask.
14
+
15
+ A bare `/skill:project-docs` reads and reports. Nothing is written until a mode is
16
+ named.
17
+
18
+ ## Pick the mode
19
+
20
+ | The words after `/skill:project-docs` | Mode | Owns | Writes | Follow |
21
+ |---|---|---|---|---|
22
+ | nothing | audit | every document, read-only | no | [`references/audit.md`](./references/audit.md) |
23
+ | `changelog` | changelog | the unreleased window of the changelog | yes | [`references/changelog.md`](./references/changelog.md) |
24
+ | `release <version>` | release | one version's section and link refs | yes | [`references/release.md`](./references/release.md) |
25
+ | `roadmap` | roadmap | items, ids, and buckets | yes | [`references/roadmap.md`](./references/roadmap.md) |
26
+ | `readme` | readme | the front door and its mirror | yes | [`references/readme.md`](./references/readme.md) |
27
+ | anything else | refuse, and name the five | — | no | — |
28
+
29
+ Audit is the default because the skill spans four documents: a bare invocation that
30
+ writes would edit a document nobody asked about.
31
+
32
+ ## Start here
33
+
34
+ Read [`references/discovery.md`](./references/discovery.md) first, in every mode. It
35
+ finds the project's documents, the version's single source, the changelog's local
36
+ conventions, the roadmap's rules, the check command, and the guards by name. State
37
+ that profile in one paragraph before writing anything; it is how a misread is caught
38
+ in a line instead of in a diff.
39
+
40
+ For the changelog's mechanical half, run the state script, resolved against this
41
+ skill's own directory:
42
+
43
+ ```bash
44
+ bun <skill>/scripts/state.ts <project-root>
45
+ ```
46
+
47
+ It prints the changelog file it found, the last tag and the commits since it, the
48
+ `[Unreleased]` categories with counts and line numbers, the empty and duplicate
49
+ headings, the scope prefixes in use, and the link refs. That is the state; read the
50
+ diffs for judgement, not for counting. When it finds no changelog, no repository, or no
51
+ Bun to run it with, say so and fall back to discovery by hand. The git commands these
52
+ references give are git's; use the project's VCS where it differs.
53
+
54
+ ## Non-negotiables
55
+
56
+ 1. **Discover, don't impose.** The project's document set, category spelling, scope
57
+ prefix, bullet shape, item ids, bucket caps, and release procedure are the rules.
58
+ State the profile in one paragraph, and ask when two sources disagree.
59
+ 2. **One bullet per user-visible outcome**, in the same commit as the change. A
60
+ feature and the bug it fixed before release are one bullet; two observable
61
+ changes are two.
62
+ 3. **A shipped item is deleted here, with its reason, never ticked.** A roadmap that
63
+ keeps what already landed describes a tree that no longer exists.
64
+ 4. **One id per thing, across every document.** A README row, a roadmap item, and a
65
+ changelog entry that name the same feature use the same name. A mismatch is
66
+ reported, never renamed.
67
+ 5. **A judgement is not a finding.** Positioning, priority, dates, non-goals, and
68
+ contribution policy are the maintainer's: list them and ask.
69
+ 6. **One owner per artefact.** The changelog belongs here; what to do next belongs to
70
+ the `next` skill; structure belongs to `refactor`.
71
+
72
+ ## Modes
73
+
74
+ - **Audit** — read-only, five faces: the tree against the docs, the docs against each
75
+ other, the changelog's commit window, the roadmap's own ids and caps, and the front
76
+ door's examples. Every finding names the mode that fixes it.
77
+ - **Changelog** — one bullet under the project's category for one user-visible
78
+ outcome, re-reading the file first. It never decides whether something has already
79
+ shipped.
80
+ - **Release** — only for a version the user named, and only after the project's
81
+ release document has been read; everything after moving the entries follows it.
82
+ - **Roadmap** — re-derived from the commits since the last tag rather than from the
83
+ last tag: shipped items deleted, ids renumbered, every citation and link fixed.
84
+ - **Readme** — the front door's catalog rows, counts, examples, and mirror, kept equal
85
+ to the tree; deep detail stays in the project's own guides.
86
+
87
+ ## Handover
88
+
89
+ - **A changelog entry, an audit, or a release** is this skill: do not look for
90
+ another one.
91
+ - **What to do next** is `next`, where it is installed: it triages loose work and
92
+ broken promises across the project, and its candidates are not a doc audit's findings.
93
+ - **A structural change to the docs or the code** is `refactor`, where it is installed.
94
+ - **Who may contribute, and how** is a decision for the maintainer: ask, and edit
95
+ nothing until it is answered.
96
+
97
+ ## Report
98
+
99
+ Open with the profile in one paragraph, then:
100
+
101
+ - **Stale** — the claim, `path:line`, the evidence in the tree, and the mode that
102
+ fixes it.
103
+ - **Missing** — a document, a row, an entry, or an item the project's own rules call
104
+ for and the tree does not have.
105
+ - **Suggested edit** — the diff or the exact replacement, for the mechanical items
106
+ only, and never applied until the user says so.
107
+ - **Needs a decision** — one line each: the question, and what it changes.
108
+
109
+ Nothing found is a valid result, and the whole report may be empty. Say what was
110
+ checked and stop; an audit that invents four entries to look thorough is worse than
111
+ one that finds nothing.
112
+
113
+ ## Quality gate
114
+
115
+ - The project's own check passes, including any guard on the release window, the
116
+ documentation's parity, or the roadmap's ids.
117
+ - Every edit names the document and the line, and every bullet names a scope in the
118
+ project's spelling and a user outcome.
119
+ - No judgement is smuggled into a diff, and the changelog entry is in the change's
120
+ own commit.
121
+
122
+ ## Stop conditions
123
+
124
+ - The project has only a README, no roadmap, and no changelog: say so. Whether to
125
+ adopt one is the maintainer's decision, not an edit.
126
+ - The changelog is generated — by `semantic-release`, `changesets`, `git-cliff`, or a
127
+ step in the release workflow: the entry lands upstream, in the commit message, a
128
+ changeset fragment, or the generator's config. Never hand-edit the file.
129
+ - Two sources disagree — two changelogs, a version in two places, a roadmap item the
130
+ changelog contradicts: ask instead of averaging them.
131
+ - The change would reverse a documented non-goal: it is a decision, and the item is
132
+ listed rather than written.
133
+ - The request is really triage or a refactor: name the sibling skill and stop.
@@ -0,0 +1,131 @@
1
+ # Audit
2
+
3
+ Read-only. The audit answers one question per claim: is this still true, and if not,
4
+ which mode fixes it? It never edits — not even a typo, not even "while we are here".
5
+ If the user asks for the fixes, finish the report first, then enter the mode it names.
6
+
7
+ Read [`discovery.md`](./discovery.md) first and open the report with the profile. The
8
+ five faces below are a reading order, not a checklist: a face with no evidence
9
+ produces no findings.
10
+
11
+ ## 1. The tree against the docs
12
+
13
+ The claims a reader acts on: a catalog row, a limit stated in a package README, a
14
+ default in a configuration table, a roadmap item, a non-goal, a "supported format"
15
+ list. For each, find the code that does it — the registration, the branch, the config
16
+ default — and name where it disagrees.
17
+
18
+ | Where the claim lives | What falsifies it |
19
+ |---|---|
20
+ | A catalog row or feature bullet | The tool, command, flag, or route no longer registers |
21
+ | A limitations section | The gap was closed, or widened, and the text did not move |
22
+ | A configuration default | The loader's default differs from the table |
23
+ | A roadmap item | The tree already does it (see face 4) |
24
+ | A non-goal | The changelog records the thing being shipped anyway |
25
+
26
+ ## 2. The docs against each other
27
+
28
+ - **Counts** — a number a doc states about the code (modules, tools, extensions,
29
+ screens) belongs to the tree. A project that derives it in a test has the count; one
30
+ that does not is a finding, and the fix is a guard, not a number.
31
+ - **Catalog rows** — every row names a thing that exists; every existing thing the
32
+ catalog claims to cover has a row. Both directions.
33
+ - **Cross-reference ids** — the same feature named in a front-door row, a roadmap item,
34
+ and a changelog entry. Report a mismatch; never rename one side to match.
35
+ - **The version** — the source of truth, the newest dated changelog heading, the tag,
36
+ and any badge, badge-adjacent prose, or install instruction that repeats it.
37
+ - **The mirror** — a translated README carries the original's sections, table rows, and
38
+ links. A row that exists in one and not the other is a finding even when the prose is
39
+ deliberately translated.
40
+ - **The contributor path** — the commands `CONTRIBUTING.md` tells a newcomer to run,
41
+ against the manifest's `scripts` and the CI workflow's steps. A command the docs promise
42
+ and the manifest does not define is the one stale claim a new contributor hits first,
43
+ and a step CI runs that the docs never mention is the one they skip.
44
+
45
+ ## 3. The changelog's commit window
46
+
47
+ Run `scripts/state.ts` (see the skill's *Start here*). It gives the file, the last tag,
48
+ the commits since it, the `[Unreleased]` categories, and the scopes in use.
49
+
50
+ When discovery says a tool generates the file, the window's entries live in that tool's
51
+ input — the changeset queue, the commit-message convention — so audit those, and report
52
+ a missing fragment rather than a missing bullet.
53
+
54
+ Read every commit it lists: `git show <sha>` for the diff, or the pull request when the
55
+ repository squashes. A subject line is not enough — `fix bug` and `wip` hide
56
+ user-visible changes, and `feat: rewrite the config loader` is often invisible to users.
57
+ For each commit, decide whether a user can observe it, which bullet covers it, whether
58
+ that bullet's scope is right, and whether a reader of the bullet alone would know what
59
+ changed for them.
60
+
61
+ | Commit | User-visible | Evidence | Existing entry | Action |
62
+ |---|---|---|---|---|
63
+ | `3f19a02` | yes | `src/load.ts:42` now rejects an unknown key | — | add |
64
+ | `b81c4de` | no | test-only | — | leave |
65
+ | `0ad9f12` | yes | retry limit 3 → 5 | `Changed`: "`api`: retries are now bounded" | update: the bullet never names the limit |
66
+ | `77e0a1e` | unclear | touches the public `--json` shape | — | ask |
67
+
68
+ `Action` is one of **add** (user-visible, no bullet), **update** (a bullet exists and is
69
+ wrong, unscopeable, or too vague to act on), **leave** (covered, internal, or recorded
70
+ under an older release), or **ask** (the outcome depends on intent the diff cannot show).
71
+
72
+ Report separately:
73
+
74
+ - Duplicate `##` or `###` headings — some tools render the second as its own section,
75
+ and a reader sees half the entries.
76
+ - An empty category heading, or a heading a release guard rejects.
77
+ - An `[Unreleased]` section that is missing or empty while the window contains
78
+ user-visible changes.
79
+ - An entry for something already shipped under a dated heading: the same outcome twice,
80
+ which reads as a second change.
81
+ - A stale link reference pointing at an older tag than the newest dated heading — where
82
+ the file uses link references at all. A generated or non-Keep-a-Changelog file may have
83
+ none, and the state script reports that absence as a missing reference without it being
84
+ a defect.
85
+
86
+ ## 4. The roadmap's own ids and caps
87
+
88
+ Re-derive the window before judging an item: `git log --oneline <last-tag>..HEAD` plus
89
+ the changelog's newest dated heading. A roadmap describes the tree, so work that landed
90
+ but has not shipped is already part of what it should describe.
91
+
92
+ - An item the tree already does is a deletion, with its reason recorded where the item
93
+ was.
94
+ - An id used twice, skipped in a sequence, or cited from nowhere the file defines.
95
+ - A bucket over the cap the file states; a bucket that keeps growing stops being a
96
+ priority.
97
+ - A ledger row whose items all closed, or an open item with no ledger row.
98
+ - A relative link or a `path:line` citation that no longer resolves.
99
+
100
+ ## 5. The front door's examples
101
+
102
+ - The quickstart command, run as written. A command that no longer exists is a stale
103
+ promise, and it is the most expensive one because it is the reader's first step.
104
+ - An example that imports, configures, or calls something the code no longer accepts.
105
+ - A screenshot or a recording that shows a surface that has since changed.
106
+ - A link to a guide that moved, a section anchor that was renamed, or a badge whose
107
+ target is gone.
108
+
109
+ ## Report
110
+
111
+ Open with the profile, then the four sections from the skill: **Stale**, **Missing**,
112
+ **Suggested edit**, **Needs a decision**. Every stale finding carries the document,
113
+ `path:line`, the evidence in the tree, and the mode that fixes it. Group by the mode
114
+ when there are more than a handful, so the user can act one mode at a time.
115
+
116
+ Nothing found is a valid result for the whole audit or for any face. Say what was
117
+ checked — the files read, the commands run, the commits examined — and stop. An audit
118
+ that invents findings to look thorough is worse than one that reports none.
119
+
120
+ ## What the audit cannot see
121
+
122
+ Name these in a closing line instead of guessing:
123
+
124
+ - Whether a change is user-visible to someone the diff does not show — a default that
125
+ only matters on one platform, a behavior the docs promised and the tests never
126
+ covered.
127
+ - Whether a commit message describes what the code does; only the diff does.
128
+ - Whether an item shipped: a merged change to a document is not a release, and only the
129
+ maintainer knows whether the front door's promise is meant to hold today or next
130
+ version.
131
+ - Whether a roadmap priority is still right, and whether a non-goal still stands.
@@ -0,0 +1,105 @@
1
+ # Record one bullet
2
+
3
+ This mode writes one thing: a bullet in the changelog for a change that just landed.
4
+ It does not decide whether something shipped, and it does not curate a release — that
5
+ is the `release` mode, and only for a version the user named.
6
+
7
+ Read [`discovery.md`](./discovery.md) first for the file, the categories, their order,
8
+ the scope spelling, and whether the entry ships with the change. Where a tool owns the
9
+ file — `semantic-release`, `changesets`, `git-cliff`, or a step in the release workflow —
10
+ this mode does not write it: the entry belongs upstream, in the commit message's
11
+ convention, a changeset fragment, or the generator's config.
12
+
13
+ ## Where the bullet goes
14
+
15
+ - Re-read the changelog before editing: another session, another contributor, or the
16
+ user may have written since the state script ran.
17
+ - Under `[Unreleased]`, in the category the project uses for this kind of change, in
18
+ the file's own order and spelling. Never create a second heading for a category that
19
+ already exists in the section.
20
+ - When the file keeps no `[Unreleased]` section, ask where the change is recorded — the
21
+ preamble decides, and a project that writes entries only at release has a different
22
+ procedure.
23
+ - Insert without disturbing any other bullet, keep the file's wrap column, and write it
24
+ in the same commit as the change it describes.
25
+
26
+ ## Does it qualify
27
+
28
+ It qualifies when a user can observe it: behavior, a CLI or tool or command surface, a
29
+ config default, packaging and dependencies a user installs, security, or a documented
30
+ promise that is now true or false.
31
+
32
+ It does not qualify when only the implementation moved: an internal refactor, a rename
33
+ with no behavior change, a test, formatting, a comment, a dependency bump with no
34
+ behavior change, or a typo fixed in the changelog itself.
35
+
36
+ When a change is both — a refactor that also fixes a rounding bug — the bullet is the
37
+ rounding bug, and the refactor is not mentioned.
38
+
39
+ ## One outcome, one bullet
40
+
41
+ - A feature and the bug it fixed before release are one bullet: users never saw the
42
+ broken version.
43
+ - Two observable changes are two bullets, even in one commit.
44
+ - Two commits that produce one outcome are one bullet, written where the outcome became
45
+ true.
46
+ - A breaking change is its own bullet with the required action; do not bury it in a
47
+ feature's sentence.
48
+
49
+ When the outcome is unclear, ask. Reading the diff tells you what changed; only the
50
+ author knows what a user will notice.
51
+
52
+ ## The shape
53
+
54
+ Follow the file's newest released section. Where the project states nothing, the shape
55
+ is one bullet that leads with the scope in backticks, a colon, then what the user can
56
+ now do:
57
+
58
+ ```text
59
+ - `billing`: invoices show tax as a separate line. Amounts that used to be bundled
60
+ into `total` are summed on the printed total, so an invoice stored by an older
61
+ release still reconciles.
62
+ - `cli`: `--legacy-auth` is no longer read; run `mytool migrate auth` first.
63
+ ```
64
+
65
+ - **Scope**: the area a user would name — an extension, package, module, or subsystem,
66
+ in the project's own spelling. Never a file path, a function, or a ticket number. A
67
+ bullet with no scope is a defect where the project uses scopes, and noise where it
68
+ does not.
69
+ - **Outcome first**: what is different for the user, then the mechanism if it matters,
70
+ then any action they must take.
71
+ - **Length**: a bullet may run to several sentences when the outcome needs them — what
72
+ the user sees, what it replaced, what to do about it. Brevity is not the goal;
73
+ vagueness is the defect.
74
+ - **Voice**: match the file. Most changelogs are present tense and third person; do not
75
+ switch to marketing, and do not add praise for the change.
76
+ - **Wrap**: match the file's column, usually near 80, and let one bullet be one
77
+ paragraph.
78
+
79
+ ## What does not belong
80
+
81
+ File names and paths, internal helper names, test counts and coverage, commit hashes
82
+ and pull-request numbers as the subject (a link at the end is fine where the file does
83
+ it), and empty words such as "various", "improvements", "cleanup", "refactor", "misc".
84
+ A reader who cannot tell from the bullet whether the change affects them has been told
85
+ nothing.
86
+
87
+ ## The two failure modes
88
+
89
+ ```text
90
+ - `billing`: refactored invoice rendering and added tests.
91
+ - `misc`: improvements.
92
+ ```
93
+
94
+ The first names no outcome and reports the implementation. The second names no scope,
95
+ no outcome, and would fit any release.
96
+
97
+ ```text
98
+ - `api`: `POST /v2/charge` now refuses an amount with more than two decimals
99
+ instead of truncating it, so a client that relied on the old rounding sees a
100
+ `422` with `code: "amount_precision"`. Truncation moved to `POST /v2/charge/draft`,
101
+ which is what the old behavior should have been.
102
+ ```
103
+
104
+ Three sentences, one outcome, one scope, and the migration named. Long is fine when
105
+ each sentence tells the reader something they must know.