heyspex 0.1.0 → 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 (322) hide show
  1. package/README.md +21 -0
  2. package/bin/hs.mjs +931 -98
  3. package/bin/spexcode.mjs +262 -0
  4. package/dev-factory/engine/worktree.mjs +740 -0
  5. package/dev-factory/lib/code-repo-root.mjs +67 -0
  6. package/dev-factory/lib/context-budget.mjs +84 -0
  7. package/dev-factory/lib/epic-detect.mjs +190 -0
  8. package/dev-factory/lib/fleet-queue-file.mjs +846 -0
  9. package/dev-factory/lib/fleet-queue.mjs +426 -0
  10. package/dev-factory/lib/fleet-state.mjs +14 -18
  11. package/dev-factory/lib/model-catalog.mjs +338 -0
  12. package/dev-factory/lib/seat-context.mjs +199 -0
  13. package/dev-factory/lib/spec-io.mjs +93 -0
  14. package/dev-factory/lib/sufficiency-score.mjs +8 -2
  15. package/dev-factory/lib/worktree-allocator.mjs +744 -0
  16. package/dev-factory/model-catalog.json +222 -0
  17. package/dist/cli/hs-check.mjs +1085 -103
  18. package/dist/cli/hs-claim.mjs +936 -63
  19. package/dist/cli/hs-connect.mjs +9786 -1910
  20. package/dist/cli/hs-defer.mjs +5267 -3053
  21. package/dist/cli/hs-dev.mjs +564 -0
  22. package/dist/cli/hs-env.mjs +385 -299
  23. package/dist/cli/hs-index-rebuild.mjs +7129 -0
  24. package/dist/cli/hs-index-reconcile.mjs +7852 -0
  25. package/dist/cli/hs-init.mjs +777 -138
  26. package/dist/cli/hs-install.mjs +6583 -485
  27. package/dist/cli/hs-join.mjs +10137 -2368
  28. package/dist/cli/hs-vault-pull.mjs +4659 -5882
  29. package/dist/cli/hs-vault.mjs +3793 -1537
  30. package/dist/cli/hs-workspace.mjs +2550 -524
  31. package/dist/cli-templates/customer-vault/specs/entity-model.md +594 -601
  32. package/dist/cli-templates/customer-vault/specs/protocols/canonical-frontmatter-templates.md +110 -177
  33. package/dist/cli-templates/customer-vault/specs/protocols/destructive-action-checklist.md +122 -0
  34. package/dist/cli-templates/customer-vault/specs/protocols/memory-protocol.md +13 -15
  35. package/dist/cli-templates/customer-vault/specs/protocols/session-close-protocol.md +91 -0
  36. package/dist/cli-templates/customer-vault/specs/protocols/spec-hierarchy.md +150 -168
  37. package/dist/cli-templates/customer-vault/specs/protocols/spec-summary-authoring.md +83 -0
  38. package/dist/cli-templates/harness-commands/claude/hs-auto.md +36 -0
  39. package/dist/cli-templates/harness-commands/claude/hs-backfill.md +28 -0
  40. package/dist/cli-templates/harness-commands/claude/hs-capture.md +62 -0
  41. package/dist/cli-templates/harness-commands/claude/hs-defer.md +29 -0
  42. package/dist/cli-templates/harness-commands/claude/hs-dev.md +20 -0
  43. package/dist/cli-templates/harness-commands/claude/hs-doctor.md +32 -0
  44. package/dist/cli-templates/harness-commands/claude/hs-ground.md +28 -0
  45. package/dist/cli-templates/harness-commands/claude/hs-handoff.md +33 -0
  46. package/dist/cli-templates/harness-commands/claude/hs-log.md +27 -0
  47. package/dist/cli-templates/harness-commands/claude/hs-next.md +29 -0
  48. package/dist/cli-templates/harness-commands/claude/hs-promote.md +70 -0
  49. package/dist/cli-templates/harness-commands/claude/hs-push.md +35 -0
  50. package/dist/cli-templates/harness-commands/claude/hs-qc.md +27 -0
  51. package/dist/cli-templates/harness-commands/claude/hs-res.md +63 -0
  52. package/dist/cli-templates/harness-commands/claude/hs-resolve.md +23 -0
  53. package/dist/cli-templates/harness-commands/claude/hs-review.md +23 -0
  54. package/dist/cli-templates/harness-commands/claude/hs-view.md +26 -0
  55. package/dist/cli-templates/harness-commands/claude/kill-ports.md +32 -0
  56. package/dist/cli-templates/harness-commands/claude/prototype.md +91 -0
  57. package/dist/cli-templates/harness-commands/cursor/hs-auto.md +40 -0
  58. package/dist/cli-templates/harness-commands/cursor/hs-backfill.md +31 -0
  59. package/dist/cli-templates/harness-commands/cursor/hs-capture.md +65 -0
  60. package/dist/cli-templates/harness-commands/cursor/hs-defer.md +32 -0
  61. package/dist/cli-templates/harness-commands/cursor/hs-dev.md +24 -0
  62. package/dist/cli-templates/harness-commands/cursor/hs-doctor.md +36 -0
  63. package/dist/cli-templates/harness-commands/cursor/hs-ground.md +31 -0
  64. package/dist/cli-templates/harness-commands/cursor/hs-handoff.md +37 -0
  65. package/dist/cli-templates/harness-commands/cursor/hs-log.md +31 -0
  66. package/dist/cli-templates/harness-commands/cursor/hs-next.md +32 -0
  67. package/dist/cli-templates/harness-commands/cursor/hs-promote.md +73 -0
  68. package/dist/cli-templates/harness-commands/cursor/hs-push.md +38 -0
  69. package/dist/cli-templates/harness-commands/cursor/hs-qc.md +30 -0
  70. package/dist/cli-templates/harness-commands/cursor/hs-res.md +67 -0
  71. package/dist/cli-templates/harness-commands/cursor/hs-resolve.md +26 -0
  72. package/dist/cli-templates/harness-commands/cursor/hs-review.md +26 -0
  73. package/dist/cli-templates/harness-commands/cursor/hs-view.md +30 -0
  74. package/dist/cli-templates/harness-commands/cursor/kill-ports.md +35 -0
  75. package/dist/cli-templates/harness-commands/cursor/prototype.md +95 -0
  76. package/docs/mcp-client-config.md +259 -6
  77. package/package.json +231 -124
  78. package/plugins/heyspex/.claude-plugin/plugin.json +12 -0
  79. package/plugins/heyspex/.cursor-plugin/plugin.json +15 -0
  80. package/plugins/heyspex/.mcp.json +12 -0
  81. package/plugins/heyspex/bin/launch-mcp.mjs +95 -0
  82. package/plugins/heyspex/bin/run-hook.mjs +62 -0
  83. package/plugins/heyspex/hooks/cursor-hooks.json +227 -0
  84. package/plugins/heyspex/hooks/hooks.json +361 -0
  85. package/plugins/heyspex/mcp.json +13 -0
  86. package/scripts/check-mcp-freshness.mjs +17 -9
  87. package/scripts/claude-hooks/_env-vault-events.mjs +68 -0
  88. package/scripts/claude-hooks/_guardrail-events.mjs +96 -0
  89. package/scripts/claude-hooks/_guardrail-loader.mjs +494 -0
  90. package/scripts/claude-hooks/_intent-classifier-router.mjs +410 -0
  91. package/scripts/claude-hooks/_intent-classifier-semantic.mjs +351 -0
  92. package/scripts/claude-hooks/_run.mjs +120 -0
  93. package/scripts/claude-hooks/_transcript-text.mjs +60 -0
  94. package/scripts/claude-hooks/_vault-retrieval.mjs +322 -0
  95. package/scripts/claude-hooks/agent-spawn-delegation-gate.mjs +133 -0
  96. package/scripts/claude-hooks/capture-workflow-gate.mjs +11 -0
  97. package/scripts/claude-hooks/check-auto-memory-budget.mjs +396 -0
  98. package/scripts/claude-hooks/check-claude-md-budget.mjs +327 -0
  99. package/scripts/claude-hooks/check-mcp-freshness-hook.mjs +14 -0
  100. package/scripts/claude-hooks/claim-before-code-gate.mjs +11 -0
  101. package/scripts/claude-hooks/claim-liveness-shared.mjs +575 -0
  102. package/scripts/claude-hooks/close-terminal-on-ship.mjs +64 -0
  103. package/scripts/claude-hooks/coo-denylist-gate.mjs +11 -0
  104. package/scripts/claude-hooks/coo-guard-check.mjs +11 -0
  105. package/scripts/claude-hooks/deep-research-cost-gate.mjs +11 -0
  106. package/scripts/claude-hooks/dev-server-task-reminder.mjs +15 -0
  107. package/scripts/claude-hooks/emit-claim-status.mjs +41 -0
  108. package/scripts/claude-hooks/enforce-session-sequence.mjs +11 -0
  109. package/scripts/claude-hooks/enforce-vault-naming.mjs +11 -0
  110. package/scripts/claude-hooks/env-vault-guard.mjs +11 -0
  111. package/scripts/claude-hooks/epic-milestone-phrasing-gate.mjs +11 -0
  112. package/scripts/claude-hooks/git-identity-guard.mjs +11 -0
  113. package/scripts/claude-hooks/git-reflog-audit.mjs +15 -0
  114. package/scripts/claude-hooks/git-stash-gate.mjs +11 -0
  115. package/scripts/claude-hooks/guard-auto-memory-writes.mjs +137 -0
  116. package/scripts/claude-hooks/id-display-format-gate.mjs +11 -0
  117. package/scripts/claude-hooks/inject-communication-style.mjs +66 -0
  118. package/scripts/claude-hooks/inject-coo-seat.mjs +78 -0
  119. package/scripts/claude-hooks/inject-dev-server-awareness.mjs +11 -0
  120. package/scripts/claude-hooks/inject-doctrine.mjs +13 -0
  121. package/scripts/claude-hooks/inject-vault-context.mjs +14 -0
  122. package/scripts/claude-hooks/intent-classifier-trigger.mjs +247 -0
  123. package/scripts/claude-hooks/log-session-activity.mjs +341 -0
  124. package/scripts/claude-hooks/naughty-list-gate.mjs +11 -0
  125. package/scripts/claude-hooks/notify-status-flip.mjs +72 -0
  126. package/scripts/claude-hooks/plan-exit-ingest-gate.mjs +170 -0
  127. package/scripts/claude-hooks/plan-ingest-close-reminder.mjs +66 -0
  128. package/scripts/claude-hooks/plan-review-gate.mjs +11 -0
  129. package/scripts/claude-hooks/preflight-reminder.mjs +262 -0
  130. package/scripts/claude-hooks/protected-action-intent.mjs +221 -0
  131. package/scripts/claude-hooks/research-method-guard.mjs +398 -0
  132. package/scripts/claude-hooks/research-protocol-gate.mjs +11 -0
  133. package/scripts/claude-hooks/session-end.mjs +449 -0
  134. package/scripts/claude-hooks/settings-write-gate.mjs +11 -0
  135. package/scripts/claude-hooks/settlement-check-gate.mjs +39 -0
  136. package/scripts/claude-hooks/status-flip-detect.mjs +17 -0
  137. package/scripts/claude-hooks/terminal-close-shared.mjs +426 -0
  138. package/scripts/claude-hooks/terminal-close-watcher.mjs +122 -0
  139. package/scripts/claude-hooks/wip-checkpoint.mjs +298 -0
  140. package/scripts/cursor-hooks/manifest.mjs +235 -0
  141. package/scripts/dev-server-status.mjs +34 -13
  142. package/scripts/dev-server-stop.mjs +313 -0
  143. package/scripts/heyspex-mode.mjs +268 -0
  144. package/scripts/hs-auto-resolve.mjs +240 -0
  145. package/scripts/hs-auto-source.mjs +398 -0
  146. package/scripts/hs-auto.mjs +134 -0
  147. package/scripts/hs-capture-cli.mjs +326 -0
  148. package/scripts/hs-classifier.mjs +136 -0
  149. package/scripts/hs-companion.mjs +88 -0
  150. package/scripts/hs-gateway.mjs +115 -0
  151. package/scripts/hs-mode.mjs +125 -0
  152. package/scripts/hs-next.mjs +441 -0
  153. package/scripts/hs-settings.mjs +338 -0
  154. package/scripts/hs-view.mjs +333 -0
  155. package/scripts/hs-worktree.mjs +201 -0
  156. package/scripts/install-claude-code-hooks.mjs +270 -0
  157. package/scripts/install-cursor-hooks.mjs +471 -0
  158. package/scripts/lib/agent-env-markers.mjs +38 -0
  159. package/scripts/lib/console-url-resolver.mjs +197 -60
  160. package/scripts/lib/customer-kit.mjs +886 -0
  161. package/scripts/lib/dev-mode.mjs +244 -28
  162. package/scripts/lib/heyspex-home.mjs +72 -0
  163. package/scripts/lib/hs-command.mjs +277 -0
  164. package/scripts/lib/hs-companion-settings.mjs +472 -0
  165. package/scripts/lib/hs-source-commit.mjs +59 -5
  166. package/scripts/lib/hs-source-identity.mjs +526 -0
  167. package/scripts/lib/hs-source-log.mjs +11 -21
  168. package/scripts/lib/hs-source-push.mjs +107 -58
  169. package/scripts/lib/hs-worktree-args.mjs +115 -0
  170. package/scripts/lib/shared-path-helpers.mjs +134 -0
  171. package/scripts/lib/standalone-doctor.mjs +540 -3
  172. package/scripts/lib/subagent-git-lock.mjs +109 -0
  173. package/scripts/lib/template-pin.mjs +34 -0
  174. package/scripts/provenance-lib.mjs +91 -0
  175. package/scripts/stamp-provenance-on-edit.mjs +222 -0
  176. package/scripts/wip-ledger-health.mjs +653 -0
  177. package/spexharness/doctrine/baseline/SPEXCODE-DOCTRINE.baseline.json +29 -0
  178. package/spexharness/src/adapters/audit.mjs +197 -0
  179. package/spexharness/src/adapters/claude-code.mjs +441 -0
  180. package/spexharness/src/chat/tui/ansi.mjs +448 -0
  181. package/spexharness/src/chat/tui/palette.mjs +22 -0
  182. package/spexharness/src/chat/tui/select.mjs +208 -0
  183. package/spexharness/src/config-root.mjs +54 -0
  184. package/spexharness/src/context-budget.mjs +141 -0
  185. package/spexharness/src/dev-server-control.mjs +389 -0
  186. package/spexharness/src/doctrine/behaviour.mjs +371 -0
  187. package/spexharness/src/doctrine/corpus.mjs +733 -0
  188. package/spexharness/src/doctrine/inject.mjs +338 -0
  189. package/spexharness/src/doctrine/merge.mjs +184 -0
  190. package/spexharness/src/doctrine/sources.mjs +252 -0
  191. package/spexharness/src/doctrine/synthesize.mjs +401 -0
  192. package/spexharness/src/doctrine/vault-source.mjs +574 -0
  193. package/spexharness/src/doctrine/writer.mjs +176 -0
  194. package/spexharness/src/events.mjs +84 -0
  195. package/spexharness/src/gates/capture-workflow-gate.mjs +202 -0
  196. package/spexharness/src/gates/claim-before-code-gate.decide.mjs +33 -0
  197. package/spexharness/src/gates/claim-before-code-gate.mjs +129 -0
  198. package/spexharness/src/gates/deep-research-cost-gate.mjs +274 -0
  199. package/spexharness/src/gates/enforce-session-sequence.mjs +895 -0
  200. package/spexharness/src/gates/enforce-vault-naming.mjs +215 -0
  201. package/spexharness/src/gates/epic-milestone-phrasing-gate.mjs +233 -0
  202. package/spexharness/src/gates/git-identity-guard.decide.mjs +436 -0
  203. package/spexharness/src/gates/git-identity-guard.mjs +61 -0
  204. package/spexharness/src/gates/git-reflog-audit.mjs +151 -0
  205. package/spexharness/src/gates/git-stash-gate.decide.mjs +361 -0
  206. package/spexharness/src/gates/git-stash-gate.mjs +159 -0
  207. package/spexharness/src/gates/id-display-format-gate.mjs +190 -0
  208. package/spexharness/src/gates/inject-doctrine-gate.mjs +89 -0
  209. package/spexharness/src/gates/inject-vault-context.mjs +239 -0
  210. package/spexharness/src/gates/naughty-list-gate.mjs +213 -0
  211. package/spexharness/src/gates/plan-review-gate.mjs +233 -0
  212. package/spexharness/src/gates/preflight-reminder-gate.mjs +265 -0
  213. package/spexharness/src/gates/research-protocol-gate.mjs +175 -0
  214. package/spexharness/src/gates/settings-write-gate.decide.mjs +96 -0
  215. package/spexharness/src/gates/settings-write-gate.mjs +104 -0
  216. package/spexharness/src/git-reflog-audit.mjs +294 -0
  217. package/spexharness/src/intent-classifier.mjs +194 -0
  218. package/spexharness/src/intent-directive.mjs +541 -0
  219. package/spexharness/src/profile/learn.mjs +551 -0
  220. package/spexharness/src/profile/proposals.mjs +357 -0
  221. package/spexharness/src/profile/vault-inclusion.mjs +386 -0
  222. package/spexharness/src/redact.mjs +151 -0
  223. package/spexharness/src/rule-table.mjs +819 -0
  224. package/spexharness/src/seat-context.mjs +122 -0
  225. package/spexharness/src/session-bootstrap.mjs +512 -0
  226. package/spexharness/src/session-record.mjs +815 -0
  227. package/spexharness/src/token-inventory.mjs +207 -0
  228. package/vendor/heyspex-mcp/account-switch.mjs +95 -0
  229. package/vendor/heyspex-mcp/alignment-gate.mjs +315 -1
  230. package/vendor/heyspex-mcp/blocker-resolver.mjs +37 -2
  231. package/vendor/heyspex-mcp/breakdown-ladder.mjs +119 -4
  232. package/vendor/heyspex-mcp/breakdown-source.mjs +271 -0
  233. package/vendor/heyspex-mcp/breakdown-writer.mjs +23 -3
  234. package/vendor/heyspex-mcp/capture-buffer-patches.mjs +46 -5
  235. package/vendor/heyspex-mcp/capture-channel.mjs +55 -5
  236. package/vendor/heyspex-mcp/capture-console-client.mjs +80 -1
  237. package/vendor/heyspex-mcp/capture-focus.mjs +1035 -29
  238. package/vendor/heyspex-mcp/capture-outbox.mjs +5 -1
  239. package/vendor/heyspex-mcp/capture-tools.mjs +1219 -0
  240. package/vendor/heyspex-mcp/claim-tools.mjs +1124 -0
  241. package/vendor/heyspex-mcp/cli-verbs.mjs +2076 -0
  242. package/vendor/heyspex-mcp/cli.mjs +201 -15524
  243. package/vendor/heyspex-mcp/cloud-tool-surface.mjs +128 -0
  244. package/vendor/heyspex-mcp/cloud-vault-writes.mjs +412 -0
  245. package/vendor/heyspex-mcp/config-seed.yaml +15 -0
  246. package/vendor/heyspex-mcp/config-settings.mjs +290 -7
  247. package/vendor/heyspex-mcp/console-fetch.mjs +657 -16
  248. package/vendor/heyspex-mcp/console-transport.mjs +166 -0
  249. package/vendor/heyspex-mcp/credentials.mjs +584 -0
  250. package/vendor/heyspex-mcp/defer-spec.mjs +44 -4
  251. package/vendor/heyspex-mcp/deferred-reclaim.mjs +29 -3
  252. package/vendor/heyspex-mcp/design-handlers.mjs +31 -0
  253. package/vendor/heyspex-mcp/design-tools.mjs +4 -1
  254. package/vendor/heyspex-mcp/dev-factory-bridge.mjs +4 -4
  255. package/vendor/heyspex-mcp/dev-mode-core.mjs +45 -0
  256. package/vendor/heyspex-mcp/dev-tools.mjs +124 -0
  257. package/vendor/heyspex-mcp/diagnose-handlers.mjs +54 -0
  258. package/vendor/heyspex-mcp/events-tools.mjs +207 -0
  259. package/vendor/heyspex-mcp/filing-tools.mjs +688 -0
  260. package/vendor/heyspex-mcp/fleet-handlers.mjs +37 -0
  261. package/vendor/heyspex-mcp/fleet-queue-tools.mjs +69 -14
  262. package/vendor/heyspex-mcp/focus-tools.mjs +190 -0
  263. package/vendor/heyspex-mcp/folder-trust-store.mjs +59 -0
  264. package/vendor/heyspex-mcp/http-transport.mjs +300 -0
  265. package/vendor/heyspex-mcp/list-tools.mjs +257 -0
  266. package/vendor/heyspex-mcp/login-handoff.mjs +15 -1
  267. package/vendor/heyspex-mcp/mcp-config.mjs +94 -0
  268. package/vendor/heyspex-mcp/memory-tools.mjs +523 -0
  269. package/vendor/heyspex-mcp/mvp-mode.mjs +53 -6
  270. package/vendor/heyspex-mcp/occupied-keys.mjs +141 -0
  271. package/vendor/heyspex-mcp/on-deck-brief.mjs +3360 -0
  272. package/vendor/heyspex-mcp/on-deck-scheduler.mjs +1708 -0
  273. package/vendor/heyspex-mcp/package-root.mjs +32 -0
  274. package/vendor/heyspex-mcp/peer-presence.mjs +8 -1
  275. package/vendor/heyspex-mcp/plan-ground.mjs +621 -652
  276. package/vendor/heyspex-mcp/plan-push.mjs +906 -21
  277. package/vendor/heyspex-mcp/plan-review.mjs +124 -30
  278. package/vendor/heyspex-mcp/preflight-gate.mjs +0 -0
  279. package/vendor/heyspex-mcp/procedure-handlers.mjs +325 -0
  280. package/vendor/heyspex-mcp/procedure-tools.mjs +540 -351
  281. package/vendor/heyspex-mcp/promote-capture.mjs +386 -69
  282. package/vendor/heyspex-mcp/promote-diagnose.mjs +74 -0
  283. package/vendor/heyspex-mcp/promote-research-to-diagnose.mjs +9 -2
  284. package/vendor/heyspex-mcp/promote-research.mjs +660 -53
  285. package/vendor/heyspex-mcp/promotion-helpers.mjs +251 -0
  286. package/vendor/heyspex-mcp/prompts.mjs +1460 -0
  287. package/vendor/heyspex-mcp/read-path.mjs +29 -9
  288. package/vendor/heyspex-mcp/receipt-shape.mjs +146 -0
  289. package/vendor/heyspex-mcp/recipe-handlers.mjs +117 -0
  290. package/vendor/heyspex-mcp/regen-tasks.mjs +210 -3
  291. package/vendor/heyspex-mcp/register-spec.mjs +266 -54
  292. package/vendor/heyspex-mcp/request-context.mjs +59 -0
  293. package/vendor/heyspex-mcp/research-focus.mjs +207 -4
  294. package/vendor/heyspex-mcp/research-handlers.mjs +623 -0
  295. package/vendor/heyspex-mcp/research-tools.mjs +4 -4
  296. package/vendor/heyspex-mcp/response-budget.mjs +348 -0
  297. package/vendor/heyspex-mcp/review-focus.mjs +25 -1
  298. package/vendor/heyspex-mcp/search-specs.mjs +280 -0
  299. package/vendor/heyspex-mcp/seat-block-ledger.mjs +113 -0
  300. package/vendor/heyspex-mcp/seat-identity.mjs +2 -6
  301. package/vendor/heyspex-mcp/session-owner.mjs +108 -0
  302. package/vendor/heyspex-mcp/session-tools.mjs +152 -0
  303. package/vendor/heyspex-mcp/settings-registry.mjs +232 -0
  304. package/vendor/heyspex-mcp/settings-tools.mjs +85 -12
  305. package/vendor/heyspex-mcp/spec-edit-tools.mjs +446 -0
  306. package/vendor/heyspex-mcp/spec-id-lib.mjs +93 -17
  307. package/vendor/heyspex-mcp/split-research.mjs +301 -56
  308. package/vendor/heyspex-mcp/stdio-rpc.mjs +22 -0
  309. package/vendor/heyspex-mcp/submit-for-review.mjs +132 -6
  310. package/vendor/heyspex-mcp/summary-contract.mjs +105 -0
  311. package/vendor/heyspex-mcp/summary-write-tools.mjs +224 -0
  312. package/vendor/heyspex-mcp/symptom-query.mjs +146 -0
  313. package/vendor/heyspex-mcp/test-helpers.mjs +108 -1
  314. package/vendor/heyspex-mcp/tool-catalog.mjs +2813 -0
  315. package/vendor/heyspex-mcp/tool-dispatch.mjs +639 -0
  316. package/vendor/heyspex-mcp/tool-helpers.mjs +325 -0
  317. package/vendor/heyspex-mcp/validate-linkage.mjs +414 -27
  318. package/vendor/heyspex-mcp/vault-io.mjs +724 -0
  319. package/vendor/heyspex-mcp/vault-less-endpoints.mjs +52 -0
  320. package/vendor/heyspex-mcp/vault-resolve.mjs +366 -68
  321. package/vendor/heyspex-mcp/verify-reproduction.mjs +270 -30
  322. package/vendor/heyspex-mcp/whoami.mjs +91 -0
