dsh-pstack 0.2.0-beta.1 → 0.2.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 (275) hide show
  1. package/LICENSE +2 -3
  2. package/README.md +148 -84
  3. package/README.zh.md +198 -0
  4. package/assets/pstack-config-entry.png +0 -0
  5. package/cordis.patch.yml +105 -27
  6. package/dist/client.mjs +2341 -0
  7. package/dist/client.mjs.map +1 -0
  8. package/dist/host-contract-CUPSpeNk.d.mts +22 -0
  9. package/dist/index.d.mts +49 -238
  10. package/dist/index.mjs +250 -123
  11. package/dist/models.d.mts +44 -0
  12. package/dist/models.mjs +201 -0
  13. package/dist/paths-BT77khwm.mjs +48 -0
  14. package/dist/pstack/LICENSE +21 -0
  15. package/dist/pstack/README.md +291 -0
  16. package/dist/pstack/agents/poteto-agent.md +9 -0
  17. package/{assets → dist/pstack}/docs/guide/01-setup.md +13 -11
  18. package/{assets → dist/pstack}/docs/guide/02-poteto-mode.md +4 -4
  19. package/{assets → dist/pstack}/docs/guide/04-design.md +4 -4
  20. package/{assets → dist/pstack}/docs/guide/05-build-and-clean.md +2 -2
  21. package/{assets → dist/pstack}/docs/guide/06-verify-and-ship.md +13 -3
  22. package/{assets → dist/pstack}/docs/guide/07-overnight.md +15 -13
  23. package/{assets → dist/pstack}/docs/guide/09-make-it-yours.md +6 -2
  24. package/{assets → dist/pstack}/docs/guide/10-recipes-and-pitfalls.md +7 -5
  25. package/{assets → dist/pstack}/docs/guide/README.md +1 -1
  26. package/dist/pstack/docs/harness/dsh.md +98 -0
  27. package/{assets → dist/pstack}/skills/architect/SKILL.md +12 -12
  28. package/dist/pstack/skills/arena/SKILL.md +50 -0
  29. package/{assets → dist/pstack}/skills/automate-me/SKILL.md +14 -14
  30. package/{assets → dist/pstack}/skills/benchmark-checklist/SKILL.md +1 -1
  31. package/{assets → dist/pstack}/skills/blast-radius/SKILL.md +4 -6
  32. package/{assets → dist/pstack}/skills/correct/SKILL.md +1 -1
  33. package/{assets → dist/pstack}/skills/create-formal-verification-skill/SKILL.md +4 -2
  34. package/{assets → dist/pstack}/skills/create-verification-skill/SKILL.md +5 -5
  35. package/dist/pstack/skills/figure-it-out/SKILL.md +54 -0
  36. package/dist/pstack/skills/how/SKILL.md +38 -0
  37. package/{assets → dist/pstack}/skills/in-your-own-words/SKILL.md +1 -1
  38. package/dist/pstack/skills/interrogate/SKILL.md +33 -0
  39. package/{assets → dist/pstack}/skills/ketchup/SKILL.md +3 -5
  40. package/dist/pstack/skills/ketchup-video/SKILL.md +29 -0
  41. package/{assets → dist/pstack}/skills/maintain-formal-verification-skill/SKILL.md +1 -1
  42. package/{assets → dist/pstack}/skills/maintain-verification-skill/SKILL.md +3 -3
  43. package/dist/pstack/skills/make-bot-ui/SKILL.md +117 -0
  44. package/dist/pstack/skills/no-comments/SKILL.md +26 -0
  45. package/{assets → dist/pstack}/skills/poteto-help/SKILL.md +34 -31
  46. package/{assets → dist/pstack}/skills/poteto-help/references/prompting.md +1 -1
  47. package/{assets → dist/pstack}/skills/poteto-help/references/recipes.md +3 -3
  48. package/{assets → dist/pstack}/skills/poteto-mode/SKILL.md +20 -19
  49. package/dist/pstack/skills/poteto-mode/playbooks/authoring-a-skill.md +12 -0
  50. package/dist/pstack/skills/poteto-mode/playbooks/autonomous-run.md +13 -0
  51. package/dist/pstack/skills/poteto-mode/playbooks/autopilot-full.md +25 -0
  52. package/dist/pstack/skills/poteto-mode/playbooks/autopilot-stack.md +8 -0
  53. package/{assets → dist/pstack}/skills/poteto-mode/playbooks/babysit.md +4 -4
  54. package/dist/pstack/skills/poteto-mode/playbooks/bug-fix.md +15 -0
  55. package/{assets → dist/pstack}/skills/poteto-mode/playbooks/eval.md +3 -3
  56. package/dist/pstack/skills/poteto-mode/playbooks/feature.md +21 -0
  57. package/{assets → dist/pstack}/skills/poteto-mode/playbooks/hillclimb.md +3 -3
  58. package/{assets → dist/pstack}/skills/poteto-mode/playbooks/investigation.md +2 -2
  59. package/{assets → dist/pstack}/skills/poteto-mode/playbooks/multi-phase-plan.md +23 -23
  60. package/{assets → dist/pstack}/skills/poteto-mode/playbooks/opening-a-pr.md +6 -6
  61. package/dist/pstack/skills/poteto-mode/playbooks/orchestrate.md +25 -0
  62. package/{assets → dist/pstack}/skills/poteto-mode/playbooks/pause-safely.md +2 -2
  63. package/dist/pstack/skills/poteto-mode/playbooks/perf-issue.md +25 -0
  64. package/{assets → dist/pstack}/skills/poteto-mode/playbooks/prototype.md +4 -4
  65. package/dist/pstack/skills/poteto-mode/playbooks/refactoring.md +16 -0
  66. package/dist/pstack/skills/poteto-mode/playbooks/runtime-forensics.md +11 -0
  67. package/dist/pstack/skills/poteto-mode/playbooks/session-pickup.md +11 -0
  68. package/{assets → dist/pstack}/skills/poteto-mode/playbooks/shipping.md +2 -2
  69. package/{assets → dist/pstack}/skills/poteto-mode/playbooks/trace-forensics.md +2 -2
  70. package/dist/pstack/skills/poteto-mode/playbooks/visual-parity.md +11 -0
  71. package/dist/pstack/skills/poteto-mode/playbooks/worktree-cleanup.md +12 -0
  72. package/{assets → dist/pstack}/skills/poteto-mode/scripts/check-plan.mjs +6 -8
  73. package/dist/pstack/skills/poteto-mode/scripts/check-plan.test.mjs +128 -0
  74. package/{assets/skills/poteto-mode/scripts/check-plan.test.mjs → dist/pstack/skills/poteto-mode/scripts/expect.mjs} +12 -101
  75. package/dist/pstack/skills/poteto-mode/scripts/support.mjs +93 -0
  76. package/dist/pstack/skills/poteto-mode/scripts/watch-pr/cli.mjs +123 -0
  77. package/dist/pstack/skills/poteto-mode/scripts/watch-pr/cli.test.mjs +217 -0
  78. package/dist/pstack/skills/poteto-mode/scripts/watch-pr/fakes.test-helper.mjs +119 -0
  79. package/dist/pstack/skills/poteto-mode/scripts/watch-pr/github.mjs +626 -0
  80. package/dist/pstack/skills/poteto-mode/scripts/watch-pr/github.test.mjs +521 -0
  81. package/dist/pstack/skills/poteto-mode/scripts/watch-pr/policy.mjs +657 -0
  82. package/dist/pstack/skills/poteto-mode/scripts/watch-pr/policy.test.mjs +523 -0
  83. package/dist/pstack/skills/poteto-mode/scripts/watch-pr/render.mjs +106 -0
  84. package/dist/pstack/skills/poteto-mode/scripts/watch-pr/types.mjs +9 -0
  85. package/dist/pstack/skills/poteto-mode/scripts/watch-pr/watch-pr.mjs +5 -0
  86. package/{assets → dist/pstack}/skills/poteto-mode/scripts/worktree-audit.mjs +15 -22
  87. package/dist/pstack/skills/poteto-mode/scripts/worktree-audit.test.mjs +134 -0
  88. package/{assets → dist/pstack}/skills/principle-attack-the-premise/SKILL.md +1 -1
  89. package/{assets → dist/pstack}/skills/principle-boundary-discipline/SKILL.md +1 -1
  90. package/{assets → dist/pstack}/skills/principle-encode-lessons-in-structure/SKILL.md +1 -1
  91. package/{assets → dist/pstack}/skills/principle-exhaust-the-design-space/SKILL.md +1 -1
  92. package/{assets → dist/pstack}/skills/principle-experience-first/SKILL.md +1 -1
  93. package/{assets → dist/pstack}/skills/principle-explain-the-number/SKILL.md +3 -2
  94. package/{assets → dist/pstack}/skills/principle-fix-root-causes/SKILL.md +1 -1
  95. package/{assets → dist/pstack}/skills/principle-laziness-protocol/SKILL.md +1 -1
  96. package/{assets → dist/pstack}/skills/principle-make-operations-idempotent/SKILL.md +1 -1
  97. package/{assets → dist/pstack}/skills/principle-migrate-callers-then-delete-legacy-apis/SKILL.md +1 -1
  98. package/{assets → dist/pstack}/skills/principle-minimize-reader-load/SKILL.md +1 -1
  99. package/{assets → dist/pstack}/skills/principle-model-the-domain/SKILL.md +1 -1
  100. package/{assets → dist/pstack}/skills/principle-never-block-on-the-human/SKILL.md +1 -1
  101. package/{assets → dist/pstack}/skills/principle-outcome-oriented-execution/SKILL.md +1 -1
  102. package/{assets → dist/pstack}/skills/principle-prove-it-works/SKILL.md +2 -2
  103. package/{assets → dist/pstack}/skills/principle-redesign-from-first-principles/SKILL.md +1 -1
  104. package/{assets → dist/pstack}/skills/principle-separate-before-serializing-shared-state/SKILL.md +1 -1
  105. package/{assets → dist/pstack}/skills/principle-sequence-verifiable-units/SKILL.md +1 -1
  106. package/{assets → dist/pstack}/skills/principle-subtract-before-you-add/SKILL.md +1 -1
  107. package/{assets → dist/pstack}/skills/principle-test-behavior-not-implementation/SKILL.md +1 -1
  108. package/{assets → dist/pstack}/skills/principle-type-system-discipline/SKILL.md +1 -1
  109. package/dist/pstack/skills/recall/SKILL.md +37 -0
  110. package/dist/pstack/skills/reflect/SKILL.md +71 -0
  111. package/{assets → dist/pstack}/skills/reflect/references/divergent-reviewer.md +4 -4
  112. package/{assets → dist/pstack}/skills/reflect/references/judgment-reviewer.md +2 -2
  113. package/{assets → dist/pstack}/skills/reflect/references/synthesizer.md +5 -5
  114. package/{assets → dist/pstack}/skills/reflect/references/tooling-reviewer.md +2 -2
  115. package/dist/pstack/skills/setup-pstack/SKILL.md +80 -0
  116. package/{assets → dist/pstack}/skills/sharpen/SKILL.md +1 -1
  117. package/{assets → dist/pstack}/skills/show-me-your-work/SKILL.md +8 -8
  118. package/{assets → dist/pstack}/skills/show-me-your-work/scripts/log.mjs +1 -3
  119. package/dist/pstack/skills/show-me-your-work/scripts/log.test.mjs +56 -0
  120. package/dist/pstack/skills/statechart/SKILL.md +82 -0
  121. package/dist/pstack/skills/statechart/references/render.md +93 -0
  122. package/dist/pstack/skills/statechart/scripts/backends/cfg.mjs +31 -0
  123. package/dist/pstack/skills/statechart/scripts/backends/mermaid.mjs +186 -0
  124. package/dist/pstack/skills/statechart/scripts/backends/plain-text.mjs +62 -0
  125. package/dist/pstack/skills/statechart/scripts/backends/report.mjs +84 -0
  126. package/dist/pstack/skills/statechart/scripts/frontends/config.mjs +268 -0
  127. package/dist/pstack/skills/statechart/scripts/frontends/dot.mjs +67 -0
  128. package/dist/pstack/skills/statechart/scripts/frontends/marks.mjs +94 -0
  129. package/dist/pstack/skills/statechart/scripts/frontends/messages.mjs +48 -0
  130. package/dist/pstack/skills/statechart/scripts/frontends/spec.mjs +101 -0
  131. package/dist/pstack/skills/statechart/scripts/frontends/trace.mjs +39 -0
  132. package/dist/pstack/skills/statechart/scripts/frontends/value.mjs +180 -0
  133. package/dist/pstack/skills/statechart/scripts/frontends/verdict.mjs +40 -0
  134. package/dist/pstack/skills/statechart/scripts/frontends/view.mjs +99 -0
  135. package/dist/pstack/skills/statechart/scripts/ir.mjs +277 -0
  136. package/dist/pstack/skills/statechart/scripts/passes/annotate.mjs +92 -0
  137. package/dist/pstack/skills/statechart/scripts/passes/label.mjs +210 -0
  138. package/dist/pstack/skills/statechart/scripts/passes/lift.mjs +84 -0
  139. package/dist/pstack/skills/statechart/scripts/passes/loop-check.mjs +47 -0
  140. package/dist/pstack/skills/statechart/scripts/passes/paths.mjs +72 -0
  141. package/dist/pstack/skills/statechart/scripts/passes/reach.mjs +135 -0
  142. package/dist/pstack/skills/statechart/scripts/passes/region-check.mjs +82 -0
  143. package/dist/pstack/skills/statechart/scripts/passes/regions.mjs +268 -0
  144. package/dist/pstack/skills/statechart/scripts/pipeline.mjs +72 -0
  145. package/dist/pstack/skills/statechart/scripts/run.mjs +440 -0
  146. package/dist/pstack/skills/statechart/scripts/statechart.mjs +155 -0
  147. package/dist/pstack/skills/statechart/scripts/statechart.test.mjs +198 -0
  148. package/dist/pstack/skills/statechart/scripts/worker.mjs +31 -0
  149. package/dist/pstack/skills/swarm/SKILL.md +43 -0
  150. package/{assets → dist/pstack}/skills/tdd/SKILL.md +1 -1
  151. package/{assets → dist/pstack}/skills/teach/SKILL.md +2 -2
  152. package/{assets → dist/pstack}/skills/technical-writing/SKILL.md +1 -1
  153. package/{assets → dist/pstack}/skills/typescript-best-practices/SKILL.md +3 -6
  154. package/{assets → dist/pstack}/skills/why/SKILL.md +8 -8
  155. package/dist/remote.d.mts +27 -0
  156. package/dist/remote.mjs +234 -0
  157. package/dist/role-config-NNn5r1JX.mjs +415 -0
  158. package/dist/role-manifest-C3fUzjLI.d.mts +19 -0
  159. package/dist/role-wire-DZwTn2wF.d.mts +55 -0
  160. package/dist/roles.d.mts +18 -0
  161. package/dist/roles.mjs +323 -0
  162. package/dist/script.d.mts +9 -111
  163. package/dist/script.mjs +32 -329
  164. package/dist/skill.d.mts +38 -0
  165. package/dist/skill.mjs +183 -0
  166. package/dist/skills/authored/decision-audit/SKILL.md +103 -0
  167. package/dist/skills/authored/decision-audit/SKILL.zh.md +103 -0
  168. package/dist/skills/authored/decision-audit/references/recover-commit.md +17 -0
  169. package/dist/skills/authored/decision-audit/references/recover-commit.zh.md +17 -0
  170. package/dist/skills/authored/decision-write/SKILL.md +133 -0
  171. package/dist/skills/authored/decision-write/SKILL.zh.md +133 -0
  172. package/dist/skills/authored/decision-write/references/land.md +48 -0
  173. package/dist/skills/authored/decision-write/references/land.zh.md +48 -0
  174. package/dist/skills/authored/decision-write/references/scope.md +16 -0
  175. package/dist/skills/authored/decision-write/references/scope.zh.md +16 -0
  176. package/dist/skills/authored/docs-drift/SKILL.md +120 -0
  177. package/dist/skills/authored/docs-drift/SKILL.zh.md +120 -0
  178. package/dist/skills/authored/setup-project-docs/SKILL.md +63 -0
  179. package/dist/skills/authored/setup-project-docs/SKILL.zh.md +63 -0
  180. package/dist/skills/authored/setup-project-docs/references/decision-conventions.md +13 -0
  181. package/dist/skills/authored/setup-project-docs/references/decision-conventions.zh.md +13 -0
  182. package/dist/skills/vendored/retro/SKILL.md +44 -0
  183. package/dist/skills/vendored/retro/agents/openai.yaml +5 -0
  184. package/dist/skills/vendored/writing-for-agents/SKILL-MECHANICS.md +22 -0
  185. package/dist/skills/vendored/writing-for-agents/SKILL.md +81 -0
  186. package/dist/skills/vendored/writing-for-agents/agents/openai.yaml +3 -0
  187. package/dist/subagent.d.mts +54 -206
  188. package/dist/subagent.mjs +258 -963
  189. package/locale/en.json +3 -2
  190. package/locale/zh.json +3 -2
  191. package/package.json +93 -66
  192. package/assets/agents/poteto-agent.md +0 -8
  193. package/assets/docs/harness/dsh.md +0 -60
  194. package/assets/docs/pstack-models.example.md +0 -54
  195. package/assets/skills/arena/SKILL.md +0 -50
  196. package/assets/skills/figure-it-out/SKILL.md +0 -54
  197. package/assets/skills/how/SKILL.md +0 -38
  198. package/assets/skills/interrogate/SKILL.md +0 -71
  199. package/assets/skills/interrogate/references/code-quality-review.md +0 -47
  200. package/assets/skills/interrogate/references/lead-judgment.md +0 -39
  201. package/assets/skills/interrogate/references/reviewer-prompt.md +0 -62
  202. package/assets/skills/interrogate/references/rubric.md +0 -77
  203. package/assets/skills/no-comments/SKILL.md +0 -26
  204. package/assets/skills/poteto-mode/playbooks/authoring-a-skill.md +0 -12
  205. package/assets/skills/poteto-mode/playbooks/autonomous-run.md +0 -15
  206. package/assets/skills/poteto-mode/playbooks/autopilot-full.md +0 -25
  207. package/assets/skills/poteto-mode/playbooks/autopilot-stack.md +0 -12
  208. package/assets/skills/poteto-mode/playbooks/bug-fix.md +0 -15
  209. package/assets/skills/poteto-mode/playbooks/feature.md +0 -21
  210. package/assets/skills/poteto-mode/playbooks/orchestrate.md +0 -112
  211. package/assets/skills/poteto-mode/playbooks/perf-issue.md +0 -25
  212. package/assets/skills/poteto-mode/playbooks/refactoring.md +0 -16
  213. package/assets/skills/poteto-mode/playbooks/runtime-forensics.md +0 -11
  214. package/assets/skills/poteto-mode/playbooks/session-pickup.md +0 -11
  215. package/assets/skills/poteto-mode/playbooks/visual-parity.md +0 -11
  216. package/assets/skills/poteto-mode/playbooks/worktree-cleanup.md +0 -20
  217. package/assets/skills/poteto-mode/scripts/orch/orch.mjs +0 -4282
  218. package/assets/skills/poteto-mode/scripts/orch/orch.test.mjs +0 -2042
  219. package/assets/skills/poteto-mode/scripts/watch-pr/cli.test.mjs +0 -5101
  220. package/assets/skills/poteto-mode/scripts/watch-pr/github.test.mjs +0 -1177
  221. package/assets/skills/poteto-mode/scripts/watch-pr/policy.test.mjs +0 -1441
  222. package/assets/skills/poteto-mode/scripts/watch-pr/watch-pr.mjs +0 -4601
  223. package/assets/skills/recall/SKILL.md +0 -37
  224. package/assets/skills/reflect/SKILL.md +0 -69
  225. package/assets/skills/setup-pstack/SKILL.md +0 -67
  226. package/assets/skills/swarm/SKILL.md +0 -43
  227. package/dist/frontmatter-BQX3ekwP.mjs +0 -229
  228. package/dist/frontmatter-BQX3ekwP.mjs.map +0 -1
  229. package/dist/history.d.mts +0 -429
  230. package/dist/history.mjs +0 -1129
  231. package/dist/history.mjs.map +0 -1
  232. package/dist/host-contract-o47JH_r8.d.mts +0 -527
  233. package/dist/index.mjs.map +0 -1
  234. package/dist/paths-D_JlVmBk.mjs +0 -42
  235. package/dist/paths-D_JlVmBk.mjs.map +0 -1
  236. package/dist/script.mjs.map +0 -1
  237. package/dist/subagent.mjs.map +0 -1
  238. /package/{static/icon.png → assets/logo.png} +0 -0
  239. /package/{assets → dist/pstack}/agents/comment-sicko.md +0 -0
  240. /package/{assets → dist/pstack}/docs/guide/03-understand.md +0 -0
  241. /package/{assets → dist/pstack}/docs/guide/08-principles.md +0 -0
  242. /package/{assets → dist/pstack}/docs/guide/images/design.jpg +0 -0
  243. /package/{assets → dist/pstack}/docs/guide/images/overnight.jpg +0 -0
  244. /package/{assets → dist/pstack}/docs/guide/images/recipes.jpg +0 -0
  245. /package/{assets → dist/pstack}/docs/guide/images/router.jpg +0 -0
  246. /package/{assets → dist/pstack}/docs/guide/images/understanding.jpg +0 -0
  247. /package/{assets → dist/pstack}/docs/guide/images/verification.jpg +0 -0
  248. /package/{assets → dist/pstack}/skills/architect/references/design-red-flags.md +0 -0
  249. /package/{assets → dist/pstack}/skills/architect/references/rationale-template.md +0 -0
  250. /package/{assets → dist/pstack}/skills/architect/references/runner-prompt.md +0 -0
  251. /package/{assets → dist/pstack}/skills/bro/SKILL.md +0 -0
  252. /package/{assets → dist/pstack}/skills/create-verification-skill/references/feature-map-example/README.md +0 -0
  253. /package/{assets → dist/pstack}/skills/create-verification-skill/references/feature-map-example/create-note.md +0 -0
  254. /package/{assets → dist/pstack}/skills/create-verification-skill/references/feature-map-example/search.md +0 -0
  255. /package/{assets → dist/pstack}/skills/how/references/explainer-prompt.md +0 -0
  256. /package/{assets → dist/pstack}/skills/how/references/explorer-prompt.md +0 -0
  257. /package/{assets → dist/pstack}/skills/poteto-mode/references/bugbot-triage.md +0 -0
  258. /package/{assets → dist/pstack}/skills/principle-build-the-lever/SKILL.md +0 -0
  259. /package/{assets → dist/pstack}/skills/principle-foundational-thinking/SKILL.md +0 -0
  260. /package/{assets → dist/pstack}/skills/principle-guard-the-context-window/SKILL.md +0 -0
  261. /package/{assets → dist/pstack}/skills/show-me-your-work/references/decision-log-template.tsv +0 -0
  262. /package/{assets → dist/pstack}/skills/typescript-best-practices/references/patterns.md +0 -0
  263. /package/{assets → dist/pstack}/skills/unslop/SKILL.md +0 -0
  264. /package/{assets → dist/pstack}/skills/why/references/epistemics.md +0 -0
  265. /package/{assets → dist/pstack}/skills/why/references/investigator-prompt.md +0 -0
  266. /package/{assets → dist/pstack}/skills/why/references/source-playbook.md +0 -0
  267. /package/{assets → dist/pstack}/skills/why/references/sources/code-archaeology.md +0 -0
  268. /package/{assets → dist/pstack}/skills/why/references/sources/databricks.md +0 -0
  269. /package/{assets → dist/pstack}/skills/why/references/sources/datadog.md +0 -0
  270. /package/{assets → dist/pstack}/skills/why/references/sources/incident-postmortem.md +0 -0
  271. /package/{assets → dist/pstack}/skills/why/references/sources/linear.md +0 -0
  272. /package/{assets → dist/pstack}/skills/why/references/sources/notion.md +0 -0
  273. /package/{assets → dist/pstack}/skills/why/references/sources/sentry.md +0 -0
  274. /package/{assets → dist/pstack}/skills/why/references/sources/slack.md +0 -0
  275. /package/{assets → dist/pstack}/skills/why/references/synthesizer-prompt.md +0 -0
