heyspex 0.2.5 → 0.2.7

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 (110) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/bin/hs.mjs +349 -38
  3. package/bin/spexcode.mjs +31 -0
  4. package/dev-factory/lib/dispatch-guard.mjs +75 -0
  5. package/dev-factory/lib/local-firecrawl.mjs +294 -0
  6. package/dev-factory/lib/runner-path.mjs +51 -0
  7. package/dev-factory/lib/seat-context.mjs +20 -4
  8. package/dev-factory/model-catalog.json +222 -222
  9. package/dev-factory/spexcrawl/firecrawl-cli.mjs +755 -0
  10. package/dev-factory/spexcrawl/spexcrawl-cli.mjs +734 -0
  11. package/dist/cli/hs-connect.mjs +40 -3
  12. package/dist/cli/hs-defer.mjs +3817 -3741
  13. package/dist/cli/hs-events.mjs +1296 -0
  14. package/dist/cli/hs-export-events.mjs +1252 -0
  15. package/dist/cli/hs-handoff.mjs +2576 -0
  16. package/dist/cli/hs-index-rebuild.mjs +228 -37
  17. package/dist/cli/hs-index-reconcile.mjs +231 -40
  18. package/dist/cli/hs-init.mjs +22 -3
  19. package/dist/cli/hs-install.mjs +22 -3
  20. package/dist/cli/hs-join.mjs +40 -3
  21. package/dist/cli/hs-next-launch.mjs +2777 -0
  22. package/dist/cli/hs-pin.mjs +1336 -0
  23. package/dist/cli/hs-prereq.mjs +1380 -0
  24. package/dist/cli/hs-revalidate.mjs +3257 -0
  25. package/dist/cli/hs-spawn.mjs +12403 -0
  26. package/dist/cli/hs-test.mjs +1046 -0
  27. package/dist/cli/hs-trash.mjs +362 -0
  28. package/dist/cli/hs-trust.mjs +197 -0
  29. package/dist/cli/hs-vault-pull.mjs +233 -42
  30. package/dist/cli/hs-vault-push.mjs +231 -40
  31. package/dist/cli/hs-vault.mjs +21 -7
  32. package/dist/cli/hs-workspace.mjs +19 -1
  33. package/dist/cli-templates/customer-vault/specs/entity-model.md +1728 -1728
  34. package/dist/cli-templates/customer-vault/specs/protocols/canonical-frontmatter-templates.md +464 -464
  35. package/dist/cli-templates/customer-vault/specs/protocols/destructive-action-checklist.md +122 -122
  36. package/dist/cli-templates/customer-vault/specs/protocols/memory-protocol.md +46 -46
  37. package/dist/cli-templates/customer-vault/specs/protocols/spec-hierarchy.md +530 -530
  38. package/dist/cli-templates/customer-vault/specs/protocols/spec-summary-authoring.md +83 -83
  39. package/dist/cli-templates/harness-commands/claude/hs-backfill.md +28 -28
  40. package/dist/cli-templates/harness-commands/claude/hs-capture.md +62 -62
  41. package/dist/cli-templates/harness-commands/claude/hs-defer.md +29 -29
  42. package/dist/cli-templates/harness-commands/claude/hs-ground.md +30 -30
  43. package/dist/cli-templates/harness-commands/claude/hs-next.md +29 -29
  44. package/dist/cli-templates/harness-commands/claude/hs-promote.md +70 -70
  45. package/dist/cli-templates/harness-commands/claude/hs-push.md +35 -35
  46. package/dist/cli-templates/harness-commands/claude/hs-qc.md +27 -27
  47. package/dist/cli-templates/harness-commands/claude/hs-res.md +83 -63
  48. package/dist/cli-templates/harness-commands/claude/hs-resolve.md +23 -23
  49. package/dist/cli-templates/harness-commands/claude/hs-view.md +28 -28
  50. package/dist/cli-templates/harness-commands/claude/kill-ports.md +32 -32
  51. package/dist/cli-templates/harness-commands/claude/prototype.md +91 -91
  52. package/dist/cli-templates/harness-commands/cursor/hs-backfill.md +22 -22
  53. package/dist/cli-templates/harness-commands/cursor/hs-capture.md +56 -56
  54. package/dist/cli-templates/harness-commands/cursor/hs-defer.md +23 -23
  55. package/dist/cli-templates/harness-commands/cursor/hs-ground.md +24 -24
  56. package/dist/cli-templates/harness-commands/cursor/hs-next.md +23 -23
  57. package/dist/cli-templates/harness-commands/cursor/hs-promote.md +64 -64
  58. package/dist/cli-templates/harness-commands/cursor/hs-push.md +29 -29
  59. package/dist/cli-templates/harness-commands/cursor/hs-qc.md +21 -21
  60. package/dist/cli-templates/harness-commands/cursor/hs-res.md +78 -58
  61. package/dist/cli-templates/harness-commands/cursor/hs-resolve.md +17 -17
  62. package/dist/cli-templates/harness-commands/cursor/hs-view.md +23 -23
  63. package/dist/cli-templates/harness-commands/cursor/kill-ports.md +26 -26
  64. package/dist/cli-templates/harness-commands/cursor/prototype.md +86 -86
  65. package/docs/copilot-plugin-install.md +9 -2
  66. package/docs/mcp-client-config.md +6 -0
  67. package/package.json +266 -257
  68. package/plugins/heyspex/.claude-plugin/plugin.json +1 -1
  69. package/plugins/heyspex/.cursor-plugin/plugin.json +1 -1
  70. package/plugins/heyspex/README.md +6 -0
  71. package/plugins/heyspex/bin/launch-mcp.mjs +17 -0
  72. package/plugins/heyspex/hooks/hooks.json +418 -418
  73. package/scripts/claude-hooks/_intent-classifier-semantic.mjs +2 -2
  74. package/scripts/claude-hooks/wip-checkpoint.mjs +17 -2
  75. package/scripts/claude-statusline/statusline-command.mjs +287 -27
  76. package/scripts/hs-companion.mjs +41 -3
  77. package/scripts/install-claude-code-hooks.mjs +104 -3
  78. package/scripts/install-copilot-hooks.mjs +21 -1
  79. package/scripts/install-cursor-hooks.mjs +4 -3
  80. package/scripts/lib/capture-execution-guard.mjs +221 -0
  81. package/scripts/lib/companion-install.mjs +768 -0
  82. package/scripts/lib/customer-kit.mjs +53 -3
  83. package/scripts/lib/hs-companion-settings.mjs +26 -0
  84. package/scripts/lib/hs-source-push.mjs +386 -386
  85. package/scripts/record-grounding.mjs +38 -0
  86. package/spexharness/doctrine/baseline/SPEXCODE-DOCTRINE.baseline.json +29 -29
  87. package/spexharness/src/adapters/copilot-models.mjs +179 -0
  88. package/spexharness/src/adapters/harness-detect.mjs +148 -0
  89. package/spexharness/src/gates/directive-obligation-gate.decide.mjs +132 -132
  90. package/spexharness/src/gates/vault-write-tier-guard.decide.mjs +153 -125
  91. package/spexharness/src/seat-context.mjs +10 -5
  92. package/spexharness/src/session-bootstrap.mjs +6 -3
  93. package/vendor/heyspex-mcp/cli.mjs +6 -1
  94. package/vendor/heyspex-mcp/config-seed.yaml +15 -15
  95. package/vendor/heyspex-mcp/dev-factory-overlay.mjs +142 -0
  96. package/vendor/heyspex-mcp/http-transport.mjs +1 -1
  97. package/vendor/heyspex-mcp/memory-tools.mjs +523 -523
  98. package/vendor/heyspex-mcp/on-deck-scheduler.mjs +1708 -1708
  99. package/vendor/heyspex-mcp/procedure-handlers.mjs +327 -327
  100. package/vendor/heyspex-mcp/procedure-tools.mjs +1209 -1181
  101. package/vendor/heyspex-mcp/research-tools.mjs +22 -2
  102. package/vendor/heyspex-mcp/seat-assign-cli.mjs +242 -0
  103. package/vendor/heyspex-mcp/seat-assignment-rules.mjs +96 -0
  104. package/vendor/heyspex-mcp/seat-assignments-client.mjs +265 -0
  105. package/vendor/heyspex-mcp/seat-defaults-cli.mjs +45 -0
  106. package/vendor/heyspex-mcp/seat-defaults.mjs +232 -0
  107. package/vendor/heyspex-mcp/seat-identity.mjs +171 -0
  108. package/vendor/heyspex-mcp/test-helpers.mjs +37 -23
  109. package/vendor/heyspex-mcp/vault-io.mjs +720 -720
  110. package/bin/postinstall.mjs +0 -88