@@ -5,11 +5,9 @@ type: protocol
5
5
  status: open
6
6
  priority: 1
7
7
  scope: vault
8
- owner: pwher
9
- assisted_by:
10
- - Claude Code
11
- created: "2026-06-13"
12
- updated: "2026-06-13"
8
+ owner: TODO — your name/handle
9
+ created: '2026-06-13'
10
+ updated: '2026-06-13'
13
11
  tags:
14
12
  - protocol
15
13
  - spec-filing
@@ -21,29 +19,26 @@ triggers:
21
19
  - file_epic
22
20
  - file_task
23
21
  related:
24
- - "HS-PROTO-spec-hierarchy"
25
- - "[[entity-model]]"
26
- - "HS-YXBD-1EM0-EPIC-canonical-spec-filing-surface-templates"
27
- - "HS-OFUB-CVOB-EPIC-saas-customer-vault-onboarding"
22
+ - '[[entity-model]]'
28
23
  templates:
29
24
  milestone:
30
25
  folder: milestones/
31
- id_format: "HS-MIL-<4+ random alphanumeric>"
26
+ id_format: 'HS-MIL-<4+ random alphanumeric>'
32
27
  parent_kinds: []
33
28
  required_fields: [id, name, summary, type, status, owner, created, updated, epics, target_date]
