heyspex 0.1.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.
- package/README.md +157 -0
- package/bin/hs.mjs +1028 -0
- package/bin/postinstall.mjs +88 -0
- package/dev-factory/lib/fleet-readiness.mjs +274 -0
- package/dev-factory/lib/fleet-state.mjs +250 -0
- package/dev-factory/lib/sufficiency-score.mjs +441 -0
- package/dist/cli/hs-check.mjs +747 -0
- package/dist/cli/hs-claim.mjs +541 -0
- package/dist/cli/hs-connect.mjs +3436 -0
- package/dist/cli/hs-defer.mjs +8455 -0
- package/dist/cli/hs-env.mjs +36845 -0
- package/dist/cli/hs-init.mjs +1145 -0
- package/dist/cli/hs-install.mjs +1390 -0
- package/dist/cli/hs-join.mjs +38553 -0
- package/dist/cli/hs-vault-pull.mjs +7782 -0
- package/dist/cli/hs-vault.mjs +4166 -0
- package/dist/cli/hs-workspace.mjs +2898 -0
- package/dist/cli-templates/customer-vault/specs/entity-model.md +1735 -0
- package/dist/cli-templates/customer-vault/specs/protocols/canonical-frontmatter-templates.md +531 -0
- package/dist/cli-templates/customer-vault/specs/protocols/memory-protocol.md +48 -0
- package/dist/cli-templates/customer-vault/specs/protocols/spec-hierarchy.md +548 -0
- package/docs/mcp-client-config.md +200 -0
- package/package.json +124 -0
- package/scripts/check-mcp-freshness.mjs +379 -0
- package/scripts/dev-server-status.mjs +722 -0
- package/scripts/gateway-skills-lib.mjs +421 -0
- package/scripts/lib/console-url-resolver.mjs +152 -0
- package/scripts/lib/dev-mode.mjs +369 -0
- package/scripts/lib/hs-link.mjs +154 -0
- package/scripts/lib/hs-source-commit.mjs +207 -0
- package/scripts/lib/hs-source-log.mjs +366 -0
- package/scripts/lib/hs-source-preflight.mjs +402 -0
- package/scripts/lib/hs-source-push.mjs +307 -0
- package/scripts/lib/hs-source-secret-scan.mjs +263 -0
- package/scripts/lib/standalone-doctor.mjs +89 -0
- package/scripts/vault-id-lib.mjs +173 -0
- package/vendor/heyspex-mcp/alignment-gate.mjs +1347 -0
- package/vendor/heyspex-mcp/blocker-resolver.mjs +891 -0
- package/vendor/heyspex-mcp/breakdown-ladder.mjs +309 -0
- package/vendor/heyspex-mcp/breakdown-source.mjs +236 -0
- package/vendor/heyspex-mcp/breakdown-writer.mjs +524 -0
- package/vendor/heyspex-mcp/brief-observability.mjs +67 -0
- package/vendor/heyspex-mcp/canvas-inbox.mjs +130 -0
- package/vendor/heyspex-mcp/capture-active-rehydrate.mjs +76 -0
- package/vendor/heyspex-mcp/capture-buffer-patches.mjs +147 -0
- package/vendor/heyspex-mcp/capture-channel.mjs +577 -0
- package/vendor/heyspex-mcp/capture-console-client.mjs +290 -0
- package/vendor/heyspex-mcp/capture-focus.mjs +1366 -0
- package/vendor/heyspex-mcp/capture-kind-suggest.mjs +121 -0
- package/vendor/heyspex-mcp/capture-outbox.mjs +239 -0
- package/vendor/heyspex-mcp/capture-stage-gate.mjs +160 -0
- package/vendor/heyspex-mcp/cli.mjs +15754 -0
- package/vendor/heyspex-mcp/config-settings.mjs +419 -0
- package/vendor/heyspex-mcp/console-fetch.mjs +342 -0
- package/vendor/heyspex-mcp/defer-spec.mjs +527 -0
- package/vendor/heyspex-mcp/deferred-reclaim.mjs +284 -0
- package/vendor/heyspex-mcp/design-tools.mjs +449 -0
- package/vendor/heyspex-mcp/dev-factory-bridge.mjs +66 -0
- package/vendor/heyspex-mcp/diagnose-skeleton.mjs +114 -0
- package/vendor/heyspex-mcp/fleet-queue-tools.mjs +241 -0
- package/vendor/heyspex-mcp/hooks-engine.mjs +399 -0
- package/vendor/heyspex-mcp/login-handoff.mjs +438 -0
- package/vendor/heyspex-mcp/mcp-subprocess.mjs +136 -0
- package/vendor/heyspex-mcp/mvp-mode.mjs +101 -0
- package/vendor/heyspex-mcp/next-resolution.mjs +240 -0
- package/vendor/heyspex-mcp/next-review.mjs +548 -0
- package/vendor/heyspex-mcp/peer-presence.mjs +430 -0
- package/vendor/heyspex-mcp/plan-ground-conflicts.mjs +321 -0
- package/vendor/heyspex-mcp/plan-ground.mjs +2001 -0
- package/vendor/heyspex-mcp/plan-ingest.mjs +476 -0
- package/vendor/heyspex-mcp/plan-push.mjs +1826 -0
- package/vendor/heyspex-mcp/plan-review.mjs +1419 -0
- package/vendor/heyspex-mcp/preflight-gate.mjs +0 -0
- package/vendor/heyspex-mcp/procedure-tools.mjs +970 -0
- package/vendor/heyspex-mcp/promote-capture.mjs +1280 -0
- package/vendor/heyspex-mcp/promote-diagnose.mjs +187 -0
- package/vendor/heyspex-mcp/promote-research-to-diagnose.mjs +338 -0
- package/vendor/heyspex-mcp/promote-research.mjs +1553 -0
- package/vendor/heyspex-mcp/promotion-helpers.mjs +280 -0
- package/vendor/heyspex-mcp/read-path.mjs +138 -0
- package/vendor/heyspex-mcp/recipe-tools.mjs +258 -0
- package/vendor/heyspex-mcp/regen-tasks.mjs +326 -0
- package/vendor/heyspex-mcp/register-spec.mjs +417 -0
- package/vendor/heyspex-mcp/research-focus.mjs +476 -0
- package/vendor/heyspex-mcp/research-tools.mjs +109 -0
- package/vendor/heyspex-mcp/research-type-suggest.mjs +112 -0
- package/vendor/heyspex-mcp/resolution-focus.mjs +45 -0
- package/vendor/heyspex-mcp/review-focus.mjs +55 -0
- package/vendor/heyspex-mcp/review-rollup.mjs +47 -0
- package/vendor/heyspex-mcp/run-front.mjs +60 -0
- package/vendor/heyspex-mcp/scheduler.mjs +813 -0
- package/vendor/heyspex-mcp/seat-identity.mjs +281 -0
- package/vendor/heyspex-mcp/settings-tools.mjs +119 -0
- package/vendor/heyspex-mcp/spec-id-lib.mjs +790 -0
- package/vendor/heyspex-mcp/split-research.mjs +832 -0
- package/vendor/heyspex-mcp/submit-for-review.mjs +190 -0
- package/vendor/heyspex-mcp/summary-contract.mjs +162 -0
- package/vendor/heyspex-mcp/test-helpers.mjs +43 -0
- package/vendor/heyspex-mcp/validate-linkage.mjs +574 -0
- package/vendor/heyspex-mcp/vault-resolve.mjs +297 -0
- package/vendor/heyspex-mcp/vault-settings.mjs +87 -0
- package/vendor/heyspex-mcp/verify-reproduction.mjs +314 -0
- package/vendor/heyspex-mcp/why-now.mjs +64 -0
- package/vendor/heyspex-mcp/yaml-scalar.mjs +34 -0
|
@@ -0,0 +1,1735 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: HS-L2-ENTITY
|
|
3
|
+
name: HeySpex Entity Model
|
|
4
|
+
type: l2
|
|
5
|
+
status: draft
|
|
6
|
+
priority: 0
|
|
7
|
+
owner: pwher
|
|
8
|
+
assisted_by:
|
|
9
|
+
- Claude Code
|
|
10
|
+
created: 2026-05-14
|
|
11
|
+
updated: 2026-05-18
|
|
12
|
+
tags: "[foundation, l2, entity-model, schema]"
|
|
13
|
+
related:
|
|
14
|
+
- "heyspex-north-star"
|
|
15
|
+
- "HS-DOC-architecture-foundations"
|
|
16
|
+
- "uc-ingest-anywhere"
|
|
17
|
+
- "uc-voice-ingest-hey-spex"
|
|
18
|
+
- "uc-capture-intent"
|
|
19
|
+
- "companion-capture-inbox-and-bundles"
|
|
20
|
+
- "HS-D1YU-OVFO-TASK-bundle-submit-composite-draft-source-set"
|
|
21
|
+
- "ai-deliberation-gate"
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
# HeySpex Entity Model
|
|
25
|
+
|
|
26
|
+
> [!important] Constitutional dependency
|
|
27
|
+
> Every constraint in this document derives from a numbered principle in heyspex-north-star. If a future change to this document contradicts the L1 spec, the change is wrong. When the L1 changes, this document updates downstream.
|
|
28
|
+
|
|
29
|
+
This L2 spec defines the shape of every artifact that lives in a HeySpex vault: the entity types, their frontmatter schemas, their on-disk layout, the dependency relations between them, and the wikilink resolution rules. It is the contract that the console, the CLI (`hs`), and any AI agent must satisfy when reading or writing the vault.
|
|
30
|
+
|
|
31
|
+
## Vocabulary
|
|
32
|
+
|
|
33
|
+
- **Vault.** A folder of plain-text files under git. The on-disk layout is canonical. A single Builder owns one or more vaults; this document specifies the structure of one vault.
|
|
34
|
+
- **Spec.** A single markdown file in the vault. Every spec has YAML frontmatter and a markdown body. The frontmatter declares the spec's type and identity.
|
|
35
|
+
- **Entity type.** The value of the `type:` field in frontmatter. Determines which folder the spec lives in, which other fields are required, and how the spec is rendered in the console.
|
|
36
|
+
- **Hierarchy level.** L1 / L2 / L3. Vision → architecture → use-case. A different axis from entity type. Some entity types are level-tagged (`type: l1`, `type: l2`, `type: l3`); most are not.
|
|
37
|
+
- **Wikilink.** A reference of the form `[[link-target]]`, resolved by filename match across the vault.
|
|
38
|
+
- **Memory (conceptual layer).** Durable project knowledge surfaced together in the console: `memory-lesson`, `memory-decision`, `memory-reference`, `memory-ux-principle`, `memory-ui-pattern`, and `protocol`. Protocols are filed under `specs/protocols/` on disk but are a **subsection of Memory** in navigation and in `hs prime` — not a peer of Memory beside Epics/Tasks. See memory-protocols-subsection-of-memory. Work to _create_ or change a protocol remains `type: epic` / `task`.
|
|
39
|
+
|
|
40
|
+
## Vault root layout
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
specs/
|
|
44
|
+
├── heyspex-north-star.md # the L1; one file
|
|
45
|
+
├── entity-model.md # this document; L2
|
|
46
|
+
├── architecture-foundations.md # L2 sibling (renamed 2026-05-31 from architecture-pillars.md to disambiguate from the `type: pillar` entity)
|
|
47
|
+
├── principles.md # L2 (expansion of L1's principle list)
|
|
48
|
+
├── glossary.md # L2 (authoritative term dictionary) — North Star tier
|
|
49
|
+
├── adr/ # one ADR per file
|
|
50
|
+
│ ├── adr-0001-vault-format.md
|
|
51
|
+
│ ├── adr-0002-derived-index.md
|
|
52
|
+
│ └── ...
|
|
53
|
+
├── use-cases/ # one L3 use-case spec per file
|
|
54
|
+
│ ├── uc-capture-intent.md
|
|
55
|
+
│ ├── uc-decompose-intent.md
|
|
56
|
+
│ └── ...
|
|
57
|
+
├── tasks/ # task / feature / bug specs
|
|
58
|
+
│ ├── HS-ZF0T-TASK-<slug>.md # legacy sequential, or HS-K7M2-<slug>.md (random)
|
|
59
|
+
│ └── ...
|
|
60
|
+
├── milestones/ # milestone specs (the grouping above epic)
|
|
61
|
+
│ └── HS-MIL-<suffix>-<slug>.md # e.g. HS-IART-MIL-console-ia-restructure.md
|
|
62
|
+
├── pillars/ # type: pillar — perpetual categorical containers (Scaling, Reliability, DX, etc.)
|
|
63
|
+
│ └── HS-PILR-<slug>.md # canonical Pillars; customers may also create HS-PILR-<suffix>-<slug>.md
|
|
64
|
+
├── epics/ # epic specs
|
|
65
|
+
│ └── HS-0001-EPIC-<slug>.md # legacy, or HS-EPIC-X9P4-<slug>.md (random)
|
|
66
|
+
├── branches/ # branch-brief specs (one per git branch)
|
|
67
|
+
│ └── <branch-slug>.md
|
|
68
|
+
├── memory/
|
|
69
|
+
│ ├── lessons/ # memory-lesson specs
|
|
70
|
+
│ │ └── <slug>.md
|
|
71
|
+
│ ├── decisions/ # memory-decision specs
|
|
72
|
+
│ │ └── <slug>.md
|
|
73
|
+
│ ├── references/ # memory-reference specs
|
|
74
|
+
│ │ └── <slug>.md
|
|
75
|
+
│ ├── ux-principles/ # memory-ux-principle specs (cross-brand interaction rules)
|
|
76
|
+
│ │ └── <slug>.md
|
|
77
|
+
│ └── ui-patterns/ # memory-ui-pattern specs (reusable interaction/visual rules)
|
|
78
|
+
│ └── <slug>.md
|
|
79
|
+
├── protocols/ # type: protocol — Memory subsection on disk (how-we-work rules)
|
|
80
|
+
│ └── <slug>.md # (not epic/task work; those stay in epics/ and tasks/)
|
|
81
|
+
├── reviews/ # type: review — HS-REV-<suffix>-<slug>.md companions for in_review parent specs
|
|
82
|
+
│ └── HS-REV-<suffix>-<slug>.md
|
|
83
|
+
├── business/ # business model / marketing / positioning / pricing
|
|
84
|
+
│ ├── positioning/ # business-positioning specs
|
|
85
|
+
│ │ └── <slug>.md
|
|
86
|
+
│ ├── pricing/ # business-pricing specs
|
|
87
|
+
│ │ └── <slug>.md
|
|
88
|
+
│ ├── marketing/ # business-marketing specs
|
|
89
|
+
│ │ └── <slug>.md
|
|
90
|
+
│ └── model/ # business-model specs
|
|
91
|
+
│ └── <slug>.md
|
|
92
|
+
├── canvases/ # JSON Canvas design files + .heyspex.yaml sidecars ([[adr-0013-canvas-vault-format-and-obsidian-interop]])
|
|
93
|
+
│ ├── system-design.canvas
|
|
94
|
+
│ ├── system-design.heyspex.yaml
|
|
95
|
+
│ ├── diagrams/ # per-spec editable design diagrams ([[spec-diagram-design-vs-as-built-canvas]])
|
|
96
|
+
│ │ └── <spec-basename>-design.canvas
|
|
97
|
+
│ ├── as-built/ # sealed shipped spec diagrams (read-only in HeySpex)
|
|
98
|
+
│ │ └── <spec-basename>.canvas
|
|
99
|
+
│ └── ...
|
|
100
|
+
├── roadmaps/ # phased roadmap specs (orchestration over tasks/epics)
|
|
101
|
+
│ └── HS-ROADMAP-<slug>.md
|
|
102
|
+
├── roadmap-design-v2/ # Console Roadmap surface v2 design pack (protocol docs; not manifest entities)
|
|
103
|
+
│ ├── roadmap-design-v2-index.md # hub
|
|
104
|
+
│ ├── roadmap-v2-implementation-checklist.md # printable when coding
|
|
105
|
+
│ ├── roadmap-v2-implementation-handoff.md # read order + context
|
|
106
|
+
│ ├── roadmap-v2-tabextend-reference.md
|
|
107
|
+
│ ├── roadmap-v2-narrative-board-ux.md
|
|
108
|
+
│ ├── roadmap-v2-display-titles-and-summaries.md
|
|
109
|
+
│ └── roadmap-v2-*.md # see index for full map
|
|
110
|
+
├── companion-research-board/ # Chrome + Companion mirrored research board (protocol docs)
|
|
111
|
+
│ ├── companion-research-board-index.md
|
|
112
|
+
│ ├── companion-research-board-dual-surface-mirror.md
|
|
113
|
+
│ ├── companion-research-board-implementation-checklist.md
|
|
114
|
+
│ └── companion-research-board-*.md
|
|
115
|
+
├── future-considerations/ # pre-task research (promote to tasks when scheduled)
|
|
116
|
+
│ └── <slug>.md
|
|
117
|
+
├── research/ # audit/research/draft notes
|
|
118
|
+
│ ├── HS-XBPJ-RES-bd-feature-inventory.md
|
|
119
|
+
│ └── ...
|
|
120
|
+
├── captures/ # concise core capture entries — kind: idea | bug-fix | clip | reference | question | spec-import ([[capture-guardrails]])
|
|
121
|
+
│ └── HS-CAP-<suffix>-<slug>.md
|
|
122
|
+
├── flows/ # planning-flow lifecycle diagrams ([[planning-flow-research-epic-lifecycle]])
|
|
123
|
+
│ └── HS-FLOW-<NNN>-<slug>.md
|
|
124
|
+
├── drafts/ # ingested-but-untriaged
|
|
125
|
+
│ └── <slug>.md
|
|
126
|
+
├── events/ # audit-export JSONL — one file per UTC month ([[HS-FD93-AEHR-EPIC-audit-export-heyspex-yaml-and-heyspex-retirement]])
|
|
127
|
+
│ └── YYYY-MM.jsonl # committed snapshot of claim/focus/spec events (git-clone-is-backup)
|
|
128
|
+
└── daily/ # optional daily notes
|
|
129
|
+
└── 2026-05-14.md
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Two committed siblings live **outside** `specs/` at the repo root, written/owned by the control plane:
|
|
133
|
+
|
|
134
|
+
- **`heyspex.yaml`** — the top-level vault marker (`schema_version`, `console_url`, `vault_root`) written by `hs init` (HS-FD93-AEHR-EPIC-audit-export-heyspex-yaml-and-heyspex-retirement §2). `schema_version: 2` = the post-SCAH Neon-control-plane layout; `1` was the implicit pre-SCAH `.heyspex/`-files layout. The web companion reads it to bootstrap a vault.
|
|
135
|
+
- **`.heyspex/`** — per-vault config home (adr-0009-heyspex-directory-contract): tracked `config.yaml`, `.gitignore`, `*.example` scaffolding templates, and `focus.yaml` (cross-machine pin SSOT, focus-yaml-is-tracked-pin-ssot). On the **free tier** (no Neon) this directory ALSO holds the live runtime state (`active-claims.json`, `claim-history.jsonl`, `focus-history.jsonl`); on the **paid tier** that state lives in Neon and these files are the export's free-tier source only (HS-7FA9-FREE-EPIC-zero-neon-local-only-tier). The audit export (`specs/events/`) reads whichever store is live for the tier.
|
|
136
|
+
|
|
137
|
+
The L1 lives at the vault root as `heyspex-north-star.md`. The other L2 specs (`entity-model.md`, `architecture-foundations.md`, `principles.md`, `glossary.md`) also live at the root because they are foundational — in the console they surface under the **North Star** rail group, not Business (which is scoped to `business-*` types) or Memory (scoped to `memory-*` types). The glossary carries a `marketing` _tag_ because marketing copy consumes its definitions, but its `type: l2` keeps it in the foundational tier. Everything else is filed under a folder matching its entity type.
|
|
138
|
+
|
|
139
|
+
> [!note] Why folders, not flat?
|
|
140
|
+
> Obsidian works with either, and HeySpex's link resolution treats folders as opaque (see [Wikilink resolution rules](#wikilink-resolution-rules)). Folders exist purely for human navigation and for the indexer's "list all <type>" view. Files can be moved between folders without breaking links.
|
|
141
|
+
|
|
142
|
+
## Entity types
|
|
143
|
+
|
|
144
|
+
The table below names every entity type in v1 and points at the frontmatter contract. Each type has its own subsection below with the full schema.
|
|
145
|
+
|
|
146
|
+
| `type:` value | Folder | Hierarchy level | One-line description |
|
|
147
|
+
| ---------------------- | ----------------------------------------------------------------------------------------------- | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
148
|
+
| `l1` | root | L1 | The North Star vision; one per vault. |
|
|
149
|
+
| `l2` | root | L2 | Foundational architecture or model documents. |
|
|
150
|
+
| `l3` | `use-cases/` | L3 | Use-case specs that elaborate L1 system use cases. |
|
|
151
|
+
| `adr` | `adr/` | — | Architectural Decision Record. |
|
|
152
|
+
| `task` | `tasks/` | — | The atomic unit of work. Subsumes bd's `task`, `feature`, and `bug` types. |
|
|
153
|
+
| `epic` | `epics/` | — | A grouping of related tasks under a common goal. |
|
|
154
|
+
| `milestone` | `milestones/` | — | The grouping **above** epic: a coherent multi-epic ship that closes when every child epic closes and the milestone's own acceptance gate is met. Distinct from the legacy `kind: milestone` task discriminator (see [`#### task`](#task)). |
|
|
155
|
+
| `diagnose` | `diagnoses/` | — | A user-reported **bug fix** as first-class executable work (claimable, decomposable). Standalone by default — no epic/milestone parent required — with an optional `parent:` (epic or milestone) for organization. Carries `severity:`; surfaces on the Resolution surface as a derived `kind: "bug"` row that links back to the diagnose. Elevates the bug concept that `task` historically subsumed (see [`#### task`](#task)) into its own lane. Ratified by introduction lineage HS-OXBS-BFIX-MIL-bug-fix-diagnose-lane (milestone-precedent, like `milestone`/`pillar`). See HS-AO2F-1KZK-RES-bug-fix-resolution-task-entity-model-and. Proposed (not-yet-ratified) field extensions — a `problem_layer: symptom \| core \| unknown` classifier and an optional bidirectional `caused_by`/`symptoms` link pair — are designed in HS-4QOK-UBJM-RES-diagnose-problem-layer-classification-sy. End-to-end workflow procedure: resolution-diagnose-workflow. |
|
|
156
|
+
| `pillar` | `pillars/` | — | Perpetual categorical container that never closes; cross-cutting axis for epics. Every epic carries `pillar:` (required, single primary) + optional `secondary_pillars:`. Canonical Pillars ship pre-loaded with HeySpex; customers may add scoped Pillars. Orthogonal to `milestone` (a milestone is a shippable increment; a Pillar is a perpetual concern). See HS-PILR-pillars (meta-Pillar) and HS-AWDI-PILR-RES-pm-perpetual-container-terminology (research + 2026-05-31 resolution). |
|
|
157
|
+
| `agent` | `agents/` | — | A durable, user-authored **agent identity** (the "home where agents live"): name, role, preferred tools, model tier, procedures, and persona body. Compiles to the host-native agent formats (`.claude/agents/*.md`, `.cursor/agents/*.md`) — the vault spec is the SSOT, the generated files are derived. Carries HeySpex-only extras (`lane`, `color`, `owned_paths`, `golden_cases`, and `source_attribution` when imported) stripped on compile. `owned_paths` is the machine-checkable file-ownership set for parallel-agent stomp-detection; `lane` remains a human label. An **imported** agent (community-collection per HS-SURM-TMXZ-EPIC-default-agent-roster-and-import-path AC#2, or own-agent per HS-11ME-1NL4-EPIC-import-and-adopt-your-own-existing-agent) records its provenance in `source_attribution` (collection, url, path, commit, license, imported_at); authored agents omit it. Evergreen (does not close). See HS-XNX5-UQHA-MIL-agent-home. |
|
|
158
|
+
| `golden-case` | `agents/golden-cases/` | — | A saved **eval fixture** for one agent identity: the prompt (and optional setup + deterministic graders) the test-before-publish harness runs against a draft agent (HS-R1JM-OAG3-EPIC-agent-testing-harness-try-a-draft-agent). Stored under the `agents/` tree so fixtures version beside the identities they exercise in the same git history. Evergreen (updated in place). Introduced by HS-8AQT-J6FU-TASK-golden-case-vault-artifact-format-and-st. |
|
|
159
|
+
| `branch-brief` | `branches/` | — | "What this git branch is trying to do, and how it actually went." Plan-vs-actual + evidence for one branch. |
|
|
160
|
+
| `memory-lesson` | `memory/lessons/` | — | "Here's what went wrong and how to avoid it." |
|
|
161
|
+
| `memory-decision` | `memory/decisions/` | — | "Here's what we chose and why." |
|
|
162
|
+
| `memory-reference` | `memory/references/` | — | "Here's where to look for X." |
|
|
163
|
+
| `memory-ui-pattern` | `memory/ui-patterns/` | — | "Here's a reusable console interaction/visual pattern to copy." |
|
|
164
|
+
| `memory-ux-principle` | `memory/ux-principles/` | — | "Here's a cross-brand UX rule (what/why) before implementation." |
|
|
165
|
+
| `protocol` | `protocols/` | Memory subsection | Repeatable how-we-work rules for agents/humans (session-close, memory capture, MCP usage). Browsed under Memory → Protocols in console; not a peer nav item beside Memory. |
|
|
166
|
+
| `review` | `reviews/` | — | Companion fill-in workspace for an `in_review` parent spec — acceptance verification, reviewer notes, memory candidates, decision. One per parent, suffix-matched 1:1. |
|
|
167
|
+
| `business-positioning` | `business/positioning/` | — | Brand H1, taglines, audience qualifier, message hierarchy. |
|
|
168
|
+
| `business-pricing` | `business/pricing/` | — | Tier tables, AI add-on terms, discount/refund policy. |
|
|
169
|
+
| `business-marketing` | `business/marketing/` | — | Channels, launches, campaigns, copy decks. |
|
|
170
|
+
| `business-model` | `business/model/` | — | Unit economics, cost structure, monetization decisions. |
|
|
171
|
+
| `roadmap` | `roadmaps/` | — | Phased plan orchestrating tasks/epics; compact `roadmap_manifest` for indexer/CLI (adr-0012-roadmap-storage). |
|
|
172
|
+
| `capture` | `captures/` | — | Concise capture entry; `kind:` field discriminates idea / bug-fix / clip / reference / question / spec-import. Replaces the legacy `type: idea` entity (renamed 2026-05-22 per HS-B2B8-DLQI-EPIC-capture-rename-migration-idea-to-capture). `spec-import` is the **import-origin** kind — one capture per imported foreign doc, created by the bulk spec-import feature (HS-8V8T-8SBG-EPIC-first-connect-rough-import / HS-ROIU-9P4B-EPIC-import-preview-and-confirm); grounding HS-J7T5-VEW8-RES-import-specs-one-click-feature-pipeline. |
|
|
173
|
+
| `research` | `research/` | — | Audit reports, feature inventories, exploratory notes. |
|
|
174
|
+
| `planning-flow` | `flows/` | — | Epic lifecycle orchestration diagram (mermaid source + canvas projection). |
|
|
175
|
+
| `draft` | `drafts/` | — | Ingested content awaiting triage. |
|
|
176
|
+
| `daily` | `daily/` | — | Optional daily-note scratchpad. |
|
|
177
|
+
| `run-retrospective` | `dev-factory/reports/retrospectives/` (outside `specs/`, sibling to `heyspex.yaml`/`.heyspex/`) | — | A **generated** run-close record — never hand-authored, not scheduled/claimable, not a wikilink-addressable spec. One file per COO-dispatcher run, `<runId>.md` (`runId` = the run's milestone id), produced deterministically by `dev-factory/lib/retrospective.mjs` from `run-events.jsonl` + the gate ledger + `coo-dispatcher-state.json`. Frontmatter: `runId`, `generatedAt`, `shippedUnits[]` (gate-verified units), `autoAppliedDecisions[]` (dispatcher auto-applies), `stoppedReason`, `restartCondition`, `ownerGates[]` (pending owner-only gates). Body: the three Retrospective sections (what went well / what could be improved / actionable next steps). Read by What's Next's Retrospective hero (Assisted/Autonomous fronts) — see HS-4HI5-JEPA-EPIC-what-s-next-multi-run-mode-run-dashboard and the-retrospective-is-a-generated-run-rec. |
|
|
178
|
+
|
|
179
|
+
Adding a new entity type requires an ADR. `branch-brief` was added by adr-0008-branch-brief-and-evidence-schema; `roadmap` by adr-0012-roadmap-storage; all other core types ratified at adr-0001-vault-format. `milestone` is the exception that proves the rule: the type was used informally first — 33 `HS-MIL-*` files (e.g. HS-RM22-IART-MIL-console-ia-restructure) were hand-authored before formalization — so rather than a standalone ADR, the convention is ratified by its introduction lineage, HS-VK7C-MILE-EPIC-milestone-entity-type-and-surfacing (this schema row, the validator, MCP support) followed by HS-OFR5-M2J3-EPIC-introduce-milestones-as-highest-entity (required-parent-on-epics + the roadmap drilldown). The canonical hierarchy these two epics serve is documented in [[spec-hierarchy]].
|
|
180
|
+
|
|
181
|
+
`pillar` follows the same milestone-precedent (no standalone "introduce the entity type" ADR): ratified by its introduction lineage HS-EBIL-0011-EPIC-goal-hierarchy-l2-strategic-pillars-l3 (the L2 perpetual-Pillars epic, sibling of HS-OR8V-0010-EPIC-north-star-vision-first-class-entity in HS-J6K8-NSPL-MIL-north-star-and-strategic-pillars-hierarchy) plus the design captured in HS-AWDI-PILR-RES-pm-perpetual-container-terminology; the privacy-boundary side of the work (aggregate-learning telemetry on the Pillar Library) is in adr-0016-pillar-library-privacy-boundary. The 2026-05-31 resolution that produced the Pillar tier also retired the previously planned L3 Themes tier (per-epic teleological anchoring collapsed into perpetual Pillars). First canonical Pillar filed: HS-PILR-pillars (the meta-Pillar; dogfooding instance).
|
|
182
|
+
|
|
183
|
+
`agent` follows the same milestone/pillar-precedent (no standalone "introduce the entity type" ADR): ratified by its introduction lineage HS-XNX5-UQHA-MIL-agent-home (this schema row, the frontmatter-schema branch, the `KIND_RULES`/`TYPE_TO_FOLDER` registration, and the compiler that exports identities to host-native `.claude/agents`/`.cursor/agents` formats). The agent identity is the durable, user-authored counterpart to the ephemeral control-plane presence (`active_claims`) — the vault holds _who an agent is_, the control plane holds _what it is doing now_. Positioning context: HS-O46R-R30X-RES-agent-layer-as-the-demand-side-twin-of-t.
|
|
184
|
+
|
|
185
|
+
`golden-case` follows the same introduction-lineage precedent under HS-R1JM-OAG3-EPIC-agent-testing-harness-try-a-draft-agent / HS-8AQT-J6FU-TASK-golden-case-vault-artifact-format-and-st: a first-class vault artifact for agent eval fixtures (not JSON sidecars or console-only blobs). Bodies follow a fixed section contract; optional deterministic graders validate against `specs/schemas/golden-case-body.schema.json`.
|
|
186
|
+
|
|
187
|
+
## Lifecycle classes
|
|
188
|
+
|
|
189
|
+
Entity types fall into four lifecycle classes. The class determines which subset of the [universal status enum](#frontmatter-schemas) a type uses, when its `canonical:` flag flips, and what the close-out ritual is. **A reader asking _"can I flip this file's status to `in_review`?"_ should consult this section first — the answer depends entirely on which class the file's type belongs to.**
|
|
190
|
+
|
|
191
|
+
### Evergreen (living reference substrate)
|
|
192
|
+
|
|
193
|
+
`l1` · `l2` · `l3` · `adr` · `pillar` · `agent` · `golden-case` · `protocol` · `memory-lesson` · `memory-decision` · `memory-reference` · `memory-ui-pattern` · `memory-ux-principle` · `research` · `business-positioning` · `business-pricing` · `business-marketing` · `business-model`
|
|
194
|
+
|
|
195
|
+
These are **standalone reference artifacts**. `status: open` is the resting state and stays the resting state for the doc's entire life. There are no `in_review` or `closed` transitions — the close-as-historical-record ritual does not apply.
|
|
196
|
+
|
|
197
|
+
- **Updates** happen in-place: amend the body, bump `updated:`, append a change-log row.
|
|
198
|
+
- **Supersession** is the only "lifecycle event" — record it via relational fields (`supersedes:` / `superseded_by:` on ADRs, `superseded_by:` on memories and research, `canonical: false` as the universal drift tombstone per canonicalization-arbiter-is-link-graph-not-policy). The original stays as the historical record at `status: open`.
|
|
199
|
+
- **Research lineage** to downstream artifacts is recorded via `enhances:`, `spawned_epics:`, `bound_epic:`, `incorporated_into:` — these are relational edges, **not** status transitions. See research-is-evergreen for the full rule and the deferred MCP-tool / UI-epic / validator surfaces still being remediated.
|
|
200
|
+
|
|
201
|
+
Session-close protocol carve-out: an agent who touched an evergreen doc this session **must not** flip its status. See session-close-protocol step 1.
|
|
202
|
+
|
|
203
|
+
### Trackable plan-side (open → in_progress → in_review → closed)
|
|
204
|
+
|
|
205
|
+
`task` · `epic` · `milestone` · `diagnose` · `review` · `branch-brief` · `planning-flow`
|
|
206
|
+
|
|
207
|
+
These are **work containers** with a definite scope and a moment at which they're done. They follow the full status flow and are **frozen at close** per closed-trackable-specs-are-historical-record-not-living-docs — the body becomes historical record of the plan as it was at the moment of close.
|
|
208
|
+
|
|
209
|
+
- **Session close** flips completed-this-session specs to `status: in_review` and creates an `HS-REV-<suffix>` companion (session-close-protocol).
|
|
210
|
+
- **Reviewer close** flips `in_review → closed`, flips `canonical: true → false`, optionally sets the `outcome:`/`outcome_note:` verdict (`met` | `partially-met` | `not-met` — reviewer judgment, never inferred; see §Iteration lineage), and freezes the frontmatter forever after.
|
|
211
|
+
- **`branch-brief`** closes when the branch ships; **`planning-flow`** closes with its bound epic.
|
|
212
|
+
|
|
213
|
+
### Single-shot ingest (triage-driven; promotion replaces closure)
|
|
214
|
+
|
|
215
|
+
`capture` · `draft` · `daily`
|
|
216
|
+
|
|
217
|
+
These are **inbound surfaces** scoped to one input session. They don't close in the lifecycle sense — they get **promoted** (capture → research / task / epic; draft → some other type) or remain as a dated scratchpad (daily).
|
|
218
|
+
|
|
219
|
+
- **`capture`** carries `promoted_to:` as a binary pointer to the first downstream artifact and `informs_research:` as the M:N lineage list (see the `capture` schema below).
|
|
220
|
+
- **`draft`** is triaged by editing the `type:` field in place and moving the file to the destination folder.
|
|
221
|
+
- **`daily`** is a single-date scratchpad — no status semantics; the date IS the lifecycle.
|
|
222
|
+
|
|
223
|
+
### Per-instance (class declared at filing time)
|
|
224
|
+
|
|
225
|
+
`roadmap`
|
|
226
|
+
|
|
227
|
+
`roadmap` is the one type whose lifecycle class depends on the specific roadmap. A perpetual product roadmap is evergreen; a per-quarter ship plan is trackable. Each `HS-ROADMAP-*` declares its class via its own `status:` value at filing: roadmaps that never close stay `open`; roadmaps with a defined ship horizon use the trackable flow. See adr-0012-roadmap-storage for the compact-manifest design that supports both shapes.
|
|
228
|
+
|
|
229
|
+
### Cross-reference summary
|
|
230
|
+
|
|
231
|
+
| Class | Status values used | Close-as-historical-record? | `canonical: false` trigger |
|
|
232
|
+
| ------------------- | ----------------------------------------------------------------- | --------------------------------- | ------------------------------ |
|
|
233
|
+
| Evergreen | `open` (resting state) | No | Supersession (relational edge) |
|
|
234
|
+
| Trackable plan-side | `open` → `in_progress` → `in_review` → `closed` (plus `deferred`) | Yes — frozen at close | Close-out write |
|
|
235
|
+
| Single-shot ingest | `open` (capture/draft pre-promotion) / N/A (daily) | No — promoted or archived by date | Not used |
|
|
236
|
+
| Per-instance | Declared at filing | Per-instance | Per-instance |
|
|
237
|
+
|
|
238
|
+
## Identity, IDs, and filenames
|
|
239
|
+
|
|
240
|
+
> [!important] Identifier format migration in progress (updated 2026-08-11)
|
|
241
|
+
> The vault is migrating to **file-key-first** (era 3) ordering: `HS-<file key>-<family key>-<type label>-<title slug>` — the leading token after `HS-` is the **unique per-file ID**, not the family (HS-6B0S-Q9YG-RES-naming-system-v3-file-key-first, rulings naming-v3-7-rulings-hs-namespace-kept; owner re-confirmed the token order 2026-08-11). On disk today most files are still **family-first** (era 2, `HS-<family key>-<type label>-…`) or legacy type-first (era 1); the vault-wide rename is built and **pending owner review/execution** (HS-L6Y4-01D7-EPIC-deterministic-rename-with-link-rewrite). The type label's position (1st/2nd/3rd token) tells you a filename's era — never guess which token is the file ID by position alone; read frontmatter `file_id:`/`id:`. The ID-format and filename tables below still show older orderings pending the flip; the token **names** are canonical in every era. Plain-language explainer: how-spec-ids-and-naming-work.
|
|
242
|
+
|
|
243
|
+
### Identifier tokens (file key · family key · type label · title slug)
|
|
244
|
+
|
|
245
|
+
A managed spec's basename decomposes into named tokens. Canonical names per glossary §Identifier anatomy and HS-37O7-T9KP-RES-identifier-token-terminology-family-key (external-validated; supersedes the "pipeline ID / type token / file ID" names in HS-MF8M-CCVE-RES-family-first-spec-identifier-format-hs-i).
|
|
246
|
+
|
|
247
|
+
| Token | Example | Role |
|
|
248
|
+
| -------------- | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
249
|
+
| **File key** | `L6Y4` | The per-file 4+ char uppercase-alphanumeric key (at least one letter), **unique vault-wide** — the identity and one-token citation handle for exactly one file. Recorded in frontmatter `file_id:` (SSOT) and embedded in the filename; becomes the `id:` itself (`id: HS-L6Y4`) under era 3. Server-minted, never hand-picked. |
|
|
250
|
+
| **Family key** | `P2TR` | The shared 4+ char alphanumeric code that groups one initiative's specs — an epic and all its child tasks, research, and reviews — into one greppable **family** (`grep HS-P2TR` returns the whole family). Shared across the family; uniqueness is enforced on the full **basename** per kind, never on the family key alone (see vault-id-assignment-protocol §Shared-suffix families). |
|
|
251
|
+
| **Type label** | `TASK` | The entity-kind token (`TASK`, `EPIC`, `MILESTONE`, `RESEARCH`, `REVIEW`, …). A **human-readable hint only**. |
|
|
252
|
+
| **Title slug** | `verification-state-schema` | The lowercased-hyphenated descriptive tail derived from `title:` — the part that makes each basename unique within a family. |
|
|
253
|
+
|
|
254
|
+
**Filename shapes (era = type-label position):**
|
|
255
|
+
|
|
256
|
+
- **File-key-first (era 3, ratified target):** `HS-<file key>-<family key>-<type label>-<title slug>.md` → `HS-L6Y4-01D7-EPIC-deterministic-rename-with-link-rewrite.md` — lands vault-wide with HS-L6Y4-01D7-EPIC-deterministic-rename-with-link-rewrite.
|
|
257
|
+
- **Family-first (era 2, current on disk / current minting):** `HS-<family key>-<type label>-[<file key>-]<title slug>.md` → `HS-P2TR-TASK-verification-state-schema.md`, `HS-0G910-EPIC-G3D3-api-foundation-keys-scopes-error.md`
|
|
258
|
+
- **Type-first (era 1, legacy):** `HS-<type label>-<family key>-<title slug>.md` → `HS-TASK-P2TR-verification-state-schema.md`
|
|
259
|
+
|
|
260
|
+
**Routing rule (SSOT for entity type):** code MUST determine a spec's entity type from the frontmatter **`type:`** field (and its directory), **never** by parsing the type label out of the filename. The type label is a convenience hint that survives out of directory context (wikilinks, search results, clipboard, terminal output); it is **not** authoritative and must never drive a mutation, a route, or a reclassification on its own. This is the semantic-identifier guardrail from HS-MF8M-CCVE-RES-family-first-spec-identifier-format-hs-i (don't route on parsed-ID semantics).
|
|
261
|
+
|
|
262
|
+
**Retired / avoid:** **"suffix"** (the legacy name for the family key — self-contradictory once the family key leads), **"pipeline ID"** (overloaded with CI/CD + the feature-pipeline graph), **"prefix" / "type prefix"** for the family key (industry convention encodes _type_, not a family). The legacy term `<suffix>` still appears in the tables below and in the `legacy_slug_only` naming atoms until the Phase 3 codegen flip.
|
|
263
|
+
|
|
264
|
+
### ID format
|
|
265
|
+
|
|
266
|
+
| Entity type | ID format | Example |
|
|
267
|
+
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
|
|
268
|
+
| `l1` | `HS-L1` | `HS-L1` |
|
|
269
|
+
| `l2` | `HS-L2-<UPPER>` | `HS-L2-ENTITY`, `HS-L2-FOUNDATIONS` |
|
|
270
|
+
| `l3` | `HS-UC-<short>` | `HS-UC-CAPTURE` |
|
|
271
|
+
| `adr` | `HS-ADR-NNNN` (zero-padded sequence) | `HS-ADR-0001` |
|
|
272
|
+
| `task` | `HS-TASK-<suffix>` — `<suffix>` is 4+ random A-Z0-9 (vault-id-assignment-protocol). Pre-2026-05-22 entries (`HS-NNNN`, `HS-<4+ A-Z0-9>`) were migrated to this prefix. | `HS-TASK-K7M2` |
|
|
273
|
+
| `epic` | `HS-EPIC-<suffix>` — same rules | `HS-DE8L`, `HS-V888` |
|
|
274
|
+
| `milestone` | `HS-MIL-<suffix>` — `<suffix>` is 4+ uppercase `A–Z0–9` (vault-id-assignment-protocol); legacy 4-character mnemonic IDs (e.g. `HS-RM22`) remain valid | `HS-RM22`, `HS-1JC8` |
|
|
275
|
+
| `diagnose` | `HS-DIAG-<suffix>` — `<suffix>` is 4+ random A-Z0-9 (vault-id-assignment-protocol) | `HS-DIAG-K7M2` |
|
|
276
|
+
| `pillar` | `HS-PILR-<slug>` (canonical; slug uniquely identifies the concept; no random suffix) or `HS-PILR-<suffix>-<slug>` (customer-scoped; random 4+ A-Z0-9) | `HS-PILR-pillars`, `HS-PILR-scaling`, `HS-PILR-K7M2-team-onboarding` |
|
|
277
|
+
| `branch-brief` | `HS-BB-<slug>` | `HS-BB-feature-checkout-redesign` |
|
|
278
|
+
| `memory-lesson` | `HS-LES-<slug>` | `HS-LES-bd-process-leak` |
|
|
279
|
+
| `memory-decision` | `HS-DEC-<slug>` | `HS-DEC-dep-relate-for-epic-children` |
|
|
280
|
+
| `memory-reference` | `HS-REF-<slug>` | `HS-REF-dolt-time-travel-docs` |
|
|
281
|
+
| `memory-ui-pattern` | `HS-UIP-<slug>` | `HS-UIP-rail-active-vs-keyboard-cursor` |
|
|
282
|
+
| `memory-ux-principle` | `HS-UXP-<slug>` | `HS-UXP-toggle-current-state-semantics` |
|
|
283
|
+
| `protocol` | `HS-PROTO-<slug>` | `HS-PROTO-session-close` |
|
|
284
|
+
| `review` | `HS-REV-<suffix>` — `<suffix>` matches the parent task/epic id 1:1 (e.g. parent `HS-76RX` → review `HS-QMHO`). Detection: [`extractSpecSuffix` in `console/src/lib/vault.ts:155`](../console/src/lib/vault.ts). | `HS-QMHO`, `HS-R3HO`, `HS-CCEQ` |
|
|
285
|
+
| `business-positioning` | `HS-BIZ-POS-<slug>` | `HS-BIZ-POS-2nd-brain-harness-for-specs` |
|
|
286
|
+
| `business-pricing` | `HS-BIZ-PRI-<slug>` | `HS-BIZ-PRI-tiers-and-byok-2026-05` |
|
|
287
|
+
| `business-marketing` | `HS-BIZ-MKT-<slug>` | `HS-BIZ-MKT-launch-playbook-companion` |
|
|
288
|
+
| `business-model` | `HS-BIZ-MOD-<slug>` | `HS-BIZ-MOD-flat-per-vault-economics` |
|
|
289
|
+
| `roadmap` | `HS-ROADMAP-<SLUG>` | `HS-ROADMAP-PRODUCT` |
|
|
290
|
+
| `research` | `HS-RES-<suffix>` — legacy `HS-RES-NNN` or random `HS-RES-<4+ A-Z0-9>` (vault-id-assignment-protocol) | `HS-RES-001`, `HS-RES-K7M2` |
|
|
291
|
+
| `capture` | `HS-CAP-<suffix>` — same rules; legacy `HS-IDEA-<suffix>` preserved in `legacy_idea_id:` for archaeology | `HS-CAP-JKLN`, `HS-CAP-OAP3` |
|
|
292
|
+
| `agent` | `HS-AGENT-<suffix>` — `<suffix>` is 4+ random A-Z0-9 (vault-id-assignment-protocol) | `HS-634I` |
|
|
293
|
+
| `golden-case` | `HS-GCASE-<suffix>` — same rules | `HS-HPIO` |
|
|
294
|
+
| `planning-flow` | `HS-FLOW-NNN` | `HS-FLOW-001` |
|
|
295
|
+
| `draft` | `HS-DRAFT-<slug>` | `HS-DRAFT-2026-05-14-1130-article-link` |
|
|
296
|
+
| `daily` | `HS-DAILY-YYYY-MM-DD` | `HS-DAILY-2026-05-14` |
|
|
297
|
+
|
|
298
|
+
**New task/epic/research/capture IDs** (console `POST /api/specs`, MCP `heyspex_save_research`, agents): allocate a random 4-character suffix from `A–Z` and `0–9`, checking the full vault for collisions (frontmatter `id` and filename prefix). When every combination at the current length is taken, the suffix grows to 5 characters, then 6, and so on. Legacy sequential IDs (`HS-NNNN`, `HS-RES-NNN`, `HS-IDEA-*`, slug-only research filenames) remain valid in the read-path until HS-23PN-9HVY-TASK-capture-rename-repo-wide-wikilink-rewrite retires them. Validate with `npm run validate:vault-ids` at the repo root.
|
|
299
|
+
|
|
300
|
+
### Filename derivation
|
|
301
|
+
|
|
302
|
+
The filename is **derived from the ID + an optional slug**, lowercased, with the same prefix the ID uses minus the `HS-` prefix (kept lowercase in filenames for readability):
|
|
303
|
+
|
|
304
|
+
| Entity | Filename pattern | Example |
|
|
305
|
+
| --------------------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
|
|
306
|
+
| `l1` | `heyspex-north-star.md` (literal, only one) | `heyspex-north-star.md` |
|
|
307
|
+
| `l2` | `<topic>.md` (literal slug) | `entity-model.md` |
|
|
308
|
+
| `l3` | `uc-<short>.md` | `uc-capture-intent.md` |
|
|
309
|
+
| `adr` | `adr-NNNN-<slug>.md` | `adr-0001-vault-format.md` |
|
|
310
|
+
| `task` | `HS-TASK-<suffix>-<slug>.md` | `HS-TASK-K7M2-fix-foo.md` |
|
|
311
|
+
| `epic` | `HS-EPIC-<suffix>-<slug>.md` | `HS-0007-EPIC-console-resilience.md`, `HS-W9ZE-EPIC-design-system-enforcement-auto-surface-u.md` |
|
|
312
|
+
| `milestone` | `HS-MIL-<suffix>-<slug>.md` | `HS-IART-MIL-console-ia-restructure.md` |
|
|
313
|
+
| `diagnose` | `HS-DIAG-<suffix>-<slug>.md` | `HS-DIAG-K7M2-console-startup-lag.md` |
|
|
314
|
+
| `pillar` | `HS-PILR-<slug>.md` (canonical; slug IS the ID with no random suffix) or `HS-PILR-<suffix>-<slug>.md` (customer-scoped) | `HS-PILR-pillars.md`, `HS-PILR-K7M2-team-onboarding.md` |
|
|
315
|
+
| `branch-brief` | `<branch-slug>.md` | `feature-checkout-redesign.md` |
|
|
316
|
+
| `memory-lesson` | `<slug>.md` | `bd-process-leak.md` |
|
|
317
|
+
| `memory-decision` | `<slug>.md` | `dep-relate-for-epic-children.md` |
|
|
318
|
+
| `memory-reference` | `<slug>.md` | `dolt-time-travel-docs.md` |
|
|
319
|
+
| `memory-ui-pattern` | `<slug>.md` | `rail-active-vs-keyboard-cursor.md` |
|
|
320
|
+
| `memory-ux-principle` | `<slug>.md` | `toggle-current-state-semantics.md` |
|
|
321
|
+
| `protocol` | `<slug>.md` | `session-close-protocol.md` |
|
|
322
|
+
| `review` | `HS-REV-<suffix>-<slug>.md` (slug truncated from parent's slug, ≤40 chars) | `HS-SK1L-REV-hs-idea-skill-four-beats-layered-confirms.md` |
|
|
323
|
+
| `research` | `HS-RES-<suffix>-<slug>.md` (legacy: `<slug>.md` only) | `HS-RES-K7M2-agent-governance.md` |
|
|
324
|
+
| `capture` | `HS-CAP-<suffix>-<slug>.md` | `HS-CAP-JKLN-vault-triage.md` |
|
|
325
|
+
| `agent` | `HS-AGENT-<suffix>-<slug>.md` | `HS-9TNK-AGENT-code-reviewer.md` |
|
|
326
|
+
| `golden-case` | `HS-GCASE-<suffix>-<slug>.md` | `HS-R4VW-GCASE-review-missing-ac.md` |
|
|
327
|
+
| `planning-flow` | `HS-FLOW-<NNN>-<slug>.md` | `HS-FLOW-001-epic-planning-flow-studio.md` |
|
|
328
|
+
| `draft` | `<slug>.md` | `2026-05-14-1130-article-link.md` |
|
|
329
|
+
| `daily` | `YYYY-MM-DD.md` | `2026-05-14.md` |
|
|
330
|
+
|
|
331
|
+
Slug rules: lowercase, ASCII, dash-separated, no trailing punctuation, no leading number for non-task types.
|
|
332
|
+
|
|
333
|
+
> [!note] Branch-brief slug
|
|
334
|
+
> For `branch-brief` the slug is **derived from the git branch name**: lowercased, every run of non-`[a-z0-9]` characters collapsed to a single `-`, trailing `-` stripped. `feature/checkout-redesign` → `feature-checkout-redesign`. The raw, unsanitized branch name is preserved in the required `branch:` field — the slug is for the filesystem and wikilink resolution only; git lookups use `branch:`. Ratified in adr-0008-branch-brief-and-evidence-schema.
|
|
335
|
+
|
|
336
|
+
> [!note] Why not put the ID in the filename for memories?
|
|
337
|
+
> bd memory keys are content-derived (`lessons/bd-process-leak`), and the Builder already thinks in those terms. The filename `bd-process-leak.md` IS the key, the ID is the metadata. Wikilink resolution finds the file by name; the `HS-LES-` prefix in the `id:` field is for the index and for stable cross-references.
|
|
338
|
+
|
|
339
|
+
### ID + filename for the migration
|
|
340
|
+
|
|
341
|
+
The migration plan (migration-from-bd) maps each bd issue to a new HeySpex task ID by sorting bd issues by `created_at` and assigning `HS-U2K9`, `HS-FMWM`, etc., in that order. The original bd ID is preserved as `legacy_bd_id` in frontmatter so cross-references in old commits/logs remain resolvable.
|
|
342
|
+
|
|
343
|
+
## Frontmatter schemas
|
|
344
|
+
|
|
345
|
+
Every spec opens with a YAML frontmatter block. The schemas below define **required** fields (must be present and non-empty) and **optional** fields (may be omitted).
|
|
346
|
+
|
|
347
|
+
Universal fields (every spec has these):
|
|
348
|
+
|
|
349
|
+
```yaml
|
|
350
|
+
id: # required, string, matches the entity type's ID format
|
|
351
|
+
name: # required, string, human-readable title
|
|
352
|
+
type: # required, one of the entity type values above
|
|
353
|
+
status: # required, see status enum below
|
|
354
|
+
priority: # required, integer 0–4 (0 = highest)
|
|
355
|
+
owner: # required, string (email or handle) — the ORIGINATING + accountable human (doubles as author).
|
|
356
|
+
# See §Authorship provenance below.
|
|
357
|
+
created: # required, ISO-8601 date (YYYY-MM-DD)
|
|
358
|
+
updated: # required, ISO-8601 date
|
|
359
|
+
contributors: # optional, list of "Name <email>" — OTHER humans who later enhanced the doc (append-only;
|
|
360
|
+
# OMIT when empty). Auto-stamped, never hand-maintained. See §Authorship provenance.
|
|
361
|
+
assisted_by: # optional, list of "AGENT" or "AGENT:MODEL" — agents/IDEs + model that assisted (append-only;
|
|
362
|
+
# OMIT when empty). Auto-stamped, never hand-maintained. See §Authorship provenance.
|
|
363
|
+
tags: # optional, list of strings
|
|
364
|
+
related: # optional, list of wikilinks (alternative to inline body links)
|
|
365
|
+
what_matters: # optional, enum: star | heart — per-spec user-priority signal
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
**`what_matters`** is the per-spec user-priority signal that replaced the retired What Matters column (scheduler-and-whats-next-what-matters-column-mechanics, HS-78E7-Y9OJ-EPIC-deterministic-priority-scheduler). It is optional and two-level:
|
|
369
|
+
|
|
370
|
+
- `star` (★) — _priority_: "consider this please."
|
|
371
|
+
- `heart` (♥) — _very important_: "appreciate this being next if at all possible." A stronger signal than `star`.
|
|
372
|
+
- absent — unflagged (no default is injected).
|
|
373
|
+
|
|
374
|
+
The value is held verbatim; an unrecognized value is tolerated by the parser and emits a warn-only `INVALID_WHAT_MATTERS` validator notice rather than an error. A Phase 7b scheduler stage consumes it for ordering.
|
|
375
|
+
|
|
376
|
+
### Authorship provenance
|
|
377
|
+
|
|
378
|
+
Three universal fields carry GitHub-faithful provenance, following the cross-foundation `Assisted-by:` convention (Linux Kernel, Fedora, LLVM, OpenTelemetry) that keeps the human as the sole accountable author and records AI as a tool that _assisted_, not a co-author. Origin: HS-N1WG-W48S-RES-git-github-authorship-attribution-best-p → HS-Y4JH-IKIM-EPIC-authorship-provenance-frontmatter-owner. The SSOT question (frontmatter vs git history) is resolved in provenance-frontmatter-is-ssot-not-git-echo.
|
|
379
|
+
|
|
380
|
+
| Field | Who | Item format | Cardinality |
|
|
381
|
+
| -------------- | ----------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------- |
|
|
382
|
+
| `owner` | the **originating + accountable** human (doubles as author) | handle or email (e.g. `pwher`) | single scalar |
|
|
383
|
+
| `contributors` | **other** humans who later enhanced the doc | `Name <email>` — GitHub form, round-trips with the `Co-authored-by:` trailer | append-only list |
|
|
384
|
+
| `assisted_by` | agents/IDEs + model that assisted | `AGENT` or `AGENT:MODEL` — e.g. `Claude Opus 4.8`, `Cursor` | append-only list |
|
|
385
|
+
|
|
386
|
+
Semantics (apply to every entity kind):
|
|
387
|
+
|
|
388
|
+
- **`owner` is universally required** and unchanged in type — only its meaning is enriched here (originator + accountable, not merely a pointer). A later ownership _transfer_ is not preserved in frontmatter; git history (first-commit author) retains the original creator. Acceptable trade per HS-N1WG-W48S-RES-git-github-authorship-attribution-best-p.
|
|
389
|
+
- **`contributors` and `assisted_by` are universal-but-optional and omit-when-empty** — they are not emitted as empty lists, so a solo-vault doc stays clean and only grows a list once a second human or an agent touches the doc.
|
|
390
|
+
- **Append-only + de-dup, never reorder/remove.** A new acting human ≠ `owner` is appended to `contributors`; an acting agent is appended to `assisted_by`; an entry already present is not duplicated.
|
|
391
|
+
- **Auto-stamped, never hand-maintained.** Seeded at creation (`owner` from the resolved user, `assisted_by` from the acting agent) and appended on edit, sourced from the existing claim/session trail (Neon `active_claims`). Authoring/wiring lives in HS-Y4JH-IKIM-EPIC-authorship-provenance-frontmatter-owner.
|
|
392
|
+
|
|
393
|
+
> [!note] Schema addition self-gating
|
|
394
|
+
> Per entity-model-self-gates-schema-changes-via-adr, new reserved frontmatter keys are normally gated behind an ADR. `contributors`/`assisted_by` are admitted here **without a standalone ADR** under the same milestone-precedent the `milestone` and `pillar` entity types used: they are additive, optional, omit-when-empty enrichments of the existing universal `owner` field (not a new entity type or a new lifecycle), ratified by their introduction lineage HS-N1WG-W48S-RES-git-github-authorship-attribution-best-p → HS-Y4JH-IKIM-EPIC-authorship-provenance-frontmatter-owner. The decision rationale is recorded in provenance-frontmatter-is-ssot-not-git-echo.
|
|
395
|
+
|
|
396
|
+
### Artifact linkage
|
|
397
|
+
|
|
398
|
+
An optional `artifact:` mapping records a published Claude Artifact that this spec/doc is the vault source for, so the artifact is never the only copy of its content — HS-6YIS-5GSW-EPIC-artifacts-as-vault-documents. **Universal** — unlike the type-specific schemas below, it attaches to ANY entity kind (a task, an epic, a research doc, a memory doc, or a non-frontmatter file like a roadmap page — see the HTML variant below), because a published artifact can belong to a doc at any level, not one lifecycle stage.
|
|
399
|
+
|
|
400
|
+
```yaml
|
|
401
|
+
artifact:
|
|
402
|
+
{ title: "…", url: "https://claude.ai/code/artifact/…", version: "…", updated: "2026-08-23" }
|
|
403
|
+
# title: required when artifact: is present — the artifact's display title (matches its published <title>/heading).
|
|
404
|
+
# url: required — the published URL.
|
|
405
|
+
# version: optional, string — the last-published version stamp this vault file was confirmed against. This is
|
|
406
|
+
# a LOCAL claim, not a live read: it is the freshness anchor for the push-first stale-guard
|
|
407
|
+
# (HS-6YIS-5GSW-EPIC part 2) — before publishing this file over the artifact, the publishing session
|
|
408
|
+
# reads the LIVE page and confirms it is not ahead of this stamp, THEN writes the new version back
|
|
409
|
+
# here after a successful publish. Never hand-edited to "catch up" without actually reading the live
|
|
410
|
+
# page first (the incident this field exists to prevent: [[a-published-artifact-and-its-vault-copy]]).
|
|
411
|
+
# updated: optional, ISO-8601 date — when this vault file was last published/stamped against the artifact.
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
Either a single-line flow mapping (above) or an equivalent nested block mapping is valid YAML; the artifact-publish tooling (HS-6YIS-5GSW-EPIC-artifacts-as-vault-documents part 2, `scripts/hs-artifact.mjs`) reads and writes the flow-mapping form. Omit the whole `artifact:` key when the doc has no published artifact (omit-when-empty, same posture as `contributors`/`assisted_by`).
|
|
415
|
+
|
|
416
|
+
**Non-frontmatter vault files** (a raw HTML page under `specs/roadmap/`, for example, has no YAML frontmatter at all): the same four fields are carried as a single machine-readable `ARTIFACT-STAMP: {...}` JSON line inside the file's existing leading `<!-- -->` source-of-truth comment, read/written by the same tooling. This is the shape `specs/roadmap/heyspex-sprint-roadmap.html` uses.
|
|
417
|
+
|
|
418
|
+
> [!note] Schema addition self-gating
|
|
419
|
+
> Per entity-model-self-gates-schema-changes-via-adr, `artifact:` is admitted here **without a standalone ADR** under the same milestone-precedent as `contributors`/`assisted_by` above: additive, optional, omit-when-empty, not a new entity type or lifecycle — ratified by its introduction lineage, the owner's immediate order following the incident recorded in a-published-artifact-and-its-vault-copy → HS-6YIS-5GSW-EPIC-artifacts-as-vault-documents.
|
|
420
|
+
|
|
421
|
+
Status enum (universal):
|
|
422
|
+
|
|
423
|
+
- `draft` — under active authorship, not yet ratified.
|
|
424
|
+
- `open` — ratified and available to work against (for tasks, epics) or stable (for L1/L2/L3/ADR).
|
|
425
|
+
- `in_progress` — claimed and being executed (tasks only).
|
|
426
|
+
- `in_review` — implementation complete, awaiting human verification before closure (tasks only).
|
|
427
|
+
- `closed` — done (tasks) or superseded (ADRs).
|
|
428
|
+
- `deferred` — **deprecated** (2026-06-24 per parked-is-the-single-hold-status-deferre). Use `status: parked` for indefinite hold or `defer_until:` for dated snooze instead. Kept for read-back-compat only.
|
|
429
|
+
|
|
430
|
+
### Type-specific schemas
|
|
431
|
+
|
|
432
|
+
#### `l1`
|
|
433
|
+
|
|
434
|
+
```yaml
|
|
435
|
+
type: l1
|
|
436
|
+
aliases: # optional, list of alternative names
|
|
437
|
+
brand: # optional, mapping with canonical/variants/pronunciation/comma
|
|
438
|
+
domains: # optional, list of relevant domains
|
|
439
|
+
version: # optional, monotonic integer — bumped on every material edit to the record.
|
|
440
|
+
# The alignment-drift detector ([[HS-E3D3-RDFT-EPIC-alignment-drift-detector-into-resolution]])
|
|
441
|
+
# compares the version an epic was last aligned against (its `alignment_baseline`)
|
|
442
|
+
# to this current version; a bump past the baseline surfaces a `drift` resolution item.
|
|
443
|
+
last_edited_at: # optional, ISO-8601 timestamp of the last edit to the record. Timestamp FALLBACK for
|
|
444
|
+
# drift detection when an epic carries no per-layer `alignment_baseline`: the layer's
|
|
445
|
+
# `last_edited_at` newer than the epic's `alignment_reviewed_at` means drift.
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
Only one `l1` exists per vault. The `version` / `last_edited_at` fields are the versioning prerequisites carried from HS-OR8V-0010-EPIC-north-star-vision-first-class-entity; they make the L1 record a drift baseline anchor for the alignment-drift detector.
|
|
449
|
+
|
|
450
|
+
#### `l2`
|
|
451
|
+
|
|
452
|
+
Universal fields only. No required L2-specific fields.
|
|
453
|
+
|
|
454
|
+
#### `l3` (use case)
|
|
455
|
+
|
|
456
|
+
```yaml
|
|
457
|
+
type: l3
|
|
458
|
+
actors: # required, list of actor names from L1
|
|
459
|
+
trigger: # required, string — what initiates this use case
|
|
460
|
+
outcomes: # required, list — observable end states
|
|
461
|
+
depends_on: # optional, list of wikilinks to other use cases
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
#### `adr`
|
|
465
|
+
|
|
466
|
+
```yaml
|
|
467
|
+
type: adr
|
|
468
|
+
decision_date: # required, ISO-8601 date
|
|
469
|
+
deciders: # required, list of strings
|
|
470
|
+
supersedes: # optional, wikilink to ADR this replaces
|
|
471
|
+
superseded_by: # optional, wikilink to ADR replacing this
|
|
472
|
+
status: # adr-status enum: proposed | accepted | deprecated
|
|
473
|
+
# `superseded` is DEPRECATED 2026-06-03 per [[superseded-enum-values-deprecated-use-canonical-false-and-superseded-by]]
|
|
474
|
+
# New writes: set `canonical: false` + `superseded_by: '[[<successor>]]'` instead. Existing
|
|
475
|
+
# ADRs that already carry `status: superseded` stay as historical record per the
|
|
476
|
+
# immutability principle ([[closed-trackable-specs-are-historical-record-not-living-docs]]) —
|
|
477
|
+
# readers infer `canonical: false` from the legacy value.
|
|
478
|
+
canonical: # universal flag — true (or absent) = current/authoritative; false = historical record
|
|
479
|
+
# (current canonical is at `superseded_by:`). Flipped at supersession-time via
|
|
480
|
+
# [[supersession-protocol]]; frozen thereafter.
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
The ADR-specific `status` enum overrides the universal status enum for ADRs. The `canonical:` field applies to ADRs the same way it does to every spec type.
|
|
484
|
+
|
|
485
|
+
#### `task`
|
|
486
|
+
|
|
487
|
+
```yaml
|
|
488
|
+
type: task
|
|
489
|
+
kind: # one of: infra | foundation | feature | polish (scheduler tier — SSOT is
|
|
490
|
+
# SCHEDULER_KIND_VOCAB in console/src/lib/indexer/vault-rules.mjs). Legacy bd
|
|
491
|
+
# kinds (bug | spike | story | milestone) are retired; migrate via
|
|
492
|
+
# scripts/migrate-to-scheduler-metadata.mjs. Bugs now have their own lane
|
|
493
|
+
# (kind: bug-fix capture → HS-DIAG-* diagnose spec → Resolution surface).
|
|
494
|
+
assignee: # optional, string
|
|
495
|
+
started_at: # optional, ISO-8601 datetime — set on first transition to in_progress
|
|
496
|
+
closed_at: # optional, ISO-8601 datetime
|
|
497
|
+
close_reason: # optional, enum: shipped | deprecated | obsolete | wont_fix | duplicate
|
|
498
|
+
# shipped → "Done" archive view; deprecated* → "Deprecated" archive view
|
|
499
|
+
# `superseded` is DEPRECATED 2026-06-03 per [[superseded-enum-values-deprecated-use-canonical-false-and-superseded-by]]
|
|
500
|
+
# New writes that involve supersession: omit `close_reason` (or use another value
|
|
501
|
+
# like `deprecated`) and set `canonical: false` + `superseded_by:` instead.
|
|
502
|
+
# Existing closed specs with `close_reason: superseded` stay as historical record
|
|
503
|
+
# per immutability ([[closed-trackable-specs-are-historical-record-not-living-docs]]).
|
|
504
|
+
defer_until: # optional, ISO-8601 date — dated snooze evaluated by isDeferredNow(); scheduler-invisible
|
|
505
|
+
# until the date, then auto-returns with no status change ([[parked-is-the-single-hold-status-deferre]]).
|
|
506
|
+
# Distinct from `status: parked` (indefinite hold). Do NOT pair with deprecated `status: deferred`.
|
|
507
|
+
target: # optional, string — repo-relative path(s) of the file(s) an autonomous builder edits
|
|
508
|
+
# for this task (comma-separated for multi-file). DISPATCH METADATA for the dev-factory
|
|
509
|
+
# overnight loop: its backlog selector only dispatches an open, dependency-ready task
|
|
510
|
+
# that carries target:; without it the task is skipped with a warning. Hand-editing this
|
|
511
|
+
# field is allowed (it is not status). Owner-approved 2026-07-04 (HS-BMAW go-live);
|
|
512
|
+
# interim docs lived in dev-factory/README.md §Vault-task target: frontmatter.
|
|
513
|
+
test: # optional, string — the test file that gates the autonomous build of this task
|
|
514
|
+
# (scoped vitest run / self-test). When omitted the gate falls back to tsc --noEmit
|
|
515
|
+
# plus the module's own self-test conventions. Pairs with target: above.
|
|
516
|
+
suggested_model: # optional, string — breakdown-authored Ollama model id for local builder dispatch
|
|
517
|
+
# (e.g. qwen3-coder:30b). Honored as first candidate in scheduler/backlog-selector;
|
|
518
|
+
# falls back through routing-table build chain when unavailable.
|
|
519
|
+
suggested_machine:# optional, string — machine key from routing-table (specops-gpu0, basement-geek, …).
|
|
520
|
+
# Scheduler tries this machine first when reachable + capable.
|
|
521
|
+
recommended_num_ctx: # optional, integer — Ollama num_ctx bucket (16384 | 32768 | 65536 | 131072).
|
|
522
|
+
# pick-num-ctx.mjs honors when ≤ machine ceiling (spec-ops 65536, basement 131072).
|
|
523
|
+
estimated_context_tokens: # optional, integer — breakdown estimate of prompt tokens (target + deps + spec).
|
|
524
|
+
context_files: # optional, list of repo-relative paths — passed to builder.mjs as --extra (types, deps).
|
|
525
|
+
# Omit the target file (builder always reads it). Body duplicate: ## Builder brief.
|
|
526
|
+
fit_assessment: # optional, enum: safe | tight | overflow — breakdown confidence in context fit.
|
|
527
|
+
parallel_safe: # optional, boolean — false when task must not run concurrently (shared config/schema).
|
|
528
|
+
affects_paths: # optional, list of repo-relative paths — read/write set for stomp detection at dispatch.
|
|
529
|
+
parallel_group: # optional, string — wave id; tasks in same group may run together when paths disjoint.
|
|
530
|
+
builder_profile: # optional on child tasks only when inherited from epic; see builder-fleet-capability-reference.
|
|
531
|
+
canonical: # universal flag — true (or absent) = current/authoritative; false = historical record.
|
|
532
|
+
# Flipped to false during the in_review → closed transition for plan-side specs per
|
|
533
|
+
# [[session-close-protocol]] §Reviewer responsibilities step 4, or at supersession per
|
|
534
|
+
# [[supersession-protocol]]. `status: parked` keeps `canonical: true` (paused, not historical).
|
|
535
|
+
superseded_by: # optional, wikilink — pointer to the current canonical when canonical: false.
|
|
536
|
+
# Required when canonical: false AND there is a successor (per [[supersession-protocol]]).
|
|
537
|
+
# When close_reason was historically deprecated|duplicate, this field can still point
|
|
538
|
+
# at the successor; the legacy enum value stays as historical record.
|
|
539
|
+
|
|
540
|
+
# Dependency edges (see "Dependencies" section below)
|
|
541
|
+
blocks: # optional, list of wikilinks — this task blocks these
|
|
542
|
+
blocked_by: # optional, list of wikilinks — these tasks block this one
|
|
543
|
+
related: # optional, list of wikilinks — soft, navigational
|
|
544
|
+
parent: # optional, single wikilink — hierarchical parent
|
|
545
|
+
children: # optional, list of wikilinks — hierarchical children
|
|
546
|
+
discovered_from: # optional, single wikilink — provenance edge ("this task was born while
|
|
547
|
+
# working on X"). Also the code-audit **cleanup→task exit**: a task filed
|
|
548
|
+
# from a `research_type: code-audit` finding row (Action: task) sets this to
|
|
549
|
+
# the source `[[HS-RES-…]]` (see §research "Code-audit findings table" /
|
|
550
|
+
# [[HS-7D0I-WL88-TASK-code-audit-research-type-with-a-defined]]).
|
|
551
|
+
|
|
552
|
+
# Delegation / task-split lineage ([[HS-HXE2-YQ5A-EPIC-delegation-defer-work-from-one-agent-to]],
|
|
553
|
+
# [[HS-DTL1-CX5K-CAP-task-split-handoff-when-context-runs-low]], [[HS-PD6K-NCH5-TASK-handoff-envelope-schema-and-split-child]])
|
|
554
|
+
split_of: # optional, single wikilink — parent task or epic this spec continues (option B:
|
|
555
|
+
# random child id + frontmatter linkage). Must pair with split_index.
|
|
556
|
+
split_index: # optional, positive integer — 1-based sequence among siblings split from the
|
|
557
|
+
# same split_of parent. Required when split_of is set.
|
|
558
|
+
handoff_id: # optional, string — dedup key for idempotent defer re-posts
|
|
559
|
+
# ([[HS-PJN4-W146-TASK-defer-idempotency-handoff-id-and-cross-a]]).
|
|
560
|
+
|
|
561
|
+
# Ingest + roadmap admission ([[plan-ingest-review-roadmap-workflow]], [[adr-0012-roadmap-storage]])
|
|
562
|
+
ingest_draft: # optional, wikilink to draft this spec was promoted from
|
|
563
|
+
forked_from: # optional, wikilink — source spec when forked from sealed as-built diagram ([[HS-G8JS-F6P1-TASK-fork-spec-from-as-built-canvas]])
|
|
564
|
+
forked_from_canvas: # optional, string — vault-relative as-built canvas path
|
|
565
|
+
has_diagram: # optional, boolean — spec contains architecture mermaid; indexes Shipped gallery
|
|
566
|
+
source_intent_hash: # optional, copied from draft at promote time
|
|
567
|
+
roadmap_admission: # optional, enum: pending | scheduled | horizon | declined
|
|
568
|
+
roadmap_phase: # optional, string — phase id from a HS-ROADMAP-* manifest (e.g. M3)
|
|
569
|
+
# horizon backlog: set priority: 4 and/or tag horizon; roadmap_admission: horizon
|
|
570
|
+
|
|
571
|
+
# Optional structured content; preferred form is markdown sections in body
|
|
572
|
+
acceptance: # optional, list of acceptance criteria. Each entry is EITHER a plain string
|
|
573
|
+
# (prose criterion — stays fully valid) OR an object carrying a runnable check:
|
|
574
|
+
# - text: "<the criterion>"
|
|
575
|
+
# verification: # optional — how a machine proves this criterion
|
|
576
|
+
# kind: test | lint | types | command | guard | evidence
|
|
577
|
+
# run: "<command or test path>" # required for machine kinds
|
|
578
|
+
# expect: exit-0 | no-net-new # default exit-0
|
|
579
|
+
# `kind: evidence` names an evidence type a human/receipt records instead of a
|
|
580
|
+
# command. Prose-only criteria are receipt-marked "human-verified" honestly.
|
|
581
|
+
# Backward compatible by construction ([[HS-MNW5-IU2S-EPIC-executable-acceptance-criteria-and]]);
|
|
582
|
+
# kinds/expects mirror the checks-manifest contract ([[checks-manifest-authoring]],
|
|
583
|
+
# parser: spex-console/src/lib/cli/checks-manifest.ts).
|
|
584
|
+
skills: # optional, list of strings
|
|
585
|
+
context: # optional, list of strings
|
|
586
|
+
evidence: # optional, evidence array — sources proving acceptance met
|
|
587
|
+
# (see "Evidence linking" below)
|
|
588
|
+
|
|
589
|
+
# Council session output ([[adr-0015-council-as-cross-cutting-capability]])
|
|
590
|
+
deliberation_record: # optional; multi-LLM debate output, append-only `runs[]`. Permitted on task/epic/review
|
|
591
|
+
# in addition to draft. Schema lives under `draft` §`deliberation_record` above. Attaches
|
|
592
|
+
# on promoted-spec recheck (invocation #3) via `/hs-next` claim path; never gates work.
|
|
593
|
+
|
|
594
|
+
# Parallel-agent module hints ([[HS-ZMAQ-M15C-TASK-declare-owned-path-globs-on-agent-identi]])
|
|
595
|
+
affects_paths: # optional, list of repo-relative glob strings — coarse module hints for
|
|
596
|
+
# overlap detection when multiple agents work in parallel; advisory in v1
|
|
597
|
+
# (same posture as the advisory `lane:` label on agent identities).
|
|
598
|
+
|
|
599
|
+
# Migration provenance
|
|
600
|
+
legacy_bd_id: # optional, string — original bd id for migrated entries
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
##### Handoff envelope (body)
|
|
604
|
+
|
|
605
|
+
When an agent defers or splits remaining work into a child task, the **handoff envelope** carries the next agent's starting context. SSOT is the **body**, not frontmatter — a `## Handoff envelope` heading followed by a fenced ` ```yaml ` block matching `schemas/handoff-envelope.schema.json`:
|
|
606
|
+
|
|
607
|
+
```yaml
|
|
608
|
+
reason: "Why the defer/split happened (context budget, blocked, lane hand-off)"
|
|
609
|
+
summary_done:
|
|
610
|
+
- "Work completed before the handoff"
|
|
611
|
+
remaining:
|
|
612
|
+
- "Actionable items for the picking-up agent"
|
|
613
|
+
success_criteria:
|
|
614
|
+
- "How the reviewer knows the deferred work is done"
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
Field semantics align with the WIP ledger (`remaining` / verified-style `summary_done`) plus delegation-specific `reason` and `success_criteria` per HS-SUMD-4T35-RES-parallel-agent-coordination-handoff-and. A task with `split_of:` **must** include this section; `scripts/validate-vault-ids.mjs` enforces shape. The defer command (HS-MS3T-1U0Z-TASK-hs-defer-mcp-tool-and-slash-command) authors both the lineage frontmatter and this block.
|
|
618
|
+
|
|
619
|
+
#### `agent`
|
|
620
|
+
|
|
621
|
+
Durable agent identity (HS-XNX5-UQHA-MIL-agent-home). Evergreen — does not close. Compiles to `.claude/agents/<name>.md` and `.cursor/agents/<name>.md`; the vault spec is the SSOT.
|
|
622
|
+
|
|
623
|
+
```yaml
|
|
624
|
+
type: agent
|
|
625
|
+
role: # required, string — human-readable role title (also used as description fallback on compile)
|
|
626
|
+
model: # optional, enum: opus | sonnet | haiku
|
|
627
|
+
description: # optional, string — host-native description on compile
|
|
628
|
+
goal: # optional, string — HeySpex-resident intent label (not compiled)
|
|
629
|
+
allowed_tools: # optional, list of strings — compiled to host `tools:` when present
|
|
630
|
+
disallowed_tools: # optional, list of strings — compiled to host `disallowedTools:` when present
|
|
631
|
+
procedures: # optional, list of wikilinks — HeySpex-resident procedure refs
|
|
632
|
+
handoffs: # optional, list — HeySpex-resident handoff targets
|
|
633
|
+
guardrails: # optional, list of strings — HeySpex-resident; persona body carries compiled guardrails
|
|
634
|
+
lane: # optional, string — human label for parallel work (advisory in v1)
|
|
635
|
+
isolation: # optional, enum: default | worktree — operator guidance for checkout
|
|
636
|
+
# isolation when parallel agents each need a dev server; advisory in v1
|
|
637
|
+
# ([[parallel-agent-isolation-guidance]]). `worktree` = use a dedicated git
|
|
638
|
+
# worktree before implementation. HeySpex-only — stripped on compile (like `lane`).
|
|
639
|
+
color: # optional, string — console roster accent (HeySpex-only)
|
|
640
|
+
owned_paths: # optional, list of repo-relative glob strings — machine-checkable file/module
|
|
641
|
+
# ownership for stomp-detection ([[HS-8PNX-Q1KC-EPIC-lanes-and-stomp-detection-for-parallel-a]]).
|
|
642
|
+
# Example: spex-console/src/lib/scheduler/**, vendor/heyspex-mcp/**. HeySpex-only — stripped on compile.
|
|
643
|
+
golden_cases: # optional, list of wikilinks to HS-GCASE-* fixtures owned by this agent.
|
|
644
|
+
# Reverse of each case's `agent:` pointer. HeySpex-only — stripped on compile
|
|
645
|
+
# ([[HS-8AQT-J6FU-TASK-golden-case-vault-artifact-format-and-st]]).
|
|
646
|
+
source_attribution: # optional object — import provenance for community/own-agent imports only
|
|
647
|
+
tags: # required for roster grouping — MUST include `agent` plus at least one
|
|
648
|
+
# `purpose/*` tag (see Purpose tags below). Plain frontmatter array;
|
|
649
|
+
# no agent-only grouping engine ([[HS-IAYA-5345-TASK-lock-agent-purpose-taxonomy-and-tag-conv]]).
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
**Purpose tags** (HS-E2VS-LBUS-EPIC-roster-organization-and-discovery-for-a, HS-WDHW-0009-EPIC-tag-taxonomy-tag-browser-obsidian-style): agent identities reuse the vault's nested-tag namespaces — a dedicated **`purpose/`** namespace (seventh namespace alongside 0009's `area/`, `type/`, `surface/`, `theme/`, `dep/`, `stage/`) for roster discovery. Values are multi-select tags in `tags:`; grouping UI and `GET /api/agents` read them later (HS-NRND-UF9J-TASK-expose-agent-tags-in-get-api-agents-rost).
|
|
653
|
+
|
|
654
|
+
| Tag | When to use |
|
|
655
|
+
| --------------------- | -------------------------------------------------------------------------- |
|
|
656
|
+
| `purpose/reviewer` | Verify acceptance criteria, review diffs, read-only audit before close-out |
|
|
657
|
+
| `purpose/researcher` | Synthesize cited research into durable `HS-RES-*` specs |
|
|
658
|
+
| `purpose/planner` | Ground plans/epics, stress-test assumptions at the plan→execute boundary |
|
|
659
|
+
| `purpose/triager` | Intake routing — captures, resolution items, smallest-fix triage |
|
|
660
|
+
| `purpose/implementer` | Build, edit, deploy — agents that modify code or infra |
|
|
661
|
+
| `purpose/writer` | Prose/docs authoring (reserved; no starter roster member yet) |
|
|
662
|
+
|
|
663
|
+
Rules:
|
|
664
|
+
|
|
665
|
+
1. **Required:** every shipped `type: agent` spec carries **at least one** `purpose/*` tag in `tags:` (in addition to the `agent` marker).
|
|
666
|
+
2. **Primary purpose:** the **first** `purpose/*` tag in `tags:` array order is the roster section key. Downstream surfaces expose it as `primaryPurpose` (computed server-side — not a separate frontmatter field). When an agent legitimately spans multiple purposes, list the primary group first and secondary `purpose/*` tags after.
|
|
667
|
+
3. **`lane:` is not a substitute:** `lane` is parallel-work coordination (advisory, HeySpex-only, stripped on compile). `purpose/*` is vault-resident discovery metadata that flows to the API. They often align but are independent fields.
|
|
668
|
+
|
|
669
|
+
#### `golden-case`
|
|
670
|
+
|
|
671
|
+
Saved eval fixture for the agent testing harness (HS-R1JM-OAG3-EPIC-agent-testing-harness-try-a-draft-agent). Evergreen — updated in place as the agent evolves; does not close. One golden case exercises exactly one `type: agent` identity. The eval spawn (HS-YNIE-ZDQ7-TASK-transient-eval-spawn-and-trajectory-capt) reads the body; the verdict engine (HS-ZOHQ-MOOE-TASK-verdict-engine-deterministic-graders-plu) consumes optional deterministic graders. Expected trajectories (regression baselines) are **run artifacts**, not stored in the fixture at v1 — they land in run history later (HS-ZR0Z-TS11-TASK-run-history-storage).
|
|
672
|
+
|
|
673
|
+
```yaml
|
|
674
|
+
type: golden-case
|
|
675
|
+
agent: # required, wikilink to HS-AGENT-* — the identity under test
|
|
676
|
+
tags: # should include golden-case, agents, testing
|
|
677
|
+
related: # optional wikilinks — e.g. the task spec used as setup context
|
|
678
|
+
```
|
|
679
|
+
|
|
680
|
+
**Bidirectional linkage:** each golden case carries `agent:`; the agent MAY carry `golden_cases:` (list of wikilinks). Filing via `createSpec` / `heyspex_file_spec` with `frontmatter.agent` auto-appends to the agent's `golden_cases:` array (same pattern as task→epic `children:`).
|
|
681
|
+
|
|
682
|
+
**Required body sections:**
|
|
683
|
+
|
|
684
|
+
| Section | Required | Purpose |
|
|
685
|
+
| -------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
686
|
+
| `## Prompt` | yes | The user message the eval spawn sends to the draft agent (≥12 characters). |
|
|
687
|
+
| `## Setup` | no | Freeform context — wikilinks to task specs, files in scope, env hints. |
|
|
688
|
+
| `## Deterministic graders` | no | Fenced `yaml` block matching `specs/schemas/golden-case-body.schema.json`. Keys the reproducible pass/fail signal; LLM-judge critique remains advisory per OAG3 AC#4. |
|
|
689
|
+
|
|
690
|
+
**On-disk layout:** `specs/agents/golden-cases/HS-GCASE-<suffix>-<slug>.md` — nested under `agents/` so fixtures travel in the same git subtree as agent identities.
|
|
691
|
+
|
|
692
|
+
#### `epic`
|
|
693
|
+
|
|
694
|
+
Same as `task` schema (including optional `affects_paths:`). The `type: epic` is what differentiates. An epic typically has many `children:` and few `blocks:`/`blocked_by:`.
|
|
695
|
+
|
|
696
|
+
**Planning flow requirements** (planning-flow-research-epic-lifecycle): every epic MUST include `research:` and `planning_flow:` wikilinks. Console Epic Studio and `POST /api/specs` enforce this for newly filed epics.
|
|
697
|
+
|
|
698
|
+
```yaml
|
|
699
|
+
research: # required for new epics — wikilink to HS-RES-*
|
|
700
|
+
planning_flow: # required for new epics — wikilink to HS-FLOW-*
|
|
701
|
+
milestone: # REQUIRED — single wikilink to the parent HS-MIL-* this epic belongs to.
|
|
702
|
+
# The inverse of the milestone's `epics:` array (write both sides;
|
|
703
|
+
# `scripts/validate-vault-ids.mjs` rejects one-sided drift).
|
|
704
|
+
# Grace window: missing `milestone:` is a validator warning until
|
|
705
|
+
# 2026-06-26, then escalates to an error
|
|
706
|
+
# ([[HS-V5UA-T5PX-TASK-required-milestone-parent-on-epic-validator-and-grace-window]],
|
|
707
|
+
# part of [[HS-OFR5-M2J3-EPIC-introduce-milestones-as-highest-entity]]).
|
|
708
|
+
# Pre-rule orphan epics live at
|
|
709
|
+
# [[HS-3DJS-ORPH-MIL-uncategorized-pre-2026-05-26-epics]]
|
|
710
|
+
# pending walk-the-floor reassignment.
|
|
711
|
+
derived_from: # optional, single wikilink to HS-RES-* — the research that spawned this epic.
|
|
712
|
+
# Reverse of `research.spawned_epics:` (1:N). See §Provenance edges.
|
|
713
|
+
```
|
|
714
|
+
|
|
715
|
+
**Alignment fields** (drift-detection prerequisites; HS-E3D3-RDFT-EPIC-alignment-drift-detector-into-resolution, owned by HS-KA1E-0012-EPIC-creation-guardrails-agent-pushback for the vault-wide backfill):
|
|
716
|
+
|
|
717
|
+
```yaml
|
|
718
|
+
alignment_rationale: # optional (backfill in progress), string — a wikilink to the Pillar / L1 principle
|
|
719
|
+
# this epic advances PLUS a one-line "why", e.g.
|
|
720
|
+
# "[[HS-PILR-architecture]] — advances the foundations concern by converging detection paths".
|
|
721
|
+
# Distinct from the membership `pillar:` field: `pillar:` categorizes; `alignment_rationale`
|
|
722
|
+
# carries the teleological "why" the drift detector reasons over. The wikilink target
|
|
723
|
+
# SHOULD match the epic's `pillar:`. An `alignment_rationale` that resolves to no layer
|
|
724
|
+
# record surfaces as an `orphan` resolution item.
|
|
725
|
+
alignment_baseline: # optional, mapping { <layer-id>: <int version>, anti_goals?: <fingerprint> } — the layer
|
|
726
|
+
# versions this epic was last aligned against. PRIMARY drift baseline: when a referenced
|
|
727
|
+
# layer's current `version` exceeds the baseline here, a `drift` item is emitted. The
|
|
728
|
+
# `anti_goals` key stamps the L1 anti-goal fingerprint so a changed anti-goal set re-checks
|
|
729
|
+
# every active + recently-closed epic. Absent → the detector falls back to
|
|
730
|
+
# `alignment_reviewed_at` vs the layer's `last_edited_at`; absent both → no drift (never a
|
|
731
|
+
# false positive). Stamped by the alignment checkpoint on re-alignment.
|
|
732
|
+
```
|
|
733
|
+
|
|
734
|
+
#### `milestone`
|
|
735
|
+
|
|
736
|
+
The grouping **above** epic: a coherent multi-epic ship (a restructure or release) that closes when every child epic closes and the milestone's own acceptance gate is met. Formalized by HS-VK7C-MILE-EPIC-milestone-entity-type-and-surfacing; the canonical hierarchy and filing rules live in [[spec-hierarchy]]. The 33 `HS-MIL-*` files on disk (seed: HS-RM22-IART-MIL-console-ia-restructure) predate this schema row and are described by it retroactively.
|
|
737
|
+
|
|
738
|
+
```yaml
|
|
739
|
+
type: milestone
|
|
740
|
+
status: # one of: open | in_progress | closed (subset of the universal enum)
|
|
741
|
+
epics: # list of wikilinks to every child epic — the mirror of each child epic's
|
|
742
|
+
# `milestone:` pointer. Write both sides (bidirectional linkage; see [[spec-hierarchy]]).
|
|
743
|
+
informed_by: # optional, list of wikilinks to HS-RES-* — research docs that enhance this milestone.
|
|
744
|
+
# Reverse of `research.enhances:` (each research enhances exactly one milestone, M:1;
|
|
745
|
+
# one milestone may be informed by many research docs over time). Bidirectional
|
|
746
|
+
# consistency enforced by `scripts/validate-vault-ids.mjs`. See §Provenance edges.
|
|
747
|
+
target_date: # optional, ISO-8601 date or empty string "" — the intended ship date
|
|
748
|
+
tags: # optional, list of strings
|
|
749
|
+
related: # optional, list of wikilinks
|
|
750
|
+
```
|
|
751
|
+
|
|
752
|
+
**No scalar `priority:` field.** Milestone ordering is the **output** of the deterministic priority scheduler, never a stored scalar (deterministic-priority-scheduler-supersedes-scored-priority, HS-78E7-Y9OJ-EPIC-deterministic-priority-scheduler). This deliberately diverges from the universal "`priority:` required" rule above — the same way current epics and tasks omit the scalar. Do not add a `priority:` to a milestone.
|
|
753
|
+
|
|
754
|
+
Sub-milestones are **out of scope**: large milestones are split horizontally (more milestones at the same level), not nested ([[spec-hierarchy]] §Open questions). There is no `milestone:` (parent-milestone) field on a milestone.
|
|
755
|
+
|
|
756
|
+
Required body sections ([[spec-hierarchy]] §Frontmatter requirements per level): rationale ("why this is a milestone, not loose epics"), an acceptance gate (numbered closure conditions), suggested landing order, and out-of-scope.
|
|
757
|
+
|
|
758
|
+
#### `diagnose`
|
|
759
|
+
|
|
760
|
+
A user-reported **bug fix** as first-class executable work — claimable and decomposable like a task, but typed so it reads as "a reported bug to fix," not planned roadmap work. Introduced by HS-OXBS-BFIX-MIL-bug-fix-diagnose-lane (milestone-precedent, no standalone ADR). Standalone by default; an optional `parent:` (epic OR milestone) groups related fixes. Surfaces on the Resolution surface as a derived `kind: "bug"` row (the row is derived; this spec is the work — see blockers-are-gating-subset-of-resolution and HS-AO2F-1KZK-RES-bug-fix-resolution-task-entity-model-and).
|
|
761
|
+
|
|
762
|
+
```yaml
|
|
763
|
+
type: diagnose
|
|
764
|
+
status: # universal enum: open | in_progress | in_review | closed | …
|
|
765
|
+
severity: # REQUIRED — one of: error | warning | info. Maps onto the scheduler's
|
|
766
|
+
# existing priority signals (channel B): a higher-severity diagnose
|
|
767
|
+
# competes higher for on-deck. Drives the derived bug row's color.
|
|
768
|
+
parent: # OPTIONAL — single wikilink to an HS-EPIC-* or HS-MIL-* parent.
|
|
769
|
+
# Standalone (absent) is the DEFAULT and is exempt from the
|
|
770
|
+
# epic→milestone mandatory-parent rule. One-way pointer (no auto back-link).
|
|
771
|
+
depends_on: # optional, list of wikilinks — tasks/specs that must close first.
|
|
772
|
+
blocks: # optional, list of wikilinks to HS-EPIC-*/HS-TASK-* this fix gates.
|
|
773
|
+
# Surfaces as a gating item in that spec's On-Deck overlay (channel A).
|
|
774
|
+
promoted_from: # optional, single wikilink to HS-CAP-* — set when this diagnose was promoted
|
|
775
|
+
# from a bug-report capture via `heyspex_promote_capture_to_diagnose`.
|
|
776
|
+
# Reverse of `capture.promoted_to:` (first-promotion).
|
|
777
|
+
derived_from: # optional, single wikilink to HS-RES-* — the research that surfaced this bug,
|
|
778
|
+
# set when this diagnose was promoted from a research investigation via
|
|
779
|
+
# `heyspex_promote_research_to_diagnose` (mirrors `epic.derived_from`).
|
|
780
|
+
# Reverse of `research.produces_diagnose:` (1:N).
|
|
781
|
+
tags: # optional, list of strings
|
|
782
|
+
related: # optional, list of wikilinks
|
|
783
|
+
```
|
|
784
|
+
|
|
785
|
+
**No scalar `priority:`** — like task/epic/milestone, ordering is the scheduler's output; `severity:` is the diagnose's contribution to that ranking, not a stored priority.
|
|
786
|
+
|
|
787
|
+
Required body sections: Symptom, Reproduction, Root cause, Fix, Acceptance criteria.
|
|
788
|
+
|
|
789
|
+
#### `pillar`
|
|
790
|
+
|
|
791
|
+
Perpetual categorical container that never closes — the cross-cutting axis to which every epic associates via a primary `pillar:` field. Pillars are the structural primitive that makes HeySpex's "preserve context across time" claim true rather than aspirational ("Linear and Jira are queues; HeySpex is context" — see heyspex-market-positioning). Introduced 2026-05-31 per HS-AWDI-PILR-RES-pm-perpetual-container-terminology; ratified by introduction lineage HS-EBIL-0011-EPIC-goal-hierarchy-l2-strategic-pillars-l3 (milestone precedent, no standalone ADR for the entity itself). The meta-Pillar — the Pillar about Pillars themselves, dogfooding instance — is HS-PILR-pillars.
|
|
792
|
+
|
|
793
|
+
```yaml
|
|
794
|
+
type: pillar
|
|
795
|
+
status: # `perpetual` — non-terminal. Pillars never transition to closed/in_review/etc.
|
|
796
|
+
# Universal status enum does NOT apply.
|
|
797
|
+
canonical: # required, boolean
|
|
798
|
+
# true → curated by HeySpex team; ships pre-loaded in customer vaults; read-only (fork to customize)
|
|
799
|
+
# false → customer-scoped Pillar (filed by the customer with high friction)
|
|
800
|
+
library_tier: # optional enum: meta | foundational | discretionary (placeholder; library taxonomy TBD)
|
|
801
|
+
secondary_pillars: # always present; usually empty []. Reserved for future cross-Pillar linking.
|
|
802
|
+
version: # optional, monotonic integer — same semantics as the `l1` `version` field above.
|
|
803
|
+
# A Pillar edit that materially changes scope bumps this; epics aligned against the
|
|
804
|
+
# prior version surface as `drift` items ([[HS-E3D3-RDFT-EPIC-alignment-drift-detector-into-resolution]]).
|
|
805
|
+
last_edited_at: # optional, ISO-8601 timestamp of the last edit — drift timestamp fallback (see `l1`).
|
|
806
|
+
related: # optional, list of wikilinks
|
|
807
|
+
tags: # optional, list of strings
|
|
808
|
+
```
|
|
809
|
+
|
|
810
|
+
The `version` / `last_edited_at` fields are the versioning prerequisites carried from HS-EBIL-0011-EPIC-goal-hierarchy-l2-strategic-pillars-l3; together with the L1 fields they let the alignment-drift detector tell a material Pillar revision apart from a no-op touch.
|
|
811
|
+
|
|
812
|
+
**Per-epic membership** (new fields on every epic, added 2026-05-31 by HS-EBIL-0011-EPIC-goal-hierarchy-l2-strategic-pillars-l3):
|
|
813
|
+
|
|
814
|
+
```yaml
|
|
815
|
+
pillar: # required on every epic, single wikilink to a Pillar.
|
|
816
|
+
# The home for library/learning. Forces "what perpetual concern does this advance?"
|
|
817
|
+
# at filing time. HARD-BLOCKED at the filing boundary (owner decision 2026-06-18):
|
|
818
|
+
# POST /api/specs / heyspex_file_spec refuse an epic with no resolvable HS-PILR pillar
|
|
819
|
+
# (400 pillar_required). Legacy pillar-less epics are caught by the EPIC_MISSING_PILLAR
|
|
820
|
+
# vault-rule — warning (Resolution backfill queue) until 2026-07-31, then error.
|
|
821
|
+
# Full rules: [[pillar-assignment-protocol]].
|
|
822
|
+
secondary_pillars: # optional, list of wikilinks to Pillars.
|
|
823
|
+
# For genuinely cross-cutting work ("Add caching layer" is primarily Scaling but also Reliability).
|
|
824
|
+
# Tasks inherit their epic's primary pillar; do not set secondary on tasks.
|
|
825
|
+
```
|
|
826
|
+
|
|
827
|
+
**Authored as the work surfaces themes.** Pillars are created over time, not enumerated up front — there are deliberately only a few today and many more are expected. When filing an epic surfaces a theme with no pillar yet, the agent is prompted to author one (`heyspex_file_spec({ type: "pillar", name })`); the owner may also author a pillar standalone whenever a theme is foreseen. The procedure is pillar-assignment-protocol.
|
|
828
|
+
|
|
829
|
+
**Milestones surface a derived pillar roll-up.** A milestone has **no authored `pillar:` field** — it is a dated ship that groups epics, which may belong to different pillars. Instead a milestone _surfaces_ the de-duped set of pillars its child epics carry (computed in `getSpec`, rendered on the milestone detail drawer). The roll-up is derived and may list multiple pillars, so it never drifts from the epics' `pillar:` fields.
|
|
830
|
+
|
|
831
|
+
**Status semantics.** Pillars carry `status: perpetual` as a single non-terminal value, distinct from the universal enum. The close-out protocol skips Pillars; the scheduler skips Pillars as on-deck candidates (only their epics are scheduled); review-doc flow does not apply. A Pillar's body grows over time as epics close and lessons accumulate against the concern — accumulation IS the point.
|
|
832
|
+
|
|
833
|
+
**Body sections.** Required: a one-line "why this Pillar exists" hook; `## In scope` / `## Out of scope`; `## Anticipated epics`; `## Library status` (canonical | customer-scoped). The body is a living document, not a frozen artifact.
|
|
834
|
+
|
|
835
|
+
**Disambiguation — three distinct uses of "pillar" in this vault:**
|
|
836
|
+
|
|
837
|
+
1. **`type: pillar` entities (`HS-PILR-*`)** — this section. Perpetual product concerns (Scaling, Reliability, DX, etc.). Queryable, schematized.
|
|
838
|
+
2. **HS-DOC-architecture-foundations** (renamed 2026-05-31 from `architecture-pillars`) — L2 doc that names the five technical foundations of the system (vault, indexer, console, CLI, sync mesh) and refers to them as "Pillars 0–5" in internal section headers. Unrelated to (1); the section names are preserved for now and may be renamed in a future cosmetic pass.
|
|
839
|
+
3. **HS-OR8V-0010-EPIC-north-star-vision-first-class-entity's FIVE COMPONENTS section** — five implementation parts of that epic. Previously named "FIVE PILLARS"; renamed 2026-05-31 to remove the overload.
|
|
840
|
+
|
|
841
|
+
Only sense (1) is a queryable entity. (2) and (3) use the word as a non-schematized noun within their own documents.
|
|
842
|
+
|
|
843
|
+
#### `branch-brief`
|
|
844
|
+
|
|
845
|
+
A durable "plan receipt" for one git branch. Ratified by adr-0008-branch-brief-and-evidence-schema; closes the Continuity Layer schema gaps (HS-7KOO-0022-EPIC-continuity-layer-gaps). One brief per branch; re-generation overwrites the file in place (git history is the version trail). Generated by HS-838Y-ALDY-TASK-branch-brief-generation.
|
|
846
|
+
|
|
847
|
+
```yaml
|
|
848
|
+
type: branch-brief
|
|
849
|
+
branch: # required, string — the raw (unsanitized) git branch name
|
|
850
|
+
repo: # optional, string — repo name if multi-repo
|
|
851
|
+
goal: # required, string — what this branch is trying to accomplish
|
|
852
|
+
implements: # optional, list of wikilinks — tasks/epics this branch implements
|
|
853
|
+
plan: # optional, list of { step: int, description: string }
|
|
854
|
+
# the ORIGINAL intent. Sourced (priority order) from:
|
|
855
|
+
# 1. the linked implementing spec's acceptance criteria
|
|
856
|
+
# (its `acceptance:` array, else its `## Acceptance` body)
|
|
857
|
+
# 2. a manual plan authored here (exploratory branches)
|
|
858
|
+
# Commit messages / PR bodies are NOT v1 plan sources.
|
|
859
|
+
actual: # optional, list of { step: int, description: string,
|
|
860
|
+
# status: <drift enum>, evidence: [<evidence ref>] }
|
|
861
|
+
# what was implemented, captured at brief-generation time.
|
|
862
|
+
risks: # optional, list of strings — identified risks/concerns
|
|
863
|
+
open_questions: # optional, list of strings — unresolved questions
|
|
864
|
+
next_steps: # optional, list of strings — recommended next actions
|
|
865
|
+
decisions: # optional, list of wikilinks — memory-decisions made on this branch
|
|
866
|
+
evidence: # optional, evidence array (see "Evidence linking" below)
|
|
867
|
+
```
|
|
868
|
+
|
|
869
|
+
**Drift enum** (the `status:` of each `actual` step) — defined once here, reused by HS-838Y-ALDY-TASK-branch-brief-generation and any drift tooling (HS-CM22-0019-EPIC-post-edit-alignment-drift-detection):
|
|
870
|
+
|
|
871
|
+
| Value | Meaning |
|
|
872
|
+
| --------- | ------------------------------------------------------- |
|
|
873
|
+
| `match` | Implementation achieves the planned step. |
|
|
874
|
+
| `drift` | Implementation differs from the plan in a material way. |
|
|
875
|
+
| `missing` | Planned step not implemented. |
|
|
876
|
+
| `extra` | Implemented change that was not in the plan. |
|
|
877
|
+
|
|
878
|
+
Required body sections: `## Goal`, `## Plan vs Actual` (a table rendering `plan`/`actual` with an `Evidence` column), and — when any step is `drift`/`missing`/`extra` — a `## Drift Analysis` section explaining each, with risk and a recommendation. Optional: `## Decisions`, `## Risks`, `## Open Questions`, `## Next Steps`, `## Evidence`. The frontmatter `plan`/`actual` arrays are canonical for queries; the body table is the human view (same canonical-frontmatter rule as dependencies and tags).
|
|
879
|
+
|
|
880
|
+
#### `memory-lesson`
|
|
881
|
+
|
|
882
|
+
```yaml
|
|
883
|
+
type: memory-lesson
|
|
884
|
+
topic: # required, short string — the subject
|
|
885
|
+
observed: # required, ISO-8601 date — when the lesson was learned
|
|
886
|
+
related: # optional, list of wikilinks
|
|
887
|
+
evidence: # optional, evidence array — sources grounding the problem/fix
|
|
888
|
+
# (see "Evidence linking" below)
|
|
889
|
+
```
|
|
890
|
+
|
|
891
|
+
The body of a memory-lesson spec has two required sections: `## Problem` and `## Fix`.
|
|
892
|
+
|
|
893
|
+
#### `memory-decision`
|
|
894
|
+
|
|
895
|
+
```yaml
|
|
896
|
+
type: memory-decision
|
|
897
|
+
topic: # required, short string
|
|
898
|
+
decided: # required, ISO-8601 date
|
|
899
|
+
deciders: # required, list of strings
|
|
900
|
+
supersedes: # optional, wikilink to a prior decision
|
|
901
|
+
evidence: # optional, evidence array — sources grounding the rationale
|
|
902
|
+
# (see "Evidence linking" below)
|
|
903
|
+
```
|
|
904
|
+
|
|
905
|
+
The body has two required sections: `## Decision` and `## Rationale`. (An ADR is a heavier-weight decision; a `memory-decision` is the day-to-day choice that doesn't warrant an ADR but should still be persisted.)
|
|
906
|
+
|
|
907
|
+
#### `memory-reference`
|
|
908
|
+
|
|
909
|
+
```yaml
|
|
910
|
+
type: memory-reference
|
|
911
|
+
topic: # required, short string
|
|
912
|
+
url: # optional, URL the reference points at
|
|
913
|
+
evidence: # optional, evidence array — additional grounded sources
|
|
914
|
+
# (see "Evidence linking" below)
|
|
915
|
+
```
|
|
916
|
+
|
|
917
|
+
Body is the brief context for why this reference matters.
|
|
918
|
+
|
|
919
|
+
#### `memory-ui-pattern`
|
|
920
|
+
|
|
921
|
+
```yaml
|
|
922
|
+
type: memory-ui-pattern
|
|
923
|
+
topic: # required, short string — the pattern name/slug
|
|
924
|
+
documented: # required, ISO-8601 date — when the pattern was captured
|
|
925
|
+
related: # optional, list of wikilinks
|
|
926
|
+
evidence: # optional, evidence array
|
|
927
|
+
```
|
|
928
|
+
|
|
929
|
+
Reusable **console interaction and visual patterns** (keyboard ownership, two-layer highlights, drill-in between panes). Distinct from `memory-ux-principle` (cross-brand rules) and `memory-decision` (a one-time choice). Body sections: `## Pattern`, `## When to apply`, `## Rules`, `## Implementation` (file map + copy-paste shape). See rail-active-vs-keyboard-cursor.
|
|
930
|
+
|
|
931
|
+
#### `memory-ux-principle`
|
|
932
|
+
|
|
933
|
+
```yaml
|
|
934
|
+
type: memory-ux-principle
|
|
935
|
+
topic: # required, short string — the principle name/slug
|
|
936
|
+
documented: # required, ISO-8601 date — when the principle was captured
|
|
937
|
+
related: # optional, list of wikilinks
|
|
938
|
+
evidence: # optional, evidence array
|
|
939
|
+
```
|
|
940
|
+
|
|
941
|
+
Cross-brand **interaction rules** (Apple HIG, Material, Linear, Nielsen) — product-agnostic **what/why**. Distinct from `memory-ui-pattern` (HeySpex **how**). Body sections: `## Principle`, `## When to apply`, `## Rules`, `## Related UI patterns`, `## Sources`. See toggle-current-state-semantics and ux-principles-vs-ui-patterns.
|
|
942
|
+
|
|
943
|
+
#### `protocol`
|
|
944
|
+
|
|
945
|
+
Part of the **Memory** layer (memory-protocols-subsection-of-memory). Epics/tasks that _implement_ or _revise_ a protocol stay in `epics/` / `tasks/`; only the finished operational doc is `type: protocol`.
|
|
946
|
+
|
|
947
|
+
```yaml
|
|
948
|
+
type: protocol
|
|
949
|
+
scope: # required, one of: session | project | vault | tool
|
|
950
|
+
version: # optional, semver-ish version of the protocol
|
|
951
|
+
```
|
|
952
|
+
|
|
953
|
+
Body describes the protocol with numbered steps.
|
|
954
|
+
|
|
955
|
+
#### `review`
|
|
956
|
+
|
|
957
|
+
Companion fill-in workspace for a parent spec at `status: in_review`. One review doc per parent spec; created by the agent at the moment of flipping the parent to `in_review`. The reviewer (human) walks acceptance criteria, reads the agent's session observations, scores memory candidates, and records pass/reopen. Naming: `HS-REV-<suffix>-<slug>.md` where `<suffix>` matches the parent's id 1:1 (`HS-76RX` → `HS-SK1L-REV-…`, `HS-KQ5O` → `HS-IDFV-REV-…`).
|
|
958
|
+
|
|
959
|
+
```yaml
|
|
960
|
+
type: review
|
|
961
|
+
parent: # required, single wikilink — the spec under review
|
|
962
|
+
reviews: # optional, single wikilink — same as parent (legacy alias retained for back-compat reads)
|
|
963
|
+
# parent: is the canonical edge; reviews: is kept for older docs
|
|
964
|
+
deliberation_record: # optional; Council session output for invocation #4 (review close-out)
|
|
965
|
+
# ([[adr-0015-council-as-cross-cutting-capability]]). Schema lives under `draft`
|
|
966
|
+
# §`deliberation_record` above. Attached when the human triggers council during
|
|
967
|
+
# `/hs-review` close-out; never gates the human's pass/reopen decision.
|
|
968
|
+
```
|
|
969
|
+
|
|
970
|
+
Body has four required sections — the unified workspace:
|
|
971
|
+
|
|
972
|
+
- `## Acceptance verification` — checkboxes mirroring the parent spec's acceptance criteria; reviewer ticks them during verification and adds inline deviation notes. For epic-level reviews, expand into a manual testing walkthrough (fast-fail commands, click-by-click steps, expected behavior the reviewer can follow top-to-bottom).
|
|
973
|
+
- `## Reviewer notes` — free-form workspace. **The agent writes implementation observations here during the work session** (architecture choices, judgment calls, surprises, gotchas). The reviewer adds deviation/surprise notes during the testing pass. This prose is the raw material the close-out memory-extraction pass reads.
|
|
974
|
+
- `## Memory candidates` — table of proposed lessons / decisions / UI patterns / references derived from the Reviewer notes. Each row scored against the four-axis rubric (non-derivability / reusability / surprise-cost / concreteness, 0–3 each, threshold ≥ 7/12) and **MUST include a "Conflict check" column** noting `New`, `Refines [[existing-memory]]`, or `Conflict [[existing-memory]]`. A `Conflict` row is a red flag and must be resolved before accepting. Owned by HS-35JN-REVD-TASK-review-doc-fill-in-template-and-memory-extraction.
|
|
975
|
+
- `## Decision: close or reopen` — explicit pass/fail outcome with reasoning, plus a checkbox indicating whether to materialize accepted memory candidates.
|
|
976
|
+
|
|
977
|
+
Cross-link from the parent spec: every parent spec at `in_review` MUST add a `## Review` section pointing to its companion: `Reviewer workspace for this spec lives at [[HS-REV-<suffix>-<slug>]] — pre-review checklist, manual verification steps, reviewer notes, and memory candidates extracted at close-out.`
|
|
978
|
+
|
|
979
|
+
The console shows a "Review" button on cards only when the parent spec is `status: in_review` and an `HS-REV-<suffix>-*` companion exists (detection: `console/src/lib/vault.ts:155 extractSpecSuffix`). Once the parent moves to `closed`, the button disappears but the wikilink in the parent body remains.
|
|
980
|
+
|
|
981
|
+
The four-section unified-workspace template and the close-out flow are specified in HS-35JN-REVD-TASK-review-doc-fill-in-template-and-memory-extraction and CLAUDE.md §Session Completion. The MCP tool that loads a review doc into agent context (`heyspex_review_on_deck` + `/hs-review`) is specified in HS-XRO1-RVDC-TASK-heyspex-review-on-deck-mcp-and-hs-review. The legacy `{basename}.review.md` sibling naming was migrated by `scripts/migrate-review-doc-naming.mjs` — do not use it for new docs.
|
|
982
|
+
|
|
983
|
+
#### `business-positioning` / `business-pricing` / `business-marketing` / `business-model`
|
|
984
|
+
|
|
985
|
+
Parallel layer to Memory for **business-side** knowledge: how the product is positioned, priced, marketed, and the business model itself. Like Memory, browsed in the console on its own surface (**Business**) with category filters.
|
|
986
|
+
|
|
987
|
+
```yaml
|
|
988
|
+
type: business-positioning # or business-pricing | business-marketing | business-model
|
|
989
|
+
topic: # required, short string — the subject (e.g. "homepage-h1", "tier-table")
|
|
990
|
+
status: # universal status enum — draft | open | in_progress | in_review | closed | deferred
|
|
991
|
+
# `active` is allowed as a synonym for `open` on migrated docs.
|
|
992
|
+
related: # optional, list of wikilinks
|
|
993
|
+
evidence: # optional, evidence array — sources grounding the claim/decision
|
|
994
|
+
```
|
|
995
|
+
|
|
996
|
+
Body is free-form prose; the recommended shape is a one-line H1 frame, then sections that match the doc's purpose (e.g. **Decision** / **Why each word is load-bearing** for positioning; **Tier table** / **AI add-on** / **What this also unlocks** for pricing).
|
|
997
|
+
|
|
998
|
+
Distinct from `memory-decision` — memory captures _how-we-work_ decisions for agents/humans inside the project; business docs capture _what-we-sell-and-how_ decisions for the outside world. A pricing change is a `business-pricing` doc; a "don't mock the database in tests" rule is a `memory-decision`.
|
|
999
|
+
|
|
1000
|
+
#### `capture`
|
|
1001
|
+
|
|
1002
|
+
Concise core-intent capture **before** research (capture-guardrails). Replaces the legacy `type: idea` entity (renamed 2026-05-22 per HS-B2B8-DLQI-EPIC-capture-rename-migration-idea-to-capture, source rationale HS-ZKFN-1FXG-CAP-capture-as-universal-companion-verb-and-parent-term). Not a draft inbox item and not a research doc.
|
|
1003
|
+
|
|
1004
|
+
```yaml
|
|
1005
|
+
type: capture
|
|
1006
|
+
kind: # required, one of: idea | bug-fix | clip | reference | question | spec-import | feedback
|
|
1007
|
+
# idea → speculative concept worth exploring (default — migrated entries land here)
|
|
1008
|
+
# bug-fix → defect observation paired with proposed fix
|
|
1009
|
+
# clip → web/document excerpt saved verbatim for later use
|
|
1010
|
+
# reference → a pointer to an external resource worth keeping
|
|
1011
|
+
# question → an open question to revisit when more context lands
|
|
1012
|
+
# spec-import→ an imported foreign doc (README / top-level project doc) landed as a RAW
|
|
1013
|
+
# capture by the bulk spec-import feature ([[HS-8V8T-8SBG-EPIC-first-connect-rough-import]]);
|
|
1014
|
+
# source doc in ## Source Material; carries source_repo/source_path for
|
|
1015
|
+
# (repo, vault) idempotency; stays RAW for manual triage. The
|
|
1016
|
+
# "pin → run feature pipeline" exit ([[HS-J7T5-VEW8-RES-import-specs-one-click-feature-pipeline]])
|
|
1017
|
+
# is a deferred follow-on — NOT wired in this wave.
|
|
1018
|
+
# feedback → app feedback / bug report / product idea / support question captured through
|
|
1019
|
+
# a deterministic (no-AI) intake channel ([[HS-KQEW-I5DV-EPIC-feedback-capture-type-deterministic]]);
|
|
1020
|
+
# classified by `routeFeedback()` ([[HS-FUII-EI9R-TASK-deterministic-feedback-router-module-no]]) toward diagnose/research/
|
|
1021
|
+
# answered, or stays `feedback` when unmatched. Optional structured fields below
|
|
1022
|
+
# (declared alongside `source:` further down this block — see `example`/
|
|
1023
|
+
# `user_story`/`situation`).
|
|
1024
|
+
example: # optional, string — a concrete example/repro illustrating the feedback (e.g. steps to reproduce a bug).
|
|
1025
|
+
# Only ever populated on `kind: feedback` captures; never forced, never required by the schema.
|
|
1026
|
+
user_story: # optional, string — "as a user, I want to… so that…" framing for a feedback-sourced product idea.
|
|
1027
|
+
# Same optionality as `example`.
|
|
1028
|
+
situation: # optional, string — the situational context the user was in when the feedback arose.
|
|
1029
|
+
# Same optionality as `example`.
|
|
1030
|
+
capture_status: # required, one of: raw | expanded — default raw
|
|
1031
|
+
# raw → no Core Idea content yet (single textarea / quick capture)
|
|
1032
|
+
# expanded → Core Idea / Concept / Details has been written (modal v3 or agent rewrite)
|
|
1033
|
+
# Flips raw → expanded automatically when an agent writes to core_idea,
|
|
1034
|
+
# concept, or agent_expansion via executeUpdateCapture (vendor/heyspex-mcp).
|
|
1035
|
+
# Console save-time linter force-corrects raw → expanded when `# Core Idea`
|
|
1036
|
+
# body has content. See [[HS-BDDT-Q1B7-EPIC-idea-capture-modal-v3-single-textbox-cle]].
|
|
1037
|
+
promoted_to: # binary: null (not promoted) or "[[HS-RES-<suffix>-<slug>]]" (promoted to research).
|
|
1038
|
+
# Records the FIRST research doc this capture was promoted into; not the full set.
|
|
1039
|
+
# For the M:N "every research doc this capture informs" view, see `informs_research:`.
|
|
1040
|
+
informs_research: # optional, list of wikilinks to HS-RES-* — every research doc this capture informs (M:N).
|
|
1041
|
+
# Reverse of `research.sources_captures:`. Distinct from `promoted_to:` (binary
|
|
1042
|
+
# first-promotion pointer); a capture may appear in multiple research docs over time.
|
|
1043
|
+
# Bidirectional consistency enforced by `scripts/validate-vault-ids.mjs`. See §Provenance edges.
|
|
1044
|
+
source: # optional capture channel (console, cli, companion, agent, …). On `kind: feedback` captures this
|
|
1045
|
+
# also doubles as the free-text originating-channel/page-context signal `routeFeedback()`
|
|
1046
|
+
# reads ([[HS-FUII-EI9R-TASK-deterministic-feedback-router-module-no]]) — still optional, never forced.
|
|
1047
|
+
related: # optional wikilinks
|
|
1048
|
+
legacy_idea_id: # optional, string — original HS-IDEA-* id for migrated entries (archaeology)
|
|
1049
|
+
```
|
|
1050
|
+
|
|
1051
|
+
`promoted_to` is the **single binary promotion field** (HS-KQ5O-IDFV-EPIC-unified-idea-workflow-v2 / HS-QOAC-IDFL-RES-unified-idea-workflow-v2). `research_stage` was removed 2026-05-22; intermediate "promoted-but-research-not-written-yet" state lives in `.heyspex/research-focus.yaml`, not in the spec.
|
|
1052
|
+
|
|
1053
|
+
`kind:` is the taxonomy field locked in by HS-B2B8-DLQI-EPIC-capture-rename-migration-idea-to-capture Milestone A. Migration of pre-2026-05-22 `type: idea` entries set `kind: idea` for every record; new captures pick the kind at creation time. The enum was extended from 5 to 6 values on 2026-07-10 — `spec-import` added as the **import-origin** kind for the bulk spec-import feature (HS-8V8T-8SBG-EPIC-first-connect-rough-import / HS-ROIU-9P4B-EPIC-import-preview-and-confirm, grounding HS-J7T5-VEW8-RES-import-specs-one-click-feature-pipeline). `spec-import` was added as a documentation/protocol convention only, not to the hard validator enum — `scripts/validate-vault-schema` (`schemas/heyspex-frontmatter.schema.json`) only required that a capture carry a `kind:` and a `capture_status:`, so `spec-import` slipped past AJV. `feedback` (7th value, HS-KQEW-I5DV-EPIC-feedback-capture-type-deterministic / HS-PUK1-48ZZ-TASK-add-feedback-capture-kind-optional) was added to BOTH the doc above and the hard AJV `kind` enum in `schemas/heyspex-frontmatter.schema.json` — a `kind: feedback` capture passes `scripts/validate-vault-schema.mjs` the same way the original five values do. Further consolidation (getting `spec-import` onto the hard enum too) is still deferred.
|
|
1054
|
+
|
|
1055
|
+
Body **must** use four named sections — `# Core Idea` / `## Notes` (verbatim human words inside `"quotes"`) / `## Concept` (AI brief summary, ≤1200 chars hard / ≤800 soft) / `<details>Details</details>` (AI synthesis / deep dive, collapsed by default). Core Idea ≤280 chars soft / ≤500 hard. (The body section names retain the legacy "Idea" / "Notes" / "Concept" / "Details" wording even for captures whose `kind:` is not `idea`; the headings are a fixed scaffold, not a taxonomy field — agents and humans use the same four-section shape for every kind.) Legacy `# Core idea` / `## Notes` / `<details>Expanded idea (agent)</details>` is read back-compat during the deprecation window; writes always emit v2. AI may write to any section but: (a) never alters words inside a quote, (b) `## Notes` format-wrap is confirm-free, (c) `# Core Idea` / `## Concept` / `## Details` writes require user confirm. Agents must not add research sections (Executive Summary, Findings, Sources) to capture files — only the separate research doc after `/hs-res` (capture-guardrails).
|
|
1056
|
+
|
|
1057
|
+
#### `research`
|
|
1058
|
+
|
|
1059
|
+
Research is **evergreen** per the lifecycle-class taxonomy above and the canonical decision research-is-evergreen. `status: open` is the resting state for the doc's entire life — there are no `in_review` or `closed` transitions. Lineage to downstream artifacts is recorded through the relational fields below (`enhances:`, `spawned_epics:`, `bound_epic:`, `incorporated_into:`, `superseded_by:`), **never** through a status flip.
|
|
1060
|
+
|
|
1061
|
+
```yaml
|
|
1062
|
+
type: research
|
|
1063
|
+
research_type: # REQUIRED, enum — the declared purpose of this research doc, set at creation
|
|
1064
|
+
# ([[HS-45YJ-120I-EPIC-research-type-field-the-declared-purpose]]). Coherent with the
|
|
1065
|
+
# capture `kind:` vocabulary (`idea | bug-fix | clip | reference | question`) one
|
|
1066
|
+
# level up the lifecycle, but not identical — research_type describes what the
|
|
1067
|
+
# research is FOR, not what kind of capture seeded it. Five values:
|
|
1068
|
+
# new-feature — grounds a not-yet-built capability or product surface
|
|
1069
|
+
# enhancement — improves or extends something already shipped
|
|
1070
|
+
# diagnose — investigates a bug, defect, or quality problem
|
|
1071
|
+
# code-audit — reviews existing code/architecture with no specific bug in hand
|
|
1072
|
+
# reference — captures external/background knowledge for reuse (the default)
|
|
1073
|
+
# Enforced by `schemas/heyspex-frontmatter.schema.json`. Missing on a pre-existing
|
|
1074
|
+
# doc is a WARNING during the grace window (`RESEARCH_TYPE_GRACE_END` in
|
|
1075
|
+
# `spex-console/src/lib/indexer/vault-rules.mjs`, mirroring `EPIC_PILLAR_GRACE_END`),
|
|
1076
|
+
# then a hard error. Deterministic kind→research_type suggestion is out of scope
|
|
1077
|
+
# here — owned by [[HS-6CFV-MVC1-EPIC-deterministic-type-assist-suggest-resear]].
|
|
1078
|
+
scope: # optional, enum — how broad a search context this research was run at:
|
|
1079
|
+
# internal — specs/, memories, ADRs only
|
|
1080
|
+
# codebase — the repo (console/, vendor/, scripts/, etc.)
|
|
1081
|
+
# external — web search
|
|
1082
|
+
# all — vault + codebase + web
|
|
1083
|
+
# Default "internal" when omitted. This is a CONSISTENCY fix, not a new
|
|
1084
|
+
# requirement — scope is NOT required and has no grace window
|
|
1085
|
+
# ([[HS-NGD1-TASK-consolidate-and-fix-the-research-scope-field]]). Written the
|
|
1086
|
+
# same way (same enum, same default) by `heyspex_save_research`,
|
|
1087
|
+
# `heyspex_promote_capture`, and `heyspex_complete_research`. Validated as a
|
|
1088
|
+
# string enum by `schemas/heyspex-frontmatter.schema.json` (distinct from the
|
|
1089
|
+
# unrelated freetext `scope:` on `type: protocol`).
|
|
1090
|
+
enhances: # REQUIRED when set — bidirectional consistency rule. If `enhances:` exists, the
|
|
1091
|
+
# target milestone MUST list this research in `informed_by:` (see §Provenance edges).
|
|
1092
|
+
# Single wikilink to the HS-MIL-* this research enhances. Not an array (M:1 rule).
|
|
1093
|
+
# Open research may omit during exploration; the validator enforces bidirectional
|
|
1094
|
+
# consistency whenever the field IS set. A research doc that spans multiple
|
|
1095
|
+
# milestones must be split first ([[HS-TQQS-GTH9-TASK-hs-split-research-mcp-tool]]).
|
|
1096
|
+
# NOTE: `scripts/validate-vault-ids.mjs` still gates on the legacy
|
|
1097
|
+
# `status: closed` framing — validator catch-up to this "when set" framing is on
|
|
1098
|
+
# the deferred list in [[research-is-evergreen]].
|
|
1099
|
+
sources_captures: # optional, list of wikilinks to HS-CAP-* — captures this research aggregates (M:N).
|
|
1100
|
+
# Reverse of `capture.informs_research:`. Bidirectional consistency enforced.
|
|
1101
|
+
spawned_epics: # optional, list of wikilinks to HS-EPIC-* — epics this research spawned (1:N).
|
|
1102
|
+
# Reverse of `epic.derived_from:`.
|
|
1103
|
+
enhances_epics: # optional, list of wikilinks to HS-EPIC-* — already-existing epics this research
|
|
1104
|
+
# augmented (M:N, rare). One-sided in v1 — no reverse field on epic.
|
|
1105
|
+
produces_diagnose: # optional, list of wikilinks to HS-DIAG-* — bugs found during this research and
|
|
1106
|
+
# promoted to a diagnose (1:N, mirrors `spawned_epics`). Reverse of
|
|
1107
|
+
# `diagnose.derived_from:`. Written by `heyspex_promote_research_to_diagnose`
|
|
1108
|
+
# ([[HS-W5VP-MSHY-TASK-research-diagnose-link-send-bugs-to-the]]); reuses the existing
|
|
1109
|
+
# diagnose machinery — see [[resolution-diagnose-workflow]].
|
|
1110
|
+
split_into: # optional, list of wikilinks — on the original (archive) research when split;
|
|
1111
|
+
# names the child research docs that carry forward.
|
|
1112
|
+
split_from: # optional, single wikilink — on a research created by splitting from an ancestor;
|
|
1113
|
+
# mirror of `split_into:` on the ancestor.
|
|
1114
|
+
source_capture: # optional wikilink to HS-CAP-* — legacy single-capture seed pointer; retained for
|
|
1115
|
+
# read-side back-compat. New research uses `sources_captures:` (M:N) as canonical.
|
|
1116
|
+
planning_flow: # optional until flow filed; then wikilink to HS-FLOW-*
|
|
1117
|
+
bound_epic: # optional; set when epic filed — locks findings to append-only ([[planning-flow-research-epic-lifecycle]])
|
|
1118
|
+
forked_from: # optional, wikilink — source HS-RES when forked for a new epic
|
|
1119
|
+
```
|
|
1120
|
+
|
|
1121
|
+
Body is the research note. After `bound_epic:` is set, findings sections are append-only; new epic scope uses `## Scope for <epic name>` addendum sections.
|
|
1122
|
+
|
|
1123
|
+
##### Code-audit findings table (`research_type: code-audit`)
|
|
1124
|
+
|
|
1125
|
+
A `research_type: code-audit` doc's body **must** carry a findings table — the authored standard for "reviewed the code, found N things, here's what happens to each" (HS-7D0I-WL88-TASK-code-audit-research-type-with-a-defined). Four columns, in this order:
|
|
1126
|
+
|
|
1127
|
+
| Finding | Severity | Action (diagnose\|task\|reference) | Exit (open\|closed) |
|
|
1128
|
+
| -------------------------------------- | ---------------------------- | ----------------------------------- | ------------------- |
|
|
1129
|
+
| One-line description of what was found | freetext (e.g. high/med/low) | `diagnose` \| `task` \| `reference` | `open` \| `closed` |
|
|
1130
|
+
|
|
1131
|
+
Every row's `Action` maps to exactly one of three defined exits — no fourth "just leave it" option:
|
|
1132
|
+
|
|
1133
|
+
- **`diagnose`** — a real bug. Promote it with the existing `heyspex_promote_research_to_diagnose` tool (HS-W5VP-MSHY-TASK-research-diagnose-link-send-bugs-to-the), which writes `research.produces_diagnose:` / `diagnose.derived_from:` (see §Provenance edges). Not new machinery — reuse it.
|
|
1134
|
+
- **`task`** — a cleanup/follow-up with no bug attached. File a task and set its `discovered_from: [[HS-RES-…]]` back to this research doc (see `task.discovered_from` above and §Dependencies "Discovered-from").
|
|
1135
|
+
- **`reference`** — non-actionable; the row itself IS the exit. Set `Exit: closed` directly, no further linkage required.
|
|
1136
|
+
|
|
1137
|
+
**Enforcement** (`spex-console/src/lib/indexer/vault-rules.mjs`):
|
|
1138
|
+
|
|
1139
|
+
- `CODE_AUDIT_FINDINGS_MALFORMED` — no findings table, or one that doesn't match the 4-column header shape, or a data row with an unrecognized `Action`/`Exit` value. Warning during the `CODE_AUDIT_GRACE_END` grace window (mirrors `RESEARCH_TYPE_GRACE_END`'s pattern — pre-existing code-audit docs like `HS-ZHAB-RES-doc-authoring-contract-audit-required-st` predate this format and are exempt while the window is open), then a hard error.
|
|
1140
|
+
- `CODE_AUDIT_FINDINGS_OPEN_ON_CLOSE` — the **closure gate**: a code-audit doc at `status: closed` or `review_pending` with any finding row whose `Exit` is `open`. Warning during the same grace window, then error — blocks closing a code-audit doc until every finding has exited.
|
|
1141
|
+
|
|
1142
|
+
#### `planning-flow`
|
|
1143
|
+
|
|
1144
|
+
Orchestration artifact for epic filing (planning-flow-research-epic-lifecycle). Body contains a `## Planning flow` section with fenced `mermaid` (semantic source for canvas projection per spec-diagram-design-vs-as-built-canvas).
|
|
1145
|
+
|
|
1146
|
+
```yaml
|
|
1147
|
+
type: planning-flow
|
|
1148
|
+
research: # required, wikilink to HS-RES-*
|
|
1149
|
+
decisions: # optional, list of wikilinks — memory-decision or adr
|
|
1150
|
+
epic: # optional until epic filed; then wikilink to HS-EPIC-*
|
|
1151
|
+
has_diagram: # required, true — indexes canvas bridge + Shipped gallery when closed
|
|
1152
|
+
related: # optional, wikilinks to tasks and supporting specs
|
|
1153
|
+
```
|
|
1154
|
+
|
|
1155
|
+
#### `roadmap`
|
|
1156
|
+
|
|
1157
|
+
```yaml
|
|
1158
|
+
type: roadmap
|
|
1159
|
+
roadmap_manifest: # required, machine-readable phase index (see below)
|
|
1160
|
+
related_roadmaps: # optional, wikilinks to other HS-ROADMAP-* specs
|
|
1161
|
+
```
|
|
1162
|
+
|
|
1163
|
+
`roadmap_manifest` shape (indexer validates; agents request via `--compact`):
|
|
1164
|
+
|
|
1165
|
+
```yaml
|
|
1166
|
+
roadmap_manifest:
|
|
1167
|
+
version: 1
|
|
1168
|
+
phases:
|
|
1169
|
+
- id: M2 # short stable id
|
|
1170
|
+
name: Indexer MVP
|
|
1171
|
+
tasks: [HS-V3YS, HS-1BML] # HS-NNNN or HS-EPIC-NNNN ids
|
|
1172
|
+
horizon: # may not ship — priority-4 / tag:horizon backlog
|
|
1173
|
+
- HS-WYHZ
|
|
1174
|
+
initiatives: # optional links to other roadmap docs
|
|
1175
|
+
- HS-ROADMAP-VOICE-CHROME
|
|
1176
|
+
```
|
|
1177
|
+
|
|
1178
|
+
Body is the human narrative (goals, exit criteria, risks). **Do not duplicate** the task list in prose without mirroring ids in `roadmap_manifest` — the manifest is the console/CLI source of truth for ordering.
|
|
1179
|
+
|
|
1180
|
+
Horizon items use native `HS-NNNN` ids (or wikilinks to `future-considerations/` research until promoted). No separate FC id namespace (adr-0012-roadmap-storage).
|
|
1181
|
+
|
|
1182
|
+
#### `draft`
|
|
1183
|
+
|
|
1184
|
+
```yaml
|
|
1185
|
+
type: draft
|
|
1186
|
+
source: # optional, where this draft came from (URL, "phone capture", "screenshot", etc.)
|
|
1187
|
+
captured_at: # required, ISO-8601 datetime
|
|
1188
|
+
source_intent_hash: # optional but required on Agent ingest; SHA-256 of canonical capture blob ([[plan-ingest-review-roadmap-workflow]])
|
|
1189
|
+
source_intent: # optional verbatim excerpt (≤2 KB) of human inputs at capture time
|
|
1190
|
+
agent_output_hash: # optional; SHA-256 of structured Agent preview at Save-to-drafts
|
|
1191
|
+
review_stage: # optional, enum: inbox | deliberating | staging | review | promoted | rejected
|
|
1192
|
+
council_requested: # optional bool | null — per-submit override; null = apply deliberation.triggers policy ([[council-opt-in-pre-review-conditioning]])
|
|
1193
|
+
triage_record: # optional; scout pre-pass ([[council-triage-scout-optional-llm]], [[review-inbox-workshop-scout-overview]])
|
|
1194
|
+
deliberation_record: # optional; Gate 0 output ([[ai-deliberation-gate]]) — append-only runs
|
|
1195
|
+
suggestions: # optional; staged Gate A records ([[HS-EU98-GCGE-TASK-staged-draft-suggestion-schema]]) — omit when empty
|
|
1196
|
+
review_record: # optional; Gate A commit audit — who/when/per-suggestion outcomes
|
|
1197
|
+
ingest_mode: # optional, enum: manual | agent_llm — default manual when omitted
|
|
1198
|
+
capture_scope: # optional, enum: selection | full — did a highlight scope the body? (HS-M54O); absent ⇒ full
|
|
1199
|
+
purpose: # optional free string — the user's stated "why" for capturing (HS-7S40)
|
|
1200
|
+
context_blocks: # optional list of { source: typed | voice, text, at: ISO-8601 } — enrichment
|
|
1201
|
+
# added on the intent card (HS-JQ7O/0077), each bound to this draft's trace_id.
|
|
1202
|
+
# Append-only within a trace_id; ordered by `at`. Absent ⇒ no extra context.
|
|
1203
|
+
llm_route: # optional, required when ingest_mode is agent_llm — builder-selected route from console picker:
|
|
1204
|
+
# chatgpt | gemini | claude | auto | ... (enum grows with integrations; must stay in sync with UI labels)
|
|
1205
|
+
llm_resolved_at: # optional, ISO-8601 datetime when ingest_mode agent_llm — when the routed model finished
|
|
1206
|
+
resolved_model: # optional free string or structured id — actual provider/model id after routing (meaningful when llm_route: auto or when aliases map to concrete models)
|
|
1207
|
+
submission_kind: # optional, enum: external_media | refined_intent — Gate 0 epistemic mode ([[companion-external-media-vs-refined-intent-council]]); companion defaults external_media
|
|
1208
|
+
capture_channel: # optional, enum: manual_ui | cli | voice | extension | companion | ...
|
|
1209
|
+
companion_dialogue: # optional append-only [{ role: user|assistant, text, at }] — pre-send chat about capture ([[HS-67TW-2966-TASK-companion-pre-council-context-dialogue]]); omit when empty
|
|
1210
|
+
capture_group_id: # optional string — shared id linking multiple captures made in one multi-capture
|
|
1211
|
+
# companion session; drafts sharing this id render as a connected set on the
|
|
1212
|
+
# Captures surface, ordered by capture_group_seq. Distinct from capture_bundle_id
|
|
1213
|
+
# below (one composite draft with multiple sources) — this links multiple SEPARATE
|
|
1214
|
+
# draft files. Omit for standalone single captures.
|
|
1215
|
+
capture_group_seq: # optional positive integer — 1-based position within capture_group_id's group.
|
|
1216
|
+
# Only meaningful when capture_group_id is set.
|
|
1217
|
+
capture_bundle_id: # optional UUID — companion-local bundle id when submitted from Capture inbox ([[companion-capture-inbox-and-bundles]])
|
|
1218
|
+
source_set: # optional — multi-source bundle; list of members, each with { url | file_path, title, member_trace_id, member_note, file_size?, file_type? }
|
|
1219
|
+
# For web captures: url (required), title, member_trace_id, member_note ([[HS-D1YU-OVFO-TASK-bundle-submit-composite-draft-source-set]])
|
|
1220
|
+
# For file captures: file_path (required), title (filename), file_size, file_type, member_trace_id, member_note ([[HS-5FI0-0036-EPIC-file-system-selection-voice-capture]])
|
|
1221
|
+
# Omit for single-source captures
|
|
1222
|
+
wake_used: # optional bool — companion wake phrase invoked (vs shortcut-only capture)
|
|
1223
|
+
foreground_app: # optional string — OS-visible focused app title/name at capture time
|
|
1224
|
+
spoken_command_tail: # optional sanitized transcript excerpt when capture_channel includes voice (see [[uc-voice-ingest-hey-spex]])
|
|
1225
|
+
shortcut_binding_id: # optional stable identifier for whichever hotkey initiated capture
|
|
1226
|
+
voice_companion_semver: # optional — installed companion semantic version emitting the draft
|
|
1227
|
+
pointer_screen_x: # optional — mouse pointer X in screen px, sampled once at ingest trigger
|
|
1228
|
+
pointer_screen_y: # mouse pointer Y (screen px)
|
|
1229
|
+
pointer_dpi_scale:
|
|
1230
|
+
pointer_sampled_at: # ISO-8601
|
|
1231
|
+
last_click_screen_x:
|
|
1232
|
+
last_click_screen_y:
|
|
1233
|
+
last_click_at:
|
|
1234
|
+
spatial_hint_ttl_ms:
|
|
1235
|
+
chrome_viewport_ratio_x:
|
|
1236
|
+
chrome_viewport_ratio_y:
|
|
1237
|
+
pointer_dom_hint: # optional heuristic from Chrome elementFromPoint; non-authoritative
|
|
1238
|
+
|
|
1239
|
+
# File capture provenance (when source_type: local_file) — [[HS-5FI0-0036-EPIC-file-system-selection-voice-capture]]
|
|
1240
|
+
source_type: # optional enum: local_file | url — discriminator; url is default/implicit for browser captures
|
|
1241
|
+
file_path: # optional string — absolute path (single file or root folder); present when source_type: local_file
|
|
1242
|
+
file_size: # optional int — file size in bytes
|
|
1243
|
+
file_type: # optional string — MIME type or file extension
|
|
1244
|
+
file_modified_at: # optional ISO-8601 — file mtime at capture
|
|
1245
|
+
folder_depth: # optional int — recursion depth when folder captured
|
|
1246
|
+
folder_file_count: # optional int — total files in folder/zip capture
|
|
1247
|
+
zip_extracted: # optional bool — true if zip was extracted to temp for ingestion
|
|
1248
|
+
zip_source_path: # optional string — original zip path when zip_extracted: true
|
|
1249
|
+
sensitive_files_included: # optional list of { path, pattern_matched, user_confirmed_at } — audit when user overrode sensitive file warning
|
|
1250
|
+
```
|
|
1251
|
+
|
|
1252
|
+
Body is the ingested content; triage promotes a draft into a task, memory, or research file by editing the frontmatter `type:` and moving the file.
|
|
1253
|
+
|
|
1254
|
+
Agent-assisted drafts **should** end the markdown body with a short human-readable provenance line so readers skimming raw files see how the draft was produced; **frontmatter carries the authoritative fields.**
|
|
1255
|
+
|
|
1256
|
+
Example footer (console-rendered; values must mirror frontmatter):
|
|
1257
|
+
|
|
1258
|
+
```markdown
|
|
1259
|
+
---
|
|
1260
|
+
|
|
1261
|
+
_Ingest provenance:_ route `claude` → resolved `anthropic/claude-3-7-sonnet` · _Captured:_ 2026-05-16T12:00:00Z
|
|
1262
|
+
```
|
|
1263
|
+
|
|
1264
|
+
See uc-ingest-anywhere §Console toggle: Manual vs Agent ingest, HS-DOC-architecture-foundations §What it exposes (API), companion capture + optional spatial hints in uc-voice-ingest-hey-spex §Persistence / §Spatial pointers when `capture_channel: voice`.
|
|
1265
|
+
|
|
1266
|
+
**`deliberation_record`** (when present):
|
|
1267
|
+
|
|
1268
|
+
Permitted on `draft`, `task`, `epic`, and `review` types — Council session output, append-only across all four ai-deliberation-gate invocation points per adr-0015-council-as-cross-cutting-capability. The host spec retains its existing type; the record is purely advisory and never gates anything (human disposition stays in Gates A/B/C per heyspex-north-star Principle 3).
|
|
1269
|
+
|
|
1270
|
+
```yaml
|
|
1271
|
+
deliberation_record:
|
|
1272
|
+
latest_run_id: "<uuid>"
|
|
1273
|
+
runs:
|
|
1274
|
+
- run_id: "<uuid>"
|
|
1275
|
+
at: "<ISO-8601>"
|
|
1276
|
+
invocation_point: pre_review | canvas_live | promoted_recheck | review_close
|
|
1277
|
+
# which of the four Council invocation points produced this run
|
|
1278
|
+
# (per [[adr-0015-council-as-cross-cutting-capability]])
|
|
1279
|
+
submission_lens: refined_intent | external_media | promoted_spec_recheck
|
|
1280
|
+
# role objective discriminator — lifts the draft body's
|
|
1281
|
+
# `submission_kind` to the run so promoted-spec contexts carry it
|
|
1282
|
+
parent_run_id: "<uuid>" | null # loop-suppression input; null on first run for a spec
|
|
1283
|
+
test_preset: free | cheap | production | null # when [[ai-deliberation-gate]] test_mode was active
|
|
1284
|
+
api_calls: 4 # optional audit — varies by invocation: 1 (canvas_live),
|
|
1285
|
+
# 3 (review_close, skip rebuttal), 4 (pre_review skip_rebuttal),
|
|
1286
|
+
# 7 (full pre_review or promoted_recheck)
|
|
1287
|
+
roles:
|
|
1288
|
+
- id: tech_lead | program_lead | ux_lead
|
|
1289
|
+
provider: "<string>"
|
|
1290
|
+
model: "<string>"
|
|
1291
|
+
position:
|
|
1292
|
+
disposition: schedule_now | schedule_later | horizon | defer | deprecated | merge | reject | split
|
|
1293
|
+
priority: 0-4
|
|
1294
|
+
roadmap_phase: "<id>"
|
|
1295
|
+
merge_into: "[[HS-NNNN]]"
|
|
1296
|
+
north_star_alignment: aligned | tension | conflict
|
|
1297
|
+
arguments: ["<bullet>"]
|
|
1298
|
+
facilitator: # absent on `canvas_live` (single-role) and on
|
|
1299
|
+
# `review_close` when skip_rebuttal is set
|
|
1300
|
+
recommended_disposition: "<enum>"
|
|
1301
|
+
confidence: 0.0-1.0
|
|
1302
|
+
disagreements: ["<role_a vs role_b on topic>"]
|
|
1303
|
+
north_star_conflict: # present when ≥2 roles report conflict
|
|
1304
|
+
agreed: true
|
|
1305
|
+
summary: "<string>"
|
|
1306
|
+
path_a_change_l1: { summary, typical: false }
|
|
1307
|
+
path_b_reshape_plan: { summary, suggested_edits: [] }
|
|
1308
|
+
```
|
|
1309
|
+
|
|
1310
|
+
**Storage bound:** `runs[]` is capped at the last 10 entries in frontmatter; older runs archive to `specs/.deliberation-archive/<spec-id>.yaml` (gitignored, audit-only) per adr-0015-council-as-cross-cutting-capability §Consequences.
|
|
1311
|
+
|
|
1312
|
+
**`triage_record`** (when present; scout only — not council):
|
|
1313
|
+
|
|
1314
|
+
```yaml
|
|
1315
|
+
triage_record:
|
|
1316
|
+
at: "<ISO-8601>"
|
|
1317
|
+
model: "<slug>"
|
|
1318
|
+
title_line: "<≤80 chars>"
|
|
1319
|
+
memory_jogger: "<2-3 sentences>"
|
|
1320
|
+
review_category: feature_request | external_media | brainstorm | research | bug | mixed | unclear
|
|
1321
|
+
recommend_council: true | false
|
|
1322
|
+
confidence: 0.0-1.0
|
|
1323
|
+
rationale: "<string>"
|
|
1324
|
+
suggested_actions:
|
|
1325
|
+
- id: run_council | add_context | gate_a_review | defer | promote_quick | discard
|
|
1326
|
+
label: "<string>"
|
|
1327
|
+
primary: true
|
|
1328
|
+
quick_tags: ["<optional>"]
|
|
1329
|
+
```
|
|
1330
|
+
|
|
1331
|
+
**`suggestions`** (when present; omit block entirely when empty — pre-HS-GCGE-TASK drafts unchanged):
|
|
1332
|
+
|
|
1333
|
+
```yaml
|
|
1334
|
+
suggestions:
|
|
1335
|
+
- id: "<stable-uuid-within-draft>"
|
|
1336
|
+
kind: roadmap | priority | child_task | consideration
|
|
1337
|
+
payload: {} # kind-specific proposed fields (epic stub, priority, etc.)
|
|
1338
|
+
rationale: "<one line>"
|
|
1339
|
+
disposition: pending | accepted | edited | declined
|
|
1340
|
+
edited_payload: {} # optional; present when disposition: edited
|
|
1341
|
+
provenance:
|
|
1342
|
+
llm_route: "<enum>"
|
|
1343
|
+
resolved_model: "<provider/model>"
|
|
1344
|
+
at: "<ISO-8601>"
|
|
1345
|
+
```
|
|
1346
|
+
|
|
1347
|
+
**`review_record`** (written on Gate A staging commit):
|
|
1348
|
+
|
|
1349
|
+
```yaml
|
|
1350
|
+
review_record:
|
|
1351
|
+
at: "<ISO-8601>"
|
|
1352
|
+
by: pwher
|
|
1353
|
+
outcomes:
|
|
1354
|
+
- suggestion_id: "<uuid>"
|
|
1355
|
+
disposition: accepted | edited | declined
|
|
1356
|
+
note: "<optional>"
|
|
1357
|
+
```
|
|
1358
|
+
|
|
1359
|
+
#### `daily`
|
|
1360
|
+
|
|
1361
|
+
```yaml
|
|
1362
|
+
type: daily
|
|
1363
|
+
date: # required, ISO-8601 date
|
|
1364
|
+
```
|
|
1365
|
+
|
|
1366
|
+
Body is free-form notes for the day.
|
|
1367
|
+
|
|
1368
|
+
## Body structure conventions
|
|
1369
|
+
|
|
1370
|
+
Beyond the type-specific required sections noted above, all specs follow these structural conventions:
|
|
1371
|
+
|
|
1372
|
+
- The first heading is `# <Name>` (the human-readable title), matching `name:` in frontmatter.
|
|
1373
|
+
- Optional first block: a single `> [!note]` / `> [!important]` callout if there's a one-line framing message.
|
|
1374
|
+
- Sections use `##` headings. Sub-sections `###`.
|
|
1375
|
+
- A spec ends with `## Related specs` (optional) and `## Change log` (required for L1, L2, L3, ADR, and protocol; optional but encouraged elsewhere).
|
|
1376
|
+
|
|
1377
|
+
### Recommended sections for long-lived specs
|
|
1378
|
+
|
|
1379
|
+
Two SCEH-Pattern conventions (HS-U88E-SP34-EPIC-sceh-patterns-3-and-4-markdown-conventions) define optional `##` sections useful on specs that accumulate work across many sessions:
|
|
1380
|
+
|
|
1381
|
+
| Section | Protocol | Use when | Placement |
|
|
1382
|
+
| ------------------------ | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
|
|
1383
|
+
| `## Session Boundaries` | session-boundary-marker | Multi-session epics, milestones, and HS-REV review docs benefit from a five-column session-by-session trail (`session_id` / `agent` / `started` / `ended` / `summary`). | Immediately above `## Change log`. |
|
|
1384
|
+
| `## Conflict Resolution` | conflict-resolution-section | Two or more sessions left contradictory opinions in the body, change log, or HS-REV companions and a reviewer has had to pick. Three-row table (opinions + bold `**resolution**`) with optional memory-extraction routing into `memory-decision` specs. | Below `## Session Boundaries` if present, above `## Change log`. |
|
|
1385
|
+
|
|
1386
|
+
Both are **recommended** — opt-in per spec, not enforced by the wikilink validator. They are content commentary about the spec; control-plane runtime state (claim/focus/spec events, handoff context) stays in Neon (control-plane-belongs-in-neon).
|
|
1387
|
+
|
|
1388
|
+
## Dependencies
|
|
1389
|
+
|
|
1390
|
+
HeySpex inherits beads' four dependency types and adds a normalization choice: dependencies are expressed **both** as structured frontmatter arrays **and** as inline wikilinks in body prose. The frontmatter is canonical for queries; the body wikilinks are for reading flow.
|
|
1391
|
+
|
|
1392
|
+
| Type | Frontmatter field | Inverse field | Semantics |
|
|
1393
|
+
| ------------------- | -------------------------- | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
1394
|
+
| **Blocks** | `blocks: [[...]]` | `blocked_by: [[...]]` | Hard. A blocked task is not ready until all `blocked_by` resolve. |
|
|
1395
|
+
| **Related** | `related: [[...]]` | `related:` (symmetric) | Soft. Navigational only; no readiness implication. |
|
|
1396
|
+
| **Parent-child** | `children: [[...]]` | `parent: [[...]]` | Hierarchical. Children roll up to parent for "completion of parent" calculations. |
|
|
1397
|
+
| **Discovered-from** | `discovered_from: [[...]]` | `discovered:` (list) | Provenance. "This task was born while working on X." |
|
|
1398
|
+
| **Iterates-on** | `iterates_on: [[...]]` | `iteratedBy:` (computed) | Re-attempt. "This initiative re-attempts an outcome the target shipped but did not fully deliver." No readiness implication; neither doc is demoted. See §Iteration lineage below. |
|
|
1399
|
+
|
|
1400
|
+
Rules:
|
|
1401
|
+
|
|
1402
|
+
- The indexer maintains both sides of every edge; the Builder only needs to write one side, and the console fills the other on save. (Implementation detail; specified in HS-DOC-architecture-foundations.)
|
|
1403
|
+
- The indexer rejects edges that form a cycle in the `blocks` graph or the `parent`/`children` graph.
|
|
1404
|
+
- `related` edges are symmetric; the indexer enforces symmetry on save.
|
|
1405
|
+
- A task without a `parent:` and not referenced as a child by anyone is treated as a top-level task.
|
|
1406
|
+
- `discovered_from` is single-valued; if a task has multiple origins, model the additional ones as `related:`.
|
|
1407
|
+
|
|
1408
|
+
## Provenance edges (capture → research → milestone)
|
|
1409
|
+
|
|
1410
|
+
The promotion lifecycle — capture observation → research synthesis → milestone commitment — has cross-type provenance edges with strict cardinalities. Ratified by HS-OFR5-M2J3-EPIC-introduce-milestones-as-highest-entity §Architecture; enforced by `scripts/validate-vault-ids.mjs` (HS-HQRM-YJX6-TASK-research-enhances-exactly-one-milestone-validator-and-bidirectional-linkage).
|
|
1411
|
+
|
|
1412
|
+
| Edge | Cardinality | Forward field | Reverse field |
|
|
1413
|
+
| ----------------------------------- | ---------------- | ----------------------------------------------------- | ---------------------------------------------- |
|
|
1414
|
+
| **Capture → Research** | M:N | `capture.informs_research: [[[HS-RES-…]]]` | `research.sources_captures: [[[HS-CAP-…]]]` |
|
|
1415
|
+
| **Research → Milestone** | **M:1** (strict) | `research.enhances: [[HS-MIL-…]]` (single, not array) | `milestone.informed_by: [[[HS-RES-…]]]` |
|
|
1416
|
+
| **Research → Epic (spawned)** | 1:N | `research.spawned_epics: [[[HS-EPIC-…]]]` | `epic.derived_from: [[HS-RES-…]]` (single) |
|
|
1417
|
+
| **Research → Epic (augmented)** | M:N | `research.enhances_epics: [[[HS-EPIC-…]]]` | (one-sided — no reverse field on epic in v1) |
|
|
1418
|
+
| **Research → Diagnose (bug found)** | 1:N | `research.produces_diagnose: [[[HS-DIAG-…]]]` | `diagnose.derived_from: [[HS-RES-…]]` (single) |
|
|
1419
|
+
|
|
1420
|
+
Rules:
|
|
1421
|
+
|
|
1422
|
+
- **Research is M:1 to milestone — strict.** A single research doc that spans multiple milestones must be split before promotion. The split-action protocol is owned by HS-TQQS-GTH9-TASK-hs-split-research-mcp-tool; the original research stays as the audit archive with `status: closed` and `split_into: [[HS-RES-A]], [[HS-RES-B]]`, while N child research docs each carry `split_from: [[HS-RES-original]]` and their own `enhances:` target.
|
|
1423
|
+
- **Open research may omit `enhances:`.** The validator only requires it on `status: closed` research (the promotion-time gate); during exploration the target milestone can still be ambiguous.
|
|
1424
|
+
- **`enhances:` is single-valued.** Not an array — the validator rejects array form and points the author at the split flow.
|
|
1425
|
+
- **Bidirectional consistency is enforced.** If research X has `enhances: Y`, milestone Y MUST list X in `informed_by:`. If capture C has `informs_research: [X, Y]`, both X.sources_captures and Y.sources_captures MUST include C. The validator surfaces one-sided drift as a hard error on each side.
|
|
1426
|
+
- **Captures M:N research is intentional.** A single capture may inform multiple research docs over time (e.g. a "voice capture works" observation that lands in both companion research and console-voice research). The first promotion writes `capture.promoted_to:` (binary pointer); subsequent re-uses extend `capture.informs_research:` without touching `promoted_to:`.
|
|
1427
|
+
- **`spawned_epics` vs `enhances_epics`.** `spawned_epics` is the canonical 1:N edge — epics this research _created_, mirrored as `epic.derived_from:` on each child. `enhances_epics` is the rarer case where research _augmented_ an already-existing epic; it's a one-sided list with no reverse field in v1.
|
|
1428
|
+
- **`produces_diagnose` mirrors `spawned_epics`.** A research investigation may surface a bug, which is promoted into a first-class `HS-DIAG-*` (not new machinery — the existing diagnose entity per resolution-diagnose-workflow). `research.produces_diagnose:` is the canonical 1:N edge, mirrored as `diagnose.derived_from:` on each child, written by `heyspex_promote_research_to_diagnose`. This is the research-side sibling of the capture-side exit `heyspex_promote_capture_to_diagnose` (which writes `diagnose.promoted_from:` ⇔ `capture.promoted_to:`/`informs_diagnose:` instead).
|
|
1429
|
+
|
|
1430
|
+
Promotion-action contract (`/hs-promote-research`, HS-2ERO-QQHP-TASK-hs-promote-research-mcp-tool): writes all four sides (research.enhances, research.spawned_epics, milestone.informed_by, epic.derived_from) atomically. The validator is the safety net for hand-edited drift, not the primary write path.
|
|
1431
|
+
|
|
1432
|
+
## Iteration lineage (round-to-round re-attempts)
|
|
1433
|
+
|
|
1434
|
+
The **third doc-to-doc relation tier**, alongside supersession (terminal, whole-doc) and amends (partial, non-terminal) — ratified via HS-3TZX-T9T6-RES-iteration-loop-lineage-and-capture Part A, built by HS-O97P-T9T6-EPIC-iteration-loop-lineage-relation-tier. It expresses what neither existing tier can: _work shipped and closed, the outcome fell short of the goal, and a NEW family re-attempts the SAME goal._ Supersession would falsify round 1 (it wasn't wrong — it shipped, its review is accurate history); amends would misdescribe it (round 2 contradicts nothing).
|
|
1435
|
+
|
|
1436
|
+
### Fields
|
|
1437
|
+
|
|
1438
|
+
```yaml
|
|
1439
|
+
iterates_on: # optional, YAML list of wikilinks — lives ONLY on the NEWER doc (one-edit-on-source,
|
|
1440
|
+
# same principle as amends). Semantics: "this initiative re-attempts an outcome the
|
|
1441
|
+
# target initiative shipped but did not fully deliver." Typically carried by the
|
|
1442
|
+
# round-2 research doc pointing at the round-1 research doc — the research chain is
|
|
1443
|
+
# the spine (research is evergreen, so the root research id is the durable handle
|
|
1444
|
+
# spanning every round; no new entity type).
|
|
1445
|
+
# iteratedBy — COMPUTED reverse map (indexer/validator output, like amendedBy) — never written
|
|
1446
|
+
# by hand into frontmatter.
|
|
1447
|
+
outcome: # optional, on TRACKABLE docs only, set by the HUMAN REVIEWER at close — never
|
|
1448
|
+
# inferred, never agent-set. Enum: met | partially-met | not-met. Lives ONLY on
|
|
1449
|
+
# the closed doc (not echoed onto the round-2 doc; discovery goes through the
|
|
1450
|
+
# iteratedBy reverse map).
|
|
1451
|
+
outcome_note: # optional, one-line reviewer prose qualifying the verdict.
|
|
1452
|
+
```
|
|
1453
|
+
|
|
1454
|
+
### Invariants
|
|
1455
|
+
|
|
1456
|
+
- **Nothing is demoted.** Both docs stay `canonical: true`; round 1 keeps `status: closed`. `iterates_on:` is a lineage edge, not a supersession — demoting round 1 to `canonical: false` would falsify the record and hide shipped scope from round 2's breakdown.
|
|
1457
|
+
- **`outcome:` is the reviewer's judgment alone.** `status: closed` without an `outcome:` says only "shipped"; it must never be read as "goal met." The verdict is written at reviewer close (the one mutable-at-close moment), per session-close-protocol.
|
|
1458
|
+
- **Distinct family keys are correct.** Round 2 is its own initiative with its own children and review, so it takes a new family key; `iterates_on:` is the cross-family edge that replaces the missing shared grep handle.
|
|
1459
|
+
|
|
1460
|
+
### Required `## Related / lineage` section on promoted docs
|
|
1461
|
+
|
|
1462
|
+
Every promoted doc's outline ends with a resolved-wikilink table (immediately before `## Change log`), authored at promote-time and gated by `heyspex_validate_linkage` (every row must resolve under `specs/`):
|
|
1463
|
+
|
|
1464
|
+
```markdown
|
|
1465
|
+
## Related / lineage
|
|
1466
|
+
|
|
1467
|
+
| Doc | Role |
|
|
1468
|
+
| -------------------- | ---------------------- |
|
|
1469
|
+
| [[round-1-research]] | Iterates on |
|
|
1470
|
+
| [[HS-REV-...]] | Prior attempt's review |
|
|
1471
|
+
| [[HS-CAP-...]] | Feedback capture |
|
|
1472
|
+
```
|
|
1473
|
+
|
|
1474
|
+
Role vocabulary: **Iterates on · Prior attempt's review · Feedback capture · Amends · Superseded by · Pillar · Spawned epics** (extend with prose roles when none fits — e.g. "Source capture", "Enhances").
|
|
1475
|
+
|
|
1476
|
+
## Evidence linking
|
|
1477
|
+
|
|
1478
|
+
> [!important] "Summaries with receipts"
|
|
1479
|
+
> Ratified by adr-0008-branch-brief-and-evidence-schema for HS-7KOO-0022-EPIC-continuity-layer-gaps. Every claim a memory or brief makes should be able to point at a verifiable source. Without evidence, a summary is unfalsifiable; with it, a reader can navigate from claim to proof.
|
|
1480
|
+
|
|
1481
|
+
`evidence:` is an optional array on `branch-brief`, `memory-lesson`, `memory-decision`, `memory-reference`, `memory-ui-pattern`, and `task`. Each entry:
|
|
1482
|
+
|
|
1483
|
+
```yaml
|
|
1484
|
+
evidence:
|
|
1485
|
+
- type: commit # required — one of the evidence types below
|
|
1486
|
+
ref: "abc123" # required — the reference, format per type
|
|
1487
|
+
line: 42 # optional — line number (file/diff only)
|
|
1488
|
+
description: "..." # optional — what this evidence shows
|
|
1489
|
+
```
|
|
1490
|
+
|
|
1491
|
+
Evidence types:
|
|
1492
|
+
|
|
1493
|
+
| Type | `ref` format | Example |
|
|
1494
|
+
| -------- | ------------------------------------ | ---------------------------------------------------------------- |
|
|
1495
|
+
| `commit` | short or full SHA | `abc123`, `abc123def…` |
|
|
1496
|
+
| `file` | repo-relative path, optional `:line` | `src/foo.ts`, `src/foo.ts:42` |
|
|
1497
|
+
| `pr` | PR number | `#123` |
|
|
1498
|
+
| `diff` | `commit:path` | `abc123:src/pages/dashboard.tsx` |
|
|
1499
|
+
| `issue` | issue number | `#42` |
|
|
1500
|
+
| `note` | freeform text | `Builder confirmed via Slack 2026-05-15` |
|
|
1501
|
+
| `test` | test/gate identifier | `vitest:src/lib/continuity/plan-vs-actual.test.ts`, `tsc:noEmit` |
|
|
1502
|
+
|
|
1503
|
+
> [!note] `test` added 2026-08-11 (receipt-on-ship, HS-XGG4-IU2S-EPIC-receipt-on-ship-plan-vs-actual-proof-at). Additive extension per adr-0008-branch-brief-and-evidence-schema §Consequences ("a future change to evidence types … is a normal entity-model edit"); lets Plan Receipts cite test/gate results as typed evidence.
|
|
1504
|
+
|
|
1505
|
+
### Inline shorthand
|
|
1506
|
+
|
|
1507
|
+
In body prose, evidence may be cited inline as `[evidence:<type>:<ref>]`:
|
|
1508
|
+
|
|
1509
|
+
```markdown
|
|
1510
|
+
We chose Payment Elements over hosted checkout [evidence:commit:abc123]
|
|
1511
|
+
because it gives better customization [evidence:pr:#123].
|
|
1512
|
+
```
|
|
1513
|
+
|
|
1514
|
+
The indexer harvests inline shorthand and the frontmatter `evidence:` array into the same evidence index; **frontmatter is canonical** for "what grounds this spec?" queries (same rule as `tags:` and dependency edges). Console rendering of evidence references (commit → diff view, file → file viewer at line, pr/issue → git host) is an implementation concern specified downstream, not part of this schema contract.
|
|
1515
|
+
|
|
1516
|
+
## Delivery snapshot
|
|
1517
|
+
|
|
1518
|
+
> [!note] User-persisted, not auto-maintained
|
|
1519
|
+
> See HS-WB81-RBJ8-TASK-spec-delivery-frontmatter-snapshot. The live source of truth for "which commits touched this spec" is always `git log -- <spec_path>`; the `delivery:` block is an _optional persisted snapshot_ the Builder takes from the console's On Deck row so the vault carries its own delivery trail.
|
|
1520
|
+
|
|
1521
|
+
`delivery:` is an **optional, cross-type** key. It exists only after the Builder has clicked "snapshot to spec" in the console's delivery dropdown. Shape:
|
|
1522
|
+
|
|
1523
|
+
```yaml
|
|
1524
|
+
delivery:
|
|
1525
|
+
snapshot_at: 2026-05-21T07:00:00-05:00 # ISO timestamp of when the snapshot was taken
|
|
1526
|
+
commits:
|
|
1527
|
+
- sha: 8648ad5e3f... # full SHA
|
|
1528
|
+
short_sha: 8648ad5 # 7-char SHA
|
|
1529
|
+
branch: hs-mvp0520 # primary branch (local before remote)
|
|
1530
|
+
pushed: true # boolean — reachable from origin/*
|
|
1531
|
+
at: 2026-05-21T05:14:32-05:00 # commit author time
|
|
1532
|
+
author: pwher
|
|
1533
|
+
message: "feat(console): per-spec delivery dropdown on On Deck child rows"
|
|
1534
|
+
```
|
|
1535
|
+
|
|
1536
|
+
Rules:
|
|
1537
|
+
|
|
1538
|
+
- One primary branch per row, not the full branch list (live view stays authoritative for fan-out).
|
|
1539
|
+
- `message` is the first commit-message line only; full commit bodies live in git, not the vault.
|
|
1540
|
+
- `delivery:` may be present on **any** spec type; treat it as a presentational artifact, not a dependency edge — the indexer does not crawl it.
|
|
1541
|
+
- A stale snapshot (live count ≠ snapshot count) is rendered as such in the console; the snapshot is never auto-refreshed.
|
|
1542
|
+
- Persisted by `PUT /api/specs/[id]/delivery`; no git hook or agent workflow rewrites it.
|
|
1543
|
+
|
|
1544
|
+
## Wikilink resolution rules
|
|
1545
|
+
|
|
1546
|
+
HeySpex uses Obsidian-compatible wikilinks: `[[target]]` or `[[target|display text]]`.
|
|
1547
|
+
|
|
1548
|
+
Resolution algorithm:
|
|
1549
|
+
|
|
1550
|
+
1. **Strip extension.** `[[foo]]`, `[[foo.md]]`, and `[[foo|Foo]]` all target the file basename `foo`.
|
|
1551
|
+
2. **Case-insensitive match.** The resolver compares lowercased basenames. `[[Foo]]` and `[[foo]]` resolve to the same file.
|
|
1552
|
+
3. **No path qualifier needed.** Folders are not part of the resolution. `[[entity-model]]` finds `specs/entity-model.md` regardless of where the linking spec lives. (Consistent with Obsidian's "default" link mode.)
|
|
1553
|
+
4. **Aliases.** If a spec's frontmatter has `aliases: [foo, bar]`, both `[[foo]]` and `[[bar]]` also resolve to that spec.
|
|
1554
|
+
5. **Forward references are valid.** A wikilink to a non-existent spec is not an error; it is a signal that the linked spec should be written. The indexer records forward references in a `forward_refs` view; the console shows them inline so the Builder can see what's pending.
|
|
1555
|
+
6. **Duplicate basenames are forbidden.** Two specs may not share a basename. The indexer rejects writes that would create a duplicate.
|
|
1556
|
+
7. **Filename is canonical; do not author id-form links.** The resolver also matches a link target against a spec's frontmatter `id:` (it tries id → basename → alias, in that order). This is a **tolerant fallback** so that hand-typed or legacy `[[HS-DEC-…]]`/`[[HS-TASK-…]]` links still resolve — it is **not** the form to write. Author every link by **filename basename** so the vault stays Obsidian-portable (Obsidian does not resolve by the `id:` field). For memory specs (decisions, lessons, references, ui-patterns) the file is slug-named while its `id` carries a type prefix, so `[[HS-DEC-foo]]` is the id form and `[[foo]]` is the canonical filename form — prefer the latter. The vault was swept to filename form on 2026-05-28 (`scripts/sweep-hs-dec-links-to-basename.mjs`).
|
|
1557
|
+
|
|
1558
|
+
Display text:
|
|
1559
|
+
|
|
1560
|
+
- `[[entity-model|the entity model]]` renders "the entity model" as a link to `entity-model.md`.
|
|
1561
|
+
- This is the same syntax Obsidian uses; HeySpex inherits it unchanged.
|
|
1562
|
+
|
|
1563
|
+
## Tags
|
|
1564
|
+
|
|
1565
|
+
Tags use the `tags:` array in frontmatter. They are flat strings, no nesting (no `#foo/bar` semantics in v1 beyond convention).
|
|
1566
|
+
|
|
1567
|
+
Body-inline `#tag` syntax is allowed for compatibility with Obsidian users; the indexer harvests both frontmatter tags and body inline tags into the same index, but frontmatter is canonical for "is this spec tagged X?" queries.
|
|
1568
|
+
|
|
1569
|
+
## Reserved frontmatter keys
|
|
1570
|
+
|
|
1571
|
+
The following keys are reserved by HeySpex and must not be repurposed:
|
|
1572
|
+
|
|
1573
|
+
- `id`, `name`, `type`, `status`, `priority`, `owner`, `created`, `updated`, `tags`, `related`, `aliases`
|
|
1574
|
+
- `blocks`, `blocked_by`, `parent`, `children`, `discovered_from`, `discovered`
|
|
1575
|
+
- `assignee`, `started_at`, `closed_at`, `close_reason`, `defer_until`
|
|
1576
|
+
- `evidence` (cross-type; see [Evidence linking](#evidence-linking))
|
|
1577
|
+
- `delivery` (cross-type; user-persisted git-log snapshot — see [Delivery snapshot](#delivery-snapshot))
|
|
1578
|
+
- `legacy_bd_id`, `legacy_dolt_commit`
|
|
1579
|
+
- Type-specific fields named above (including `branch-brief`'s `branch`, `goal`, `implements`, `plan`, `actual`, `risks`, `open_questions`, `next_steps`, `decisions`; `milestone`'s `epics`, `target_date`, `informed_by`; the `epic`'s `milestone` parent pointer and optional `derived_from`; `task`'s `split_of`, `split_index`, `handoff_id` (split lineage — envelope lives in body) and optional `affects_paths`; `research`'s `enhances`, `sources_captures`, `spawned_epics`, `enhances_epics`, `produces_diagnose`, `split_into`, `split_from`; `diagnose`'s optional `promoted_from` and `derived_from`; `capture`'s `informs_research`; the `agent` type's `role`, `model`, `allowed_tools`, `disallowed_tools`, `procedures`, `handoffs`, `guardrails`, `lane`, `color`, `owned_paths`, and `source_attribution` import-provenance object). Type-specific fields are additive and do **not** require an ADR (only a new _universal_ reserved key does); `source_attribution` was added under HS-GMLJ-K3KR-TASK-lock-the-community-import-design-and-add; `owned_paths` / `affects_paths` under HS-ZMAQ-M15C-TASK-declare-owned-path-globs-on-agent-identi.
|
|
1580
|
+
- `reviews` (review type — back-compat alias for `parent:` pointing at the spec under review)
|
|
1581
|
+
|
|
1582
|
+
Adding a new universal reserved key requires an ADR.
|
|
1583
|
+
|
|
1584
|
+
## Validation
|
|
1585
|
+
|
|
1586
|
+
The indexer (see HS-DOC-architecture-foundations §Indexer) runs frontmatter validation on every write:
|
|
1587
|
+
|
|
1588
|
+
- All required fields present and of the expected type.
|
|
1589
|
+
- `id` matches the entity type's pattern.
|
|
1590
|
+
- `id` is unique across the vault.
|
|
1591
|
+
- `status` is in the enum.
|
|
1592
|
+
- All wikilinks in frontmatter resolve, or are tracked as forward references.
|
|
1593
|
+
- No cycles in `blocks` or `parent`.
|
|
1594
|
+
- No duplicate basenames.
|
|
1595
|
+
|
|
1596
|
+
Validation failures are surfaced in the console and via `hs lint`. They do not block git writes (the vault is plain text and the Builder is trusted), but the indexer marks the affected spec as invalid until corrected.
|
|
1597
|
+
|
|
1598
|
+
## Examples
|
|
1599
|
+
|
|
1600
|
+
### Minimal task
|
|
1601
|
+
|
|
1602
|
+
```markdown
|
|
1603
|
+
---
|
|
1604
|
+
id: HS-O3E0
|
|
1605
|
+
name: Fix console keyboard navigation
|
|
1606
|
+
type: task
|
|
1607
|
+
status: open
|
|
1608
|
+
priority: 2
|
|
1609
|
+
owner: pwher
|
|
1610
|
+
created: 2026-05-14
|
|
1611
|
+
updated: 2026-05-14
|
|
1612
|
+
kind: bug
|
|
1613
|
+
blocked_by:
|
|
1614
|
+
- "[[HS-IS1A-TASK-cockpit-routing-rewrite]]"
|
|
1615
|
+
related:
|
|
1616
|
+
- "[[HS-582Q-TASK-arrow-key-conflicts]]"
|
|
1617
|
+
tags: [console, ux, keyboard]
|
|
1618
|
+
---
|
|
1619
|
+
|
|
1620
|
+
# Fix console keyboard navigation
|
|
1621
|
+
|
|
1622
|
+
Arrow keys do not move focus between issues in the list view; only Tab works. Compare to Linear, where ↑/↓ navigates the list.
|
|
1623
|
+
|
|
1624
|
+
## Acceptance
|
|
1625
|
+
|
|
1626
|
+
- Up/Down arrow keys move focus between rows in `IssuesSurface`.
|
|
1627
|
+
- Enter on a focused row opens the detail pane.
|
|
1628
|
+
- No regression for input fields (arrow keys still move the caret inside text inputs).
|
|
1629
|
+
|
|
1630
|
+
## Change log
|
|
1631
|
+
|
|
1632
|
+
| Date | Author | Change |
|
|
1633
|
+
| ---------- | ------ | --------------------------- |
|
|
1634
|
+
| 2026-05-14 | pwher | Created from drafts/triage. |
|
|
1635
|
+
```
|
|
1636
|
+
|
|
1637
|
+
### Memory lesson
|
|
1638
|
+
|
|
1639
|
+
```markdown
|
|
1640
|
+
---
|
|
1641
|
+
id: HS-LES-bd-process-leak
|
|
1642
|
+
name: bd CLI process leak
|
|
1643
|
+
type: memory-lesson
|
|
1644
|
+
status: open
|
|
1645
|
+
priority: 1
|
|
1646
|
+
owner: pwher
|
|
1647
|
+
created: 2026-05-14
|
|
1648
|
+
updated: 2026-05-14
|
|
1649
|
+
topic: bd-process-leak
|
|
1650
|
+
observed: 2026-05-14
|
|
1651
|
+
related:
|
|
1652
|
+
- "[[HS-LES-dolt-embedded-windows]]"
|
|
1653
|
+
- "[[adr-0006-replace-beads]]"
|
|
1654
|
+
tags: [bd, dolt, windows, process-leak]
|
|
1655
|
+
---
|
|
1656
|
+
|
|
1657
|
+
# bd CLI process leak
|
|
1658
|
+
|
|
1659
|
+
## Problem
|
|
1660
|
+
|
|
1661
|
+
A single `bd create` issued the prior session sat alive consuming 107 GB working set, plus seven orphaned bd procs at ~67 MB each. RAM hit 80% of 128 GB.
|
|
1662
|
+
|
|
1663
|
+
## Fix
|
|
1664
|
+
|
|
1665
|
+
At session start, run `Get-Process bd | Sort WorkingSet -Desc` on Windows and kill any orphans before issuing new bd commands. Be wary of invoking `bd create` with `run_in_background` — bd does not always exit cleanly when the parent harness moves on.
|
|
1666
|
+
|
|
1667
|
+
## Change log
|
|
1668
|
+
|
|
1669
|
+
| Date | Author | Change |
|
|
1670
|
+
| ---------- | ------ | -------------------------------------------------- |
|
|
1671
|
+
| 2026-05-14 | pwher | Migrated from bd memory `lessons/bd-process-leak`. |
|
|
1672
|
+
```
|
|
1673
|
+
|
|
1674
|
+
## Open questions
|
|
1675
|
+
|
|
1676
|
+
These are intentionally left for the Builder's confirmation in Phase 5 (migration), to avoid pre-committing the migration translation rules:
|
|
1677
|
+
|
|
1678
|
+
1. **Resolved (2026-05-18):** Memory uses subfolders — `memory/lessons`, `memory/decisions`, `memory/references`, plus `protocols/` as a Memory subsection on disk (memory-protocols-subsection-of-memory). **2026-05-20:** added `memory/ui-patterns/` (`memory-ui-pattern`). **2026-05-21:** added `memory/ux-principles/` (`memory-ux-principle`). Console Memory surface: All / Lessons / Decisions / References / **UX Principles** / UI Patterns / Protocols.
|
|
1679
|
+
2. The id format for migrated tasks — `HS-NNNN-<slug>` with `legacy_bd_id` preserved. Confirm the slug source (proposal: from `title:` lowercased, truncated to ~40 chars, dash-separated).
|
|
1680
|
+
3. Whether to expose `body inline tags` (`#tag` inside prose) as queryable, or treat them as decorative-only. Proposal: queryable but frontmatter `tags:` wins on ties.
|
|
1681
|
+
4. Whether the `daily/` notes folder should exist at all in v1 (it's not in L1's use cases). Proposal: include it for Builder convenience; cost is one folder.
|
|
1682
|
+
|
|
1683
|
+
## Related specs
|
|
1684
|
+
|
|
1685
|
+
- heyspex-north-star — the L1 this entity model serves.
|
|
1686
|
+
- HS-DOC-architecture-foundations — the tech that implements the contract this document specifies.
|
|
1687
|
+
- uc-capture-intent — first-class typed capture and the phone-to-draft path; promotes drafts per §`draft` below.
|
|
1688
|
+
- uc-ingest-anywhere — Manual vs Agent ingest; drives optional `draft` LLM provenance fields and body footer conventions.
|
|
1689
|
+
- uc-voice-ingest-hey-spex — Hey Spex wake companion + shortcuts; optional `capture_channel: voice` fields above.
|
|
1690
|
+
- migration-from-bd — the L3 spec that uses the IDs/filenames defined here.
|
|
1691
|
+
- adr-0001-vault-format — the ADR that locks in markdown + YAML + wikilinks as the file format.
|
|
1692
|
+
- adr-0008-branch-brief-and-evidence-schema — the ADR that ratifies the `branch-brief` type and `evidence:` key.
|
|
1693
|
+
- adr-0012-roadmap-storage — `roadmap` type, `roadmap_manifest`, horizon backlog, ingest provenance fields.
|
|
1694
|
+
- plan-ingest-review-roadmap-workflow — default ingest → review → roadmap admission protocol.
|
|
1695
|
+
- ai-deliberation-gate — Gate 0 multi-model debate on drafts.
|
|
1696
|
+
- ingest-review-deliberation-roadmap-lifecycle — consolidated ingest/roadmap/council decision.
|
|
1697
|
+
- HS-ROADMAP-product-master — product phases + horizon manifest.
|
|
1698
|
+
- HS-7KOO-0022-EPIC-continuity-layer-gaps — the Continuity Layer epic these additions serve.
|
|
1699
|
+
- HS-BVZT-XBPJ-RES-bd-feature-inventory — the research spec that justifies each row of the schema.
|
|
1700
|
+
- memory-protocols-subsection-of-memory — Protocols are a Memory subsection in navigation; epics author protocols.
|
|
1701
|
+
|
|
1702
|
+
## Change log
|
|
1703
|
+
|
|
1704
|
+
| Date | Author | Change |
|
|
1705
|
+
| ---------- | ------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
1706
|
+
| 2026-05-14 | pwher (with claude opus 4.7) | Initial draft. Derived the entity-type set from L1 use cases plus the bd inventory. Locked in four dependency types (matching bd) and Obsidian-compatible wikilink resolution. Folder layout uses subfolders per type for human navigation; resolution is folder-agnostic. |
|
|
1707
|
+
| 2026-05-16 | pwher | §`draft`: companion/voice + optional spatial cursor/click hints (uc-voice-ingest-hey-spex §Spatial pointers). |
|
|
1708
|
+
| 2026-05-16 | pwher (with claude opus 4.7) | Added `branch-brief` entity type (folder `branches/`, ID `HS-BB-<slug>`, plan/actual + drift enum) and the cross-type `evidence:` array with inline shorthand. Per adr-0008-branch-brief-and-evidence-schema; closes HS-7E41/0052/0053 of HS-7KOO-0022-EPIC-continuity-layer-gaps. |
|
|
1709
|
+
| 2026-05-17 | pwher | Added `roadmap` type + `roadmap_manifest`; `future-considerations/` layout; draft `source_intent_hash` / `review_stage`; task `roadmap_admission` / `ingest_draft`. Per adr-0012-roadmap-storage. |
|
|
1710
|
+
| 2026-05-17 | pwher | Draft `deliberation_record` (ai-deliberation-gate); task `close_reason` enum + `superseded_by`; archive = filter not folder. |
|
|
1711
|
+
| 2026-05-17 | pwher | Draft `suggestions:` + `review_record:` per HS-EU98-GCGE-TASK-staged-draft-suggestion-schema; omit-when-empty rule. |
|
|
1712
|
+
| 2026-05-17 | pwher | `submission_kind`, `companion_dialogue[]`; companion `capture_channel` per companion-external-media-vs-refined-intent-council. |
|
|
1713
|
+
| 2026-05-17 | pwher | `capture_bundle_id`, `source_set[]` for companion multi-article bundle submit (companion-capture-inbox-and-bundles, HS-D1YU-OVFO-TASK-bundle-submit-composite-draft-source-set). |
|
|
1714
|
+
| 2026-05-17 | pwher | `triage_record` scout schema for Review inbox workshop (review-inbox-workshop-scout-overview). |
|
|
1715
|
+
| 2026-05-18 | pwher (with claude opus 4.5) | Added `in_review` status to universal enum — human gate between agent work and closure (HS-YYEO-FLX9-TASK-review-column-human-gate-before-done). |
|
|
1716
|
+
| 2026-05-20 | pwher | `canvases/diagrams/` + `canvases/as-built/` for spec diagram dual-surface (spec-diagram-design-vs-as-built-canvas). |
|
|
1717
|
+
| 2026-05-20 | pwher | Added `specs/canvases/` for JSON Canvas design files per adr-0013-canvas-vault-format-and-obsidian-interop. |
|
|
1718
|
+
| 2026-05-20 | pwher | Task/epic ID formats: random alphanumeric suffix for new specs (vault-id-assignment-protocol); legacy `HS-NNNN` migration IDs retained. |
|
|
1719
|
+
| 2026-05-21 | pwher | Added `planning-flow` type (`specs/flows/`); research `bound_epic` / `planning_flow`; epic `research` / `planning_flow` requirements (planning-flow-research-epic-lifecycle). |
|
|
1720
|
+
| 2026-05-22 | pwher + Claude Opus 4.7 (1M) | `idea` schema: `research_stage` removed (single binary `promoted_to`); body shape v2 — `# Core Idea` / `## Notes` / `## Concept` (≤1200 chars) / `<details>Details</details>`. See HS-KQ5O-IDFV-EPIC-unified-idea-workflow-v2 / HS-QOAC-IDFL-RES-unified-idea-workflow-v2. |
|
|
1721
|
+
| 2026-05-22 | pwher + Claude Opus 4.7 (1M) | **Capture rename:** `type: idea` → `type: capture`; new required `kind:` field (idea / bug-fix / clip / reference / question); folder `specs/captures/` → `specs/captures/`; ID prefix `HS-IDEA-*` → `HS-CAP-*` (legacy preserved in `legacy_idea_id:`); research `source_idea:` → `source_capture:`. Per HS-B2B8-DLQI-EPIC-capture-rename-migration-idea-to-capture; source rationale HS-ZKFN-1FXG-CAP-capture-as-universal-companion-verb-and-parent-term. |
|
|
1722
|
+
| 2026-05-24 | Claude Opus 4.7 (1M) | Capture schema: added `capture_status: raw \| expanded` (default `raw`). Flipped to `expanded` by MCP `executeUpdateCapture` on core_idea/concept/agent_expansion writes; force-corrected by console save-time linter when `# Core Idea` body has content. Backfilled across 21 existing captures by `scripts/backfill-capture-status.mjs`. Per HS-20PH-P2WA-TASK-b3-new-frontmatter-field-idea-status (B3 of HS-BDDT-Q1B7-EPIC-idea-capture-modal-v3-single-textbox-cle). |
|
|
1723
|
+
| 2026-05-25 | pwher (with Claude Opus 4.7) | **Business layer added.** New entity types `business-positioning` / `business-pricing` / `business-marketing` / `business-model` filed under `specs/business/{positioning,pricing,marketing,model}/`. IDs `HS-BIZ-POS-* / HS-BIZ-PRI-* / HS-BIZ-MKT-* / HS-BIZ-MOD-*`. Browsed in the console on a dedicated **Business** surface that mirrors Memory's category-rail layout. `positioning-2nd-brain-harness-for-specs` migrated from `memory/decisions/` (`type: memory-decision`) to `business/positioning/` (`type: business-positioning`); basename unchanged so wikilinks resolve. |
|
|
1724
|
+
| 2026-05-29 | pwher (with Claude Opus 4.8 [1m]) | **`milestone` entity type formalized.** Added folder `specs/milestones/`, Entity-types-table row, ID format `HS-MIL-<suffix>` (4+ uppercase; legacy 4-char mnemonics like `HS-RM22` valid), filename pattern `HS-MIL-<suffix>-<slug>.md`, and a full `#### milestone` schema subsection (`epics`, `target_date`, status enum, explicit "no scalar priority"). Disambiguated the legacy `kind: milestone` task discriminator from the new `type: milestone` entity; added the `milestone:` parent pointer to the `#### epic` schema; registered the new fields under Reserved frontmatter keys. Describes the 33 `HS-MIL-*` files already on disk (seed HS-RM22-IART-MIL-console-ia-restructure). Ratified by introduction lineage HS-VK7C-MILE-EPIC-milestone-entity-type-and-surfacing → HS-OFR5-M2J3-EPIC-introduce-milestones-as-highest-entity (in lieu of a standalone ADR); canonical hierarchy in [[spec-hierarchy]]. Per HS-9AUC-HRMZ-TASK-define-milestone-entity-type-in-entity-m. |
|
|
1725
|
+
| 2026-05-26 | pwher (with Claude Opus 4.7) | **`review` entity type formalized.** Added folder `specs/reviews/`, ID format `HS-REV-<suffix>` (suffix matches parent task/epic id 1:1), filename pattern `HS-REV-<suffix>-<slug>.md`, and full `#### review` schema subsection documenting the four required body sections (Acceptance verification / Reviewer notes / Memory candidates / Decision). Documents what CLAUDE.md §Session Completion + ~100 existing review files already implement; provides the authoritative L2 schema for console, indexer, MCP, and future CLI consumers. Per T1 of HS-3K55-0033-EPIC-review-sibling-testing-workflow (grounded against HS-19F9-TEST-MIL-api-testing-dual-path + HS-UKD6-CLR4-RES-close-out-review-screen-jtbd-architecture). |
|
|
1726
|
+
| 2026-05-29 | pwher (with Claude Opus 4.7 [1m]) | **Provenance edges formalized (capture → research → milestone).** Added new §Provenance edges section between §Dependencies and §Evidence linking with the cross-type cardinality table (Capture→Research M:N, Research→Milestone M:1 strict, Research→Epic spawned 1:N, Research→Epic augmented M:N). New frontmatter fields: `research.enhances` (M:1 required on closed), `research.sources_captures` (M:N), `research.spawned_epics` (1:N), `research.enhances_epics` (M:N rare), `research.split_into` / `research.split_from` (split-flow audit); `milestone.informed_by` (reverse of enhances); `capture.informs_research` (M:N, distinct from binary `promoted_to`); optional `epic.derived_from` (reverse of spawned_epics). Reserved-keys list updated. Per HS-HQRM-YJX6-TASK-research-enhances-exactly-one-milestone-validator-and-bidirectional-linkage of HS-OFR5-M2J3-EPIC-introduce-milestones-as-highest-entity. |
|
|
1727
|
+
| 2026-05-31 | pwher (with claude opus 4.7) | **`pillar` entity type added** (folder `specs/pillars/`, ID format `HS-PILR-<slug>` for canonical or `HS-PILR-<suffix>-<slug>` for customer-scoped, filename matches ID, `status: perpetual` non-terminal). New required fields on every epic: `pillar:` (single primary) and optional `secondary_pillars:` array. Type ratified by introduction lineage HS-EBIL-0011-EPIC-goal-hierarchy-l2-strategic-pillars-l3 following the milestone precedent (no standalone ADR for the entity itself); privacy-boundary for the Pillar Library learning loop is adr-0016-pillar-library-privacy-boundary. **`architecture-pillars.md` renamed to `architecture-foundations.md`** (ID `HS-L2-PILLARS` → `HS-L2-FOUNDATIONS`) to disambiguate from the new entity; 172 wikilinks updated in a single bulk pass. Three "pillar" usages now coexist: the `type: pillar` entity, the unrelated "Pillars 0–5" section names in HS-DOC-architecture-foundations, and the renamed "FIVE COMPONENTS" section in HS-OR8V-0010-EPIC-north-star-vision-first-class-entity (previously "FIVE PILLARS"). L3 Themes (per-epic teleological anchor) retired in the same resolution — collapsed into perpetual Pillars. See HS-AWDI-PILR-RES-pm-perpetual-container-terminology §"Resolution against existing HS-J6K8" for the full rationale. |
|
|
1728
|
+
| 2026-06-03 | claude opus 4.7 [1m] · session `local` (with pwher) | **`canonical:` universal field added; two `superseded` enum values deprecated.** Per evergreen-doc-architecture-srp-and-seo-pillars + canonicalization-arbiter-is-link-graph-not-policy + closed-trackable-specs-are-historical-record-not-living-docs: `canonical: true \| false` is now a universal frontmatter field on every spec type (pillars, L1/L2/L3 docs, HS-DOC-\*, ADRs, protocols, memory specs, epics, tasks, milestones, reviews). `true` (or absent) = current/authoritative; `false` = historical record. Trigger event for the flip: plan-side specs at the in_review → closed transition (per session-close-protocol step 4); evergreen docs at supersession (per supersession-protocol). `status: parked` / `status: deferred` keeps `canonical: true`. **Two enum values deprecated forward-only** per superseded-enum-values-deprecated-use-canonical-false-and-superseded-by: `status: superseded` removed from the ADR-status enum; `superseded` removed from the close_reason enum. Both were redundant with `canonical: false` + `superseded_by:`. Forward-only retirement — existing 11 specs (8 ADRs + 3 plan-side) keep their legacy values as historical record per immutability. New writes use `canonical: false` + `superseded_by:` instead. Added the `canonical:` field to the ADR and task schemas; expanded the `superseded_by:` description to clarify it's the pointer (vs. `canonical:` which is the state). |
|
|
1729
|
+
| 2026-06-03 | claude opus 4.7 [1m] · session `local` (with pwher) | **`## Lifecycle classes` section added; `research` schema de-coupled from `status: closed`.** New top-level section between §Entity types and §Identity, IDs, and filenames classifying all 24 types into four lifecycle classes — **Evergreen** (`l1`/`l2`/`l3`/`adr`/`pillar`/`protocol`/`memory-*`/`research`/`business-*`), **Trackable plan-side** (`task`/`epic`/`milestone`/`review`/`branch-brief`/`planning-flow`), **Single-shot ingest** (`capture`/`draft`/`daily`), **Per-instance** (`roadmap`). Closes the discoverability gap that produced the research-is-evergreen incident: a reader asking _"can I flip this file's status to `in_review`?"_ now has one canonical place to look. Cross-references research-is-evergreen, closed-trackable-specs-are-historical-record-not-living-docs, canonicalization-arbiter-is-link-graph-not-policy, session-close-protocol. **Research schema (`#### research`) amended**: the `enhances:` field gate changed from "REQUIRED on `status: closed`" to "REQUIRED when set" — bidirectional consistency is enforced whenever the field is present, independent of status. Added a one-line note above the schema declaring research evergreen with a pointer to research-is-evergreen. The matching validator update in `scripts/validate-vault-ids.mjs` is on the deferred list — schema-vs-validator drift is acknowledged in the schema comment until that catches up. |
|
|
1730
|
+
| 2026-06-13 | claude opus 4.8 [1m] · session `local` (with pwher) | **`diagnose` entity type added** (folder `specs/diagnoses/`, ID `HS-DIAG-<suffix>`, filename `HS-DIAG-<suffix>-<slug>.md`). A user-reported bug fix as first-class executable work — standalone by default (exempt from the epic→milestone parent rule), optional `parent:` (epic or milestone), required `severity:` (error/warning/info) that maps onto the scheduler's existing priority signals, optional `blocks:` gating edges. Surfaces on the Resolution surface as a derived `kind: "bug"` row that links back to the diagnose. Added entity-types-table row, ID-format row, filename row, `#### diagnose` schema subsection, and Trackable-plan-side lifecycle classification. Ratified by introduction lineage HS-OXBS-BFIX-MIL-bug-fix-diagnose-lane (milestone-precedent, no standalone ADR). Wiring: `vault.ts` (TYPE_TO_FOLDER + KIND_LINKAGE + body skeleton + generateId), `vault-id.ts`, `vault-rules.mjs` (KIND_RULES/KIND_ORDER), `validator.ts`, `validate-vault-ids.mjs`. Per HS-AO2F-1KZK-RES-bug-fix-resolution-task-entity-model-and. |
|
|
1731
|
+
| 2026-06-23 | Cursor · session `local` | **Delegation handoff envelope + task split lineage.** Task frontmatter: `split_of`, `split_index`, `handoff_id` (option B from HS-DTL1-CX5K-CAP-task-split-handoff-when-context-runs-low). Handoff envelope SSOT is body (`## Handoff envelope` + fenced yaml) per `schemas/handoff-envelope.schema.json`; validated by `handoff-envelope.mjs` + `validate-vault-ids.mjs`. Engine rules in `vault-rules.mjs` (`TASK_SPLIT_*`). Per HS-PD6K-NCH5-TASK-handoff-envelope-schema-and-split-child / HS-HXE2-YQ5A-EPIC-delegation-defer-work-from-one-agent-to. |
|
|
1732
|
+
| 2026-06-23 | Cursor · session `local` | **`owned_paths` / `affects_paths` for parallel-agent stomp-detection.** New `#### agent` schema subsection documents `owned_paths:` (machine-checkable file globs on agent identities). Task schema adds optional `affects_paths:` (advisory module hints on trackable specs). Entity-types table + reserved-keys list updated. Per HS-ZMAQ-M15C-TASK-declare-owned-path-globs-on-agent-identi / HS-8PNX-Q1KC-EPIC-lanes-and-stomp-detection-for-parallel-a. |
|
|
1733
|
+
| 2026-07-05 | Claude Sonnet 5 [1m] · session `local` (with pwher) | **`research.produces_diagnose` → `diagnose.derived_from` edge added (research → diagnose intake).** Bugs found during a research investigation now route into the Resolution lane without new diagnose machinery: `research.produces_diagnose:` (optional, list of wikilinks to `HS-DIAG-*`, mirrors `spawned_epics`) reverse-linked by `diagnose.derived_from:` (optional, single wikilink, mirrors `epic.derived_from`). Written by the new `heyspex_promote_research_to_diagnose` tool (`vendor/heyspex-mcp/promote-research-to-diagnose.mjs`), the research-side sibling of `heyspex_promote_capture_to_diagnose`. Also documented `diagnose.promoted_from:` (existing capture-side back-reference, previously undocumented in this schema subsection). Provenance cardinality table + reserved-keys list updated; validated by the `type: research` block of `schemas/heyspex-frontmatter.schema.json`. Per HS-W5VP-MSHY-TASK-research-diagnose-link-send-bugs-to-the of HS-0FTO-MSHY-EPIC-research-to-diagnose-link-send-bugs-foun. |
|
|
1734
|
+
| 2026-07-05 | Claude Sonnet 5 [1m] · session `local` (with pwher) | **`code-audit` findings-table format + closure gate.** New `##### Code-audit findings table` subsection under `#### research` documents the required 4-column body table (`Finding \| Severity \| Action (diagnose\|task\|reference) \| Exit (open\|closed)`) and its three defined exits: bug→diagnose (reuses `heyspex_promote_research_to_diagnose`/`research.produces_diagnose`, no new tooling), cleanup→task (new `task.discovered_from:` reverse pointer to the source research doc), non-actionable→reference (the row itself is the exit). Enriched the existing `task.discovered_from:` doc comment to name this use. Added `discovered_from` to the `type: task` block of `schemas/heyspex-frontmatter.schema.json` (previously documented in entity-model.md only, unenforced). Validator rules in `vault-rules.mjs`: `CODE_AUDIT_FINDINGS_MALFORMED` (no/malformed table) and `CODE_AUDIT_FINDINGS_OPEN_ON_CLOSE` (the closure gate — a `closed`/`review_pending` code-audit doc with any `Exit: open` row) — both warn during a new `CODE_AUDIT_GRACE_END` (2026-08-15, mirrors `RESEARCH_TYPE_GRACE_END`) so pre-existing docs like `HS-ZHAB-RES-doc-authoring-contract-audit-required-st` (no `research_type:` set, predates this format) aren't hard-failed, then error. Per HS-7D0I-WL88-TASK-code-audit-research-type-with-a-defined of HS-BI9D-WL88-EPIC-code-audit-research-type-with-a-defined. |
|
|
1735
|
+
| 2026-08-14 | Claude Code (Fable 5) · session `5785e74c` (with pwher) | **Iteration lineage — third relation tier added.** New §Iteration lineage section (between §Provenance edges and §Evidence linking): `iterates_on:` (list of wikilinks, newer-doc-only, one-edit-on-source like amends; computed reverse map `iteratedBy`) expresses "re-attempts an outcome the target shipped but did not fully deliver" — the case supersession (would falsify round 1) and amends (nothing is contradicted) both misdescribe. `outcome:` (`met` \| `partially-met` \| `not-met`) + `outcome_note:` — reviewer-set at close on trackable docs, never inferred, closed-doc-only (not echoed onto round 2). Required `## Related / lineage` resolved-wikilink table on promoted docs with role vocabulary. Invariants: both docs stay `canonical: true`, round 1 keeps `status: closed`, round 2 takes its own family key. Dependencies table gained the Iterates-on row; Reviewer-close bullet gained the outcome write. Field-name + echo decisions resolved at breakdown (flagged for owner Walk). Per HS-VGQV-T9T6-TASK-entity-model-iterates-on-relation-tier of HS-O97P-T9T6-EPIC-iteration-loop-lineage-relation-tier, from HS-3TZX-T9T6-RES-iteration-loop-lineage-and-capture Part A. |
|