package/dist/skill.mjs ADDED
@@ -0,0 +1,183 @@
1
+ import { resolve, sep } from "node:path";
2
+ import { readFile } from "node:fs/promises";
3
+ // src/skill.ts
4
+ /**
5
+ * `pstack_skill`: the trusted skill loader for pstack's own instructions.
6
+ *
7
+ * pstack hides most of its skills from the model catalog: `how`, `why`, `architect`,
8
+ * `arena`, and the principle skills all declare `disable-model-invocation: true`, so
9
+ * `poteto-mode` cannot route to them through DSH's `skill` tool. The registry's
10
+ * `get()` is deliberately usable by trusted callers without that policy, which is the
11
+ * public seam this tool consumes. It accepts a skill name, not a path, so a call can
12
+ * only load a skill the package itself registered.
13
+ *
14
+ * The optional `resource` argument reads one file below the skill's directory. It is a
15
+ * convenience for the references and playbooks that live beside `SKILL.md`; the path is
16
+ * resolved and checked against the skill directory before reading, so `../` cannot
17
+ * escape it.
18
+ */
19
+ /** Model-facing tool name. */
20
+ const TOOL_NAME = "pstack_skill";
21
+ /** Cordis row name, used by Loader diagnostics. */
22
+ const name = "pstack-skill";
23
+ /** The tool registry and the skill registry. */
24
+ const inject = ["skills", "tools"];
25
+ const SKILL_NAME = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
26
+ /** Render one loaded skill in the canonical `<skill_content>` shape. */
27
+ function renderLoadedSkill(result) {
28
+ const lines = [`<skill_content name="${escapeAttr(result.name)}">`, "<skill_resources>"];
29
+ if (result.resourceBase === void 0) lines.push(`Resources for this skill are managed by provider "${escapeText(result.provider)}".`, "Load referenced resources only as needed.");
30
+ else if (result.resourceBase.kind === "directory") lines.push(`Base directory for this skill: ${escapeText(result.resourceBase.path)}`, "Resolve relative paths mentioned by this skill against the base directory before using them. Load referenced resources only as needed.");
31
+ else if (result.resourceBase.kind === "url") lines.push(`Base URL for this skill: ${escapeText(result.resourceBase.url)}`, "Resolve relative URLs mentioned by this skill against the base URL before using them. Load referenced resources only as needed.");
32
+ else lines.push(`Resources for this skill: ${escapeText(result.resourceBase.description)}`, "Load referenced resources only as needed.");
33
+ lines.push("</skill_resources>", "", "<skill_instructions>", result.content, "</skill_instructions>");
34
+ if (result.resource !== void 0) lines.push("", `<skill_resource path="${escapeAttr(result.resource.path)}">`, result.resource.content, "</skill_resource>");
35
+ lines.push("</skill_content>");
36
+ return lines.join("\n");
37
+ }
38
+ function escapeAttr(value) {
39
+ return value.replaceAll("&", "&amp;").replaceAll("\"", "&quot;").replaceAll("<", "&lt;");
40
+ }
41
+ function escapeText(value) {
42
+ return value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
43
+ }
44
+ /** Read one resource below a directory skill, refusing traversal and absolute paths. */
45
+ async function readSkillResource(definition, resource) {
46
+ const base = definition.resourceBase;
47
+ if (base === void 0 || base.kind !== "directory") throw new Error(`skill "${definition.name}" does not expose a directory resource base`);
48
+ if (resource.trim() === "" || resource.includes("\0")) throw new Error("resource must be a non-empty relative path");
49
+ if (resource.startsWith("/") || resource.startsWith("\\") || /^[a-zA-Z]:[\\/]/.test(resource)) throw new Error(`resource "${resource}" must be relative to the skill directory`);
50
+ const root = resolve(base.path);
51
+ const target = resolve(root, resource);
52
+ if (target !== root && !target.startsWith(root + sep)) throw new Error(`resource "${resource}" escapes the skill directory`);
53
+ try {
54
+ return {
55
+ path: resource,
56
+ content: await readFile(target, "utf8")
57
+ };
58
+ } catch (error) {
59
+ const code = error.code;
60
+ if (code === "ENOENT" || code === "EISDIR") throw new Error(`resource "${resource}" is not available for skill "${definition.name}"`);
61
+ throw error;
62
+ }
63
+ }
64
+ const OUTPUT_SCHEMA = {
65
+ type: "object",
66
+ additionalProperties: false,
67
+ properties: {
68
+ name: { type: "string" },
69
+ provider: { type: "string" },
70
+ resourceBase: { oneOf: [
71
+ {
72
+ type: "object",
73
+ additionalProperties: false,
74
+ properties: {
75
+ kind: {
76
+ type: "string",
77
+ const: "directory"
78
+ },
79
+ path: { type: "string" }
80
+ },
81
+ required: ["kind", "path"]
82
+ },
83
+ {
84
+ type: "object",
85
+ additionalProperties: false,
86
+ properties: {
87
+ kind: {
88
+ type: "string",
89
+ const: "url"
90
+ },
91
+ url: { type: "string" }
92
+ },
93
+ required: ["kind", "url"]
94
+ },
95
+ {
96
+ type: "object",
97
+ additionalProperties: false,
98
+ properties: {
99
+ kind: {
100
+ type: "string",
101
+ const: "opaque"
102
+ },
103
+ description: { type: "string" }
104
+ },
105
+ required: ["kind", "description"]
106
+ }
107
+ ] },
108
+ content: { type: "string" },
109
+ resource: {
110
+ type: "object",
111
+ additionalProperties: false,
112
+ properties: {
113
+ path: { type: "string" },
114
+ content: { type: "string" }
115
+ },
116
+ required: ["path", "content"]
117
+ }
118
+ },
119
+ required: [
120
+ "name",
121
+ "provider",
122
+ "content"
123
+ ]
124
+ };
125
+ const TOOL_DESCRIPTION = [
126
+ "Load the full instructions of any pstack skill by name, including skills hidden from the model catalog.",
127
+ "",
128
+ "Use this when a pstack skill tells you to route through another pstack skill (for example how, why, or architect) and the `skill` tool reports that it is unavailable because the skill disables model invocation.",
129
+ "",
130
+ "Pass `resource` with a path relative to the skill directory to read one reference or playbook beside its SKILL.md. The path cannot leave the skill directory."
131
+ ].join("\n");
132
+ /** Build the tool definition. Exported so tests can drive `execute` directly. */
133
+ function createPstackSkillTool(skills) {
134
+ return {
135
+ name: TOOL_NAME,
136
+ description: TOOL_DESCRIPTION,
137
+ parameters: {
138
+ type: "object",
139
+ additionalProperties: false,
140
+ properties: {
141
+ name: {
142
+ type: "string",
143
+ description: "Exact kebab-case skill name, such as `how` or `principle-prove-it-works`."
144
+ },
145
+ resource: {
146
+ type: "string",
147
+ description: "Optional path relative to the skill directory, such as `references/explorer-prompt.md`."
148
+ }
149
+ },
150
+ required: ["name"]
151
+ },
152
+ output: {
153
+ schema: OUTPUT_SCHEMA,
154
+ render: (_args, value) => [{
155
+ type: "text",
156
+ text: renderLoadedSkill(value)
157
+ }]
158
+ },
159
+ isConcurrencySafe: () => true,
160
+ async execute(rawArgs, exec) {
161
+ const args = rawArgs;
162
+ if (typeof args.name !== "string" || !SKILL_NAME.test(args.name)) throw new Error(`invalid skill name "${String(args.name)}"`);
163
+ if (args.resource !== void 0 && typeof args.resource !== "string") throw new Error("resource must be a string when present");
164
+ const definition = await skills.get(args.name, {
165
+ signal: exec.signal,
166
+ ...exec.agent === void 0 ? {} : { scope: exec.agent }
167
+ });
168
+ if (definition === void 0) throw new Error(`skill "${args.name}" is unknown or no longer available`);
169
+ return {
170
+ name: definition.name,
171
+ provider: definition.provider,
172
+ ...definition.resourceBase === void 0 ? {} : { resourceBase: definition.resourceBase },
173
+ content: definition.content,
174
+ ...args.resource === void 0 ? {} : { resource: await readSkillResource(definition, args.resource) }
175
+ };
176
+ }
177
+ };
178
+ }
179
+ /** Register `pstack_skill` on one row. */
180
+ function apply(ctx) {
181
+ ctx.tools.register(createPstackSkillTool(ctx.skills));
182
+ }
183
+ export { TOOL_NAME, apply, createPstackSkillTool, inject, name, readSkillResource, renderLoadedSkill };
@@ -0,0 +1,103 @@
1
+ ---
2
+ name: decision-audit
3
+ description: Read-only audit of decision records for a PR, local changes, or the whole repository. Report routing, status, scope, anchor, supersession, and overdue-review findings with command evidence.
4
+ disable-model-invocation: true
5
+ ---
6
+
7
+ # Audit decision records
8
+
9
+ Produce a read-only report of records needing human attention, without judging whether code still honors a decision. Cite each finding with its command and observed output; leave every edit to `decision-write`.
10
+
11
+ ## 1. Resolve the inputs
12
+
13
+ Accept `mode` (`pr`, `local`, or `full`; default `pr`), optional `base`, and optional `scope` paths replacing the computed change set.
14
+
15
+ For `pr`, resolve the PR base. For `local` or `full`, try `origin/main`. When absent, try `origin/master`, `main`, `master`, the newest tag, then `HEAD~20`. Report the selected ref. An unresolved base blocks base-relative change sets and commit-anchor checks; continue the other checks and list every attempted ref under `Unverified`.
16
+
17
+ Resolve `<dir>` in this order:
18
+
19
+ 1. Use a caller-supplied record or directory path.
20
+ 2. Otherwise, resolve the decision pointer in root `AGENTS.md` under `## Project docs` when it points to an existing `<dir>/AGENTS.md`.
21
+ 3. Otherwise, inspect `docs/decisions/`, `docs/adr/`, and `doc/adr/`.
22
+
23
+ Report the selected path. If several candidates remain, ask which is current and wait. If none exists or it contains no records, report that normal result and stop.
24
+
25
+ ## 2. Collect the evidence
26
+
27
+ When `scope` is absent, compute the change set:
28
+
29
+ ```bash
30
+ # pr
31
+ git diff --name-only "$(git merge-base HEAD <base>)"..HEAD
32
+
33
+ # local: base-relative commits plus the working tree and index
34
+ git diff --name-only "$(git merge-base HEAD <base>)"..HEAD
35
+ git status --porcelain=v1 --untracked-files=all
36
+ ```
37
+
38
+ Decode `git status` paths, including the destination of a rename. For `full`, use all tracked files. Exclude lock files, generated files, snapshots, and pure assets from the computed set; record these exclusions and the final set. An explicit `scope` replaces the computed set but does not change base-dependent anchor checks.
39
+
40
+ Read `<dir>/AGENTS.md` and `<dir>/README.md` when present; these are conventions, not records. Apply their conventions to every other `*.md`. Parse each header through its first `## ` heading. List records missing any of `Status`, `Date`, `Scope`, `Implemented-by`, or `Review` separately as `Legacy`; they receive no further checks until the required fields are restored. `Superseded-by` is optional for current records; check it only under E.
41
+
42
+ Apply every applicable check to every current record; a record may have multiple findings. Use [Match Scope paths](../decision-write/references/scope.md) for every glob/path check and retain the matches as evidence.
43
+
44
+ ## 3. Run the checks
45
+
46
+ Apply A, B, B′, and D only to non-`superseded` records; apply C and E as specified below.
47
+
48
+ **A — Route.** For each record whose `Scope` matches the change set, report its title, path, matched paths, and change-set evidence in one line.
49
+
50
+ **B — Status pair.** Use the anchor results below and report each matching row:
51
+
52
+ | Status | Anchor result | Finding |
53
+ |---|---|---|
54
+ | `proposed` | verified | Should be `accepted` |
55
+ | `accepted` | `-` or missing | Landing lacks verified evidence |
56
+
57
+ For `proposed`, `-` is pending. For either `proposed` or `accepted`, a pending anchor is not a finding; report the record as pending. An unverified anchor belongs in `Unverified`, outside B and C.
58
+
59
+ **B′ — Dead scope.** For each `accepted` record with no `Scope` glob matching an existing file, report its path and glob-check evidence. Ask whether the decision is obsolete or its scope is wrong.
60
+
61
+ **C — Broken anchor.** For each non-`superseded` `Implemented-by` value, classify it with evidence:
62
+
63
+ | Value | Verification | Result |
64
+ |---|---|---|
65
+ | `-` or missing | None | Pending |
66
+ | `PR #N` | `gh pr view N --json state,files` | `MERGED`: continue below; `OPEN`: pending; `CLOSED`: C; otherwise: unverified |
67
+ | `commit:SHA` | `git merge-base --is-ancestor SHA <base>` | Exit 0: continue below; exit 1: C; otherwise: unverified |
68
+ | Any value | Command unavailable, authentication fails, or object cannot be read | Unverified |
69
+
70
+ For a landed PR or ancestral commit, list its paths with `gh pr view N --json files --jq '.files[].path'` or `git show --pretty=format: --name-only SHA`. `Verified` requires a path matching `Scope` and at least one path outside `<dir>`; otherwise report C with the path evidence.
71
+
72
+ Before reporting a commit as lost, read [Recover a rewritten commit](references/recover-commit.md) and attempt patch-identity recovery while its object remains available.
73
+
74
+ **D — Overdue review.** In `full` mode only, report each record whose `Review` date is before the current date. Collect matching changes since the decision date:
75
+
76
+ ```bash
77
+ date +%F
78
+ git log --since=<Date> --format=%H <base> --
79
+ ```
80
+
81
+ List each commit's paths and filter them with the shared matcher before counting it; the record's `Scope` value is matcher input, not a Git pathspec. Include the matched-commit count and latest subject when present. An overdue date is the finding even when there are no matching changes; suggest human review and a new `Review` date.
82
+
83
+ **E — Superseded record.** For each current `superseded` record, report when `Superseded-by` is missing, does not resolve to a record in `<dir>`, or carries no ` — <reason>` text. Suggest adding the replacing record path and a one-line reason.
84
+
85
+ ## 4. Report and trim
86
+
87
+ Account for every current record as pending, clean, unverified, or carrying one or more findings. Order findings `C`, `B`, `B′`, `E`, `D`, `A`; within each class, put more matched files first.
88
+
89
+ - `pr`: at most 15 findings, followed by the omitted count.
90
+ - `local`: at most 8 findings, including at most 3 class-A findings.
91
+ - `full`: no trimming; report every class count, including zeroes.
92
+
93
+ Use this structure for findings; include `Evidence` for every class:
94
+
95
+ ```text
96
+ [C] Decision title
97
+ Record: docs/decisions/2026-08-14-use-postgres.md
98
+ Basis: commit:3f9a1c2 is not in history
99
+ Evidence: git merge-base --is-ancestor 3f9a1c2 origin/main -> exit 1
100
+ Suggest: replace the anchor with commit:8ff9f762 (matching patch-id d064e03f4e53)
101
+ ```
102
+
103
+ List `Legacy` and `Unverified` separately from findings. An unavailable or unauthenticated `gh` leaves PR anchors unverified while the other checks continue. Say when no current record carries a finding. Route all edits to `decision-write`; suggest `/setup-project-docs` only when the decision directory or its root pointer is missing.
@@ -0,0 +1,103 @@
1
+ ---
2
+ name: decision-audit
3
+ description: 只读审计 PR、本地改动或整个仓库的决策记录,报告路由、状态、范围、锚点、取代与复核逾期发现,并附命令证据。
4
+ disable-model-invocation: true
5
+ ---
6
+
7
+ # 审计决策记录
8
+
9
+ 以只读方式报告需要人工关注的记录,不判断代码是否仍符合决策。每项发现都附上支持它的命令与实际输出;所有修改交给 `decision-write`。
10
+
11
+ ## 1. 确定输入
12
+
13
+ 接受 `mode`(`pr`、`local` 或 `full`,默认 `pr`)、可选的 `base`,以及用于替代计算所得改动集合的可选 `scope` 路径。
14
+
15
+ `pr` 解析 PR 基线,`local` 或 `full` 先尝试 `origin/main`。不存在时依次尝试 `origin/master`、`main`、`master`、最新 tag、`HEAD~20`。报告实际选中的 ref。基线无法解析会阻止相对基线的改动集合计算与提交锚点校验;继续其他检查,并在 `Unverified` 中列出每个尝试过的 ref。
16
+
17
+ 按以下顺序定位 `<dir>`:
18
+
19
+ 1. 使用调用方提供的记录或目录路径。
20
+ 2. 否则,解析根目录 `AGENTS.md` 的 `## Project docs` 中的决策指针;目标为现存的 `<dir>/AGENTS.md` 时使用该目录。
21
+ 3. 否则,检查 `docs/decisions/`、`docs/adr/` 和 `doc/adr/`。
22
+
23
+ 报告选中的路径。仍有多个候选时,询问哪个是当前目录并等待。都不存在或没有记录时,报告这一正常结果并停止。
24
+
25
+ ## 2. 收集证据
26
+
27
+ 未提供 `scope` 时计算改动集合:
28
+
29
+ ```bash
30
+ # pr
31
+ git diff --name-only "$(git merge-base HEAD <base>)"..HEAD
32
+
33
+ # local:相对基线的提交,加上工作区与暂存区
34
+ git diff --name-only "$(git merge-base HEAD <base>)"..HEAD
35
+ git status --porcelain=v1 --untracked-files=all
36
+ ```
37
+
38
+ 解析 `git status` 中的路径,重命名取目标路径。`full` 使用所有受 Git 跟踪的文件。从计算结果中剔除锁文件、生成文件、快照和纯资源文件;记录这些排除项与最终集合。显式 `scope` 替换计算所得集合,但不改变依赖基线的锚点校验。
39
+
40
+ 存在 `<dir>/AGENTS.md` 和 `<dir>/README.md` 时读取;它们是约定而非记录。将其约定应用到其他所有 `*.md`。读取每条记录至第一个 `## ` 标题并解析头部。缺少 `Status`、`Date`、`Scope`、`Implemented-by`、`Review` 中任一项的记录单列为 `Legacy`,补齐必需字段前不执行后续检查。现行记录的 `Superseded-by` 可选,只在 E 类检查中处理。
41
+
42
+ 对每条现行记录执行所有适用的检查;同一记录可以产生多项发现。所有 glob/路径检查都使用[匹配 Scope 路径](../decision-write/references/scope.zh.md),并保留匹配结果作为证据。
43
+
44
+ ## 3. 执行检查
45
+
46
+ A、B、B′ 和 D 只用于非 `superseded` 记录;C 和 E 按下方说明执行。
47
+
48
+ **A——路由。** 对每条 `Scope` 匹配改动集合的记录,用一行报告标题、路径、匹配路径及改动集合证据。
49
+
50
+ **B——状态成对。** 使用下方的锚点结果,报告每个匹配行:
51
+
52
+ | Status | 锚点结果 | 发现 |
53
+ |---|---|---|
54
+ | `proposed` | 已核验 | 应改为 `accepted` |
55
+ | `accepted` | `-` 或缺失 | 落地状态缺少已核验证据 |
56
+
57
+ `proposed` 带 `-` 时归为待落地。`proposed` 或 `accepted` 带待落地锚点都不是发现;将记录归为待落地。带未核验锚点时归入 `Unverified`,不归入 B 或 C。
58
+
59
+ **B′——范围失效。** 对 `Scope` 中所有 glob 都不匹配现存文件的每条 `accepted` 记录,报告路径与 glob 检查证据,并询问是决策已过时还是范围写错。
60
+
61
+ **C——锚点断裂。** 对每条非 `superseded` 记录的每个 `Implemented-by` 值,按证据分类:
62
+
63
+ | 值 | 校验 | 结果 |
64
+ |---|---|---|
65
+ | `-` 或缺失 | 无 | 待落地 |
66
+ | `PR #N` | `gh pr view N --json state,files` | `MERGED`:继续下方检查;`OPEN`:待落地;`CLOSED`:C;其他:未核验 |
67
+ | `commit:SHA` | `git merge-base --is-ancestor SHA <base>` | 退出码 0:继续下方检查;1:C;其他:未核验 |
68
+ | 任意值 | 命令不可用、认证失败或对象无法读取 | 未核验 |
69
+
70
+ 对已合并 PR 或祖先提交,用 `gh pr view N --json files --jq '.files[].path'` 或 `git show --pretty=format: --name-only SHA` 列出路径。“已核验”要求至少一个路径匹配 `Scope`,且至少一个路径在 `<dir>` 之外;否则附路径证据报告 C。
71
+
72
+ 报告提交丢失前,读取[恢复被改写的提交](references/recover-commit.zh.md);只要其对象仍可用,就尝试恢复 patch 标识。
73
+
74
+ **D——复核逾期。** 仅在 `full` 模式,报告 `Review` 日期早于当前日期的每条记录,并收集决策日期以来匹配 `Scope` 的改动:
75
+
76
+ ```bash
77
+ date +%F
78
+ git log --since=<Date> --format=%H <base> --
79
+ ```
80
+
81
+ 列出每个提交的路径,先用共享匹配器筛选,再计数;记录的 `Scope` 是匹配器输入,不是 Git pathspec。附上匹配提交的数量和最新主题(如有)。日期逾期本身就是发现,即使没有匹配改动;建议人工复核并更新 `Review` 日期。
82
+
83
+ **E——取代记录。** 对每条现行 `superseded` 记录,在 `Superseded-by` 缺失、无法解析到 `<dir>` 内的记录,或没有 ` — <原因>` 文本时报告。建议补上替代记录路径和一句原因。
84
+
85
+ ## 4. 报告与裁剪
86
+
87
+ 每条现行记录都必须归为待落地、无发现、未核验,或带一项或多项发现。按 `C`、`B`、`B′`、`E`、`D`、`A` 排列;同类中匹配文件更多的在前。
88
+
89
+ - `pr`:最多 15 项,随后给出省略数量。
90
+ - `local`:最多 8 项,其中 A 类最多 3 项。
91
+ - `full`:不裁剪,报告每类计数,包括零。
92
+
93
+ 各项发现使用以下结构;每一类都要包含 `Evidence`:
94
+
95
+ ```text
96
+ [C] Decision title
97
+ Record: docs/decisions/2026-08-14-use-postgres.md
98
+ Basis: commit:3f9a1c2 is not in history
99
+ Evidence: git merge-base --is-ancestor 3f9a1c2 origin/main -> exit 1
100
+ Suggest: replace the anchor with commit:8ff9f762 (matching patch-id d064e03f4e53)
101
+ ```
102
+
103
+ `Legacy` 与 `Unverified` 分别单列,不计为发现。`gh` 缺失或未认证时,将 PR 锚点标为未核验,继续其他检查。没有现行记录带发现时明确说明。所有修改都交给 `decision-write`;仅在决策目录或根指针缺失时建议使用 `/setup-project-docs`。
@@ -0,0 +1,17 @@
1
+ # Recover a rewritten commit
2
+
3
+ When an `Implemented-by: commit:SHA` is outside `<base>` but its object remains available, recover its patch identity before reporting it as lost:
4
+
5
+ ```bash
6
+ git show <dead-sha> | git patch-id --stable
7
+ ```
8
+
9
+ Search plausible replacements within the record's date and scope:
10
+
11
+ ```bash
12
+ git log --since=<Date> --format=%H <base> -- |
13
+ while read -r sha; do git show "$sha" | git patch-id --stable | awk -v sha="$sha" '{print $1, sha}'; done |
14
+ grep -F "<patch-id>"
15
+ ```
16
+
17
+ Filter each candidate commit's paths with the shared `Scope` matcher before comparing its patch identity. A match supports suggesting the replacement SHA; otherwise leave replacement to a human. Prefer PR anchors in squash-merged repositories.
@@ -0,0 +1,17 @@
1
+ # 恢复被改写的提交
2
+
3
+ `Implemented-by: commit:SHA` 不在 `<base>` 中、但其对象仍可用时,先恢复 patch 标识,再报告提交丢失:
4
+
5
+ ```bash
6
+ git show <dead-sha> | git patch-id --stable
7
+ ```
8
+
9
+ 在记录的日期与范围内搜索可能的替代提交:
10
+
11
+ ```bash
12
+ git log --since=<Date> --format=%H <base> -- |
13
+ while read -r sha; do git show "$sha" | git patch-id --stable | awk -v sha="$sha" '{print $1, sha}'; done |
14
+ grep -F "<patch-id>"
15
+ ```
16
+
17
+ 比较 patch 标识前,先用共享 `Scope` 匹配器筛选每个候选提交的路径。命中可支持建议改用替代 SHA;未命中则留给人判断替代项。使用 squash 合并的仓库优先采用 PR 锚点。
@@ -0,0 +1,133 @@
1
+ ---
2
+ name: decision-write
3
+ description: Write, update, land, or supersede decision records. Use for resolved alternatives, missing rationale, reversed decisions, or record-file changes. Land finds and verifies the implementation; Review-only updates keep the current status.
4
+ ---
5
+
6
+ # Write or update a decision record
7
+
8
+ Deliver one settled choice as a verified record and evidence report. All record edits go through this skill; `decision-audit` only reports.
9
+
10
+ ## Entry rule
11
+
12
+ Use this procedure for every change to `Status`, `Implemented-by`, `Superseded-by`, `Review`, body, or links. If it cannot run, stop and report; this rule overrides `<dir>/AGENTS.md` conventions permitting direct edits.
13
+
14
+ ## Locate the records
15
+
16
+ Resolve `<dir>` in this order:
17
+
18
+ 1. Use a caller-supplied record or directory path.
19
+ 2. Otherwise, resolve the decision pointer in root `AGENTS.md` under `## Project docs` when it points to an existing `<dir>/AGENTS.md`.
20
+ 3. Otherwise, inspect `docs/decisions/`, `docs/adr/`, and `doc/adr/`.
21
+
22
+ Use the selected directory, follow its naming convention, and read its `AGENTS.md` and `README.md` conventions when present. If several candidates remain, ask which is current and wait. If none exists, report that no decision directory was found, suggest `/setup-project-docs`, and stop.
23
+
24
+ `AGENTS.md` and `README.md` are conventions, not records; exclude both from searches, classification, and updates.
25
+
26
+ ## Choose the mode
27
+
28
+ - **Draft:** no record owns this decision, a new record replaces an old one, or an existing record needs substantive body or relationship updates. Duplicate and overlapping dispositions stay in Draft; explicit status-field updates use Land. Do steps 1–5, present the approval gate in step 6, then write only after confirmation and report with step 7.
29
+ - **Land:** the user explicitly asks to mark an existing record `accepted` or update its status fields. Read the full target record, then do steps 4, 5, and 7. A record path plus `accepted` is sufficient input; never enter Land autonomously. Without a path, list records whose `Scope` matches the landed change and ask which to update. For a Review-only update, preserve `Status` and `Implemented-by`, skip steps 4 and 5, and report with step 7.
30
+
31
+ ## 1. Establish the choice
32
+
33
+ Obtain all three from the change and discussion; ask only about missing items and wait:
34
+
35
+ - **Goal:** the problem this decision answers.
36
+ - **Constraint:** the boundary that eliminates an option.
37
+ - **Alternative:** an option actually rejected, or the explicit fact that only one candidate was considered.
38
+
39
+ ## 2. Find related records
40
+
41
+ Search for distinctive terms from the topic, affected modules, and alternatives:
42
+
43
+ ```bash
44
+ grep -ril --exclude=AGENTS.md --exclude=README.md \
45
+ -e "<keyword-1>" -e "<keyword-2>" <dir>/*.md
46
+ ```
47
+
48
+ Read each hit through its first `## ` heading; read the body only when the header cannot distinguish its disposition or cannot supply the content needed for an update. Tighten broad searches rather than reading the whole directory. Classify every hit:
49
+
50
+ - **Duplicate:** the existing record owns this decision. Update it instead of writing a second one.
51
+ - **Replaced:** draft the new record and cross-link both records. Include the old record's supersession in the approval gate.
52
+ - **Overlapping:** keep both, cross-link them, and reconcile changed facts.
53
+ - **Unrelated:** leave it unchanged.
54
+ - **Unresolved:** carry the relationship and human question into the report.
55
+
56
+ This step is complete when every hit has a disposition and every resulting edit is explicit.
57
+
58
+ ## 3. Draft the record
59
+
60
+ Follow `<dir>/AGENTS.md`, including heading language. In its absence, use:
61
+
62
+ ```markdown
63
+ # Decision: <one-line title>
64
+
65
+ Status: proposed | accepted | superseded
66
+ Date: YYYY-MM-DD
67
+ Scope: <glob>[, <glob>...]
68
+ Implemented-by: <PR #N | commit:SHA | ->
69
+ Review: YYYY-MM-DD
70
+ Superseded-by: <record path> — <one-line reason> (only when Status is superseded)
71
+
72
+ ## Background
73
+ ## Decision
74
+ ## Alternatives
75
+ ## Consequences
76
+ ```
77
+
78
+ Write `Background` independently of the chosen solution. For an accepted record, write `Decision` in the present tense. Give every considered alternative its own paragraph and rejection reason; when there was only one candidate, state that fact.
79
+
80
+ ## 4. Set status and verify the anchor
81
+
82
+ `Status` and `Implemented-by` are one pair. Select the row supported by evidence and write both fields together:
83
+
84
+ | Evidence | Status | Implemented-by |
85
+ |---|---|---|
86
+ | No verified landing anchor | `proposed` | `-` |
87
+ | `PR #N` is `MERGED` | `accepted` | `PR #N` |
88
+ | `commit:SHA` is an ancestor of the default branch | `accepted` | `commit:SHA` |
89
+ | Confirmed record-only exception | `accepted` | `commit:<record-commit>` |
90
+ | Replaced by a newer draft | `superseded` | Keep the existing value |
91
+
92
+ A new record stays `proposed` until it lands. `Implemented-by` identifies the implementing change, including an earlier implementation for a retrospective record; a record-only commit requires the confirmed exception. Prefer a merged PR in a squash-merged repository.
93
+
94
+ For Land without an anchor, or the record-only exception, read [Find and verify the implementation](references/land.md) before editing. For any other proposed anchor, use that reference's verification procedure without its discovery steps.
95
+
96
+ Resolve `<base>` as the repository's default branch and report the selected ref. Verify every anchor. In Draft, unavailable evidence or an unresolved base leaves a new record `proposed` + `-`; in Land, stop and report without editing. If an existing `accepted` record's anchor fails verification, stop and report it rather than silently demoting it. Change only fields required by evidence; advancing `Review` alone leaves status unchanged.
97
+
98
+ When a new draft replaces an old record, set the old record to `superseded` in the same approved edit set, even when it was `accepted`. Keep its body and anchor, add the cross-link, and write `Superseded-by: <new record path> — <one-line reason>` below `Review`. Ask for a missing reason and wait. A `proposed` old record keeps `Implemented-by: -`.
99
+
100
+ ## 5. Check scope covers the change
101
+
102
+ Use [Match Scope paths](references/scope.md) for every glob/path check, including anchor discovery in Land. Use caller-supplied `scope` paths when present. For Land with a verified implementing change, list its paths with:
103
+
104
+ ```bash
105
+ gh pr view N --json files --jq '.files[].path'
106
+ git show --pretty=format: --name-only SHA
107
+ ```
108
+
109
+ For the confirmed record-only fallback, skip this check and report the exception. For every other mode, collect base-relative commits and uncommitted changes:
110
+
111
+ ```bash
112
+ git diff --name-only "$(git merge-base HEAD <base>)"..HEAD
113
+ git status --porcelain=v1 --untracked-files=all
114
+ ```
115
+
116
+ Decode `git status` paths, including the destination of a rename. Require each new or updated record to match at least one selected path to a `Scope` glob. When none matches, ask whether to widen the glob or omit the record. Record matched paths for the report.
117
+
118
+ ## 6. Draft approval gate
119
+
120
+ For every Draft write, including a Duplicate update, present the complete resulting content of every new or updated record and every related-record disposition. Include each proposed supersession with its `Superseded-by` path and reason. Request explicit confirmation and wait. After confirmation, apply exactly the approved edits; a declined draft leaves every file unchanged.
121
+
122
+ ## 7. Report
123
+
124
+ When root `AGENTS.md` has no resolving decision pointer for the selected `<dir>`, suggest `/setup-project-docs` to register it. Account for every search hit, changed record, relationship, anchor verification, scope match, and unresolved question. A `proposed` record awaiting landing needs a Land update after merge. Name any discovered implementation and its changed paths; mark a record-only anchor as a confirmed exception. Include every `Superseded-by` path and reason.
125
+
126
+ ```text
127
+ Record: docs/decisions/2026-10-27-use-postgres.md
128
+ Status: accepted
129
+ Related: 2026-03-02-mysql-setup.md -> overlapping, cross-linked
130
+ Anchor: PR #412 -> MERGED (gh pr view 412 --json state,files)
131
+ Scope: src/db/** matched src/db/client.ts
132
+ Open: none
133
+ ```