34
29
  optional_fields: [informed_by, tags, related, what_matters, blast_radius]
35
- schema_source: "specs/entity-model.md §milestone (lines 497–519)"
30
+ schema_source: 'specs/entity-model.md §milestone (lines 497–519)'
36
31
  frontmatter:
37
- id: "{{ID}}"
38
- name: "{{NAME}}"
39
- summary: ""
32
+ id: '{{ID}}'
33
+ name: '{{NAME}}'
34
+ summary: ''
40
35
  type: milestone
41
36
  status: open
42
- owner: "{{OWNER}}"
43
- created: "{{TODAY}}"
44
- updated: "{{TODAY}}"
37
+ owner: '{{OWNER}}'
38
+ created: '{{TODAY}}'
39
+ updated: '{{TODAY}}'
45
40
  epics: []
46
- target_date: ""
41
+ target_date: ''
47
42
  tags:
48
43
  - milestone
49
44
  body_skeleton: |
@@ -69,38 +64,23 @@ templates:
69
64
  <!-- Cross-epic seams at milestone altitude — author at plan ingest ([[spec-hierarchy]] §Expected Breakage). Auto-embedded after H1 by createSpec when omitted; listed here for template parity. -->
70
65
  epic:
71
66
  folder: epics/
72
- id_format: "HS-EPIC-<4+ random alphanumeric>"
67
+ id_format: 'HS-EPIC-<4+ random alphanumeric>'
73
68
  parent_kinds: [milestone]