@@ -1,464 +1,464 @@
1
- ---
2
- id: HS-PROTO-canonical-frontmatter-templates
3
- name: Canonical frontmatter templates per entity kind
4
- type: protocol
5
- status: open
6
- priority: 1
7
- scope: vault
8
- owner: TODO — your name/handle
9
- created: '2026-06-13'
10
- updated: '2026-06-13'
11
- tags:
12
- - protocol
13
- - spec-filing
14
- - canonical-templates
15
- - agent-experience
16
- - frontmatter
17
- triggers:
18
- - file_milestone
19
- - file_epic
20
- - file_task
21
- related:
22
- - '[[entity-model]]'
23
- templates:
24
- milestone:
25
- folder: milestones/
26
- id_format: 'HS-MIL-<4+ random alphanumeric>'
27
- parent_kinds: []
28
- required_fields: [id, name, summary, type, status, owner, created, updated, epics, target_date]
29
- optional_fields: [informed_by, tags, related, what_matters, blast_radius]
30
- schema_source: 'specs/entity-model.md §milestone (lines 497–519)'
31
- frontmatter:
32
- id: '{{ID}}'
33
- name: '{{NAME}}'
34
- summary: ''
35
- type: milestone
36
- status: open
37
- owner: '{{OWNER}}'
38
- created: '{{TODAY}}'
39
- updated: '{{TODAY}}'
40
- epics: []
41
- target_date: ''
42
- tags:
43
- - milestone
44
- body_skeleton: |
45
- # {{NAME}}
46
-
47
- ## Intended outcome
48
-
49
- <!-- Re-derive from the source research's intended outcome — do NOT copy it (HS-K4D4-2I29-RES-outcome-cascade-through-a-requirements-h). -->
50
- **Outcome at the milestone altitude (required):** What outcome does this milestone deliver?
51
-
52
- **Moves (↑ link, required):** Which research/parent outcome does it move — and by what **mechanism of contribution**? (Name the mechanism; don't echo the parent's words.)
53
-
54
- ## Why this is a milestone, not loose epics
55
-
56
- ## Acceptance gate
57
-
58
- ## Suggested landing order
59
-
60
- ## Out of scope
61
-
62
- ## Expected Breakage & Consequences
63
-
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. -->
65
- epic:
66
- folder: epics/
67
- id_format: 'HS-EPIC-<4+ random alphanumeric>'
68
- parent_kinds: [milestone]
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)'
72
- frontmatter:
73
- id: '{{ID}}'
74
- name: '{{NAME}}'
75
- summary: ''
76
- type: epic
77
- status: open
78
- kind: feature
79
- effort: 3
80
- owner: '{{OWNER}}'
81
- created: '{{TODAY}}'
82
- updated: '{{TODAY}}'
83
- milestone: '{{PARENT_ID}}'
84
- children: []
85
- tags: []
86
- body_skeleton: |
87
- # {{NAME}}
88
-
89
- ## Intended outcome
90
-
91
- <!-- Re-derive from the parent milestone's intended outcome — do NOT copy it (HS-K4D4-2I29-RES-outcome-cascade-through-a-requirements-h). -->
92
- **User-visible outcome of this epic (required):** What changes for the user when this epic ships?
93
-
94
- **Moves (↑ link, required):** Which milestone outcome does it move — and by what **mechanism of contribution**?
95
-
96
- ## Expected Breakage & Consequences
97
-
98
- ## Why this epic exists
99
-
100
- <!-- Substantive priority rationale (HS-XMSD). Plain language, no scores. -->
101
- **Problem right now (required):** One sentence — what specific problem does this solve, and why is now (not next cycle) the right time?
102
-
103
- **What this unlocks (required if `kind: infra` or `foundation`):** What future work becomes possible after this ships that isn't possible today?
104
-
105
- **Skip cost (write before pinning this as on-deck):** If we skip this cycle, we lose: …
106
-
107
- **Confidence note (optional):** Flag any part of the rationale above where your confidence is low.
108
-
109
- ## Tasks
110
-
111
- ## Acceptance gate — epic close
112
-
113
- ## Change log
114
- task:
115
- folder: tasks/
116
- id_format: 'HS-TASK-<4+ random alphanumeric>'
117
- parent_kinds: [epic, task]
118
- required_fields: [id, name, summary, type, status, owner, created, updated, kind, effort]
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)'
121
- frontmatter:
122
- id: '{{ID}}'
123
- name: '{{NAME}}'
124
- summary: ''
125
- type: task
126
- status: open
127
- kind: feature
128
- effort: 3
129
- owner: '{{OWNER}}'
130
- created: '{{TODAY}}'
131
- updated: '{{TODAY}}'
132
- parent: '{{PARENT_ID}}'
133
- tags:
134
- - near-term
135
- body_skeleton: |
136
- # {{NAME}}
137
-
138
- ## Intended outcome
139
-
140
- <!-- Re-derive from the parent epic's intended outcome — do NOT copy it (HS-K4D4-2I29-RES-outcome-cascade-through-a-requirements-h). -->
141
- **Observable condition this task produces (required):** What can you monitor and control once this task is done? Express it as a checkable condition — this directly seeds the Acceptance criteria below.
142
-
143
- **Moves (↑ link, required):** Which epic outcome does it move?
144
-
145
- ## Expected Breakage & Consequences
146
-
147
- ## Scope
148
-
149
- ## Acceptance criteria
150
-
151
- <!-- Each criterion is a monitorable + controllable condition derived from the Intended outcome above, traceable ↑ to the epic outcome. -->
152
-
153
- ## Builder brief
154
-
155
- <!-- Fleet dispatch hints for dev-factory (optional until breakdown files the task). Consult builder-fleet-capability-reference. -->
156
- - **Target:** `{{TARGET_OR_TBD}}`
157
- - **Context files:** `path/to/dep.ts`
158
- - **Estimated context:** ~0 tokens
159
- - **recommended_num_ctx:** 65536
160
- - **suggested_model:** `qwen3-coder:30b`
161
- - **suggested_machine:** `specops-gpu0`
162
- - **fit_assessment:** safe
163
-
164
- ## References
165
- research:
166
- folder: research/
167
- id_format: 'HS-RES-<NNN> (zero-padded numeric, server auto-increments)'
168
- parent_kinds: []
169
- required_fields: [id, name, type, status, owner, created, updated]
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)'
172
- frontmatter:
173
- id: '{{ID}}'
174
- name: '{{NAME}}'
175
- type: research
176
- status: open
177
- owner: '{{OWNER}}'
178
- created: '{{TODAY}}'
179
- updated: '{{TODAY}}'
180
- tags:
181
- - research
182
- body_skeleton: |
183
- # {{NAME}}
184
-
185
- ## Executive Summary
186
-
187
- ## Conclusion & intended outcome
188
-
189
- <!-- The root outcome that milestones/epics/tasks spawned from this research refine (translate, don't copy) (HS-K4D4-2I29-RES-outcome-cascade-through-a-requirements-h). -->
190
- **Conclusion (one line):** Acting on this research, what is the conclusion?
191
-
192
- **What acting on this achieves:** What changes for the user or system if we act on it?
193
-
194
- ## Findings
195
-
196
- ## Sources
197
- memory-lesson:
198
- folder: memory/lessons/
199
- id_format: 'HS-LES-<slug>'
200
- parent_kinds: []
201
- required_fields: [id, name, type, status, owner, created, updated, topic, observed]
202
- optional_fields: [related, evidence, tags]
203
- schema_source: 'specs/entity-model.md §memory-lesson (lines 604–615)'
204
- frontmatter:
205
- id: '{{ID}}'
206
- name: '{{NAME}}'
207
- type: memory-lesson
208
- status: open
209
- owner: '{{OWNER}}'
210
- created: '{{TODAY}}'
211
- updated: '{{TODAY}}'
212
- topic: '{{SLUG}}'
213
- observed: '{{TODAY}}'
214
- body_skeleton: |
215
- # {{NAME}}
216
-
217
- ## Problem
218
-
219
- ## Fix
220
- memory-decision:
221
- folder: memory/decisions/
222
- id_format: 'HS-DEC-<slug>'
223
- parent_kinds: []
224
- required_fields: [id, name, type, status, owner, created, updated, topic, decided, deciders]
225
- optional_fields: [supersedes, evidence, related, tags]
226
- schema_source: 'specs/entity-model.md §memory-decision (lines 617–629)'
227
- frontmatter:
228
- id: '{{ID}}'
229
- name: '{{NAME}}'
230
- type: memory-decision
231
- status: open
232
- owner: '{{OWNER}}'
233
- created: '{{TODAY}}'
234
- updated: '{{TODAY}}'
235
- topic: '{{SLUG}}'
236
- decided: '{{TODAY}}'
237
- deciders:
238
- - '{{OWNER}}'
239
- body_skeleton: |
240
- # {{NAME}}
241
-
242
- ## Decision
243
-
244
- ## Rationale
245
- memory-reference:
246
- folder: memory/references/
247
- id_format: 'HS-REF-<slug>'
248
- parent_kinds: []
249
- required_fields: [id, name, type, status, owner, created, updated, topic]
250
- optional_fields: [url, evidence, related, tags]
251
- schema_source: 'specs/entity-model.md §memory-reference (lines 631–641)'
252
- frontmatter:
253
- id: '{{ID}}'
254
- name: '{{NAME}}'
255
- type: memory-reference
256
- status: open
257
- owner: '{{OWNER}}'
258
- created: '{{TODAY}}'
259
- updated: '{{TODAY}}'
260
- topic: '{{SLUG}}'
261
- body_skeleton: |
262
- # {{NAME}}
263
-
264
- Brief context for why this reference matters.
265
- memory-ui-pattern:
266
- folder: memory/ui-patterns/
267
- id_format: 'HS-UIP-<slug>'
268
- parent_kinds: []
269
- required_fields: [id, name, type, status, owner, created, updated, topic, documented]
270
- optional_fields: [related, evidence, tags]
271
- schema_source: 'specs/entity-model.md §memory-ui-pattern (lines 643–653)'
272
- frontmatter:
273
- id: '{{ID}}'
274
- name: '{{NAME}}'
275
- type: memory-ui-pattern
276
- status: open
277
- owner: '{{OWNER}}'
278
- created: '{{TODAY}}'
279
- updated: '{{TODAY}}'
280
- topic: '{{SLUG}}'
281
- documented: '{{TODAY}}'
282
- body_skeleton: |
283
- # {{NAME}}
284
-
285
- ## Pattern
286
-
287
- ## When to apply
288
-
289
- ## Rules
290
-
291
- ## Implementation
292
- review:
293
- folder: reviews/
294
- id_format: 'HS-REV-<parent-suffix> (suffix = parent id segment [2]; slug rides only in the filename)'
295
- parent_kinds: [task, epic, milestone]
296
- required_fields: [id, name, type, status, owner, created, updated, parent]
297
- optional_fields: [reviews, deliberation_record]
298
- schema_source: 'specs/entity-model.md §review (lines 679–705)'
299
- frontmatter:
300
- id: '{{ID}}'
301
- name: '{{NAME}}'
302
- type: review
303
- status: open
304
- owner: '{{OWNER}}'
305
- created: '{{TODAY}}'
306
- updated: '{{TODAY}}'
307
- parent: '{{PARENT_ID}}'
308
- reviews: '{{PARENT_ID}}'
309
- body_skeleton: |
310
- # Review — {{NAME}}
311
-
312
- ## Acceptance verification
313
-
314
- ## Reviewer notes
315
-
316
- ## Memory candidates
317
-
318
- | Candidate | Type | Conflict check | Score | Accept? |
319
- |---|---|---|---|---|
320
-
321
- ## Decision: close or reopen
322
- agent:
323
- folder: agents/
324
- id_format: 'HS-AGENT-<4+ random alphanumeric>'
325
- parent_kinds: []
326
- required_fields: [id, name, type, status, owner, created, updated, role]
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'
329
- frontmatter:
330
- id: '{{ID}}'
331
- name: '{{NAME}}'
332
- type: agent
333
- status: open
334
- owner: '{{OWNER}}'
335
- role: '{{NAME}}'
336
- created: '{{TODAY}}'
337
- updated: '{{TODAY}}'
338
- owned_paths: []
339
- tags:
340
- - agent
341
- body_skeleton: |
342
- # {{NAME}}
343
-
344
- > Persona / instructions for this agent identity. This body compiles to the system-prompt of `.claude/agents/<name>.md` and `.cursor/agents/<name>.md` ([[entity-model]] §agent). The vault spec is the SSOT; the generated host files are derived.
345
-
346
- You are {{NAME}}. <describe the role, what it optimizes for, and how it works.>
347
-
348
- ## Responsibilities
349
-
350
- ## Workflow conventions
351
-
352
- ## Guardrails
353
- pillar:
354
- folder: pillars/
355
- id_format: 'HS-PILR-<slug> (slug-only; owner-curated canonical pillars share id == basename)'
356
- parent_kinds: []
357
- required_fields: [id, name, type, status, owner, created, updated, canonical, secondary_pillars]
358
- optional_fields: [library_tier, version, last_edited_at, related, tags]
359
- schema_source: 'specs/entity-model.md §pillar'
360
- frontmatter:
361
- id: '{{ID}}'
362
- name: '{{NAME}}'
363
- type: pillar
364
- status: perpetual
365
- owner: '{{OWNER}}'
366
- created: '{{TODAY}}'
367
- updated: '{{TODAY}}'
368
- canonical: true
369
- secondary_pillars: []
370
- tags:
371
- - pillar
372
- body_skeleton: |
373
- # {{NAME}}
374
-
375
- > Perpetual structural theme — never closes. Epics name this pillar as their home for accumulated learning ([[entity-model]] §pillar).
376
-
377
- ## What this pillar is
378
-
379
- ## Why it's perpetual
380
-
381
- ## Through-line across milestones
382
- summary: |
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
-
385
- ---
386
-
387
- # Canonical frontmatter templates per entity kind
388
-
389
- This protocol is the single source of truth for the frontmatter shape of every new spec. The executable data lives in the **frontmatter** `templates:` map above — one entry per kind, each carrying `folder`, `id_format`, `parent_kinds`, `required_fields`, `optional_fields`, a `schema_source` citation, a ready-to-stamp `frontmatter` template, and a `body_skeleton`. The procedure-catalog builder (`scripts/build-procedure-catalog.mjs`) parses protocol frontmatter, so the catalog picks the templates up with no builder change, and `heyspex_get_procedure({ name: 'canonical-frontmatter-templates' })` returns the whole file (frontmatter + this body) to a calling agent.
390
-
391
- **Never compose frontmatter from a sibling example.** That is the exact anti-pattern this protocol exists to retire (user-memory `feedback_consult_procedures_dont_pattern_match`). Call `heyspex_file_spec` (or `POST /api/specs`); the server allocates the id and stamps the template. These templates are also the SSOT HS-OFUB-CVOB-EPIC-saas-customer-vault-onboarding scaffolds customer workspaces from.
392
-
393
- ## Placeholders
394
-
395
- The `frontmatter`/`body_skeleton` templates use these tokens, all server-substituted at filing time:
396
-
397
- - `{{ID}}` — server-allocated id (`allocateRandomVaultId()` for task/epic/milestone, numeric increment for research, slug-derived for memory kinds, parent-suffix for review). **Never client-supplied.**
398
- - `{{NAME}}` — the human-readable title.
399
- - `{{OWNER}}` — canonical owner (`pwher`).
400
- - `{{TODAY}}` — filing date / timestamp (`YYYY-MM-DD`).
401
- - `{{PARENT_ID}}` — the parent's id, for the `milestone:`/`parent:` wikilink.
402
- - `{{SLUG}}` — the title slug (memory `topic:` default).
403
-
404
- ## Per-kind reference
405
-
406
- The authoritative schema for every field below is **[[entity-model]] §Frontmatter schemas** — each entry's `schema_source` names the exact section + line range. The notes here cover the recovery path and parent-kind constraints; they do not restate the schema.
407
-
408
- ### `milestone` — `specs/entity-model.md` §milestone (lines 497–519)
409
-
410
- The top of the hierarchy: `parent_kinds: []` — a milestone has no parent (sub-milestones are out of scope; split horizontally). No scalar `kind`/`effort`/`priority` — milestone ordering is the deterministic scheduler's output, never a stored scalar. `epics:` is the mirror of each child epic's `milestone:` pointer (write both sides). Required body sections: rationale, acceptance gate, landing order, out-of-scope.
411
-
412
- ### `epic` — `specs/entity-model.md` §epic (lines 455–494)
413
-
414
- `parent_kinds: [milestone]` — an epic belongs to exactly one milestone via `milestone:` (the reverse of the milestone's `epics:` array). The `milestone:` requirement is in a **validator grace window until 2026-06-26**, after which a missing parent escalates from warning to error (HS-V5UA-T5PX-TASK-required-milestone-parent-on-epic-validator-and-grace-window). **`pillar:` is required and HARD-BLOCKED at filing** (owner decision 2026-06-18): every epic must name the perpetual Pillar that is its home for accumulated learning, and `POST /api/specs` / `heyspex_file_spec` refuse a `type: epic` with no resolvable `HS-PILR` theme (400 `pillar_required`, which lists existing pillars and how to author a net-new one). When no existing pillar fits, author one first via `heyspex_file_spec({ type: "pillar", name })`. Full rules: pillar-assignment-protocol. The ~226 legacy pillar-less epics are surfaced as a non-blocking Resolution backfill queue (`EPIC_MISSING_PILLAR`, grace until 2026-07-31). `research:` and `planning_flow:` are required for new epics by [[entity-model]] §epic but are filed during the milestone grace window per FRZE precedent — listed `optional_fields` here until the grace closes (HS-YXBD-1EM0-EPIC-canonical-spec-filing-surface-templates §Scope cuts). Shares the §task base schema; `type: epic` is the discriminator.
415
-
416
- ### `task` — `specs/entity-model.md` §task (lines 392–453)
417
-
418
- `parent_kinds: [epic, task]`. A **child task** is NOT a separate type — it is `type: task` whose `parent:` points at another task instead of an epic (same shape, different parent kind). `parent:` is optional at the schema level (the generic new-spec form and Epic Studio file parentless specs), but when present the server validates the parent kind and back-links the child into the parent's `children:` array at filing time (bidirectional linkage — see HS-3J4S-U13O-TASK-extend-post-api-specs-to-all-kinds-with).
419
-
420
- ### `research` — `specs/entity-model.md` §research (lines 761–793)
421
-
422
- **Evergreen** (research-is-evergreen): `status: open` is the resting state for the doc's whole life — there are no `in_review`/`closed` transitions; lineage is recorded through relational fields, never a status flip. Not hierarchical (`parent_kinds: []`): a research doc `enhances:` a single milestone (bidirectional with that milestone's `informed_by:`), it is not a child in a `children:` array. Numeric id (`HS-RES-<NNN>`), server-incremented. Required body sections: Executive Summary + Sources (research-capture-protocol).
423
-
424
- ### `memory-lesson` — `specs/entity-model.md` §memory-lesson (lines 604–615)
425
-
426
- `parent_kinds: []` — memory specs link via `related:` wikilinks, not hierarchy. Slug-derived id (`HS-LES-<slug>`). Required: `topic` + `observed`. Body sections: `## Problem`, `## Fix`. Full capture rules: [[memory-protocol]].
427
-
428
- ### `memory-decision` — `specs/entity-model.md` §memory-decision (lines 617–629)
429
-
430
- Slug id (`HS-DEC-<slug>`). Required: `topic` + `decided` + `deciders`. Body: `## Decision`, `## Rationale`. A `memory-decision` is the day-to-day choice that doesn't warrant a full ADR but should still persist.
431
-
432
- ### `memory-reference` — `specs/entity-model.md` §memory-reference (lines 631–641)
433
-
434
- Slug id (`HS-REF-<slug>`). Required: `topic`. Body is the brief context for why the reference matters; `url:` is optional.
435
-
436
- ### `memory-ui-pattern` — `specs/entity-model.md` §memory-ui-pattern (lines 643–653)
437
-
438
- Slug id (`HS-UIP-<slug>`). Required: `topic` + `documented`. Reusable console interaction/visual patterns. Body sections: `## Pattern`, `## When to apply`, `## Rules`, `## Implementation`. Distinct from `memory-ux-principle` (cross-brand rules).
439
-
440
- ### `review` — `specs/entity-model.md` §review (lines 679–705)
441
-
442
- `parent_kinds: [task, epic, milestone]`; `parent:` is **required** (a review with no subject is meaningless). The id is the bare `HS-REV-<parent-suffix>` — the suffix is segment `[2]` of the parent id (`HS-U13O-TASK` → `HS-U13O-REV`, `HS-0028-EPIC` → `HS-0028-REV`); the slug rides only in the filename. `reviews:` mirrors `parent:` (legacy alias for back-compat reads). A review has **no** `children:`/parent-array back-link — it cross-links to its subject via `parent:`/`reviews:` plus a `## Review` section the parent spec must carry. Four required body sections: `## Acceptance verification`, `## Reviewer notes`, `## Memory candidates` (scored table with a Conflict-check column), `## Decision: close or reopen`.
443
-
444
- ### `pillar` — `specs/entity-model.md` §pillar
445
-
446
- `parent_kinds: []` — a Pillar is a perpetual structural theme, not a child in any hierarchy; epics point UP at it via their required `pillar:` field. **`status: perpetual`** always (it never closes) and **`canonical:` is required** (`true` for owner-curated library pillars). Slug-only id (`HS-PILR-<slug>`, so id == basename and `[[HS-PILR-<slug>]]` resolves without a suffix). `secondary_pillars:` is always present (usually `[]`). Authoring a net-new pillar as a subject naturally arises during development is a **first-class, encouraged act** — file one with `heyspex_file_spec({ type: "pillar", name })` (or `POST /api/specs`), then point the epic's `pillar:` at it. The owner may also author a pillar standalone at any time. Full rules: pillar-assignment-protocol.
447
-
448
- ## Out of scope
449
-
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`).
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.)
452
-
453
- ## Drift gate
454
-
455
- Adding or removing a kind here changes the file, so `npm run build:procedure-catalog` must be re-run and the regenerated `specs/protocols/.catalog.json` committed; `npm run validate:procedure-catalog` is the CI drift gate. The inline `BODY_SKELETONS` in `spex-console/src/lib/vault.ts` (the server's create-time skeleton injection for `review`, the four memory kinds, `diagnose`, and `pillar`) must stay in lockstep with the `body_skeleton` entries above.
456
-
457
- ## Change log
458
-
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. |
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`. |
1
+ ---
2
+ id: HS-PROTO-canonical-frontmatter-templates
3
+ name: Canonical frontmatter templates per entity kind
4
+ type: protocol
5
+ status: open
6
+ priority: 1
7
+ scope: vault
8
+ owner: TODO — your name/handle
9
+ created: '2026-06-13'
10
+ updated: '2026-06-13'
11
+ tags:
12
+ - protocol
13
+ - spec-filing
14
+ - canonical-templates
15
+ - agent-experience
16
+ - frontmatter
17
+ triggers:
18
+ - file_milestone
19
+ - file_epic
20
+ - file_task
21
+ related:
22
+ - '[[entity-model]]'
23
+ templates:
24
+ milestone:
25
+ folder: milestones/
26
+ id_format: 'HS-MIL-<4+ random alphanumeric>'
27
+ parent_kinds: []
28
+ required_fields: [id, name, summary, type, status, owner, created, updated, epics, target_date]
29
+ optional_fields: [informed_by, tags, related, what_matters, blast_radius]
30
+ schema_source: 'specs/entity-model.md §milestone (lines 497–519)'
31
+ frontmatter:
32
+ id: '{{ID}}'
33
+ name: '{{NAME}}'
34
+ summary: ''
35
+ type: milestone
36
+ status: open
37
+ owner: '{{OWNER}}'
38
+ created: '{{TODAY}}'
39
+ updated: '{{TODAY}}'
40
+ epics: []
41
+ target_date: ''
42
+ tags:
43
+ - milestone
44
+ body_skeleton: |
45
+ # {{NAME}}
46
+
47
+ ## Intended outcome
48
+
49
+ <!-- Re-derive from the source research's intended outcome — do NOT copy it (HS-K4D4-2I29-RES-outcome-cascade-through-a-requirements-h). -->
50
+ **Outcome at the milestone altitude (required):** What outcome does this milestone deliver?
51
+
52
+ **Moves (↑ link, required):** Which research/parent outcome does it move — and by what **mechanism of contribution**? (Name the mechanism; don't echo the parent's words.)
53
+
54
+ ## Why this is a milestone, not loose epics
55
+
56
+ ## Acceptance gate
57
+
58
+ ## Suggested landing order
59
+
60
+ ## Out of scope
61
+
62
+ ## Expected Breakage & Consequences
63
+
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. -->
65
+ epic:
66
+ folder: epics/
67
+ id_format: 'HS-EPIC-<4+ random alphanumeric>'
68
+ parent_kinds: [milestone]
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)'
72
+ frontmatter:
73
+ id: '{{ID}}'
74
+ name: '{{NAME}}'
75
+ summary: ''
76
+ type: epic
77
+ status: open
78
+ kind: feature
79
+ effort: 3
80
+ owner: '{{OWNER}}'
81
+ created: '{{TODAY}}'
82
+ updated: '{{TODAY}}'
83
+ milestone: '{{PARENT_ID}}'
84
+ children: []
85
+ tags: []
86
+ body_skeleton: |
87
+ # {{NAME}}
88
+
89
+ ## Intended outcome
90
+
91
+ <!-- Re-derive from the parent milestone's intended outcome — do NOT copy it (HS-K4D4-2I29-RES-outcome-cascade-through-a-requirements-h). -->
92
+ **User-visible outcome of this epic (required):** What changes for the user when this epic ships?
93
+
94
+ **Moves (↑ link, required):** Which milestone outcome does it move — and by what **mechanism of contribution**?
95
+
96
+ ## Expected Breakage & Consequences
97
+
98
+ ## Why this epic exists
99
+
100
+ <!-- Substantive priority rationale (HS-XMSD). Plain language, no scores. -->
101
+ **Problem right now (required):** One sentence — what specific problem does this solve, and why is now (not next cycle) the right time?
102
+
103
+ **What this unlocks (required if `kind: infra` or `foundation`):** What future work becomes possible after this ships that isn't possible today?
104
+
105
+ **Skip cost (write before pinning this as on-deck):** If we skip this cycle, we lose: …
106
+
107
+ **Confidence note (optional):** Flag any part of the rationale above where your confidence is low.
108
+
109
+ ## Tasks
110
+
111
+ ## Acceptance gate — epic close
112
+
113
+ ## Change log
114
+ task:
115
+ folder: tasks/
116
+ id_format: 'HS-TASK-<4+ random alphanumeric>'
117
+ parent_kinds: [epic, task]
118
+ required_fields: [id, name, summary, type, status, owner, created, updated, kind, effort]
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)'
121
+ frontmatter:
122
+ id: '{{ID}}'
123
+ name: '{{NAME}}'
124
+ summary: ''
125
+ type: task
126
+ status: open
127
+ kind: feature
128
+ effort: 3
129
+ owner: '{{OWNER}}'
130
+ created: '{{TODAY}}'
131
+ updated: '{{TODAY}}'
132
+ parent: '{{PARENT_ID}}'
133
+ tags:
134
+ - near-term
135
+ body_skeleton: |
136
+ # {{NAME}}
137
+
138
+ ## Intended outcome
139
+
140
+ <!-- Re-derive from the parent epic's intended outcome — do NOT copy it (HS-K4D4-2I29-RES-outcome-cascade-through-a-requirements-h). -->
141
+ **Observable condition this task produces (required):** What can you monitor and control once this task is done? Express it as a checkable condition — this directly seeds the Acceptance criteria below.
142
+
143
+ **Moves (↑ link, required):** Which epic outcome does it move?
144
+
145
+ ## Expected Breakage & Consequences
146
+
147
+ ## Scope
148
+
149
+ ## Acceptance criteria
150
+
151
+ <!-- Each criterion is a monitorable + controllable condition derived from the Intended outcome above, traceable ↑ to the epic outcome. -->
152
+
153
+ ## Builder brief
154
+
155
+ <!-- Fleet dispatch hints for dev-factory (optional until breakdown files the task). Consult builder-fleet-capability-reference. -->
156
+ - **Target:** `{{TARGET_OR_TBD}}`
157
+ - **Context files:** `path/to/dep.ts`
158
+ - **Estimated context:** ~0 tokens
159
+ - **recommended_num_ctx:** 65536
160
+ - **suggested_model:** `qwen3-coder:30b`
161
+ - **suggested_machine:** `specops-gpu0`
162
+ - **fit_assessment:** safe
163
+
164
+ ## References
165
+ research:
166
+ folder: research/
167
+ id_format: 'HS-RES-<NNN> (zero-padded numeric, server auto-increments)'
168
+ parent_kinds: []
169
+ required_fields: [id, name, type, status, owner, created, updated]
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)'
172
+ frontmatter:
173
+ id: '{{ID}}'
174
+ name: '{{NAME}}'
175
+ type: research
176
+ status: open
177
+ owner: '{{OWNER}}'
178
+ created: '{{TODAY}}'
179
+ updated: '{{TODAY}}'
180
+ tags:
181
+ - research
182
+ body_skeleton: |
183
+ # {{NAME}}
184
+
185
+ ## Executive Summary
186
+
187
+ ## Conclusion & intended outcome
188
+
189
+ <!-- The root outcome that milestones/epics/tasks spawned from this research refine (translate, don't copy) (HS-K4D4-2I29-RES-outcome-cascade-through-a-requirements-h). -->
190
+ **Conclusion (one line):** Acting on this research, what is the conclusion?
191
+
192
+ **What acting on this achieves:** What changes for the user or system if we act on it?
193
+
194
+ ## Findings
195
+
196
+ ## Sources
197
+ memory-lesson:
198
+ folder: memory/lessons/
199
+ id_format: 'HS-LES-<slug>'
200
+ parent_kinds: []
201
+ required_fields: [id, name, type, status, owner, created, updated, topic, observed]
202
+ optional_fields: [related, evidence, tags]
203
+ schema_source: 'specs/entity-model.md §memory-lesson (lines 604–615)'
204
+ frontmatter:
205
+ id: '{{ID}}'
206
+ name: '{{NAME}}'
207
+ type: memory-lesson
208
+ status: open
209
+ owner: '{{OWNER}}'
210
+ created: '{{TODAY}}'
211
+ updated: '{{TODAY}}'
212
+ topic: '{{SLUG}}'
213
+ observed: '{{TODAY}}'
214
+ body_skeleton: |
215
+ # {{NAME}}
216
+
217
+ ## Problem
218
+
219
+ ## Fix
220
+ memory-decision:
221
+ folder: memory/decisions/
222
+ id_format: 'HS-DEC-<slug>'
223
+ parent_kinds: []
224
+ required_fields: [id, name, type, status, owner, created, updated, topic, decided, deciders]
225
+ optional_fields: [supersedes, evidence, related, tags]
226
+ schema_source: 'specs/entity-model.md §memory-decision (lines 617–629)'
227
+ frontmatter:
228
+ id: '{{ID}}'
229
+ name: '{{NAME}}'
230
+ type: memory-decision
231
+ status: open
232
+ owner: '{{OWNER}}'
233
+ created: '{{TODAY}}'
234
+ updated: '{{TODAY}}'
235
+ topic: '{{SLUG}}'
236
+ decided: '{{TODAY}}'
237
+ deciders:
238
+ - '{{OWNER}}'
239
+ body_skeleton: |
240
+ # {{NAME}}
241
+
242
+ ## Decision
243
+
244
+ ## Rationale
245
+ memory-reference:
246
+ folder: memory/references/
247
+ id_format: 'HS-REF-<slug>'
248
+ parent_kinds: []
249
+ required_fields: [id, name, type, status, owner, created, updated, topic]
250
+ optional_fields: [url, evidence, related, tags]
251
+ schema_source: 'specs/entity-model.md §memory-reference (lines 631–641)'
252
+ frontmatter:
253
+ id: '{{ID}}'
254
+ name: '{{NAME}}'
255
+ type: memory-reference
256
+ status: open
257
+ owner: '{{OWNER}}'
258
+ created: '{{TODAY}}'
259
+ updated: '{{TODAY}}'
260
+ topic: '{{SLUG}}'
261
+ body_skeleton: |
262
+ # {{NAME}}
263
+
264
+ Brief context for why this reference matters.
265
+ memory-ui-pattern:
266
+ folder: memory/ui-patterns/
267
+ id_format: 'HS-UIP-<slug>'
268
+ parent_kinds: []
269
+ required_fields: [id, name, type, status, owner, created, updated, topic, documented]
270
+ optional_fields: [related, evidence, tags]
271
+ schema_source: 'specs/entity-model.md §memory-ui-pattern (lines 643–653)'
272
+ frontmatter:
273
+ id: '{{ID}}'
274
+ name: '{{NAME}}'
275
+ type: memory-ui-pattern
276
+ status: open
277
+ owner: '{{OWNER}}'
278
+ created: '{{TODAY}}'
279
+ updated: '{{TODAY}}'
280
+ topic: '{{SLUG}}'
281
+ documented: '{{TODAY}}'
282
+ body_skeleton: |
283
+ # {{NAME}}
284
+
285
+ ## Pattern
286
+
287
+ ## When to apply
288
+
289
+ ## Rules
290
+
291
+ ## Implementation
292
+ review:
293
+ folder: reviews/
294
+ id_format: 'HS-REV-<parent-suffix> (suffix = parent id segment [2]; slug rides only in the filename)'
295
+ parent_kinds: [task, epic, milestone]
296
+ required_fields: [id, name, type, status, owner, created, updated, parent]
297
+ optional_fields: [reviews, deliberation_record]
298
+ schema_source: 'specs/entity-model.md §review (lines 679–705)'
299
+ frontmatter:
300
+ id: '{{ID}}'
301
+ name: '{{NAME}}'
302
+ type: review
303
+ status: open
304
+ owner: '{{OWNER}}'
305
+ created: '{{TODAY}}'
306
+ updated: '{{TODAY}}'
307
+ parent: '{{PARENT_ID}}'
308
+ reviews: '{{PARENT_ID}}'
309
+ body_skeleton: |
310
+ # Review — {{NAME}}
311
+
312
+ ## Acceptance verification
313
+
314
+ ## Reviewer notes
315
+
316
+ ## Memory candidates
317
+
318
+ | Candidate | Type | Conflict check | Score | Accept? |
319
+ |---|---|---|---|---|
320
+
321
+ ## Decision: close or reopen
322
+ agent:
323
+ folder: agents/
324
+ id_format: 'HS-AGENT-<4+ random alphanumeric>'
325
+ parent_kinds: []
326
+ required_fields: [id, name, type, status, owner, created, updated, role]
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'
329
+ frontmatter:
330
+ id: '{{ID}}'
331
+ name: '{{NAME}}'
332
+ type: agent
333
+ status: open
334
+ owner: '{{OWNER}}'
335
+ role: '{{NAME}}'
336
+ created: '{{TODAY}}'
337
+ updated: '{{TODAY}}'
338
+ owned_paths: []
339
+ tags:
340
+ - agent
341
+ body_skeleton: |
342
+ # {{NAME}}
343
+
344
+ > Persona / instructions for this agent identity. This body compiles to the system-prompt of `.claude/agents/<name>.md` and `.cursor/agents/<name>.md` ([[entity-model]] §agent). The vault spec is the SSOT; the generated host files are derived.
345
+
346
+ You are {{NAME}}. <describe the role, what it optimizes for, and how it works.>
347
+
348
+ ## Responsibilities
349
+
350
+ ## Workflow conventions
351
+
352
+ ## Guardrails
353
+ pillar:
354
+ folder: pillars/
355
+ id_format: 'HS-PILR-<slug> (slug-only; owner-curated canonical pillars share id == basename)'
356
+ parent_kinds: []
357
+ required_fields: [id, name, type, status, owner, created, updated, canonical, secondary_pillars]
358
+ optional_fields: [library_tier, version, last_edited_at, related, tags]
359
+ schema_source: 'specs/entity-model.md §pillar'
360
+ frontmatter:
361
+ id: '{{ID}}'
362
+ name: '{{NAME}}'
363
+ type: pillar
364
+ status: perpetual
365
+ owner: '{{OWNER}}'
366
+ created: '{{TODAY}}'
367
+ updated: '{{TODAY}}'
368
+ canonical: true
369
+ secondary_pillars: []
370
+ tags:
371
+ - pillar
372
+ body_skeleton: |
373
+ # {{NAME}}
374
+
375
+ > Perpetual structural theme — never closes. Epics name this pillar as their home for accumulated learning ([[entity-model]] §pillar).
376
+
377
+ ## What this pillar is
378
+
379
+ ## Why it's perpetual
380
+
381
+ ## Through-line across milestones
382
+ summary: |
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
+
385
+ ---
386
+
387
+ # Canonical frontmatter templates per entity kind
388
+
389
+ This protocol is the single source of truth for the frontmatter shape of every new spec. The executable data lives in the **frontmatter** `templates:` map above — one entry per kind, each carrying `folder`, `id_format`, `parent_kinds`, `required_fields`, `optional_fields`, a `schema_source` citation, a ready-to-stamp `frontmatter` template, and a `body_skeleton`. The procedure-catalog builder (`scripts/build-procedure-catalog.mjs`) parses protocol frontmatter, so the catalog picks the templates up with no builder change, and `heyspex_get_procedure({ name: 'canonical-frontmatter-templates' })` returns the whole file (frontmatter + this body) to a calling agent.
390
+
391
+ **Never compose frontmatter from a sibling example.** That is the exact anti-pattern this protocol exists to retire (user-memory `feedback_consult_procedures_dont_pattern_match`). Call `heyspex_file_spec` (or `POST /api/specs`); the server allocates the id and stamps the template. These templates are also the SSOT HS-OFUB-CVOB-EPIC-saas-customer-vault-onboarding scaffolds customer workspaces from.
392
+
393
+ ## Placeholders
394
+
395
+ The `frontmatter`/`body_skeleton` templates use these tokens, all server-substituted at filing time:
396
+
397
+ - `{{ID}}` — server-allocated id (`allocateRandomVaultId()` for task/epic/milestone, numeric increment for research, slug-derived for memory kinds, parent-suffix for review). **Never client-supplied.**
398
+ - `{{NAME}}` — the human-readable title.
399
+ - `{{OWNER}}` — canonical owner (`pwher`).
400
+ - `{{TODAY}}` — filing date / timestamp (`YYYY-MM-DD`).
401
+ - `{{PARENT_ID}}` — the parent's id, for the `milestone:`/`parent:` wikilink.
402
+ - `{{SLUG}}` — the title slug (memory `topic:` default).
403
+
404
+ ## Per-kind reference
405
+
406
+ The authoritative schema for every field below is **[[entity-model]] §Frontmatter schemas** — each entry's `schema_source` names the exact section + line range. The notes here cover the recovery path and parent-kind constraints; they do not restate the schema.
407
+
408
+ ### `milestone` — `specs/entity-model.md` §milestone (lines 497–519)
409
+
410
+ The top of the hierarchy: `parent_kinds: []` — a milestone has no parent (sub-milestones are out of scope; split horizontally). No scalar `kind`/`effort`/`priority` — milestone ordering is the deterministic scheduler's output, never a stored scalar. `epics:` is the mirror of each child epic's `milestone:` pointer (write both sides). Required body sections: rationale, acceptance gate, landing order, out-of-scope.
411
+
412
+ ### `epic` — `specs/entity-model.md` §epic (lines 455–494)
413
+
414
+ `parent_kinds: [milestone]` — an epic belongs to exactly one milestone via `milestone:` (the reverse of the milestone's `epics:` array). The `milestone:` requirement is in a **validator grace window until 2026-06-26**, after which a missing parent escalates from warning to error (HS-V5UA-T5PX-TASK-required-milestone-parent-on-epic-validator-and-grace-window). **`pillar:` is required and HARD-BLOCKED at filing** (owner decision 2026-06-18): every epic must name the perpetual Pillar that is its home for accumulated learning, and `POST /api/specs` / `heyspex_file_spec` refuse a `type: epic` with no resolvable `HS-PILR` theme (400 `pillar_required`, which lists existing pillars and how to author a net-new one). When no existing pillar fits, author one first via `heyspex_file_spec({ type: "pillar", name })`. Full rules: pillar-assignment-protocol. The ~226 legacy pillar-less epics are surfaced as a non-blocking Resolution backfill queue (`EPIC_MISSING_PILLAR`, grace until 2026-07-31). `research:` and `planning_flow:` are required for new epics by [[entity-model]] §epic but are filed during the milestone grace window per FRZE precedent — listed `optional_fields` here until the grace closes (HS-YXBD-1EM0-EPIC-canonical-spec-filing-surface-templates §Scope cuts). Shares the §task base schema; `type: epic` is the discriminator.
415
+
416
+ ### `task` — `specs/entity-model.md` §task (lines 392–453)
417
+
418
+ `parent_kinds: [epic, task]`. A **child task** is NOT a separate type — it is `type: task` whose `parent:` points at another task instead of an epic (same shape, different parent kind). `parent:` is optional at the schema level (the generic new-spec form and Epic Studio file parentless specs), but when present the server validates the parent kind and back-links the child into the parent's `children:` array at filing time (bidirectional linkage — see HS-3J4S-U13O-TASK-extend-post-api-specs-to-all-kinds-with).
419
+
420
+ ### `research` — `specs/entity-model.md` §research (lines 761–793)
421
+
422
+ **Evergreen** (research-is-evergreen): `status: open` is the resting state for the doc's whole life — there are no `in_review`/`closed` transitions; lineage is recorded through relational fields, never a status flip. Not hierarchical (`parent_kinds: []`): a research doc `enhances:` a single milestone (bidirectional with that milestone's `informed_by:`), it is not a child in a `children:` array. Numeric id (`HS-RES-<NNN>`), server-incremented. Required body sections: Executive Summary + Sources (research-capture-protocol).
423
+
424
+ ### `memory-lesson` — `specs/entity-model.md` §memory-lesson (lines 604–615)
425
+
426
+ `parent_kinds: []` — memory specs link via `related:` wikilinks, not hierarchy. Slug-derived id (`HS-LES-<slug>`). Required: `topic` + `observed`. Body sections: `## Problem`, `## Fix`. Full capture rules: [[memory-protocol]].
427
+
428
+ ### `memory-decision` — `specs/entity-model.md` §memory-decision (lines 617–629)
429
+
430
+ Slug id (`HS-DEC-<slug>`). Required: `topic` + `decided` + `deciders`. Body: `## Decision`, `## Rationale`. A `memory-decision` is the day-to-day choice that doesn't warrant a full ADR but should still persist.
431
+
432
+ ### `memory-reference` — `specs/entity-model.md` §memory-reference (lines 631–641)
433
+
434
+ Slug id (`HS-REF-<slug>`). Required: `topic`. Body is the brief context for why the reference matters; `url:` is optional.
435
+
436
+ ### `memory-ui-pattern` — `specs/entity-model.md` §memory-ui-pattern (lines 643–653)
437
+
438
+ Slug id (`HS-UIP-<slug>`). Required: `topic` + `documented`. Reusable console interaction/visual patterns. Body sections: `## Pattern`, `## When to apply`, `## Rules`, `## Implementation`. Distinct from `memory-ux-principle` (cross-brand rules).
439
+
440
+ ### `review` — `specs/entity-model.md` §review (lines 679–705)
441
+
442
+ `parent_kinds: [task, epic, milestone]`; `parent:` is **required** (a review with no subject is meaningless). The id is the bare `HS-REV-<parent-suffix>` — the suffix is segment `[2]` of the parent id (`HS-U13O-TASK` → `HS-U13O-REV`, `HS-0028-EPIC` → `HS-0028-REV`); the slug rides only in the filename. `reviews:` mirrors `parent:` (legacy alias for back-compat reads). A review has **no** `children:`/parent-array back-link — it cross-links to its subject via `parent:`/`reviews:` plus a `## Review` section the parent spec must carry. Four required body sections: `## Acceptance verification`, `## Reviewer notes`, `## Memory candidates` (scored table with a Conflict-check column), `## Decision: close or reopen`.
443
+
444
+ ### `pillar` — `specs/entity-model.md` §pillar
445
+
446
+ `parent_kinds: []` — a Pillar is a perpetual structural theme, not a child in any hierarchy; epics point UP at it via their required `pillar:` field. **`status: perpetual`** always (it never closes) and **`canonical:` is required** (`true` for owner-curated library pillars). Slug-only id (`HS-PILR-<slug>`, so id == basename and `[[HS-PILR-<slug>]]` resolves without a suffix). `secondary_pillars:` is always present (usually `[]`). Authoring a net-new pillar as a subject naturally arises during development is a **first-class, encouraged act** — file one with `heyspex_file_spec({ type: "pillar", name })` (or `POST /api/specs`), then point the epic's `pillar:` at it. The owner may also author a pillar standalone at any time. Full rules: pillar-assignment-protocol.
447
+
448
+ ## Out of scope
449
+
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`).
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.)
452
+
453
+ ## Drift gate
454
+
455
+ Adding or removing a kind here changes the file, so `npm run build:procedure-catalog` must be re-run and the regenerated `specs/protocols/.catalog.json` committed; `npm run validate:procedure-catalog` is the CI drift gate. The inline `BODY_SKELETONS` in `spex-console/src/lib/vault.ts` (the server's create-time skeleton injection for `review`, the four memory kinds, `diagnose`, and `pillar`) must stay in lockstep with the `body_skeleton` entries above.
456
+
457
+ ## Change log
458
+
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. |
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`. |