74
- required_fields:
75
- [id, name, summary, type, status, owner, created, updated, kind, effort, milestone, pillar]
76
- optional_fields:
77
- [
78
- research,
79
- planning_flow,
80
- secondary_pillars,
81
- depends_on,
82
- children,
83
- related,
84
- tags,
85
- requires_user_testing,
86
- derived_from,
87
- alignment_rationale,
88
- affects_paths,
89
- blast_radius,
90
- ]
91
- schema_source: "specs/entity-model.md §epic (lines 455–494; shares the §task base at 392–453)"
69
+ required_fields: [id, name, summary, type, status, owner, created, updated, kind, effort, milestone, pillar]
70
+ optional_fields: [research, planning_flow, secondary_pillars, depends_on, children, related, tags, requires_user_testing, derived_from, alignment_rationale, affects_paths, blast_radius]
71
+ schema_source: 'specs/entity-model.md §epic (lines 455–494; shares the §task base at 392–453)'
92
72
  frontmatter:
93
- id: "{{ID}}"
94
- name: "{{NAME}}"
95
- summary: ""
73
+ id: '{{ID}}'
74
+ name: '{{NAME}}'
75
+ summary: ''
96
76
  type: epic
97
77
  status: open
98
78
  kind: feature
99
79
  effort: 3
100
- owner: "{{OWNER}}"
101
- created: "{{TODAY}}"
102
- updated: "{{TODAY}}"
103
- milestone: "{{PARENT_ID}}"
80
+ owner: '{{OWNER}}'
81
+ created: '{{TODAY}}'
82
+ updated: '{{TODAY}}'
83
+ milestone: '{{PARENT_ID}}'
104
84
  children: []
105
85
  tags: []
106
86
  body_skeleton: |
@@ -133,42 +113,23 @@ templates:
133
113
  ## Change log
134
114
  task:
135
115
  folder: tasks/
136
- id_format: "HS-TASK-<4+ random alphanumeric>"
116
+ id_format: 'HS-TASK-<4+ random alphanumeric>'
137
117
  parent_kinds: [epic, task]
138
118
  required_fields: [id, name, summary, type, status, owner, created, updated, kind, effort]
139
- optional_fields:
140
- [
141
- parent,
142
- depends_on,
143
- blocks,
144
- related,
145
- children,
146
- tags,
147
- requires_user_testing,
148
- assignee,
149
- affects_paths,
150
- target,
151
- test,
152
- suggested_model,
153
- suggested_machine,
154
- recommended_num_ctx,
155
- estimated_context_tokens,
156
- context_files,
157
- fit_assessment,
158
- ]
159
- schema_source: "specs/entity-model.md §task (lines 392–453)"
119
+ optional_fields: [parent, depends_on, blocks, related, children, tags, requires_user_testing, assignee, affects_paths, target, test, suggested_model, suggested_machine, recommended_num_ctx, estimated_context_tokens, context_files, fit_assessment]
120
+ schema_source: 'specs/entity-model.md §task (lines 392–453)'
160
121
  frontmatter:
161
- id: "{{ID}}"
162
- name: "{{NAME}}"
163
- summary: ""
122
+ id: '{{ID}}'
123
+ name: '{{NAME}}'
124
+ summary: ''
164
125
  type: task
165
126
  status: open
166
127
  kind: feature
167
128
  effort: 3
168
- owner: "{{OWNER}}"
169
- created: "{{TODAY}}"
170
- updated: "{{TODAY}}"
171
- parent: "{{PARENT_ID}}"
129
+ owner: '{{OWNER}}'
130
+ created: '{{TODAY}}'
131
+ updated: '{{TODAY}}'
132
+ parent: '{{PARENT_ID}}'
172
133
  tags:
173
134
  - near-term
174
135
  body_skeleton: |
@@ -203,31 +164,19 @@ templates:
203
164
  ## References
204
165
  research:
205
166
  folder: research/
206
- id_format: "HS-RES-<NNN> (zero-padded numeric, server auto-increments)"
167
+ id_format: 'HS-RES-<NNN> (zero-padded numeric, server auto-increments)'
207
168
  parent_kinds: []
208
169
  required_fields: [id, name, type, status, owner, created, updated]
209
- optional_fields:
210
- [
211
- enhances,
212
- sources_captures,
213
- spawned_epics,
214
- enhances_epics,
215
- split_into,
216
- split_from,
217
- planning_flow,
218
- bound_epic,
219
- tags,
220
- related,
221
- ]
222
- schema_source: "specs/entity-model.md §research (lines 761–793)"
170
+ optional_fields: [enhances, sources_captures, spawned_epics, enhances_epics, split_into, split_from, planning_flow, bound_epic, tags, related]
171
+ schema_source: 'specs/entity-model.md §research (lines 761–793)'
223
172
  frontmatter:
224
- id: "{{ID}}"
225
- name: "{{NAME}}"
173
+ id: '{{ID}}'
174
+ name: '{{NAME}}'
226
175
  type: research
227
176
  status: open
228
- owner: "{{OWNER}}"
229
- created: "{{TODAY}}"
230
- updated: "{{TODAY}}"
177
+ owner: '{{OWNER}}'
178
+ created: '{{TODAY}}'
179
+ updated: '{{TODAY}}'
231
180
  tags:
232
181
  - research
233
182
  body_skeleton: |
@@ -247,21 +196,21 @@ templates:
247
196
  ## Sources
248
197
  memory-lesson:
249
198
  folder: memory/lessons/
250
- id_format: "HS-LES-<slug>"
199
+ id_format: 'HS-LES-<slug>'
251
200
  parent_kinds: []
252
201
  required_fields: [id, name, type, status, owner, created, updated, topic, observed]
253
202
  optional_fields: [related, evidence, tags]
254
- schema_source: "specs/entity-model.md §memory-lesson (lines 604–615)"
203
+ schema_source: 'specs/entity-model.md §memory-lesson (lines 604–615)'
255
204
  frontmatter:
256
- id: "{{ID}}"
257
- name: "{{NAME}}"
205
+ id: '{{ID}}'
206
+ name: '{{NAME}}'
258
207
  type: memory-lesson
259
208
  status: open
260
- owner: "{{OWNER}}"
261
- created: "{{TODAY}}"
262
- updated: "{{TODAY}}"
263
- topic: "{{SLUG}}"
264
- observed: "{{TODAY}}"
209
+ owner: '{{OWNER}}'
210
+ created: '{{TODAY}}'
211
+ updated: '{{TODAY}}'
212
+ topic: '{{SLUG}}'
213
+ observed: '{{TODAY}}'
265
214
  body_skeleton: |
266
215
  # {{NAME}}
267
216
 
@@ -270,23 +219,23 @@ templates:
270
219
  ## Fix
271
220
  memory-decision:
272
221
  folder: memory/decisions/
273
- id_format: "HS-DEC-<slug>"
222
+ id_format: 'HS-DEC-<slug>'
274
223
  parent_kinds: []
275
224
  required_fields: [id, name, type, status, owner, created, updated, topic, decided, deciders]
276
225
  optional_fields: [supersedes, evidence, related, tags]
277
- schema_source: "specs/entity-model.md §memory-decision (lines 617–629)"
226
+ schema_source: 'specs/entity-model.md §memory-decision (lines 617–629)'
278
227
  frontmatter:
279
- id: "{{ID}}"
280
- name: "{{NAME}}"
228
+ id: '{{ID}}'
229
+ name: '{{NAME}}'
281
230
  type: memory-decision
282
231
  status: open
283
- owner: "{{OWNER}}"
284
- created: "{{TODAY}}"
285
- updated: "{{TODAY}}"
286
- topic: "{{SLUG}}"
287
- decided: "{{TODAY}}"
232
+ owner: '{{OWNER}}'
233
+ created: '{{TODAY}}'
234
+ updated: '{{TODAY}}'
235
+ topic: '{{SLUG}}'
236
+ decided: '{{TODAY}}'
288
237
  deciders:
289
- - "{{OWNER}}"
238
+ - '{{OWNER}}'
290
239
  body_skeleton: |
291
240
  # {{NAME}}
292
241
 
@@ -295,41 +244,41 @@ templates:
295
244
  ## Rationale
296
245
  memory-reference:
297
246
  folder: memory/references/
298
- id_format: "HS-REF-<slug>"
247
+ id_format: 'HS-REF-<slug>'
299
248
  parent_kinds: []
300
249
  required_fields: [id, name, type, status, owner, created, updated, topic]
301
250
  optional_fields: [url, evidence, related, tags]
302
- schema_source: "specs/entity-model.md §memory-reference (lines 631–641)"
251
+ schema_source: 'specs/entity-model.md §memory-reference (lines 631–641)'
303
252
  frontmatter:
304
- id: "{{ID}}"
305
- name: "{{NAME}}"
253
+ id: '{{ID}}'
254
+ name: '{{NAME}}'
306
255
  type: memory-reference
307
256
  status: open
308
- owner: "{{OWNER}}"
309
- created: "{{TODAY}}"
310
- updated: "{{TODAY}}"
311
- topic: "{{SLUG}}"
257
+ owner: '{{OWNER}}'
258
+ created: '{{TODAY}}'
259
+ updated: '{{TODAY}}'
260
+ topic: '{{SLUG}}'
312
261
  body_skeleton: |
313
262
  # {{NAME}}
314
263
 
315
264
  Brief context for why this reference matters.
316
265
  memory-ui-pattern:
317
266
  folder: memory/ui-patterns/
318
- id_format: "HS-UIP-<slug>"
267
+ id_format: 'HS-UIP-<slug>'
319
268
  parent_kinds: []
320
269
  required_fields: [id, name, type, status, owner, created, updated, topic, documented]
321
270
  optional_fields: [related, evidence, tags]
322
- schema_source: "specs/entity-model.md §memory-ui-pattern (lines 643–653)"
271
+ schema_source: 'specs/entity-model.md §memory-ui-pattern (lines 643–653)'
323
272
  frontmatter:
324
- id: "{{ID}}"
325
- name: "{{NAME}}"
273
+ id: '{{ID}}'
274
+ name: '{{NAME}}'
326
275
  type: memory-ui-pattern
327
276
  status: open
328
- owner: "{{OWNER}}"
329
- created: "{{TODAY}}"
330
- updated: "{{TODAY}}"
331
- topic: "{{SLUG}}"
332
- documented: "{{TODAY}}"
277
+ owner: '{{OWNER}}'
278
+ created: '{{TODAY}}'
279
+ updated: '{{TODAY}}'
280
+ topic: '{{SLUG}}'
281
+ documented: '{{TODAY}}'
333
282
  body_skeleton: |
334
283
  # {{NAME}}
335
284
 
@@ -342,21 +291,21 @@ templates:
342
291
  ## Implementation
343
292
  review:
344
293
  folder: reviews/
345
- id_format: "HS-REV-<parent-suffix> (suffix = parent id segment [2]; slug rides only in the filename)"
294
+ id_format: 'HS-REV-<parent-suffix> (suffix = parent id segment [2]; slug rides only in the filename)'
346
295
  parent_kinds: [task, epic, milestone]
347
296
  required_fields: [id, name, type, status, owner, created, updated, parent]
348
297
  optional_fields: [reviews, deliberation_record]
349
- schema_source: "specs/entity-model.md §review (lines 679–705)"
298
+ schema_source: 'specs/entity-model.md §review (lines 679–705)'
350
299
  frontmatter:
351
- id: "{{ID}}"
352
- name: "{{NAME}}"
300
+ id: '{{ID}}'
301
+ name: '{{NAME}}'
353
302
  type: review
354
303
  status: open
355
- owner: "{{OWNER}}"
356
- created: "{{TODAY}}"
357
- updated: "{{TODAY}}"
358
- parent: "{{PARENT_ID}}"
359
- reviews: "{{PARENT_ID}}"
304
+ owner: '{{OWNER}}'
305
+ created: '{{TODAY}}'
306
+ updated: '{{TODAY}}'
307
+ parent: '{{PARENT_ID}}'
308
+ reviews: '{{PARENT_ID}}'
360
309
  body_skeleton: |
361
310
  # Review — {{NAME}}
362
311
 
@@ -372,37 +321,20 @@ templates:
372
321
  ## Decision: close or reopen
373
322
  agent:
374
323
  folder: agents/
375
- id_format: "HS-AGENT-<4+ random alphanumeric>"
324
+ id_format: 'HS-AGENT-<4+ random alphanumeric>'
376
325
  parent_kinds: []
377
326
  required_fields: [id, name, type, status, owner, created, updated, role]
378
- optional_fields:
379
- [
380
- description,
381
- goal,
382
- model,
383
- allowed_tools,
384
- disallowed_tools,
385
- procedures,
386
- handoffs,
387
- guardrails,
388
- lane,
389
- isolation,
390
- color,
391
- owned_paths,
392
- source_attribution,
393
- related,
394
- tags,
395
- ]
396
- schema_source: "specs/entity-model.md §agent"
327
+ optional_fields: [description, goal, model, allowed_tools, disallowed_tools, procedures, handoffs, guardrails, lane, isolation, color, owned_paths, source_attribution, related, tags]
328
+ schema_source: 'specs/entity-model.md §agent'
397
329
  frontmatter:
398
- id: "{{ID}}"
399
- name: "{{NAME}}"
330
+ id: '{{ID}}'
331
+ name: '{{NAME}}'
400
332
  type: agent
401
333
  status: open
402
- owner: "{{OWNER}}"
403
- role: "{{NAME}}"
404
- created: "{{TODAY}}"
405
- updated: "{{TODAY}}"
334
+ owner: '{{OWNER}}'
335
+ role: '{{NAME}}'
336
+ created: '{{TODAY}}'
337
+ updated: '{{TODAY}}'
406
338
  owned_paths: []
407
339
  tags:
408
340
  - agent
@@ -420,19 +352,19 @@ templates:
420
352
  ## Guardrails
421
353
  pillar:
422
354
  folder: pillars/
423
- id_format: "HS-PILR-<slug> (slug-only; owner-curated canonical pillars share id == basename)"
355
+ id_format: 'HS-PILR-<slug> (slug-only; owner-curated canonical pillars share id == basename)'
424
356
  parent_kinds: []
425
357
  required_fields: [id, name, type, status, owner, created, updated, canonical, secondary_pillars]
426
358
  optional_fields: [library_tier, version, last_edited_at, related, tags]
427
- schema_source: "specs/entity-model.md §pillar"
359
+ schema_source: 'specs/entity-model.md §pillar'
428
360
  frontmatter:
429
- id: "{{ID}}"
430
- name: "{{NAME}}"
361
+ id: '{{ID}}'
362
+ name: '{{NAME}}'
431
363
  type: pillar
432
364
  status: perpetual
433
- owner: "{{OWNER}}"
434
- created: "{{TODAY}}"
435
- updated: "{{TODAY}}"
365
+ owner: '{{OWNER}}'
366
+ created: '{{TODAY}}'
367
+ updated: '{{TODAY}}'
436
368
  canonical: true
437
369
  secondary_pillars: []
438
370
  tags:
@@ -449,6 +381,7 @@ templates:
449
381
  ## Through-line across milestones
450
382
  summary: |
451
383
  Canonical copy-paste frontmatter templates for every vault entity kind (milestone, epic, task, review) with required fields, optional fields, and body skeletons; the source of truth for heyspex_file_spec and POST /api/specs.
384
+
452
385
  ---
453
386
 
454
387
  # Canonical frontmatter templates per entity kind
@@ -515,7 +448,7 @@ Slug id (`HS-UIP-<slug>`). Required: `topic` + `documented`. Reusable console in
515
448
  ## Out of scope
516
449
 
517
450
  - **Captures (`type: capture`).** Session-based — driven by `heyspex_active_capture` / `heyspex_update_capture` with `content_buffer` patching, focus pinning, and multi-message accumulation, none of which a single template stamp can represent. `POST /api/specs` rejects `type: capture` with a 400 pointing at the capture flow (user-memory `feedback_capture_workflow_for_captures`).
518
- - **L1 / ADR / planning-flow / branch-brief / business-\* kinds.** Filed through their own dedicated flows; their schemas live in [[entity-model]] but are not part of the universal filing surface this protocol backs. (Pillars are now part of this surface — see the `pillar` template above.)
451
+ - **L1 / ADR / planning-flow / branch-brief / business-* kinds.** Filed through their own dedicated flows; their schemas live in [[entity-model]] but are not part of the universal filing surface this protocol backs. (Pillars are now part of this surface — see the `pillar` template above.)
519
452
 
520
453
  ## Drift gate
521
454
 
@@ -523,9 +456,9 @@ Adding or removing a kind here changes the file, so `npm run build:procedure-cat
523
456
 
524
457
  ## Change log
525
458
 
526
- | Date | Author | Change |
527
- | ---------- | --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
528
- | 2026-06-13 | pwher (with Claude Opus 4.8) | Filed as the canonical, fetchable home for per-kind frontmatter templates. |
529
- | 2026-06-21 | Claude Code · claude-sonnet-4-6 (with pwher) | Moved `summary` from `optional_fields` into `required_fields` and added `summary: ''` to the frontmatter stamp for milestone, epic, and task. Root cause: the stamp for these three kinds did not include a `summary:` placeholder, so agents and automated flows (e.g. promote-research) that stamp from the template produced specs with no summary field and no visible prompt to fill one in. Matching the spec-summary-authoring policy that summary is an authoring step of filing, not an optional afterthought. |
530
- | 2026-06-23 | Cursor · session `local` | Added `agent` template with `owned_paths:`; `affects_paths` on epic/task optional_fields. Per HS-ZMAQ-M15C-TASK-declare-owned-path-globs-on-agent-identi. |
459
+ | Date | Author | Change |
460
+ |---|---|---|
461
+ | 2026-06-13 | pwher (with Claude Opus 4.8) | Filed as the canonical, fetchable home for per-kind frontmatter templates. |
462
+ | 2026-06-21 | Claude Code · claude-sonnet-4-6 (with pwher) | Moved `summary` from `optional_fields` into `required_fields` and added `summary: ''` to the frontmatter stamp for milestone, epic, and task. Root cause: the stamp for these three kinds did not include a `summary:` placeholder, so agents and automated flows (e.g. promote-research) that stamp from the template produced specs with no summary field and no visible prompt to fill one in. Matching the [[spec-summary-authoring]] policy that summary is an authoring step of filing, not an optional afterthought. |
463
+ | 2026-06-23 | Cursor · session `local` | Added `agent` template with `owned_paths:`; `affects_paths` on epic/task optional_fields. Per HS-ZMAQ-M15C-TASK-declare-owned-path-globs-on-agent-identi. |
531
464
  | 2026-06-25 | Claude Opus 4.8 [1m] · session `local` (with pwher) | Added the **intended-outcome cascade** section to the `body_skeleton` of research (`## Conclusion & intended outcome`), milestone, epic, and task (`## Intended outcome`). Each level **re-derives** the parent's outcome (translate, don't copy) and names its **mechanism of contribution** + an explicit ↑ link; the task-level outcome is expressed as monitorable+controllable conditions that seed `## Acceptance criteria`. Grounded in HS-K4D4-2I29-RES-outcome-cascade-through-a-requirements-h (GORE/KAOS HOW-down/WHY-up refinement + OKR translation-not-cascade). Companion edits: `research-capture-protocol`, `spec-hierarchy`, `plan-ingest-agent-workflow`, and the `promote-capture.mjs` / `promote-research.mjs` / task materializers. Owner-directed. Re-run `npm run build:procedure-catalog`. |
@@ -0,0 +1,122 @@
1
+ ---
2
+ id: HS-PROTO-destructive-action-checklist
3
+ name: Destructive Action Checklist (UI + API gate)
4
+ type: protocol
5
+ scope: agent-workflow
6
+ version: 1.0
7
+ status: open
8
+ priority: 0
9
+ owner: TODO — your name/handle
10
+ created: 2026-05-22
11
+ updated: 2026-08-25
12
+ tags:
13
+ - "protocol"
14
+ - "ui"
15
+ - "ux"
16
+ - "data-loss"
17
+ - "destructive"
18
+ - "console"
19
+ triggers:
20
+ - destructive_action
21
+ summary: |
22
+ Walk before merging any code that can destroy user data: explicit danger-styled button, soft-delete to .trash/ instead of permanent deletion, and a real Undo notification with a time-limited commit. Close is not the same as destroy.
23
+
24
+ ---
25
+
26
+ # Destructive Action Checklist
27
+
28
+ **Scope note:** this checklist covers screen actions — UI + API surfaces that can destroy
29
+ user data (delete spec, archive, discard buffer). Git tree actions on a shared checkout
30
+ (stash, `reset --hard`, `clean -f`, `checkout .`, `restore`, `rebase`, `push --force`,
31
+ `branch -D`, `commit --amend`) are gated in protected-shared-actions-gate — don't
32
+ duplicate that ground here.
33
+
34
+ **Run this before merging any PR that adds, changes, or routes an action
35
+ that can destroy user data** (delete spec, archive, unpin, discard buffer,
36
+ hard-revert, etc.). Pinning, hiding, or marking "closed" are non-destructive
37
+ and do not require this checklist.
38
+
39
+ Acceptance: every box ticked, or an inline `dismissed because <reason>`
40
+ note for any box that genuinely does not apply.
41
+
42
+ ## Why this exists
43
+
44
+ A past idea-discard data-loss incident showed that strong UX *principles*
45
+ (recoverable destructive actions, reversible user actions) are not
46
+ enough — they only prevent data loss if recalled and applied during
47
+ implementation. This protocol turns the principles into an enforceable
48
+ checklist that lives in the PR template / `npm run validate:*` and that
49
+ agents must walk before claiming a destructive-action task done.
50
+
51
+ ## Memory recall (before writing code)
52
+
53
+ - [ ] `heyspex_recall_memories({ tags: ["destructive"] })`
54
+ - [ ] `heyspex_recall_memories({ tags: ["ux", "ux-principle"] })`
55
+ - [ ] Read any vault memories on destructive-action recovery and Undo.
56
+
57
+ ## UI affordances
58
+
59
+ - [ ] **Explicit Discard / Delete / Archive button** — labeled with the
60
+ action verb, styled with `var(--danger)`, positioned away from the
61
+ primary CTA.
62
+ - [ ] **Close ≠ Destroy.** Backdrop click, Esc, header X, "Close", and
63
+ "Cancel" all just dismiss the surface. None of them route into a
64
+ confirmation flow whose primary button is destructive.
65
+ - [ ] **Confirm dialog has a safe default.** The cancel/keep-editing button
66
+ is default-focused, visually primary, and is not the same control
67
+ that would also destroy on a second press.
68
+ - [ ] **Confirm copy says what happens and where it goes.** Mentions the
69
+ trash location and the Undo affordance ("recoverable from the Undo
70
+ toast that follows").
71
+ - [ ] **Unsaved-changes warning** when closing a dirty editor — separate
72
+ flow from discard. (Not covered here.)
73
+
74
+ ## API + filesystem
75
+
76
+ - [ ] **Soft-delete only.** Server moves bytes to
77
+ `<folder>/.trash/<iso-stamp>-<basename>.<ext>` via `fs.rename`.
78
+ No `fs.unlink`, `fs.rm`, or equivalent on user data from a request
79
+ handler.
80
+ - [ ] **DELETE response includes restore info** — `{ trashPath,
81
+ originalRelPath }` (or analogous fields) so the UI can wire Undo.
82
+ - [ ] **Restore endpoint exists** — POST/PUT that validates both paths
83
+ resolve inside the vault root, refuses to overwrite an existing
84
+ file, and `fs.rename`s back.
85
+ - [ ] **Index ignores trash.** Confirm `walkMarkdown` (or equivalent
86
+ indexer) skips `.trash/` so trashed files don't reappear as ghosts.
87
+
88
+ ## Undo path
89
+
90
+ - [ ] **Undo toast** with a labeled action button (not just a "Deleted"
91
+ confirmation), held ≥ 8 seconds.
92
+ - [ ] **Undo actually calls restore endpoint** — wired end-to-end, tested
93
+ manually at least once.
94
+ - [ ] **Restore dispatches the same `heyspex:spec-updated` event** that
95
+ external watchers listen for, so list views refresh.
96
+
97
+ ## Tests / verification
98
+
99
+ - [ ] Manual: open the surface, perform the destructive action, click
100
+ Undo in the toast, confirm the file is back at its original path.
101
+ - [ ] Manual: open the surface, click backdrop / Esc / Close / Cancel —
102
+ confirm none of these prompt for or perform deletion.
103
+ - [ ] Optional unit test if the project has them: assert `deleteSpec`
104
+ moves to `.trash/` and `restoreSpecFromTrash` round-trips.
105
+
106
+ ## After merge
107
+
108
+ - [ ] Capture any new gotchas as a `memory-lesson` linked to this
109
+ protocol.
110
+ - [ ] If a *new* destructive surface is introduced, record it in a vault memory.
111
+
112
+ ## How this gate gets enforced
113
+
114
+ Today: agents must
115
+ walk it before marking the spec `in_review`. The reviewer ticks each box
116
+ in the spec's `.review.md`.
117
+
118
+ Future automation candidates:
119
+
120
+ - ESLint rule banning `fs.unlink`/`fs.rm` in `src/app/api/**`.
121
+ - PR template line: "Destructive action? Walk
122
+ [[destructive-action-checklist]] before requesting review."
@@ -4,9 +4,9 @@ name: Memory Protocol
4
4
  type: protocol
5
5
  status: open
6
6
  priority: 1
7
- owner: pwher
8
- created: "2026-05-14T22:47:28-05:00"
9
- updated: "2026-05-18T19:49:25-05:00"
7
+ owner: TODO — your name/handle
8
+ created: '2026-05-14T22:47:28-05:00'
9
+ updated: '2026-05-18T19:49:25-05:00'
10
10
  scope: vault
11
11
  legacy_bd_key: memory-protocol
12
12
  tags:
@@ -20,29 +20,27 @@ triggers:
20
20
  - close_session
21
21
  summary: |
22
22
  Defines the four vault memory subsections (lessons, decisions, references, ui-patterns) and their folder layout. Authoritative rule on when to capture institutional knowledge and how to link it back to the specs it bears on.
23
- related:
24
- - "HS-T4P3-7VZH-RES-governing-an-unmanaged-891-file-memory"
25
23
  ---
26
24
 
27
25
  # Memory Protocol
28
26
 
29
27
  HeySpex Memory layer (see memory-protocols-subsection-of-memory):
30
28
 
31
- | Subsection | Entity type | Folder |
32
- | ---------- | ------------------ | -------------------------- |
33
- | Lessons | `memory-lesson` | `specs/memory/lessons/` |
34
- | Decisions | `memory-decision` | `specs/memory/decisions/` |
29
+ | Subsection | Entity type | Folder |
30
+ | --- | --- | --- |
31
+ | Lessons | `memory-lesson` | `specs/memory/lessons/` |
32
+ | Decisions | `memory-decision` | `specs/memory/decisions/` |
35
33
  | References | `memory-reference` | `specs/memory/references/` |
36
- | Protocols | `protocol` | `specs/protocols/` |
34
+ | Protocols | `protocol` | `specs/protocols/` |
37
35
 
38
- Legacy bd v1 also used `goals/<scope>` — migrated to `memory-reference` where appropriate. Epics/tasks that _create_ protocols are not `type: protocol`.
36
+ Legacy bd v1 also used `goals/<scope>` — migrated to `memory-reference` where appropriate. Epics/tasks that *create* protocols are not `type: protocol`.
39
37
 
40
38
  Historical bd commands (`bd-lesson`, `bd-decision`, …) are retired; use vault files + `hs remember` / `hs prime` per HS-DOC-architecture-foundations.
41
39
 
42
40
  ## Change log
43
41
 
44
- | Date | Author | Change |
45
- | ---------- | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
46
- | 2026-05-14 | pwher (migrator) | Migrated from bd memory `memory-protocol`. |
42
+ | Date | Author | Change |
43
+ | --- | --- | --- |
44
+ | 2026-05-14 | pwher (migrator) | Migrated from bd memory `memory-protocol`. |
47
45
  | 2026-05-14 | pwher (with claude opus 4.7) | Backfilled true date (2026-05-10) for created from `.beads/issues.jsonl` git history; previously the migration-date placeholder. |
48
- | 2026-05-18 | pwher (with claude) | Body updated for HeySpex four Memory subsections including protocols (memory-protocols-subsection-of-memory). |
46
+ | 2026-05-18 | pwher (with claude) | Body updated for HeySpex four Memory subsections including protocols (memory-protocols-subsection-of-memory). |