heyspex 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -0
- package/bin/hs.mjs +931 -98
- package/bin/spexcode.mjs +262 -0
- package/dev-factory/engine/worktree.mjs +740 -0
- package/dev-factory/lib/code-repo-root.mjs +67 -0
- package/dev-factory/lib/context-budget.mjs +84 -0
- package/dev-factory/lib/epic-detect.mjs +190 -0
- package/dev-factory/lib/fleet-queue-file.mjs +846 -0
- package/dev-factory/lib/fleet-queue.mjs +426 -0
- package/dev-factory/lib/fleet-state.mjs +14 -18
- package/dev-factory/lib/model-catalog.mjs +338 -0
- package/dev-factory/lib/seat-context.mjs +199 -0
- package/dev-factory/lib/spec-io.mjs +93 -0
- package/dev-factory/lib/sufficiency-score.mjs +8 -2
- package/dev-factory/lib/worktree-allocator.mjs +744 -0
- package/dev-factory/model-catalog.json +222 -0
- package/dist/cli/hs-check.mjs +1085 -103
- package/dist/cli/hs-claim.mjs +936 -63
- package/dist/cli/hs-connect.mjs +9786 -1910
- package/dist/cli/hs-defer.mjs +5267 -3053
- package/dist/cli/hs-dev.mjs +564 -0
- package/dist/cli/hs-env.mjs +385 -299
- package/dist/cli/hs-index-rebuild.mjs +7129 -0
- package/dist/cli/hs-index-reconcile.mjs +7852 -0
- package/dist/cli/hs-init.mjs +777 -138
- package/dist/cli/hs-install.mjs +6583 -485
- package/dist/cli/hs-join.mjs +10137 -2368
- package/dist/cli/hs-vault-pull.mjs +4659 -5882
- package/dist/cli/hs-vault.mjs +3793 -1537
- package/dist/cli/hs-workspace.mjs +2550 -524
- package/dist/cli-templates/customer-vault/specs/entity-model.md +594 -601
- package/dist/cli-templates/customer-vault/specs/protocols/canonical-frontmatter-templates.md +110 -177
- package/dist/cli-templates/customer-vault/specs/protocols/destructive-action-checklist.md +122 -0
- package/dist/cli-templates/customer-vault/specs/protocols/memory-protocol.md +13 -15
- package/dist/cli-templates/customer-vault/specs/protocols/session-close-protocol.md +91 -0
- package/dist/cli-templates/customer-vault/specs/protocols/spec-hierarchy.md +150 -168
- package/dist/cli-templates/customer-vault/specs/protocols/spec-summary-authoring.md +83 -0
- package/dist/cli-templates/harness-commands/claude/hs-auto.md +36 -0
- package/dist/cli-templates/harness-commands/claude/hs-backfill.md +28 -0
- package/dist/cli-templates/harness-commands/claude/hs-capture.md +62 -0
- package/dist/cli-templates/harness-commands/claude/hs-defer.md +29 -0
- package/dist/cli-templates/harness-commands/claude/hs-dev.md +20 -0
- package/dist/cli-templates/harness-commands/claude/hs-doctor.md +32 -0
- package/dist/cli-templates/harness-commands/claude/hs-ground.md +28 -0
- package/dist/cli-templates/harness-commands/claude/hs-handoff.md +33 -0
- package/dist/cli-templates/harness-commands/claude/hs-log.md +27 -0
- package/dist/cli-templates/harness-commands/claude/hs-next.md +29 -0
- package/dist/cli-templates/harness-commands/claude/hs-promote.md +70 -0
- package/dist/cli-templates/harness-commands/claude/hs-push.md +35 -0
- package/dist/cli-templates/harness-commands/claude/hs-qc.md +27 -0
- package/dist/cli-templates/harness-commands/claude/hs-res.md +63 -0
- package/dist/cli-templates/harness-commands/claude/hs-resolve.md +23 -0
- package/dist/cli-templates/harness-commands/claude/hs-review.md +23 -0
- package/dist/cli-templates/harness-commands/claude/hs-view.md +26 -0
- package/dist/cli-templates/harness-commands/claude/kill-ports.md +32 -0
- package/dist/cli-templates/harness-commands/claude/prototype.md +91 -0
- package/dist/cli-templates/harness-commands/cursor/hs-auto.md +40 -0
- package/dist/cli-templates/harness-commands/cursor/hs-backfill.md +31 -0
- package/dist/cli-templates/harness-commands/cursor/hs-capture.md +65 -0
- package/dist/cli-templates/harness-commands/cursor/hs-defer.md +32 -0
- package/dist/cli-templates/harness-commands/cursor/hs-dev.md +24 -0
- package/dist/cli-templates/harness-commands/cursor/hs-doctor.md +36 -0
- package/dist/cli-templates/harness-commands/cursor/hs-ground.md +31 -0
- package/dist/cli-templates/harness-commands/cursor/hs-handoff.md +37 -0
- package/dist/cli-templates/harness-commands/cursor/hs-log.md +31 -0
- package/dist/cli-templates/harness-commands/cursor/hs-next.md +32 -0
- package/dist/cli-templates/harness-commands/cursor/hs-promote.md +73 -0
- package/dist/cli-templates/harness-commands/cursor/hs-push.md +38 -0
- package/dist/cli-templates/harness-commands/cursor/hs-qc.md +30 -0
- package/dist/cli-templates/harness-commands/cursor/hs-res.md +67 -0
- package/dist/cli-templates/harness-commands/cursor/hs-resolve.md +26 -0
- package/dist/cli-templates/harness-commands/cursor/hs-review.md +26 -0
- package/dist/cli-templates/harness-commands/cursor/hs-view.md +30 -0
- package/dist/cli-templates/harness-commands/cursor/kill-ports.md +35 -0
- package/dist/cli-templates/harness-commands/cursor/prototype.md +95 -0
- package/docs/mcp-client-config.md +259 -6
- package/package.json +231 -124
- package/plugins/heyspex/.claude-plugin/plugin.json +12 -0
- package/plugins/heyspex/.cursor-plugin/plugin.json +15 -0
- package/plugins/heyspex/.mcp.json +12 -0
- package/plugins/heyspex/bin/launch-mcp.mjs +95 -0
- package/plugins/heyspex/bin/run-hook.mjs +62 -0
- package/plugins/heyspex/hooks/cursor-hooks.json +227 -0
- package/plugins/heyspex/hooks/hooks.json +361 -0
- package/plugins/heyspex/mcp.json +13 -0
- package/scripts/check-mcp-freshness.mjs +17 -9
- package/scripts/claude-hooks/_env-vault-events.mjs +68 -0
- package/scripts/claude-hooks/_guardrail-events.mjs +96 -0
- package/scripts/claude-hooks/_guardrail-loader.mjs +494 -0
- package/scripts/claude-hooks/_intent-classifier-router.mjs +410 -0
- package/scripts/claude-hooks/_intent-classifier-semantic.mjs +351 -0
- package/scripts/claude-hooks/_run.mjs +120 -0
- package/scripts/claude-hooks/_transcript-text.mjs +60 -0
- package/scripts/claude-hooks/_vault-retrieval.mjs +322 -0
- package/scripts/claude-hooks/agent-spawn-delegation-gate.mjs +133 -0
- package/scripts/claude-hooks/capture-workflow-gate.mjs +11 -0
- package/scripts/claude-hooks/check-auto-memory-budget.mjs +396 -0
- package/scripts/claude-hooks/check-claude-md-budget.mjs +327 -0
- package/scripts/claude-hooks/check-mcp-freshness-hook.mjs +14 -0
- package/scripts/claude-hooks/claim-before-code-gate.mjs +11 -0
- package/scripts/claude-hooks/claim-liveness-shared.mjs +575 -0
- package/scripts/claude-hooks/close-terminal-on-ship.mjs +64 -0
- package/scripts/claude-hooks/coo-denylist-gate.mjs +11 -0
- package/scripts/claude-hooks/coo-guard-check.mjs +11 -0
- package/scripts/claude-hooks/deep-research-cost-gate.mjs +11 -0
- package/scripts/claude-hooks/dev-server-task-reminder.mjs +15 -0
- package/scripts/claude-hooks/emit-claim-status.mjs +41 -0
- package/scripts/claude-hooks/enforce-session-sequence.mjs +11 -0
- package/scripts/claude-hooks/enforce-vault-naming.mjs +11 -0
- package/scripts/claude-hooks/env-vault-guard.mjs +11 -0
- package/scripts/claude-hooks/epic-milestone-phrasing-gate.mjs +11 -0
- package/scripts/claude-hooks/git-identity-guard.mjs +11 -0
- package/scripts/claude-hooks/git-reflog-audit.mjs +15 -0
- package/scripts/claude-hooks/git-stash-gate.mjs +11 -0
- package/scripts/claude-hooks/guard-auto-memory-writes.mjs +137 -0
- package/scripts/claude-hooks/id-display-format-gate.mjs +11 -0
- package/scripts/claude-hooks/inject-communication-style.mjs +66 -0
- package/scripts/claude-hooks/inject-coo-seat.mjs +78 -0
- package/scripts/claude-hooks/inject-dev-server-awareness.mjs +11 -0
- package/scripts/claude-hooks/inject-doctrine.mjs +13 -0
- package/scripts/claude-hooks/inject-vault-context.mjs +14 -0
- package/scripts/claude-hooks/intent-classifier-trigger.mjs +247 -0
- package/scripts/claude-hooks/log-session-activity.mjs +341 -0
- package/scripts/claude-hooks/naughty-list-gate.mjs +11 -0
- package/scripts/claude-hooks/notify-status-flip.mjs +72 -0
- package/scripts/claude-hooks/plan-exit-ingest-gate.mjs +170 -0
- package/scripts/claude-hooks/plan-ingest-close-reminder.mjs +66 -0
- package/scripts/claude-hooks/plan-review-gate.mjs +11 -0
- package/scripts/claude-hooks/preflight-reminder.mjs +262 -0
- package/scripts/claude-hooks/protected-action-intent.mjs +221 -0
- package/scripts/claude-hooks/research-method-guard.mjs +398 -0
- package/scripts/claude-hooks/research-protocol-gate.mjs +11 -0
- package/scripts/claude-hooks/session-end.mjs +449 -0
- package/scripts/claude-hooks/settings-write-gate.mjs +11 -0
- package/scripts/claude-hooks/settlement-check-gate.mjs +39 -0
- package/scripts/claude-hooks/status-flip-detect.mjs +17 -0
- package/scripts/claude-hooks/terminal-close-shared.mjs +426 -0
- package/scripts/claude-hooks/terminal-close-watcher.mjs +122 -0
- package/scripts/claude-hooks/wip-checkpoint.mjs +298 -0
- package/scripts/cursor-hooks/manifest.mjs +235 -0
- package/scripts/dev-server-status.mjs +34 -13
- package/scripts/dev-server-stop.mjs +313 -0
- package/scripts/heyspex-mode.mjs +268 -0
- package/scripts/hs-auto-resolve.mjs +240 -0
- package/scripts/hs-auto-source.mjs +398 -0
- package/scripts/hs-auto.mjs +134 -0
- package/scripts/hs-capture-cli.mjs +326 -0
- package/scripts/hs-classifier.mjs +136 -0
- package/scripts/hs-companion.mjs +88 -0
- package/scripts/hs-gateway.mjs +115 -0
- package/scripts/hs-mode.mjs +125 -0
- package/scripts/hs-next.mjs +441 -0
- package/scripts/hs-settings.mjs +338 -0
- package/scripts/hs-view.mjs +333 -0
- package/scripts/hs-worktree.mjs +201 -0
- package/scripts/install-claude-code-hooks.mjs +270 -0
- package/scripts/install-cursor-hooks.mjs +471 -0
- package/scripts/lib/agent-env-markers.mjs +38 -0
- package/scripts/lib/console-url-resolver.mjs +197 -60
- package/scripts/lib/customer-kit.mjs +886 -0
- package/scripts/lib/dev-mode.mjs +244 -28
- package/scripts/lib/heyspex-home.mjs +72 -0
- package/scripts/lib/hs-command.mjs +277 -0
- package/scripts/lib/hs-companion-settings.mjs +472 -0
- package/scripts/lib/hs-source-commit.mjs +59 -5
- package/scripts/lib/hs-source-identity.mjs +526 -0
- package/scripts/lib/hs-source-log.mjs +11 -21
- package/scripts/lib/hs-source-push.mjs +107 -58
- package/scripts/lib/hs-worktree-args.mjs +115 -0
- package/scripts/lib/shared-path-helpers.mjs +134 -0
- package/scripts/lib/standalone-doctor.mjs +540 -3
- package/scripts/lib/subagent-git-lock.mjs +109 -0
- package/scripts/lib/template-pin.mjs +34 -0
- package/scripts/provenance-lib.mjs +91 -0
- package/scripts/stamp-provenance-on-edit.mjs +222 -0
- package/scripts/wip-ledger-health.mjs +653 -0
- package/spexharness/doctrine/baseline/SPEXCODE-DOCTRINE.baseline.json +29 -0
- package/spexharness/src/adapters/audit.mjs +197 -0
- package/spexharness/src/adapters/claude-code.mjs +441 -0
- package/spexharness/src/chat/tui/ansi.mjs +448 -0
- package/spexharness/src/chat/tui/palette.mjs +22 -0
- package/spexharness/src/chat/tui/select.mjs +208 -0
- package/spexharness/src/config-root.mjs +54 -0
- package/spexharness/src/context-budget.mjs +141 -0
- package/spexharness/src/dev-server-control.mjs +389 -0
- package/spexharness/src/doctrine/behaviour.mjs +371 -0
- package/spexharness/src/doctrine/corpus.mjs +733 -0
- package/spexharness/src/doctrine/inject.mjs +338 -0
- package/spexharness/src/doctrine/merge.mjs +184 -0
- package/spexharness/src/doctrine/sources.mjs +252 -0
- package/spexharness/src/doctrine/synthesize.mjs +401 -0
- package/spexharness/src/doctrine/vault-source.mjs +574 -0
- package/spexharness/src/doctrine/writer.mjs +176 -0
- package/spexharness/src/events.mjs +84 -0
- package/spexharness/src/gates/capture-workflow-gate.mjs +202 -0
- package/spexharness/src/gates/claim-before-code-gate.decide.mjs +33 -0
- package/spexharness/src/gates/claim-before-code-gate.mjs +129 -0
- package/spexharness/src/gates/deep-research-cost-gate.mjs +274 -0
- package/spexharness/src/gates/enforce-session-sequence.mjs +895 -0
- package/spexharness/src/gates/enforce-vault-naming.mjs +215 -0
- package/spexharness/src/gates/epic-milestone-phrasing-gate.mjs +233 -0
- package/spexharness/src/gates/git-identity-guard.decide.mjs +436 -0
- package/spexharness/src/gates/git-identity-guard.mjs +61 -0
- package/spexharness/src/gates/git-reflog-audit.mjs +151 -0
- package/spexharness/src/gates/git-stash-gate.decide.mjs +361 -0
- package/spexharness/src/gates/git-stash-gate.mjs +159 -0
- package/spexharness/src/gates/id-display-format-gate.mjs +190 -0
- package/spexharness/src/gates/inject-doctrine-gate.mjs +89 -0
- package/spexharness/src/gates/inject-vault-context.mjs +239 -0
- package/spexharness/src/gates/naughty-list-gate.mjs +213 -0
- package/spexharness/src/gates/plan-review-gate.mjs +233 -0
- package/spexharness/src/gates/preflight-reminder-gate.mjs +265 -0
- package/spexharness/src/gates/research-protocol-gate.mjs +175 -0
- package/spexharness/src/gates/settings-write-gate.decide.mjs +96 -0
- package/spexharness/src/gates/settings-write-gate.mjs +104 -0
- package/spexharness/src/git-reflog-audit.mjs +294 -0
- package/spexharness/src/intent-classifier.mjs +194 -0
- package/spexharness/src/intent-directive.mjs +541 -0
- package/spexharness/src/profile/learn.mjs +551 -0
- package/spexharness/src/profile/proposals.mjs +357 -0
- package/spexharness/src/profile/vault-inclusion.mjs +386 -0
- package/spexharness/src/redact.mjs +151 -0
- package/spexharness/src/rule-table.mjs +819 -0
- package/spexharness/src/seat-context.mjs +122 -0
- package/spexharness/src/session-bootstrap.mjs +512 -0
- package/spexharness/src/session-record.mjs +815 -0
- package/spexharness/src/token-inventory.mjs +207 -0
- package/vendor/heyspex-mcp/account-switch.mjs +95 -0
- package/vendor/heyspex-mcp/alignment-gate.mjs +315 -1
- package/vendor/heyspex-mcp/blocker-resolver.mjs +37 -2
- package/vendor/heyspex-mcp/breakdown-ladder.mjs +119 -4
- package/vendor/heyspex-mcp/breakdown-source.mjs +271 -0
- package/vendor/heyspex-mcp/breakdown-writer.mjs +23 -3
- package/vendor/heyspex-mcp/capture-buffer-patches.mjs +46 -5
- package/vendor/heyspex-mcp/capture-channel.mjs +55 -5
- package/vendor/heyspex-mcp/capture-console-client.mjs +80 -1
- package/vendor/heyspex-mcp/capture-focus.mjs +1035 -29
- package/vendor/heyspex-mcp/capture-outbox.mjs +5 -1
- package/vendor/heyspex-mcp/capture-tools.mjs +1219 -0
- package/vendor/heyspex-mcp/claim-tools.mjs +1124 -0
- package/vendor/heyspex-mcp/cli-verbs.mjs +2076 -0
- package/vendor/heyspex-mcp/cli.mjs +201 -15524
- package/vendor/heyspex-mcp/cloud-tool-surface.mjs +128 -0
- package/vendor/heyspex-mcp/cloud-vault-writes.mjs +412 -0
- package/vendor/heyspex-mcp/config-seed.yaml +15 -0
- package/vendor/heyspex-mcp/config-settings.mjs +290 -7
- package/vendor/heyspex-mcp/console-fetch.mjs +657 -16
- package/vendor/heyspex-mcp/console-transport.mjs +166 -0
- package/vendor/heyspex-mcp/credentials.mjs +584 -0
- package/vendor/heyspex-mcp/defer-spec.mjs +44 -4
- package/vendor/heyspex-mcp/deferred-reclaim.mjs +29 -3
- package/vendor/heyspex-mcp/design-handlers.mjs +31 -0
- package/vendor/heyspex-mcp/design-tools.mjs +4 -1
- package/vendor/heyspex-mcp/dev-factory-bridge.mjs +4 -4
- package/vendor/heyspex-mcp/dev-mode-core.mjs +45 -0
- package/vendor/heyspex-mcp/dev-tools.mjs +124 -0
- package/vendor/heyspex-mcp/diagnose-handlers.mjs +54 -0
- package/vendor/heyspex-mcp/events-tools.mjs +207 -0
- package/vendor/heyspex-mcp/filing-tools.mjs +688 -0
- package/vendor/heyspex-mcp/fleet-handlers.mjs +37 -0
- package/vendor/heyspex-mcp/fleet-queue-tools.mjs +69 -14
- package/vendor/heyspex-mcp/focus-tools.mjs +190 -0
- package/vendor/heyspex-mcp/folder-trust-store.mjs +59 -0
- package/vendor/heyspex-mcp/http-transport.mjs +300 -0
- package/vendor/heyspex-mcp/list-tools.mjs +257 -0
- package/vendor/heyspex-mcp/login-handoff.mjs +15 -1
- package/vendor/heyspex-mcp/mcp-config.mjs +94 -0
- package/vendor/heyspex-mcp/memory-tools.mjs +523 -0
- package/vendor/heyspex-mcp/mvp-mode.mjs +53 -6
- package/vendor/heyspex-mcp/occupied-keys.mjs +141 -0
- package/vendor/heyspex-mcp/on-deck-brief.mjs +3360 -0
- package/vendor/heyspex-mcp/on-deck-scheduler.mjs +1708 -0
- package/vendor/heyspex-mcp/package-root.mjs +32 -0
- package/vendor/heyspex-mcp/peer-presence.mjs +8 -1
- package/vendor/heyspex-mcp/plan-ground.mjs +621 -652
- package/vendor/heyspex-mcp/plan-push.mjs +906 -21
- package/vendor/heyspex-mcp/plan-review.mjs +124 -30
- package/vendor/heyspex-mcp/preflight-gate.mjs +0 -0
- package/vendor/heyspex-mcp/procedure-handlers.mjs +325 -0
- package/vendor/heyspex-mcp/procedure-tools.mjs +540 -351
- package/vendor/heyspex-mcp/promote-capture.mjs +386 -69
- package/vendor/heyspex-mcp/promote-diagnose.mjs +74 -0
- package/vendor/heyspex-mcp/promote-research-to-diagnose.mjs +9 -2
- package/vendor/heyspex-mcp/promote-research.mjs +660 -53
- package/vendor/heyspex-mcp/promotion-helpers.mjs +251 -0
- package/vendor/heyspex-mcp/prompts.mjs +1460 -0
- package/vendor/heyspex-mcp/read-path.mjs +29 -9
- package/vendor/heyspex-mcp/receipt-shape.mjs +146 -0
- package/vendor/heyspex-mcp/recipe-handlers.mjs +117 -0
- package/vendor/heyspex-mcp/regen-tasks.mjs +210 -3
- package/vendor/heyspex-mcp/register-spec.mjs +266 -54
- package/vendor/heyspex-mcp/request-context.mjs +59 -0
- package/vendor/heyspex-mcp/research-focus.mjs +207 -4
- package/vendor/heyspex-mcp/research-handlers.mjs +623 -0
- package/vendor/heyspex-mcp/research-tools.mjs +4 -4
- package/vendor/heyspex-mcp/response-budget.mjs +348 -0
- package/vendor/heyspex-mcp/review-focus.mjs +25 -1
- package/vendor/heyspex-mcp/search-specs.mjs +280 -0
- package/vendor/heyspex-mcp/seat-block-ledger.mjs +113 -0
- package/vendor/heyspex-mcp/seat-identity.mjs +2 -6
- package/vendor/heyspex-mcp/session-owner.mjs +108 -0
- package/vendor/heyspex-mcp/session-tools.mjs +152 -0
- package/vendor/heyspex-mcp/settings-registry.mjs +232 -0
- package/vendor/heyspex-mcp/settings-tools.mjs +85 -12
- package/vendor/heyspex-mcp/spec-edit-tools.mjs +446 -0
- package/vendor/heyspex-mcp/spec-id-lib.mjs +93 -17
- package/vendor/heyspex-mcp/split-research.mjs +301 -56
- package/vendor/heyspex-mcp/stdio-rpc.mjs +22 -0
- package/vendor/heyspex-mcp/submit-for-review.mjs +132 -6
- package/vendor/heyspex-mcp/summary-contract.mjs +105 -0
- package/vendor/heyspex-mcp/summary-write-tools.mjs +224 -0
- package/vendor/heyspex-mcp/symptom-query.mjs +146 -0
- package/vendor/heyspex-mcp/test-helpers.mjs +108 -1
- package/vendor/heyspex-mcp/tool-catalog.mjs +2813 -0
- package/vendor/heyspex-mcp/tool-dispatch.mjs +639 -0
- package/vendor/heyspex-mcp/tool-helpers.mjs +325 -0
- package/vendor/heyspex-mcp/validate-linkage.mjs +414 -27
- package/vendor/heyspex-mcp/vault-io.mjs +724 -0
- package/vendor/heyspex-mcp/vault-less-endpoints.mjs +52 -0
- package/vendor/heyspex-mcp/vault-resolve.mjs +366 -68
- package/vendor/heyspex-mcp/verify-reproduction.mjs +270 -30
- package/vendor/heyspex-mcp/whoami.mjs +91 -0
|
@@ -4,23 +4,17 @@ name: HeySpex Entity Model
|
|
|
4
4
|
type: l2
|
|
5
5
|
status: draft
|
|
6
6
|
priority: 0
|
|
7
|
-
owner:
|
|
8
|
-
assisted_by:
|
|
9
|
-
- Claude Code
|
|
7
|
+
owner: TODO — your name/handle
|
|
10
8
|
created: 2026-05-14
|
|
11
9
|
updated: 2026-05-18
|
|
12
10
|
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
11
|
---
|
|
23
12
|
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
24
18
|
# HeySpex Entity Model
|
|
25
19
|
|
|
26
20
|
> [!important] Constitutional dependency
|
|
@@ -35,7 +29,7 @@ This L2 spec defines the shape of every artifact that lives in a HeySpex vault:
|
|
|
35
29
|
- **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
30
|
- **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
31
|
- **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
|
|
32
|
+
- **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
33
|
|
|
40
34
|
## Vault root layout
|
|
41
35
|
|
|
@@ -134,7 +128,7 @@ Two committed siblings live **outside** `specs/` at the repo root, written/owned
|
|
|
134
128
|
- **`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
129
|
- **`.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
130
|
|
|
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`
|
|
131
|
+
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
132
|
|
|
139
133
|
> [!note] Why folders, not flat?
|
|
140
134
|
> 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.
|
|
@@ -143,50 +137,50 @@ The L1 lives at the vault root as `heyspex-north-star.md`. The other L2 specs (`
|
|
|
143
137
|
|
|
144
138
|
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
139
|
|
|
146
|
-
| `type:` value
|
|
147
|
-
|
|
|
148
|
-
| `l1`
|
|
149
|
-
| `l2`
|
|
150
|
-
| `l3`
|
|
151
|
-
| `adr`
|
|
152
|
-
| `task`
|
|
153
|
-
| `epic`
|
|
154
|
-
| `milestone`
|
|
155
|
-
| `diagnose`
|
|
156
|
-
| `pillar`
|
|
157
|
-
| `agent`
|
|
158
|
-
| `golden-case`
|
|
159
|
-
| `branch-brief`
|
|
160
|
-
| `memory-lesson`
|
|
161
|
-
| `memory-decision`
|
|
162
|
-
| `memory-reference`
|
|
163
|
-
| `memory-ui-pattern`
|
|
164
|
-
| `memory-ux-principle`
|
|
165
|
-
| `protocol`
|
|
166
|
-
| `review`
|
|
167
|
-
| `business-positioning` | `business/positioning/`
|
|
168
|
-
| `business-pricing`
|
|
169
|
-
| `business-marketing`
|
|
170
|
-
| `business-model`
|
|
171
|
-
| `roadmap`
|
|
172
|
-
| `capture`
|
|
173
|
-
| `research`
|
|
174
|
-
| `planning-flow`
|
|
175
|
-
| `draft`
|
|
176
|
-
| `daily`
|
|
177
|
-
| `run-retrospective`
|
|
140
|
+
| `type:` value | Folder | Hierarchy level | One-line description |
|
|
141
|
+
| --- | --- | --- | --- |
|
|
142
|
+
| `l1` | root | L1 | The North Star vision; one per vault. |
|
|
143
|
+
| `l2` | root | L2 | Foundational architecture or model documents. |
|
|
144
|
+
| `l3` | `use-cases/` | L3 | Use-case specs that elaborate L1 system use cases. |
|
|
145
|
+
| `adr` | `adr/` | — | Architectural Decision Record. |
|
|
146
|
+
| `task` | `tasks/` | — | The atomic unit of work. Subsumes bd's `task`, `feature`, and `bug` types. |
|
|
147
|
+
| `epic` | `epics/` | — | A grouping of related tasks under a common goal. |
|
|
148
|
+
| `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)). |
|
|
149
|
+
| `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. |
|
|
150
|
+
| `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). |
|
|
151
|
+
| `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. |
|
|
152
|
+
| `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. |
|
|
153
|
+
| `branch-brief` | `branches/` | — | "What this git branch is trying to do, and how it actually went." Plan-vs-actual + evidence for one branch. |
|
|
154
|
+
| `memory-lesson` | `memory/lessons/` | — | "Here's what went wrong and how to avoid it." |
|
|
155
|
+
| `memory-decision` | `memory/decisions/` | — | "Here's what we chose and why." |
|
|
156
|
+
| `memory-reference` | `memory/references/` | — | "Here's where to look for X." |
|
|
157
|
+
| `memory-ui-pattern` | `memory/ui-patterns/` | — | "Here's a reusable console interaction/visual pattern to copy." |
|
|
158
|
+
| `memory-ux-principle` | `memory/ux-principles/` | — | "Here's a cross-brand UX rule (what/why) before implementation." |
|
|
159
|
+
| `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. |
|
|
160
|
+
| `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. |
|
|
161
|
+
| `business-positioning` | `business/positioning/` | — | Brand H1, taglines, audience qualifier, message hierarchy. |
|
|
162
|
+
| `business-pricing` | `business/pricing/` | — | Tier tables, AI add-on terms, discount/refund policy. |
|
|
163
|
+
| `business-marketing` | `business/marketing/` | — | Channels, launches, campaigns, copy decks. |
|
|
164
|
+
| `business-model` | `business/model/` | — | Unit economics, cost structure, monetization decisions. |
|
|
165
|
+
| `roadmap` | `roadmaps/` | — | Phased plan orchestrating tasks/epics; compact `roadmap_manifest` for indexer/CLI (adr-0012-roadmap-storage). |
|
|
166
|
+
| `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. |
|
|
167
|
+
| `research` | `research/` | — | Audit reports, feature inventories, exploratory notes. |
|
|
168
|
+
| `planning-flow` | `flows/` | — | Epic lifecycle orchestration diagram (mermaid source + canvas projection). |
|
|
169
|
+
| `draft` | `drafts/` | — | Ingested content awaiting triage. |
|
|
170
|
+
| `daily` | `daily/` | — | Optional daily-note scratchpad. |
|
|
171
|
+
| `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
172
|
|
|
179
173
|
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
174
|
|
|
181
175
|
`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
176
|
|
|
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
|
|
177
|
+
`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
178
|
|
|
185
179
|
`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
180
|
|
|
187
181
|
## Lifecycle classes
|
|
188
182
|
|
|
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
|
|
183
|
+
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
184
|
|
|
191
185
|
### Evergreen (living reference substrate)
|
|
192
186
|
|
|
@@ -198,7 +192,7 @@ These are **standalone reference artifacts**. `status: open` is the resting stat
|
|
|
198
192
|
- **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
193
|
- **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
194
|
|
|
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.
|
|
195
|
+
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
196
|
|
|
203
197
|
### Trackable plan-side (open → in_progress → in_review → closed)
|
|
204
198
|
|
|
@@ -206,7 +200,7 @@ Session-close protocol carve-out: an agent who touched an evergreen doc this ses
|
|
|
206
200
|
|
|
207
201
|
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
202
|
|
|
209
|
-
- **Session close** flips completed-this-session specs to `status: in_review` and creates an `HS-REV-<suffix>` companion (session-close-protocol).
|
|
203
|
+
- **Session close** flips completed-this-session specs to `status: in_review` and creates an `HS-REV-<suffix>` companion ([[session-close-protocol]]).
|
|
210
204
|
- **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
205
|
- **`branch-brief`** closes when the branch ships; **`planning-flow`** closes with its bound epic.
|
|
212
206
|
|
|
@@ -228,12 +222,12 @@ These are **inbound surfaces** scoped to one input session. They don't close in
|
|
|
228
222
|
|
|
229
223
|
### Cross-reference summary
|
|
230
224
|
|
|
231
|
-
| Class
|
|
232
|
-
|
|
233
|
-
| Evergreen
|
|
234
|
-
| Trackable plan-side | `open` → `in_progress` → `in_review` → `closed` (plus `deferred`) | Yes — frozen at close
|
|
235
|
-
| Single-shot ingest
|
|
236
|
-
| Per-instance
|
|
225
|
+
| Class | Status values used | Close-as-historical-record? | `canonical: false` trigger |
|
|
226
|
+
|---|---|---|---|
|
|
227
|
+
| Evergreen | `open` (resting state) | No | Supersession (relational edge) |
|
|
228
|
+
| Trackable plan-side | `open` → `in_progress` → `in_review` → `closed` (plus `deferred`) | Yes — frozen at close | Close-out write |
|
|
229
|
+
| Single-shot ingest | `open` (capture/draft pre-promotion) / N/A (daily) | No — promoted or archived by date | Not used |
|
|
230
|
+
| Per-instance | Declared at filing | Per-instance | Per-instance |
|
|
237
231
|
|
|
238
232
|
## Identity, IDs, and filenames
|
|
239
233
|
|
|
@@ -244,56 +238,55 @@ These are **inbound surfaces** scoped to one input session. They don't close in
|
|
|
244
238
|
|
|
245
239
|
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
240
|
|
|
247
|
-
| Token
|
|
248
|
-
|
|
|
249
|
-
| **File key**
|
|
250
|
-
| **Family key** | `P2TR`
|
|
251
|
-
| **Type label** | `TASK`
|
|
252
|
-
| **Title slug** | `verification-state-schema` | The lowercased-hyphenated descriptive tail derived from `title:` — the part that makes each basename unique within a family.
|
|
241
|
+
| Token | Example | Role |
|
|
242
|
+
| --- | --- | --- |
|
|
243
|
+
| **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. |
|
|
244
|
+
| **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). |
|
|
245
|
+
| **Type label** | `TASK` | The entity-kind token (`TASK`, `EPIC`, `MILESTONE`, `RESEARCH`, `REVIEW`, …). A **human-readable hint only**. |
|
|
246
|
+
| **Title slug** | `verification-state-schema` | The lowercased-hyphenated descriptive tail derived from `title:` — the part that makes each basename unique within a family. |
|
|
253
247
|
|
|
254
248
|
**Filename shapes (era = type-label position):**
|
|
255
|
-
|
|
256
249
|
- **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
250
|
- **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
251
|
- **Type-first (era 1, legacy):** `HS-<type label>-<family key>-<title slug>.md` → `HS-TASK-P2TR-verification-state-schema.md`
|
|
259
252
|
|
|
260
253
|
**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
254
|
|
|
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
|
|
255
|
+
**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
256
|
|
|
264
257
|
### ID format
|
|
265
258
|
|
|
266
|
-
| Entity type
|
|
267
|
-
|
|
|
268
|
-
| `l1`
|
|
269
|
-
| `l2`
|
|
270
|
-
| `l3`
|
|
271
|
-
| `adr`
|
|
272
|
-
| `task`
|
|
273
|
-
| `epic`
|
|
274
|
-
| `milestone`
|
|
275
|
-
| `diagnose`
|
|
276
|
-
| `pillar`
|
|
277
|
-
| `branch-brief`
|
|
278
|
-
| `memory-lesson`
|
|
279
|
-
| `memory-decision`
|
|
280
|
-
| `memory-reference`
|
|
281
|
-
| `memory-ui-pattern`
|
|
282
|
-
| `memory-ux-principle`
|
|
283
|
-
| `protocol`
|
|
284
|
-
| `review`
|
|
285
|
-
| `business-positioning` | `HS-BIZ-POS-<slug>`
|
|
286
|
-
| `business-pricing`
|
|
287
|
-
| `business-marketing`
|
|
288
|
-
| `business-model`
|
|
289
|
-
| `roadmap`
|
|
290
|
-
| `research`
|
|
291
|
-
| `capture`
|
|
292
|
-
| `agent`
|
|
293
|
-
| `golden-case`
|
|
294
|
-
| `planning-flow`
|
|
295
|
-
| `draft`
|
|
296
|
-
| `daily`
|
|
259
|
+
| Entity type | ID format | Example |
|
|
260
|
+
| --- | --- | --- |
|
|
261
|
+
| `l1` | `HS-L1` | `HS-L1` |
|
|
262
|
+
| `l2` | `HS-L2-<UPPER>` | `HS-L2-ENTITY`, `HS-L2-FOUNDATIONS` |
|
|
263
|
+
| `l3` | `HS-UC-<short>` | `HS-UC-CAPTURE` |
|
|
264
|
+
| `adr` | `HS-ADR-NNNN` (zero-padded sequence) | `HS-ADR-0001` |
|
|
265
|
+
| `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` |
|
|
266
|
+
| `epic` | `HS-EPIC-<suffix>` — same rules | `HS-DE8L`, `HS-V888` |
|
|
267
|
+
| `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` |
|
|
268
|
+
| `diagnose` | `HS-DIAG-<suffix>` — `<suffix>` is 4+ random A-Z0-9 (vault-id-assignment-protocol) | `HS-DIAG-K7M2` |
|
|
269
|
+
| `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` |
|
|
270
|
+
| `branch-brief` | `HS-BB-<slug>` | `HS-BB-feature-checkout-redesign` |
|
|
271
|
+
| `memory-lesson` | `HS-LES-<slug>` | `HS-LES-bd-process-leak` |
|
|
272
|
+
| `memory-decision` | `HS-DEC-<slug>` | `HS-DEC-dep-relate-for-epic-children` |
|
|
273
|
+
| `memory-reference` | `HS-REF-<slug>` | `HS-REF-dolt-time-travel-docs` |
|
|
274
|
+
| `memory-ui-pattern` | `HS-UIP-<slug>` | `HS-UIP-rail-active-vs-keyboard-cursor` |
|
|
275
|
+
| `memory-ux-principle` | `HS-UXP-<slug>` | `HS-UXP-toggle-current-state-semantics` |
|
|
276
|
+
| `protocol` | `HS-PROTO-<slug>` | `HS-PROTO-session-close` |
|
|
277
|
+
| `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` |
|
|
278
|
+
| `business-positioning` | `HS-BIZ-POS-<slug>` | `HS-BIZ-POS-2nd-brain-harness-for-specs` |
|
|
279
|
+
| `business-pricing` | `HS-BIZ-PRI-<slug>` | `HS-BIZ-PRI-tiers-and-byok-2026-05` |
|
|
280
|
+
| `business-marketing` | `HS-BIZ-MKT-<slug>` | `HS-BIZ-MKT-launch-playbook-companion` |
|
|
281
|
+
| `business-model` | `HS-BIZ-MOD-<slug>` | `HS-BIZ-MOD-flat-per-vault-economics` |
|
|
282
|
+
| `roadmap` | `HS-ROADMAP-<SLUG>` | `HS-ROADMAP-PRODUCT` |
|
|
283
|
+
| `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` |
|
|
284
|
+
| `capture` | `HS-CAP-<suffix>` — same rules; legacy `HS-IDEA-<suffix>` preserved in `legacy_idea_id:` for archaeology | `HS-CAP-JKLN`, `HS-CAP-OAP3` |
|
|
285
|
+
| `agent` | `HS-AGENT-<suffix>` — `<suffix>` is 4+ random A-Z0-9 (vault-id-assignment-protocol) | `HS-634I` |
|
|
286
|
+
| `golden-case` | `HS-GCASE-<suffix>` — same rules | `HS-HPIO` |
|
|
287
|
+
| `planning-flow` | `HS-FLOW-NNN` | `HS-FLOW-001` |
|
|
288
|
+
| `draft` | `HS-DRAFT-<slug>` | `HS-DRAFT-2026-05-14-1130-article-link` |
|
|
289
|
+
| `daily` | `HS-DAILY-YYYY-MM-DD` | `HS-DAILY-2026-05-14` |
|
|
297
290
|
|
|
298
291
|
**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
292
|
|
|
@@ -301,32 +294,32 @@ A managed spec's basename decomposes into named tokens. Canonical names per glos
|
|
|
301
294
|
|
|
302
295
|
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
296
|
|
|
304
|
-
| Entity
|
|
305
|
-
|
|
|
306
|
-
| `l1`
|
|
307
|
-
| `l2`
|
|
308
|
-
| `l3`
|
|
309
|
-
| `adr`
|
|
310
|
-
| `task`
|
|
311
|
-
| `epic`
|
|
312
|
-
| `milestone`
|
|
313
|
-
| `diagnose`
|
|
314
|
-
| `pillar`
|
|
315
|
-
| `branch-brief`
|
|
316
|
-
| `memory-lesson`
|
|
317
|
-
| `memory-decision`
|
|
318
|
-
| `memory-reference`
|
|
319
|
-
| `memory-ui-pattern`
|
|
320
|
-
| `memory-ux-principle` | `<slug>.md`
|
|
321
|
-
| `protocol`
|
|
322
|
-
| `review`
|
|
323
|
-
| `research`
|
|
324
|
-
| `capture`
|
|
325
|
-
| `agent`
|
|
326
|
-
| `golden-case`
|
|
327
|
-
| `planning-flow`
|
|
328
|
-
| `draft`
|
|
329
|
-
| `daily`
|
|
297
|
+
| Entity | Filename pattern | Example |
|
|
298
|
+
| --- | --- | --- |
|
|
299
|
+
| `l1` | `heyspex-north-star.md` (literal, only one) | `heyspex-north-star.md` |
|
|
300
|
+
| `l2` | `<topic>.md` (literal slug) | `entity-model.md` |
|
|
301
|
+
| `l3` | `uc-<short>.md` | `uc-capture-intent.md` |
|
|
302
|
+
| `adr` | `adr-NNNN-<slug>.md` | `adr-0001-vault-format.md` |
|
|
303
|
+
| `task` | `HS-TASK-<suffix>-<slug>.md` | `HS-TASK-K7M2-fix-foo.md` |
|
|
304
|
+
| `epic` | `HS-EPIC-<suffix>-<slug>.md` | `HS-0007-EPIC-console-resilience.md`, `HS-W9ZE-EPIC-design-system-enforcement-auto-surface-u.md` |
|
|
305
|
+
| `milestone` | `HS-MIL-<suffix>-<slug>.md` | `HS-IART-MIL-console-ia-restructure.md` |
|
|
306
|
+
| `diagnose` | `HS-DIAG-<suffix>-<slug>.md` | `HS-DIAG-K7M2-console-startup-lag.md` |
|
|
307
|
+
| `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` |
|
|
308
|
+
| `branch-brief` | `<branch-slug>.md` | `feature-checkout-redesign.md` |
|
|
309
|
+
| `memory-lesson` | `<slug>.md` | `bd-process-leak.md` |
|
|
310
|
+
| `memory-decision` | `<slug>.md` | `dep-relate-for-epic-children.md` |
|
|
311
|
+
| `memory-reference` | `<slug>.md` | `dolt-time-travel-docs.md` |
|
|
312
|
+
| `memory-ui-pattern` | `<slug>.md` | `rail-active-vs-keyboard-cursor.md` |
|
|
313
|
+
| `memory-ux-principle` | `<slug>.md` | `toggle-current-state-semantics.md` |
|
|
314
|
+
| `protocol` | `<slug>.md` | `session-close-protocol.md` |
|
|
315
|
+
| `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` |
|
|
316
|
+
| `research` | `HS-RES-<suffix>-<slug>.md` (legacy: `<slug>.md` only) | `HS-RES-K7M2-agent-governance.md` |
|
|
317
|
+
| `capture` | `HS-CAP-<suffix>-<slug>.md` | `HS-CAP-JKLN-vault-triage.md` |
|
|
318
|
+
| `agent` | `HS-AGENT-<suffix>-<slug>.md` | `HS-9TNK-AGENT-code-reviewer.md` |
|
|
319
|
+
| `golden-case` | `HS-GCASE-<suffix>-<slug>.md` | `HS-R4VW-GCASE-review-missing-ac.md` |
|
|
320
|
+
| `planning-flow` | `HS-FLOW-<NNN>-<slug>.md` | `HS-FLOW-001-epic-planning-flow-studio.md` |
|
|
321
|
+
| `draft` | `<slug>.md` | `2026-05-14-1130-article-link.md` |
|
|
322
|
+
| `daily` | `YYYY-MM-DD.md` | `2026-05-14.md` |
|
|
330
323
|
|
|
331
324
|
Slug rules: lowercase, ASCII, dash-separated, no trailing punctuation, no leading number for non-task types.
|
|
332
325
|
|
|
@@ -347,45 +340,45 @@ Every spec opens with a YAML frontmatter block. The schemas below define **requi
|
|
|
347
340
|
Universal fields (every spec has these):
|
|
348
341
|
|
|
349
342
|
```yaml
|
|
350
|
-
id:
|
|
351
|
-
name:
|
|
352
|
-
type:
|
|
353
|
-
status:
|
|
354
|
-
priority:
|
|
355
|
-
owner:
|
|
356
|
-
|
|
357
|
-
created:
|
|
358
|
-
updated:
|
|
343
|
+
id: # required, string, matches the entity type's ID format
|
|
344
|
+
name: # required, string, human-readable title
|
|
345
|
+
type: # required, one of the entity type values above
|
|
346
|
+
status: # required, see status enum below
|
|
347
|
+
priority: # required, integer 0–4 (0 = highest)
|
|
348
|
+
owner: # required, string (email or handle) — the ORIGINATING + accountable human (doubles as author).
|
|
349
|
+
# See §Authorship provenance below.
|
|
350
|
+
created: # required, ISO-8601 date (YYYY-MM-DD)
|
|
351
|
+
updated: # required, ISO-8601 date
|
|
359
352
|
contributors: # optional, list of "Name <email>" — OTHER humans who later enhanced the doc (append-only;
|
|
360
|
-
|
|
361
|
-
assisted_by:
|
|
362
|
-
|
|
363
|
-
tags:
|
|
364
|
-
related:
|
|
353
|
+
# OMIT when empty). Auto-stamped, never hand-maintained. See §Authorship provenance.
|
|
354
|
+
assisted_by: # optional, list of "AGENT" or "AGENT:MODEL" — agents/IDEs + model that assisted (append-only;
|
|
355
|
+
# OMIT when empty). Auto-stamped, never hand-maintained. See §Authorship provenance.
|
|
356
|
+
tags: # optional, list of strings
|
|
357
|
+
related: # optional, list of wikilinks (alternative to inline body links)
|
|
365
358
|
what_matters: # optional, enum: star | heart — per-spec user-priority signal
|
|
366
359
|
```
|
|
367
360
|
|
|
368
361
|
**`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
362
|
|
|
370
|
-
- `star` (★) —
|
|
371
|
-
- `heart` (♥) —
|
|
363
|
+
- `star` (★) — *priority*: "consider this please."
|
|
364
|
+
- `heart` (♥) — *very important*: "appreciate this being next if at all possible." A stronger signal than `star`.
|
|
372
365
|
- absent — unflagged (no default is injected).
|
|
373
366
|
|
|
374
367
|
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
368
|
|
|
376
369
|
### Authorship provenance
|
|
377
370
|
|
|
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
|
|
371
|
+
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
372
|
|
|
380
|
-
| Field
|
|
381
|
-
|
|
|
382
|
-
| `owner`
|
|
383
|
-
| `contributors` | **other** humans who later enhanced the doc
|
|
384
|
-
| `assisted_by`
|
|
373
|
+
| Field | Who | Item format | Cardinality |
|
|
374
|
+
| --- | --- | --- | --- |
|
|
375
|
+
| `owner` | the **originating + accountable** human (doubles as author) | handle or email (e.g. `pwher`) | single scalar |
|
|
376
|
+
| `contributors` | **other** humans who later enhanced the doc | `Name <email>` — GitHub form, round-trips with the `Co-authored-by:` trailer | append-only list |
|
|
377
|
+
| `assisted_by` | agents/IDEs + model that assisted | `AGENT` or `AGENT:MODEL` — e.g. `Claude Opus 4.8`, `Cursor` | append-only list |
|
|
385
378
|
|
|
386
379
|
Semantics (apply to every entity kind):
|
|
387
380
|
|
|
388
|
-
- **`owner` is universally required** and unchanged in type — only its meaning is enriched here (originator + accountable, not merely a pointer). A later ownership
|
|
381
|
+
- **`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
382
|
- **`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
383
|
- **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
384
|
- **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.
|
|
@@ -398,8 +391,7 @@ Semantics (apply to every entity kind):
|
|
|
398
391
|
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
392
|
|
|
400
393
|
```yaml
|
|
401
|
-
artifact:
|
|
402
|
-
{ title: "…", url: "https://claude.ai/code/artifact/…", version: "…", updated: "2026-08-23" }
|
|
394
|
+
artifact: { title: "…", url: "https://claude.ai/code/artifact/…", version: "…", updated: "2026-08-23" }
|
|
403
395
|
# title: required when artifact: is present — the artifact's display title (matches its published <title>/heading).
|
|
404
396
|
# url: required — the published URL.
|
|
405
397
|
# version: optional, string — the last-published version stamp this vault file was confirmed against. This is
|
|
@@ -413,7 +405,7 @@ artifact:
|
|
|
413
405
|
|
|
414
406
|
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
407
|
|
|
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-
|
|
408
|
+
**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-roadmap0829.html` uses.
|
|
417
409
|
|
|
418
410
|
> [!note] Schema addition self-gating
|
|
419
411
|
> 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.
|
|
@@ -433,16 +425,16 @@ Status enum (universal):
|
|
|
433
425
|
|
|
434
426
|
```yaml
|
|
435
427
|
type: l1
|
|
436
|
-
aliases:
|
|
437
|
-
brand:
|
|
438
|
-
domains:
|
|
439
|
-
version:
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
428
|
+
aliases: # optional, list of alternative names
|
|
429
|
+
brand: # optional, mapping with canonical/variants/pronunciation/comma
|
|
430
|
+
domains: # optional, list of relevant domains
|
|
431
|
+
version: # optional, monotonic integer — bumped on every material edit to the record.
|
|
432
|
+
# The alignment-drift detector ([[HS-E3D3-RDFT-EPIC-alignment-drift-detector-into-resolution]])
|
|
433
|
+
# compares the version an epic was last aligned against (its `alignment_baseline`)
|
|
434
|
+
# to this current version; a bump past the baseline surfaces a `drift` resolution item.
|
|
443
435
|
last_edited_at: # optional, ISO-8601 timestamp of the last edit to the record. Timestamp FALLBACK for
|
|
444
|
-
|
|
445
|
-
|
|
436
|
+
# drift detection when an epic carries no per-layer `alignment_baseline`: the layer's
|
|
437
|
+
# `last_edited_at` newer than the epic's `alignment_reviewed_at` means drift.
|
|
446
438
|
```
|
|
447
439
|
|
|
448
440
|
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.
|
|
@@ -455,29 +447,29 @@ Universal fields only. No required L2-specific fields.
|
|
|
455
447
|
|
|
456
448
|
```yaml
|
|
457
449
|
type: l3
|
|
458
|
-
actors:
|
|
459
|
-
trigger:
|
|
460
|
-
outcomes:
|
|
461
|
-
depends_on:
|
|
450
|
+
actors: # required, list of actor names from L1
|
|
451
|
+
trigger: # required, string — what initiates this use case
|
|
452
|
+
outcomes: # required, list — observable end states
|
|
453
|
+
depends_on: # optional, list of wikilinks to other use cases
|
|
462
454
|
```
|
|
463
455
|
|
|
464
456
|
#### `adr`
|
|
465
457
|
|
|
466
458
|
```yaml
|
|
467
459
|
type: adr
|
|
468
|
-
decision_date:
|
|
469
|
-
deciders:
|
|
470
|
-
supersedes:
|
|
471
|
-
superseded_by:
|
|
472
|
-
status:
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
canonical:
|
|
479
|
-
|
|
480
|
-
|
|
460
|
+
decision_date: # required, ISO-8601 date
|
|
461
|
+
deciders: # required, list of strings
|
|
462
|
+
supersedes: # optional, wikilink to ADR this replaces
|
|
463
|
+
superseded_by: # optional, wikilink to ADR replacing this
|
|
464
|
+
status: # adr-status enum: proposed | accepted | deprecated
|
|
465
|
+
# `superseded` is DEPRECATED 2026-06-03 per [[superseded-enum-values-deprecated-use-canonical-false-and-superseded-by]]
|
|
466
|
+
# New writes: set `canonical: false` + `superseded_by: '[[<successor>]]'` instead. Existing
|
|
467
|
+
# ADRs that already carry `status: superseded` stay as historical record per the
|
|
468
|
+
# immutability principle ([[closed-trackable-specs-are-historical-record-not-living-docs]]) —
|
|
469
|
+
# readers infer `canonical: false` from the legacy value.
|
|
470
|
+
canonical: # universal flag — true (or absent) = current/authoritative; false = historical record
|
|
471
|
+
# (current canonical is at `superseded_by:`). Flipped at supersession-time via
|
|
472
|
+
# [[supersession-protocol]]; frozen thereafter.
|
|
481
473
|
```
|
|
482
474
|
|
|
483
475
|
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.
|
|
@@ -622,43 +614,43 @@ Durable agent identity (HS-XNX5-UQHA-MIL-agent-home). Evergreen — does not clo
|
|
|
622
614
|
|
|
623
615
|
```yaml
|
|
624
616
|
type: agent
|
|
625
|
-
role:
|
|
626
|
-
model:
|
|
627
|
-
description:
|
|
628
|
-
goal:
|
|
629
|
-
allowed_tools:
|
|
617
|
+
role: # required, string — human-readable role title (also used as description fallback on compile)
|
|
618
|
+
model: # optional, enum: opus | sonnet | haiku
|
|
619
|
+
description: # optional, string — host-native description on compile
|
|
620
|
+
goal: # optional, string — HeySpex-resident intent label (not compiled)
|
|
621
|
+
allowed_tools: # optional, list of strings — compiled to host `tools:` when present
|
|
630
622
|
disallowed_tools: # optional, list of strings — compiled to host `disallowedTools:` when present
|
|
631
|
-
procedures:
|
|
632
|
-
handoffs:
|
|
633
|
-
guardrails:
|
|
634
|
-
lane:
|
|
635
|
-
isolation:
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
color:
|
|
640
|
-
owned_paths:
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
golden_cases:
|
|
644
|
-
|
|
645
|
-
|
|
623
|
+
procedures: # optional, list of wikilinks — HeySpex-resident procedure refs
|
|
624
|
+
handoffs: # optional, list — HeySpex-resident handoff targets
|
|
625
|
+
guardrails: # optional, list of strings — HeySpex-resident; persona body carries compiled guardrails
|
|
626
|
+
lane: # optional, string — human label for parallel work (advisory in v1)
|
|
627
|
+
isolation: # optional, enum: default | worktree — operator guidance for checkout
|
|
628
|
+
# isolation when parallel agents each need a dev server; advisory in v1
|
|
629
|
+
# ([[parallel-agent-isolation-guidance]]). `worktree` = use a dedicated git
|
|
630
|
+
# worktree before implementation. HeySpex-only — stripped on compile (like `lane`).
|
|
631
|
+
color: # optional, string — console roster accent (HeySpex-only)
|
|
632
|
+
owned_paths: # optional, list of repo-relative glob strings — machine-checkable file/module
|
|
633
|
+
# ownership for stomp-detection ([[HS-8PNX-Q1KC-EPIC-lanes-and-stomp-detection-for-parallel-a]]).
|
|
634
|
+
# Example: spex-console/src/lib/scheduler/**, vendor/heyspex-mcp/**. HeySpex-only — stripped on compile.
|
|
635
|
+
golden_cases: # optional, list of wikilinks to HS-GCASE-* fixtures owned by this agent.
|
|
636
|
+
# Reverse of each case's `agent:` pointer. HeySpex-only — stripped on compile
|
|
637
|
+
# ([[HS-8AQT-J6FU-TASK-golden-case-vault-artifact-format-and-st]]).
|
|
646
638
|
source_attribution: # optional object — import provenance for community/own-agent imports only
|
|
647
|
-
tags:
|
|
648
|
-
|
|
649
|
-
|
|
639
|
+
tags: # required for roster grouping — MUST include `agent` plus at least one
|
|
640
|
+
# `purpose/*` tag (see Purpose tags below). Plain frontmatter array;
|
|
641
|
+
# no agent-only grouping engine ([[HS-IAYA-5345-TASK-lock-agent-purpose-taxonomy-and-tag-conv]]).
|
|
650
642
|
```
|
|
651
643
|
|
|
652
644
|
**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
645
|
|
|
654
|
-
| Tag
|
|
655
|
-
|
|
656
|
-
| `purpose/reviewer`
|
|
657
|
-
| `purpose/researcher`
|
|
658
|
-
| `purpose/planner`
|
|
659
|
-
| `purpose/triager`
|
|
660
|
-
| `purpose/implementer` | Build, edit, deploy — agents that modify code or infra
|
|
661
|
-
| `purpose/writer`
|
|
646
|
+
| Tag | When to use |
|
|
647
|
+
|-----|-------------|
|
|
648
|
+
| `purpose/reviewer` | Verify acceptance criteria, review diffs, read-only audit before close-out |
|
|
649
|
+
| `purpose/researcher` | Synthesize cited research into durable `HS-RES-*` specs |
|
|
650
|
+
| `purpose/planner` | Ground plans/epics, stress-test assumptions at the plan→execute boundary |
|
|
651
|
+
| `purpose/triager` | Intake routing — captures, resolution items, smallest-fix triage |
|
|
652
|
+
| `purpose/implementer` | Build, edit, deploy — agents that modify code or infra |
|
|
653
|
+
| `purpose/writer` | Prose/docs authoring (reserved; no starter roster member yet) |
|
|
662
654
|
|
|
663
655
|
Rules:
|
|
664
656
|
|
|
@@ -672,20 +664,20 @@ Saved eval fixture for the agent testing harness (HS-R1JM-OAG3-EPIC-agent-testin
|
|
|
672
664
|
|
|
673
665
|
```yaml
|
|
674
666
|
type: golden-case
|
|
675
|
-
agent:
|
|
676
|
-
tags:
|
|
677
|
-
related:
|
|
667
|
+
agent: # required, wikilink to HS-AGENT-* — the identity under test
|
|
668
|
+
tags: # should include golden-case, agents, testing
|
|
669
|
+
related: # optional wikilinks — e.g. the task spec used as setup context
|
|
678
670
|
```
|
|
679
671
|
|
|
680
672
|
**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
673
|
|
|
682
674
|
**Required body sections:**
|
|
683
675
|
|
|
684
|
-
| Section
|
|
685
|
-
|
|
|
686
|
-
| `## Prompt`
|
|
687
|
-
| `## Setup`
|
|
688
|
-
| `## Deterministic graders` | no
|
|
676
|
+
| Section | Required | Purpose |
|
|
677
|
+
| --- | --- | --- |
|
|
678
|
+
| `## Prompt` | yes | The user message the eval spawn sends to the draft agent (≥12 characters). |
|
|
679
|
+
| `## Setup` | no | Freeform context — wikilinks to task specs, files in scope, env hints. |
|
|
680
|
+
| `## 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
681
|
|
|
690
682
|
**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
683
|
|
|
@@ -696,39 +688,39 @@ Same as `task` schema (including optional `affects_paths:`). The `type: epic` is
|
|
|
696
688
|
**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
689
|
|
|
698
690
|
```yaml
|
|
699
|
-
research:
|
|
700
|
-
planning_flow:
|
|
701
|
-
milestone:
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
derived_from:
|
|
712
|
-
|
|
691
|
+
research: # required for new epics — wikilink to HS-RES-*
|
|
692
|
+
planning_flow: # required for new epics — wikilink to HS-FLOW-*
|
|
693
|
+
milestone: # REQUIRED — single wikilink to the parent HS-MIL-* this epic belongs to.
|
|
694
|
+
# The inverse of the milestone's `epics:` array (write both sides;
|
|
695
|
+
# `scripts/validate-vault-ids.mjs` rejects one-sided drift).
|
|
696
|
+
# Grace window: missing `milestone:` is a validator warning until
|
|
697
|
+
# 2026-06-26, then escalates to an error
|
|
698
|
+
# ([[HS-V5UA-T5PX-TASK-required-milestone-parent-on-epic-validator-and-grace-window]],
|
|
699
|
+
# part of [[HS-OFR5-M2J3-EPIC-introduce-milestones-as-highest-entity]]).
|
|
700
|
+
# Pre-rule orphan epics live at
|
|
701
|
+
# [[HS-3DJS-ORPH-MIL-uncategorized-pre-2026-05-26-epics]]
|
|
702
|
+
# pending walk-the-floor reassignment.
|
|
703
|
+
derived_from: # optional, single wikilink to HS-RES-* — the research that spawned this epic.
|
|
704
|
+
# Reverse of `research.spawned_epics:` (1:N). See §Provenance edges.
|
|
713
705
|
```
|
|
714
706
|
|
|
715
707
|
**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
708
|
|
|
717
709
|
```yaml
|
|
718
710
|
alignment_rationale: # optional (backfill in progress), string — a wikilink to the Pillar / L1 principle
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
alignment_baseline:
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
711
|
+
# this epic advances PLUS a one-line "why", e.g.
|
|
712
|
+
# "[[HS-PILR-architecture]] — advances the foundations concern by converging detection paths".
|
|
713
|
+
# Distinct from the membership `pillar:` field: `pillar:` categorizes; `alignment_rationale`
|
|
714
|
+
# carries the teleological "why" the drift detector reasons over. The wikilink target
|
|
715
|
+
# SHOULD match the epic's `pillar:`. An `alignment_rationale` that resolves to no layer
|
|
716
|
+
# record surfaces as an `orphan` resolution item.
|
|
717
|
+
alignment_baseline: # optional, mapping { <layer-id>: <int version>, anti_goals?: <fingerprint> } — the layer
|
|
718
|
+
# versions this epic was last aligned against. PRIMARY drift baseline: when a referenced
|
|
719
|
+
# layer's current `version` exceeds the baseline here, a `drift` item is emitted. The
|
|
720
|
+
# `anti_goals` key stamps the L1 anti-goal fingerprint so a changed anti-goal set re-checks
|
|
721
|
+
# every active + recently-closed epic. Absent → the detector falls back to
|
|
722
|
+
# `alignment_reviewed_at` vs the layer's `last_edited_at`; absent both → no drift (never a
|
|
723
|
+
# false positive). Stamped by the alignment checkpoint on re-alignment.
|
|
732
724
|
```
|
|
733
725
|
|
|
734
726
|
#### `milestone`
|
|
@@ -737,16 +729,16 @@ The grouping **above** epic: a coherent multi-epic ship (a restructure or releas
|
|
|
737
729
|
|
|
738
730
|
```yaml
|
|
739
731
|
type: milestone
|
|
740
|
-
status:
|
|
741
|
-
epics:
|
|
742
|
-
|
|
743
|
-
informed_by:
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
target_date:
|
|
748
|
-
tags:
|
|
749
|
-
related:
|
|
732
|
+
status: # one of: open | in_progress | closed (subset of the universal enum)
|
|
733
|
+
epics: # list of wikilinks to every child epic — the mirror of each child epic's
|
|
734
|
+
# `milestone:` pointer. Write both sides (bidirectional linkage; see [[spec-hierarchy]]).
|
|
735
|
+
informed_by: # optional, list of wikilinks to HS-RES-* — research docs that enhance this milestone.
|
|
736
|
+
# Reverse of `research.enhances:` (each research enhances exactly one milestone, M:1;
|
|
737
|
+
# one milestone may be informed by many research docs over time). Bidirectional
|
|
738
|
+
# consistency enforced by `scripts/validate-vault-ids.mjs`. See §Provenance edges.
|
|
739
|
+
target_date: # optional, ISO-8601 date or empty string "" — the intended ship date
|
|
740
|
+
tags: # optional, list of strings
|
|
741
|
+
related: # optional, list of wikilinks
|
|
750
742
|
```
|
|
751
743
|
|
|
752
744
|
**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.
|
|
@@ -761,25 +753,25 @@ A user-reported **bug fix** as first-class executable work — claimable and dec
|
|
|
761
753
|
|
|
762
754
|
```yaml
|
|
763
755
|
type: diagnose
|
|
764
|
-
status:
|
|
765
|
-
severity:
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
parent:
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
depends_on:
|
|
772
|
-
blocks:
|
|
773
|
-
|
|
774
|
-
promoted_from:
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
derived_from:
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
tags:
|
|
782
|
-
related:
|
|
756
|
+
status: # universal enum: open | in_progress | in_review | closed | …
|
|
757
|
+
severity: # REQUIRED — one of: error | warning | info. Maps onto the scheduler's
|
|
758
|
+
# existing priority signals (channel B): a higher-severity diagnose
|
|
759
|
+
# competes higher for on-deck. Drives the derived bug row's color.
|
|
760
|
+
parent: # OPTIONAL — single wikilink to an HS-EPIC-* or HS-MIL-* parent.
|
|
761
|
+
# Standalone (absent) is the DEFAULT and is exempt from the
|
|
762
|
+
# epic→milestone mandatory-parent rule. One-way pointer (no auto back-link).
|
|
763
|
+
depends_on: # optional, list of wikilinks — tasks/specs that must close first.
|
|
764
|
+
blocks: # optional, list of wikilinks to HS-EPIC-*/HS-TASK-* this fix gates.
|
|
765
|
+
# Surfaces as a gating item in that spec's On-Deck overlay (channel A).
|
|
766
|
+
promoted_from: # optional, single wikilink to HS-CAP-* — set when this diagnose was promoted
|
|
767
|
+
# from a bug-report capture via `heyspex_promote_capture_to_diagnose`.
|
|
768
|
+
# Reverse of `capture.promoted_to:` (first-promotion).
|
|
769
|
+
derived_from: # optional, single wikilink to HS-RES-* — the research that surfaced this bug,
|
|
770
|
+
# set when this diagnose was promoted from a research investigation via
|
|
771
|
+
# `heyspex_promote_research_to_diagnose` (mirrors `epic.derived_from`).
|
|
772
|
+
# Reverse of `research.produces_diagnose:` (1:N).
|
|
773
|
+
tags: # optional, list of strings
|
|
774
|
+
related: # optional, list of wikilinks
|
|
783
775
|
```
|
|
784
776
|
|
|
785
777
|
**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.
|
|
@@ -792,19 +784,19 @@ Perpetual categorical container that never closes — the cross-cutting axis to
|
|
|
792
784
|
|
|
793
785
|
```yaml
|
|
794
786
|
type: pillar
|
|
795
|
-
status:
|
|
796
|
-
|
|
797
|
-
canonical:
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
library_tier:
|
|
787
|
+
status: # `perpetual` — non-terminal. Pillars never transition to closed/in_review/etc.
|
|
788
|
+
# Universal status enum does NOT apply.
|
|
789
|
+
canonical: # required, boolean
|
|
790
|
+
# true → curated by HeySpex team; ships pre-loaded in customer vaults; read-only (fork to customize)
|
|
791
|
+
# false → customer-scoped Pillar (filed by the customer with high friction)
|
|
792
|
+
library_tier: # optional enum: meta | foundational | discretionary (placeholder; library taxonomy TBD)
|
|
801
793
|
secondary_pillars: # always present; usually empty []. Reserved for future cross-Pillar linking.
|
|
802
|
-
version:
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
last_edited_at:
|
|
806
|
-
related:
|
|
807
|
-
tags:
|
|
794
|
+
version: # optional, monotonic integer — same semantics as the `l1` `version` field above.
|
|
795
|
+
# A Pillar edit that materially changes scope bumps this; epics aligned against the
|
|
796
|
+
# prior version surface as `drift` items ([[HS-E3D3-RDFT-EPIC-alignment-drift-detector-into-resolution]]).
|
|
797
|
+
last_edited_at: # optional, ISO-8601 timestamp of the last edit — drift timestamp fallback (see `l1`).
|
|
798
|
+
related: # optional, list of wikilinks
|
|
799
|
+
tags: # optional, list of strings
|
|
808
800
|
```
|
|
809
801
|
|
|
810
802
|
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.
|
|
@@ -812,21 +804,21 @@ The `version` / `last_edited_at` fields are the versioning prerequisites carried
|
|
|
812
804
|
**Per-epic membership** (new fields on every epic, added 2026-05-31 by HS-EBIL-0011-EPIC-goal-hierarchy-l2-strategic-pillars-l3):
|
|
813
805
|
|
|
814
806
|
```yaml
|
|
815
|
-
pillar:
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
secondary_pillars:
|
|
823
|
-
|
|
824
|
-
|
|
807
|
+
pillar: # required on every epic, single wikilink to a Pillar.
|
|
808
|
+
# The home for library/learning. Forces "what perpetual concern does this advance?"
|
|
809
|
+
# at filing time. HARD-BLOCKED at the filing boundary (owner decision 2026-06-18):
|
|
810
|
+
# POST /api/specs / heyspex_file_spec refuse an epic with no resolvable HS-PILR pillar
|
|
811
|
+
# (400 pillar_required). Legacy pillar-less epics are caught by the EPIC_MISSING_PILLAR
|
|
812
|
+
# vault-rule — warning (Resolution backfill queue) until 2026-07-31, then error.
|
|
813
|
+
# Full rules: [[pillar-assignment-protocol]].
|
|
814
|
+
secondary_pillars: # optional, list of wikilinks to Pillars.
|
|
815
|
+
# For genuinely cross-cutting work ("Add caching layer" is primarily Scaling but also Reliability).
|
|
816
|
+
# Tasks inherit their epic's primary pillar; do not set secondary on tasks.
|
|
825
817
|
```
|
|
826
818
|
|
|
827
819
|
**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
820
|
|
|
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
|
|
821
|
+
**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
822
|
|
|
831
823
|
**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
824
|
|
|
@@ -846,34 +838,34 @@ A durable "plan receipt" for one git branch. Ratified by adr-0008-branch-brief-a
|
|
|
846
838
|
|
|
847
839
|
```yaml
|
|
848
840
|
type: branch-brief
|
|
849
|
-
branch:
|
|
850
|
-
repo:
|
|
851
|
-
goal:
|
|
852
|
-
implements:
|
|
853
|
-
plan:
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
actual:
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
risks:
|
|
863
|
-
open_questions:
|
|
864
|
-
next_steps:
|
|
865
|
-
decisions:
|
|
866
|
-
evidence:
|
|
841
|
+
branch: # required, string — the raw (unsanitized) git branch name
|
|
842
|
+
repo: # optional, string — repo name if multi-repo
|
|
843
|
+
goal: # required, string — what this branch is trying to accomplish
|
|
844
|
+
implements: # optional, list of wikilinks — tasks/epics this branch implements
|
|
845
|
+
plan: # optional, list of { step: int, description: string }
|
|
846
|
+
# the ORIGINAL intent. Sourced (priority order) from:
|
|
847
|
+
# 1. the linked implementing spec's acceptance criteria
|
|
848
|
+
# (its `acceptance:` array, else its `## Acceptance` body)
|
|
849
|
+
# 2. a manual plan authored here (exploratory branches)
|
|
850
|
+
# Commit messages / PR bodies are NOT v1 plan sources.
|
|
851
|
+
actual: # optional, list of { step: int, description: string,
|
|
852
|
+
# status: <drift enum>, evidence: [<evidence ref>] }
|
|
853
|
+
# what was implemented, captured at brief-generation time.
|
|
854
|
+
risks: # optional, list of strings — identified risks/concerns
|
|
855
|
+
open_questions: # optional, list of strings — unresolved questions
|
|
856
|
+
next_steps: # optional, list of strings — recommended next actions
|
|
857
|
+
decisions: # optional, list of wikilinks — memory-decisions made on this branch
|
|
858
|
+
evidence: # optional, evidence array (see "Evidence linking" below)
|
|
867
859
|
```
|
|
868
860
|
|
|
869
861
|
**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
862
|
|
|
871
|
-
| Value
|
|
872
|
-
|
|
|
873
|
-
| `match`
|
|
874
|
-
| `drift`
|
|
875
|
-
| `missing` | Planned step not implemented.
|
|
876
|
-
| `extra`
|
|
863
|
+
| Value | Meaning |
|
|
864
|
+
| --- | --- |
|
|
865
|
+
| `match` | Implementation achieves the planned step. |
|
|
866
|
+
| `drift` | Implementation differs from the plan in a material way. |
|
|
867
|
+
| `missing` | Planned step not implemented. |
|
|
868
|
+
| `extra` | Implemented change that was not in the plan. |
|
|
877
869
|
|
|
878
870
|
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
871
|
|
|
@@ -881,11 +873,11 @@ Required body sections: `## Goal`, `## Plan vs Actual` (a table rendering `plan`
|
|
|
881
873
|
|
|
882
874
|
```yaml
|
|
883
875
|
type: memory-lesson
|
|
884
|
-
topic:
|
|
885
|
-
observed:
|
|
886
|
-
related:
|
|
887
|
-
evidence:
|
|
888
|
-
|
|
876
|
+
topic: # required, short string — the subject
|
|
877
|
+
observed: # required, ISO-8601 date — when the lesson was learned
|
|
878
|
+
related: # optional, list of wikilinks
|
|
879
|
+
evidence: # optional, evidence array — sources grounding the problem/fix
|
|
880
|
+
# (see "Evidence linking" below)
|
|
889
881
|
```
|
|
890
882
|
|
|
891
883
|
The body of a memory-lesson spec has two required sections: `## Problem` and `## Fix`.
|
|
@@ -894,12 +886,12 @@ The body of a memory-lesson spec has two required sections: `## Problem` and `##
|
|
|
894
886
|
|
|
895
887
|
```yaml
|
|
896
888
|
type: memory-decision
|
|
897
|
-
topic:
|
|
898
|
-
decided:
|
|
899
|
-
deciders:
|
|
900
|
-
supersedes:
|
|
901
|
-
evidence:
|
|
902
|
-
|
|
889
|
+
topic: # required, short string
|
|
890
|
+
decided: # required, ISO-8601 date
|
|
891
|
+
deciders: # required, list of strings
|
|
892
|
+
supersedes: # optional, wikilink to a prior decision
|
|
893
|
+
evidence: # optional, evidence array — sources grounding the rationale
|
|
894
|
+
# (see "Evidence linking" below)
|
|
903
895
|
```
|
|
904
896
|
|
|
905
897
|
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.)
|
|
@@ -908,10 +900,10 @@ The body has two required sections: `## Decision` and `## Rationale`. (An ADR is
|
|
|
908
900
|
|
|
909
901
|
```yaml
|
|
910
902
|
type: memory-reference
|
|
911
|
-
topic:
|
|
912
|
-
url:
|
|
913
|
-
evidence:
|
|
914
|
-
|
|
903
|
+
topic: # required, short string
|
|
904
|
+
url: # optional, URL the reference points at
|
|
905
|
+
evidence: # optional, evidence array — additional grounded sources
|
|
906
|
+
# (see "Evidence linking" below)
|
|
915
907
|
```
|
|
916
908
|
|
|
917
909
|
Body is the brief context for why this reference matters.
|
|
@@ -920,10 +912,10 @@ Body is the brief context for why this reference matters.
|
|
|
920
912
|
|
|
921
913
|
```yaml
|
|
922
914
|
type: memory-ui-pattern
|
|
923
|
-
topic:
|
|
924
|
-
documented:
|
|
925
|
-
related:
|
|
926
|
-
evidence:
|
|
915
|
+
topic: # required, short string — the pattern name/slug
|
|
916
|
+
documented: # required, ISO-8601 date — when the pattern was captured
|
|
917
|
+
related: # optional, list of wikilinks
|
|
918
|
+
evidence: # optional, evidence array
|
|
927
919
|
```
|
|
928
920
|
|
|
929
921
|
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.
|
|
@@ -932,22 +924,22 @@ Reusable **console interaction and visual patterns** (keyboard ownership, two-la
|
|
|
932
924
|
|
|
933
925
|
```yaml
|
|
934
926
|
type: memory-ux-principle
|
|
935
|
-
topic:
|
|
936
|
-
documented:
|
|
937
|
-
related:
|
|
938
|
-
evidence:
|
|
927
|
+
topic: # required, short string — the principle name/slug
|
|
928
|
+
documented: # required, ISO-8601 date — when the principle was captured
|
|
929
|
+
related: # optional, list of wikilinks
|
|
930
|
+
evidence: # optional, evidence array
|
|
939
931
|
```
|
|
940
932
|
|
|
941
933
|
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
934
|
|
|
943
935
|
#### `protocol`
|
|
944
936
|
|
|
945
|
-
Part of the **Memory** layer (memory-protocols-subsection-of-memory). Epics/tasks that
|
|
937
|
+
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
938
|
|
|
947
939
|
```yaml
|
|
948
940
|
type: protocol
|
|
949
|
-
scope:
|
|
950
|
-
version:
|
|
941
|
+
scope: # required, one of: session | project | vault | tool
|
|
942
|
+
version: # optional, semver-ish version of the protocol
|
|
951
943
|
```
|
|
952
944
|
|
|
953
945
|
Body describes the protocol with numbered steps.
|
|
@@ -958,13 +950,13 @@ Companion fill-in workspace for a parent spec at `status: in_review`. One review
|
|
|
958
950
|
|
|
959
951
|
```yaml
|
|
960
952
|
type: review
|
|
961
|
-
parent:
|
|
962
|
-
reviews:
|
|
963
|
-
|
|
953
|
+
parent: # required, single wikilink — the spec under review
|
|
954
|
+
reviews: # optional, single wikilink — same as parent (legacy alias retained for back-compat reads)
|
|
955
|
+
# parent: is the canonical edge; reviews: is kept for older docs
|
|
964
956
|
deliberation_record: # optional; Council session output for invocation #4 (review close-out)
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
957
|
+
# ([[adr-0015-council-as-cross-cutting-capability]]). Schema lives under `draft`
|
|
958
|
+
# §`deliberation_record` above. Attached when the human triggers council during
|
|
959
|
+
# `/hs-review` close-out; never gates the human's pass/reopen decision.
|
|
968
960
|
```
|
|
969
961
|
|
|
970
962
|
Body has four required sections — the unified workspace:
|
|
@@ -985,17 +977,17 @@ The four-section unified-workspace template and the close-out flow are specified
|
|
|
985
977
|
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
978
|
|
|
987
979
|
```yaml
|
|
988
|
-
type: business-positioning
|
|
989
|
-
topic:
|
|
990
|
-
status:
|
|
991
|
-
|
|
992
|
-
related:
|
|
993
|
-
evidence:
|
|
980
|
+
type: business-positioning # or business-pricing | business-marketing | business-model
|
|
981
|
+
topic: # required, short string — the subject (e.g. "homepage-h1", "tier-table")
|
|
982
|
+
status: # universal status enum — draft | open | in_progress | in_review | closed | deferred
|
|
983
|
+
# `active` is allowed as a synonym for `open` on migrated docs.
|
|
984
|
+
related: # optional, list of wikilinks
|
|
985
|
+
evidence: # optional, evidence array — sources grounding the claim/decision
|
|
994
986
|
```
|
|
995
987
|
|
|
996
988
|
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
989
|
|
|
998
|
-
Distinct from `memory-decision` — memory captures
|
|
990
|
+
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
991
|
|
|
1000
992
|
#### `capture`
|
|
1001
993
|
|
|
@@ -1003,49 +995,49 @@ Concise core-intent capture **before** research (capture-guardrails). Replaces t
|
|
|
1003
995
|
|
|
1004
996
|
```yaml
|
|
1005
997
|
type: capture
|
|
1006
|
-
kind:
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
example:
|
|
1025
|
-
|
|
1026
|
-
user_story:
|
|
1027
|
-
|
|
1028
|
-
situation:
|
|
1029
|
-
|
|
1030
|
-
capture_status:
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
promoted_to:
|
|
1038
|
-
|
|
1039
|
-
|
|
998
|
+
kind: # required, one of: idea | bug-fix | clip | reference | question | spec-import | feedback
|
|
999
|
+
# idea → speculative concept worth exploring (default — migrated entries land here)
|
|
1000
|
+
# bug-fix → defect observation paired with proposed fix
|
|
1001
|
+
# clip → web/document excerpt saved verbatim for later use
|
|
1002
|
+
# reference → a pointer to an external resource worth keeping
|
|
1003
|
+
# question → an open question to revisit when more context lands
|
|
1004
|
+
# spec-import→ an imported foreign doc (README / top-level project doc) landed as a RAW
|
|
1005
|
+
# capture by the bulk spec-import feature ([[HS-8V8T-8SBG-EPIC-first-connect-rough-import]]);
|
|
1006
|
+
# source doc in ## Source Material; carries source_repo/source_path for
|
|
1007
|
+
# (repo, vault) idempotency; stays RAW for manual triage. The
|
|
1008
|
+
# "pin → run feature pipeline" exit ([[HS-J7T5-VEW8-RES-import-specs-one-click-feature-pipeline]])
|
|
1009
|
+
# is a deferred follow-on — NOT wired in this wave.
|
|
1010
|
+
# feedback → app feedback / bug report / product idea / support question captured through
|
|
1011
|
+
# a deterministic (no-AI) intake channel ([[HS-KQEW-I5DV-EPIC-feedback-capture-type-deterministic]]);
|
|
1012
|
+
# classified by `routeFeedback()` ([[HS-FUII-EI9R-TASK-deterministic-feedback-router-module-no]]) toward diagnose/research/
|
|
1013
|
+
# answered, or stays `feedback` when unmatched. Optional structured fields below
|
|
1014
|
+
# (declared alongside `source:` further down this block — see `example`/
|
|
1015
|
+
# `user_story`/`situation`).
|
|
1016
|
+
example: # optional, string — a concrete example/repro illustrating the feedback (e.g. steps to reproduce a bug).
|
|
1017
|
+
# Only ever populated on `kind: feedback` captures; never forced, never required by the schema.
|
|
1018
|
+
user_story: # optional, string — "as a user, I want to… so that…" framing for a feedback-sourced product idea.
|
|
1019
|
+
# Same optionality as `example`.
|
|
1020
|
+
situation: # optional, string — the situational context the user was in when the feedback arose.
|
|
1021
|
+
# Same optionality as `example`.
|
|
1022
|
+
capture_status: # required, one of: raw | expanded — default raw
|
|
1023
|
+
# raw → no Core Idea content yet (single textarea / quick capture)
|
|
1024
|
+
# expanded → Core Idea / Concept / Details has been written (modal v3 or agent rewrite)
|
|
1025
|
+
# Flips raw → expanded automatically when an agent writes to core_idea,
|
|
1026
|
+
# concept, or agent_expansion via executeUpdateCapture (vendor/heyspex-mcp).
|
|
1027
|
+
# Console save-time linter force-corrects raw → expanded when `# Core Idea`
|
|
1028
|
+
# body has content. See [[HS-BDDT-Q1B7-EPIC-idea-capture-modal-v3-single-textbox-cle]].
|
|
1029
|
+
promoted_to: # binary: null (not promoted) or "[[HS-RES-<suffix>-<slug>]]" (promoted to research).
|
|
1030
|
+
# Records the FIRST research doc this capture was promoted into; not the full set.
|
|
1031
|
+
# For the M:N "every research doc this capture informs" view, see `informs_research:`.
|
|
1040
1032
|
informs_research: # optional, list of wikilinks to HS-RES-* — every research doc this capture informs (M:N).
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
source:
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
related:
|
|
1048
|
-
legacy_idea_id:
|
|
1033
|
+
# Reverse of `research.sources_captures:`. Distinct from `promoted_to:` (binary
|
|
1034
|
+
# first-promotion pointer); a capture may appear in multiple research docs over time.
|
|
1035
|
+
# Bidirectional consistency enforced by `scripts/validate-vault-ids.mjs`. See §Provenance edges.
|
|
1036
|
+
source: # optional capture channel (console, cli, companion, agent, …). On `kind: feedback` captures this
|
|
1037
|
+
# also doubles as the free-text originating-channel/page-context signal `routeFeedback()`
|
|
1038
|
+
# reads ([[HS-FUII-EI9R-TASK-deterministic-feedback-router-module-no]]) — still optional, never forced.
|
|
1039
|
+
related: # optional wikilinks
|
|
1040
|
+
legacy_idea_id: # optional, string — original HS-IDEA-* id for migrated entries (archaeology)
|
|
1049
1041
|
```
|
|
1050
1042
|
|
|
1051
1043
|
`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.
|
|
@@ -1060,62 +1052,62 @@ Research is **evergreen** per the lifecycle-class taxonomy above and the canonic
|
|
|
1060
1052
|
|
|
1061
1053
|
```yaml
|
|
1062
1054
|
type: research
|
|
1063
|
-
research_type:
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
scope:
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
enhances:
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1055
|
+
research_type: # REQUIRED, enum — the declared purpose of this research doc, set at creation
|
|
1056
|
+
# ([[HS-45YJ-120I-EPIC-research-type-field-the-declared-purpose]]). Coherent with the
|
|
1057
|
+
# capture `kind:` vocabulary (`idea | bug-fix | clip | reference | question`) one
|
|
1058
|
+
# level up the lifecycle, but not identical — research_type describes what the
|
|
1059
|
+
# research is FOR, not what kind of capture seeded it. Five values:
|
|
1060
|
+
# new-feature — grounds a not-yet-built capability or product surface
|
|
1061
|
+
# enhancement — improves or extends something already shipped
|
|
1062
|
+
# diagnose — investigates a bug, defect, or quality problem
|
|
1063
|
+
# code-audit — reviews existing code/architecture with no specific bug in hand
|
|
1064
|
+
# reference — captures external/background knowledge for reuse (the default)
|
|
1065
|
+
# Enforced by `schemas/heyspex-frontmatter.schema.json`. Missing on a pre-existing
|
|
1066
|
+
# doc is a WARNING during the grace window (`RESEARCH_TYPE_GRACE_END` in
|
|
1067
|
+
# `spex-console/src/lib/indexer/vault-rules.mjs`, mirroring `EPIC_PILLAR_GRACE_END`),
|
|
1068
|
+
# then a hard error. Deterministic kind→research_type suggestion is out of scope
|
|
1069
|
+
# here — owned by [[HS-6CFV-MVC1-EPIC-deterministic-type-assist-suggest-resear]].
|
|
1070
|
+
scope: # optional, enum — how broad a search context this research was run at:
|
|
1071
|
+
# internal — specs/, memories, ADRs only
|
|
1072
|
+
# codebase — the repo (console/, vendor/, scripts/, etc.)
|
|
1073
|
+
# external — web search
|
|
1074
|
+
# all — vault + codebase + web
|
|
1075
|
+
# Default "internal" when omitted. This is a CONSISTENCY fix, not a new
|
|
1076
|
+
# requirement — scope is NOT required and has no grace window
|
|
1077
|
+
# ([[HS-NGD1-TASK-consolidate-and-fix-the-research-scope-field]]). Written the
|
|
1078
|
+
# same way (same enum, same default) by `heyspex_save_research`,
|
|
1079
|
+
# `heyspex_promote_capture`, and `heyspex_complete_research`. Validated as a
|
|
1080
|
+
# string enum by `schemas/heyspex-frontmatter.schema.json` (distinct from the
|
|
1081
|
+
# unrelated freetext `scope:` on `type: protocol`).
|
|
1082
|
+
enhances: # REQUIRED when set — bidirectional consistency rule. If `enhances:` exists, the
|
|
1083
|
+
# target milestone MUST list this research in `informed_by:` (see §Provenance edges).
|
|
1084
|
+
# Single wikilink to the HS-MIL-* this research enhances. Not an array (M:1 rule).
|
|
1085
|
+
# Open research may omit during exploration; the validator enforces bidirectional
|
|
1086
|
+
# consistency whenever the field IS set. A research doc that spans multiple
|
|
1087
|
+
# milestones must be split first ([[HS-TQQS-GTH9-TASK-hs-split-research-mcp-tool]]).
|
|
1088
|
+
# NOTE: `scripts/validate-vault-ids.mjs` still gates on the legacy
|
|
1089
|
+
# `status: closed` framing — validator catch-up to this "when set" framing is on
|
|
1090
|
+
# the deferred list in [[research-is-evergreen]].
|
|
1099
1091
|
sources_captures: # optional, list of wikilinks to HS-CAP-* — captures this research aggregates (M:N).
|
|
1100
|
-
|
|
1101
|
-
spawned_epics:
|
|
1102
|
-
|
|
1103
|
-
enhances_epics:
|
|
1104
|
-
|
|
1092
|
+
# Reverse of `capture.informs_research:`. Bidirectional consistency enforced.
|
|
1093
|
+
spawned_epics: # optional, list of wikilinks to HS-EPIC-* — epics this research spawned (1:N).
|
|
1094
|
+
# Reverse of `epic.derived_from:`.
|
|
1095
|
+
enhances_epics: # optional, list of wikilinks to HS-EPIC-* — already-existing epics this research
|
|
1096
|
+
# augmented (M:N, rare). One-sided in v1 — no reverse field on epic.
|
|
1105
1097
|
produces_diagnose: # optional, list of wikilinks to HS-DIAG-* — bugs found during this research and
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
split_into:
|
|
1111
|
-
|
|
1112
|
-
split_from:
|
|
1113
|
-
|
|
1114
|
-
source_capture:
|
|
1115
|
-
|
|
1116
|
-
planning_flow:
|
|
1117
|
-
bound_epic:
|
|
1118
|
-
forked_from:
|
|
1098
|
+
# promoted to a diagnose (1:N, mirrors `spawned_epics`). Reverse of
|
|
1099
|
+
# `diagnose.derived_from:`. Written by `heyspex_promote_research_to_diagnose`
|
|
1100
|
+
# ([[HS-W5VP-MSHY-TASK-research-diagnose-link-send-bugs-to-the]]); reuses the existing
|
|
1101
|
+
# diagnose machinery — see [[resolution-diagnose-workflow]].
|
|
1102
|
+
split_into: # optional, list of wikilinks — on the original (archive) research when split;
|
|
1103
|
+
# names the child research docs that carry forward.
|
|
1104
|
+
split_from: # optional, single wikilink — on a research created by splitting from an ancestor;
|
|
1105
|
+
# mirror of `split_into:` on the ancestor.
|
|
1106
|
+
source_capture: # optional wikilink to HS-CAP-* — legacy single-capture seed pointer; retained for
|
|
1107
|
+
# read-side back-compat. New research uses `sources_captures:` (M:N) as canonical.
|
|
1108
|
+
planning_flow: # optional until flow filed; then wikilink to HS-FLOW-*
|
|
1109
|
+
bound_epic: # optional; set when epic filed — locks findings to append-only ([[planning-flow-research-epic-lifecycle]])
|
|
1110
|
+
forked_from: # optional, wikilink — source HS-RES when forked for a new epic
|
|
1119
1111
|
```
|
|
1120
1112
|
|
|
1121
1113
|
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.
|
|
@@ -1124,9 +1116,9 @@ Body is the research note. After `bound_epic:` is set, findings sections are app
|
|
|
1124
1116
|
|
|
1125
1117
|
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
1118
|
|
|
1127
|
-
| Finding
|
|
1128
|
-
|
|
|
1129
|
-
| One-line description of what was found | freetext (e.g. high/med/low) | `diagnose` \| `task` \| `reference` | `open` \| `closed`
|
|
1119
|
+
| Finding | Severity | Action (diagnose\|task\|reference) | Exit (open\|closed) |
|
|
1120
|
+
| --- | --- | --- | --- |
|
|
1121
|
+
| One-line description of what was found | freetext (e.g. high/med/low) | `diagnose` \| `task` \| `reference` | `open` \| `closed` |
|
|
1130
1122
|
|
|
1131
1123
|
Every row's `Action` maps to exactly one of three defined exits — no fourth "just leave it" option:
|
|
1132
1124
|
|
|
@@ -1145,19 +1137,19 @@ Orchestration artifact for epic filing (planning-flow-research-epic-lifecycle).
|
|
|
1145
1137
|
|
|
1146
1138
|
```yaml
|
|
1147
1139
|
type: planning-flow
|
|
1148
|
-
research:
|
|
1149
|
-
decisions:
|
|
1150
|
-
epic:
|
|
1151
|
-
has_diagram:
|
|
1152
|
-
related:
|
|
1140
|
+
research: # required, wikilink to HS-RES-*
|
|
1141
|
+
decisions: # optional, list of wikilinks — memory-decision or adr
|
|
1142
|
+
epic: # optional until epic filed; then wikilink to HS-EPIC-*
|
|
1143
|
+
has_diagram: # required, true — indexes canvas bridge + Shipped gallery when closed
|
|
1144
|
+
related: # optional, wikilinks to tasks and supporting specs
|
|
1153
1145
|
```
|
|
1154
1146
|
|
|
1155
1147
|
#### `roadmap`
|
|
1156
1148
|
|
|
1157
1149
|
```yaml
|
|
1158
1150
|
type: roadmap
|
|
1159
|
-
roadmap_manifest:
|
|
1160
|
-
related_roadmaps:
|
|
1151
|
+
roadmap_manifest: # required, machine-readable phase index (see below)
|
|
1152
|
+
related_roadmaps: # optional, wikilinks to other HS-ROADMAP-* specs
|
|
1161
1153
|
```
|
|
1162
1154
|
|
|
1163
1155
|
`roadmap_manifest` shape (indexer validates; agents request via `--compact`):
|
|
@@ -1166,12 +1158,12 @@ related_roadmaps: # optional, wikilinks to other HS-ROADMAP-* specs
|
|
|
1166
1158
|
roadmap_manifest:
|
|
1167
1159
|
version: 1
|
|
1168
1160
|
phases:
|
|
1169
|
-
- id: M2
|
|
1161
|
+
- id: M2 # short stable id
|
|
1170
1162
|
name: Indexer MVP
|
|
1171
|
-
tasks: [HS-V3YS, HS-1BML]
|
|
1172
|
-
horizon:
|
|
1163
|
+
tasks: [HS-V3YS, HS-1BML] # HS-NNNN or HS-EPIC-NNNN ids
|
|
1164
|
+
horizon: # may not ship — priority-4 / tag:horizon backlog
|
|
1173
1165
|
- HS-WYHZ
|
|
1174
|
-
initiatives:
|
|
1166
|
+
initiatives: # optional links to other roadmap docs
|
|
1175
1167
|
- HS-ROADMAP-VOICE-CHROME
|
|
1176
1168
|
```
|
|
1177
1169
|
|
|
@@ -1183,44 +1175,44 @@ Horizon items use native `HS-NNNN` ids (or wikilinks to `future-considerations/`
|
|
|
1183
1175
|
|
|
1184
1176
|
```yaml
|
|
1185
1177
|
type: draft
|
|
1186
|
-
source:
|
|
1187
|
-
captured_at:
|
|
1178
|
+
source: # optional, where this draft came from (URL, "phone capture", "screenshot", etc.)
|
|
1179
|
+
captured_at: # required, ISO-8601 datetime
|
|
1188
1180
|
source_intent_hash: # optional but required on Agent ingest; SHA-256 of canonical capture blob ([[plan-ingest-review-roadmap-workflow]])
|
|
1189
|
-
source_intent:
|
|
1181
|
+
source_intent: # optional verbatim excerpt (≤2 KB) of human inputs at capture time
|
|
1190
1182
|
agent_output_hash: # optional; SHA-256 of structured Agent preview at Save-to-drafts
|
|
1191
|
-
review_stage:
|
|
1183
|
+
review_stage: # optional, enum: inbox | deliberating | staging | review | promoted | rejected
|
|
1192
1184
|
council_requested: # optional bool | null — per-submit override; null = apply deliberation.triggers policy ([[council-opt-in-pre-review-conditioning]])
|
|
1193
|
-
triage_record:
|
|
1185
|
+
triage_record: # optional; scout pre-pass ([[council-triage-scout-optional-llm]], [[review-inbox-workshop-scout-overview]])
|
|
1194
1186
|
deliberation_record: # optional; Gate 0 output ([[ai-deliberation-gate]]) — append-only runs
|
|
1195
|
-
suggestions:
|
|
1196
|
-
review_record:
|
|
1197
|
-
ingest_mode:
|
|
1198
|
-
capture_scope:
|
|
1199
|
-
purpose:
|
|
1200
|
-
context_blocks:
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
llm_route:
|
|
1204
|
-
|
|
1187
|
+
suggestions: # optional; staged Gate A records ([[HS-EU98-GCGE-TASK-staged-draft-suggestion-schema]]) — omit when empty
|
|
1188
|
+
review_record: # optional; Gate A commit audit — who/when/per-suggestion outcomes
|
|
1189
|
+
ingest_mode: # optional, enum: manual | agent_llm — default manual when omitted
|
|
1190
|
+
capture_scope: # optional, enum: selection | full — did a highlight scope the body? (HS-M54O); absent ⇒ full
|
|
1191
|
+
purpose: # optional free string — the user's stated "why" for capturing (HS-7S40)
|
|
1192
|
+
context_blocks: # optional list of { source: typed | voice, text, at: ISO-8601 } — enrichment
|
|
1193
|
+
# added on the intent card (HS-JQ7O/0077), each bound to this draft's trace_id.
|
|
1194
|
+
# Append-only within a trace_id; ordered by `at`. Absent ⇒ no extra context.
|
|
1195
|
+
llm_route: # optional, required when ingest_mode is agent_llm — builder-selected route from console picker:
|
|
1196
|
+
# chatgpt | gemini | claude | auto | ... (enum grows with integrations; must stay in sync with UI labels)
|
|
1205
1197
|
llm_resolved_at: # optional, ISO-8601 datetime when ingest_mode agent_llm — when the routed model finished
|
|
1206
|
-
resolved_model:
|
|
1207
|
-
submission_kind:
|
|
1208
|
-
capture_channel:
|
|
1198
|
+
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)
|
|
1199
|
+
submission_kind: # optional, enum: external_media | refined_intent — Gate 0 epistemic mode ([[companion-external-media-vs-refined-intent-council]]); companion defaults external_media
|
|
1200
|
+
capture_channel: # optional, enum: manual_ui | cli | voice | extension | companion | ...
|
|
1209
1201
|
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:
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1202
|
+
capture_group_id: # optional string — shared id linking multiple captures made in one multi-capture
|
|
1203
|
+
# companion session; drafts sharing this id render as a connected set on the
|
|
1204
|
+
# Captures surface, ordered by capture_group_seq. Distinct from capture_bundle_id
|
|
1205
|
+
# below (one composite draft with multiple sources) — this links multiple SEPARATE
|
|
1206
|
+
# draft files. Omit for standalone single captures.
|
|
1215
1207
|
capture_group_seq: # optional positive integer — 1-based position within capture_group_id's group.
|
|
1216
|
-
|
|
1208
|
+
# Only meaningful when capture_group_id is set.
|
|
1217
1209
|
capture_bundle_id: # optional UUID — companion-local bundle id when submitted from Capture inbox ([[companion-capture-inbox-and-bundles]])
|
|
1218
|
-
source_set:
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
wake_used:
|
|
1223
|
-
foreground_app:
|
|
1210
|
+
source_set: # optional — multi-source bundle; list of members, each with { url | file_path, title, member_trace_id, member_note, file_size?, file_type? }
|
|
1211
|
+
# For web captures: url (required), title, member_trace_id, member_note ([[HS-D1YU-OVFO-TASK-bundle-submit-composite-draft-source-set]])
|
|
1212
|
+
# 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]])
|
|
1213
|
+
# Omit for single-source captures
|
|
1214
|
+
wake_used: # optional bool — companion wake phrase invoked (vs shortcut-only capture)
|
|
1215
|
+
foreground_app: # optional string — OS-visible focused app title/name at capture time
|
|
1224
1216
|
spoken_command_tail: # optional sanitized transcript excerpt when capture_channel includes voice (see [[uc-voice-ingest-hey-spex]])
|
|
1225
1217
|
shortcut_binding_id: # optional stable identifier for whichever hotkey initiated capture
|
|
1226
1218
|
voice_companion_semver: # optional — installed companion semantic version emitting the draft
|
|
@@ -1237,15 +1229,15 @@ chrome_viewport_ratio_y:
|
|
|
1237
1229
|
pointer_dom_hint: # optional heuristic from Chrome elementFromPoint; non-authoritative
|
|
1238
1230
|
|
|
1239
1231
|
# File capture provenance (when source_type: local_file) — [[HS-5FI0-0036-EPIC-file-system-selection-voice-capture]]
|
|
1240
|
-
source_type:
|
|
1241
|
-
file_path:
|
|
1242
|
-
file_size:
|
|
1243
|
-
file_type:
|
|
1232
|
+
source_type: # optional enum: local_file | url — discriminator; url is default/implicit for browser captures
|
|
1233
|
+
file_path: # optional string — absolute path (single file or root folder); present when source_type: local_file
|
|
1234
|
+
file_size: # optional int — file size in bytes
|
|
1235
|
+
file_type: # optional string — MIME type or file extension
|
|
1244
1236
|
file_modified_at: # optional ISO-8601 — file mtime at capture
|
|
1245
|
-
folder_depth:
|
|
1237
|
+
folder_depth: # optional int — recursion depth when folder captured
|
|
1246
1238
|
folder_file_count: # optional int — total files in folder/zip capture
|
|
1247
|
-
zip_extracted:
|
|
1248
|
-
zip_source_path:
|
|
1239
|
+
zip_extracted: # optional bool — true if zip was extracted to temp for ingestion
|
|
1240
|
+
zip_source_path: # optional string — original zip path when zip_extracted: true
|
|
1249
1241
|
sensitive_files_included: # optional list of { path, pattern_matched, user_confirmed_at } — audit when user overrode sensitive file warning
|
|
1250
1242
|
```
|
|
1251
1243
|
|
|
@@ -1256,6 +1248,7 @@ Agent-assisted drafts **should** end the markdown body with a short human-readab
|
|
|
1256
1248
|
Example footer (console-rendered; values must mirror frontmatter):
|
|
1257
1249
|
|
|
1258
1250
|
```markdown
|
|
1251
|
+
|
|
1259
1252
|
---
|
|
1260
1253
|
|
|
1261
1254
|
_Ingest provenance:_ route `claude` → resolved `anthropic/claude-3-7-sonnet` · _Captured:_ 2026-05-16T12:00:00Z
|
|
@@ -1334,10 +1327,10 @@ triage_record:
|
|
|
1334
1327
|
suggestions:
|
|
1335
1328
|
- id: "<stable-uuid-within-draft>"
|
|
1336
1329
|
kind: roadmap | priority | child_task | consideration
|
|
1337
|
-
payload: {}
|
|
1330
|
+
payload: {} # kind-specific proposed fields (epic stub, priority, etc.)
|
|
1338
1331
|
rationale: "<one line>"
|
|
1339
1332
|
disposition: pending | accepted | edited | declined
|
|
1340
|
-
edited_payload: {}
|
|
1333
|
+
edited_payload: {} # optional; present when disposition: edited
|
|
1341
1334
|
provenance:
|
|
1342
1335
|
llm_route: "<enum>"
|
|
1343
1336
|
resolved_model: "<provider/model>"
|
|
@@ -1360,7 +1353,7 @@ review_record:
|
|
|
1360
1353
|
|
|
1361
1354
|
```yaml
|
|
1362
1355
|
type: daily
|
|
1363
|
-
date:
|
|
1356
|
+
date: # required, ISO-8601 date
|
|
1364
1357
|
```
|
|
1365
1358
|
|
|
1366
1359
|
Body is free-form notes for the day.
|
|
@@ -1378,9 +1371,9 @@ Beyond the type-specific required sections noted above, all specs follow these s
|
|
|
1378
1371
|
|
|
1379
1372
|
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
1373
|
|
|
1381
|
-
| Section
|
|
1382
|
-
|
|
1383
|
-
| `## Session Boundaries`
|
|
1374
|
+
| Section | Protocol | Use when | Placement |
|
|
1375
|
+
|---|---|---|---|
|
|
1376
|
+
| `## 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
1377
|
| `## 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
1378
|
|
|
1386
1379
|
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).
|
|
@@ -1389,13 +1382,13 @@ Both are **recommended** — opt-in per spec, not enforced by the wikilink valid
|
|
|
1389
1382
|
|
|
1390
1383
|
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
1384
|
|
|
1392
|
-
| Type
|
|
1393
|
-
|
|
|
1394
|
-
| **Blocks**
|
|
1395
|
-
| **Related**
|
|
1396
|
-
| **Parent-child**
|
|
1397
|
-
| **Discovered-from** | `discovered_from: [[...]]` | `discovered:` (list)
|
|
1398
|
-
| **Iterates-on**
|
|
1385
|
+
| Type | Frontmatter field | Inverse field | Semantics |
|
|
1386
|
+
| --- | --- | --- | --- |
|
|
1387
|
+
| **Blocks** | `blocks: [[...]]` | `blocked_by: [[...]]` | Hard. A blocked task is not ready until all `blocked_by` resolve. |
|
|
1388
|
+
| **Related** | `related: [[...]]` | `related:` (symmetric) | Soft. Navigational only; no readiness implication. |
|
|
1389
|
+
| **Parent-child** | `children: [[...]]` | `parent: [[...]]` | Hierarchical. Children roll up to parent for "completion of parent" calculations. |
|
|
1390
|
+
| **Discovered-from** | `discovered_from: [[...]]` | `discovered:` (list) | Provenance. "This task was born while working on X." |
|
|
1391
|
+
| **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
1392
|
|
|
1400
1393
|
Rules:
|
|
1401
1394
|
|
|
@@ -1409,13 +1402,13 @@ Rules:
|
|
|
1409
1402
|
|
|
1410
1403
|
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
1404
|
|
|
1412
|
-
| Edge
|
|
1413
|
-
|
|
|
1414
|
-
| **Capture → Research**
|
|
1415
|
-
| **Research → Milestone**
|
|
1416
|
-
| **Research → Epic (spawned)**
|
|
1417
|
-
| **Research → Epic (augmented)**
|
|
1418
|
-
| **Research → Diagnose (bug found)** | 1:N
|
|
1405
|
+
| Edge | Cardinality | Forward field | Reverse field |
|
|
1406
|
+
| --- | --- | --- | --- |
|
|
1407
|
+
| **Capture → Research** | M:N | `capture.informs_research: [[[HS-RES-…]]]` | `research.sources_captures: [[[HS-CAP-…]]]` |
|
|
1408
|
+
| **Research → Milestone** | **M:1** (strict) | `research.enhances: [[HS-MIL-…]]` (single, not array) | `milestone.informed_by: [[[HS-RES-…]]]` |
|
|
1409
|
+
| **Research → Epic (spawned)** | 1:N | `research.spawned_epics: [[[HS-EPIC-…]]]` | `epic.derived_from: [[HS-RES-…]]` (single) |
|
|
1410
|
+
| **Research → Epic (augmented)** | M:N | `research.enhances_epics: [[[HS-EPIC-…]]]` | (one-sided — no reverse field on epic in v1) |
|
|
1411
|
+
| **Research → Diagnose (bug found)** | 1:N | `research.produces_diagnose: [[[HS-DIAG-…]]]` | `diagnose.derived_from: [[HS-RES-…]]` (single) |
|
|
1419
1412
|
|
|
1420
1413
|
Rules:
|
|
1421
1414
|
|
|
@@ -1424,37 +1417,37 @@ Rules:
|
|
|
1424
1417
|
- **`enhances:` is single-valued.** Not an array — the validator rejects array form and points the author at the split flow.
|
|
1425
1418
|
- **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
1419
|
- **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
|
|
1420
|
+
- **`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
1421
|
- **`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
1422
|
|
|
1430
1423
|
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
1424
|
|
|
1432
1425
|
## Iteration lineage (round-to-round re-attempts)
|
|
1433
1426
|
|
|
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:
|
|
1427
|
+
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
1428
|
|
|
1436
1429
|
### Fields
|
|
1437
1430
|
|
|
1438
1431
|
```yaml
|
|
1439
|
-
iterates_on:
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1432
|
+
iterates_on: # optional, YAML list of wikilinks — lives ONLY on the NEWER doc (one-edit-on-source,
|
|
1433
|
+
# same principle as amends). Semantics: "this initiative re-attempts an outcome the
|
|
1434
|
+
# target initiative shipped but did not fully deliver." Typically carried by the
|
|
1435
|
+
# round-2 research doc pointing at the round-1 research doc — the research chain is
|
|
1436
|
+
# the spine (research is evergreen, so the root research id is the durable handle
|
|
1437
|
+
# spanning every round; no new entity type).
|
|
1445
1438
|
# iteratedBy — COMPUTED reverse map (indexer/validator output, like amendedBy) — never written
|
|
1446
|
-
# by hand into frontmatter.
|
|
1447
|
-
outcome:
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
outcome_note:
|
|
1439
|
+
# by hand into frontmatter.
|
|
1440
|
+
outcome: # optional, on TRACKABLE docs only, set by the HUMAN REVIEWER at close — never
|
|
1441
|
+
# inferred, never agent-set. Enum: met | partially-met | not-met. Lives ONLY on
|
|
1442
|
+
# the closed doc (not echoed onto the round-2 doc; discovery goes through the
|
|
1443
|
+
# iteratedBy reverse map).
|
|
1444
|
+
outcome_note: # optional, one-line reviewer prose qualifying the verdict.
|
|
1452
1445
|
```
|
|
1453
1446
|
|
|
1454
1447
|
### Invariants
|
|
1455
1448
|
|
|
1456
1449
|
- **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.
|
|
1450
|
+
- **`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
1451
|
- **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
1452
|
|
|
1460
1453
|
### Required `## Related / lineage` section on promoted docs
|
|
@@ -1464,11 +1457,11 @@ Every promoted doc's outline ends with a resolved-wikilink table (immediately be
|
|
|
1464
1457
|
```markdown
|
|
1465
1458
|
## Related / lineage
|
|
1466
1459
|
|
|
1467
|
-
| Doc
|
|
1468
|
-
|
|
1469
|
-
| [[round-1-research]] | Iterates on
|
|
1470
|
-
| [[HS-REV-...]]
|
|
1471
|
-
| [[HS-CAP-...]]
|
|
1460
|
+
| Doc | Role |
|
|
1461
|
+
|---|---|
|
|
1462
|
+
| [[round-1-research]] | Iterates on |
|
|
1463
|
+
| [[HS-REV-...]] | Prior attempt's review |
|
|
1464
|
+
| [[HS-CAP-...]] | Feedback capture |
|
|
1472
1465
|
```
|
|
1473
1466
|
|
|
1474
1467
|
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").
|
|
@@ -1482,23 +1475,23 @@ Role vocabulary: **Iterates on · Prior attempt's review · Feedback capture ·
|
|
|
1482
1475
|
|
|
1483
1476
|
```yaml
|
|
1484
1477
|
evidence:
|
|
1485
|
-
- type: commit
|
|
1486
|
-
ref: "abc123"
|
|
1487
|
-
line: 42
|
|
1488
|
-
description: "..."
|
|
1478
|
+
- type: commit # required — one of the evidence types below
|
|
1479
|
+
ref: "abc123" # required — the reference, format per type
|
|
1480
|
+
line: 42 # optional — line number (file/diff only)
|
|
1481
|
+
description: "..." # optional — what this evidence shows
|
|
1489
1482
|
```
|
|
1490
1483
|
|
|
1491
1484
|
Evidence types:
|
|
1492
1485
|
|
|
1493
|
-
| Type
|
|
1494
|
-
|
|
|
1495
|
-
| `commit` | short or full SHA
|
|
1496
|
-
| `file`
|
|
1497
|
-
| `pr`
|
|
1498
|
-
| `diff`
|
|
1499
|
-
| `issue`
|
|
1500
|
-
| `note`
|
|
1501
|
-
| `test`
|
|
1486
|
+
| Type | `ref` format | Example |
|
|
1487
|
+
| --- | --- | --- |
|
|
1488
|
+
| `commit` | short or full SHA | `abc123`, `abc123def…` |
|
|
1489
|
+
| `file` | repo-relative path, optional `:line` | `src/foo.ts`, `src/foo.ts:42` |
|
|
1490
|
+
| `pr` | PR number | `#123` |
|
|
1491
|
+
| `diff` | `commit:path` | `abc123:src/pages/dashboard.tsx` |
|
|
1492
|
+
| `issue` | issue number | `#42` |
|
|
1493
|
+
| `note` | freeform text | `Builder confirmed via Slack 2026-05-15` |
|
|
1494
|
+
| `test` | test/gate identifier | `vitest:src/lib/continuity/plan-vs-actual.test.ts`, `tsc:noEmit` |
|
|
1502
1495
|
|
|
1503
1496
|
> [!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
1497
|
|
|
@@ -1516,19 +1509,19 @@ The indexer harvests inline shorthand and the frontmatter `evidence:` array into
|
|
|
1516
1509
|
## Delivery snapshot
|
|
1517
1510
|
|
|
1518
1511
|
> [!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
|
|
1512
|
+
> 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
1513
|
|
|
1521
1514
|
`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
1515
|
|
|
1523
1516
|
```yaml
|
|
1524
1517
|
delivery:
|
|
1525
|
-
snapshot_at: 2026-05-21T07:00:00-05:00
|
|
1518
|
+
snapshot_at: 2026-05-21T07:00:00-05:00 # ISO timestamp of when the snapshot was taken
|
|
1526
1519
|
commits:
|
|
1527
|
-
- sha: 8648ad5e3f...
|
|
1528
|
-
short_sha: 8648ad5
|
|
1529
|
-
branch: hs-mvp0520
|
|
1530
|
-
pushed: true
|
|
1531
|
-
at: 2026-05-21T05:14:32-05:00
|
|
1520
|
+
- sha: 8648ad5e3f... # full SHA
|
|
1521
|
+
short_sha: 8648ad5 # 7-char SHA
|
|
1522
|
+
branch: hs-mvp0520 # primary branch (local before remote)
|
|
1523
|
+
pushed: true # boolean — reachable from origin/*
|
|
1524
|
+
at: 2026-05-21T05:14:32-05:00 # commit author time
|
|
1532
1525
|
author: pwher
|
|
1533
1526
|
message: "feat(console): per-spec delivery dropdown on On Deck child rows"
|
|
1534
1527
|
```
|
|
@@ -1576,7 +1569,7 @@ The following keys are reserved by HeySpex and must not be repurposed:
|
|
|
1576
1569
|
- `evidence` (cross-type; see [Evidence linking](#evidence-linking))
|
|
1577
1570
|
- `delivery` (cross-type; user-persisted git-log snapshot — see [Delivery snapshot](#delivery-snapshot))
|
|
1578
1571
|
- `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
|
|
1572
|
+
- 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
1573
|
- `reviews` (review type — back-compat alias for `parent:` pointing at the spec under review)
|
|
1581
1574
|
|
|
1582
1575
|
Adding a new universal reserved key requires an ADR.
|
|
@@ -1611,7 +1604,7 @@ created: 2026-05-14
|
|
|
1611
1604
|
updated: 2026-05-14
|
|
1612
1605
|
kind: bug
|
|
1613
1606
|
blocked_by:
|
|
1614
|
-
- "[[HS-IS1A-TASK-
|
|
1607
|
+
- "[[HS-IS1A-TASK-SpexConsole-routing-rewrite]]"
|
|
1615
1608
|
related:
|
|
1616
1609
|
- "[[HS-582Q-TASK-arrow-key-conflicts]]"
|
|
1617
1610
|
tags: [console, ux, keyboard]
|
|
@@ -1629,9 +1622,9 @@ Arrow keys do not move focus between issues in the list view; only Tab works. Co
|
|
|
1629
1622
|
|
|
1630
1623
|
## Change log
|
|
1631
1624
|
|
|
1632
|
-
| Date
|
|
1633
|
-
|
|
|
1634
|
-
| 2026-05-14 | pwher
|
|
1625
|
+
| Date | Author | Change |
|
|
1626
|
+
| --- | --- | --- |
|
|
1627
|
+
| 2026-05-14 | pwher | Created from drafts/triage. |
|
|
1635
1628
|
```
|
|
1636
1629
|
|
|
1637
1630
|
### Memory lesson
|
|
@@ -1666,9 +1659,9 @@ At session start, run `Get-Process bd | Sort WorkingSet -Desc` on Windows and ki
|
|
|
1666
1659
|
|
|
1667
1660
|
## Change log
|
|
1668
1661
|
|
|
1669
|
-
| Date
|
|
1670
|
-
|
|
|
1671
|
-
| 2026-05-14 | pwher
|
|
1662
|
+
| Date | Author | Change |
|
|
1663
|
+
| --- | --- | --- |
|
|
1664
|
+
| 2026-05-14 | pwher | Migrated from bd memory `lessons/bd-process-leak`. |
|
|
1672
1665
|
```
|
|
1673
1666
|
|
|
1674
1667
|
## Open questions
|
|
@@ -1701,35 +1694,35 @@ These are intentionally left for the Builder's confirmation in Phase 5 (migratio
|
|
|
1701
1694
|
|
|
1702
1695
|
## Change log
|
|
1703
1696
|
|
|
1704
|
-
| Date
|
|
1705
|
-
|
|
|
1706
|
-
| 2026-05-14 | pwher (with claude opus 4.7)
|
|
1707
|
-
| 2026-05-16 | pwher
|
|
1708
|
-
| 2026-05-16 | pwher (with claude opus 4.7)
|
|
1709
|
-
| 2026-05-17 | pwher
|
|
1710
|
-
| 2026-05-17 | pwher
|
|
1711
|
-
| 2026-05-17 | pwher
|
|
1712
|
-
| 2026-05-17 | pwher
|
|
1713
|
-
| 2026-05-17 | pwher
|
|
1714
|
-
| 2026-05-17 | pwher
|
|
1715
|
-
| 2026-05-18 | pwher (with claude opus 4.5)
|
|
1716
|
-
| 2026-05-20 | pwher
|
|
1717
|
-
| 2026-05-20 | pwher
|
|
1718
|
-
| 2026-05-20 | pwher
|
|
1719
|
-
| 2026-05-21 | pwher
|
|
1720
|
-
| 2026-05-22 | pwher + Claude Opus 4.7 (1M)
|
|
1721
|
-
| 2026-05-22 | pwher + Claude Opus 4.7 (1M)
|
|
1722
|
-
| 2026-05-24 | Claude Opus 4.7 (1M)
|
|
1723
|
-
| 2026-05-25 | pwher (with Claude Opus 4.7)
|
|
1724
|
-
| 2026-05-29 | pwher (with Claude Opus 4.8 [1m])
|
|
1725
|
-
| 2026-05-26 | pwher (with Claude Opus 4.7)
|
|
1726
|
-
| 2026-05-29 | pwher (with Claude Opus 4.7 [1m])
|
|
1727
|
-
| 2026-05-31 | pwher (with claude opus 4.7)
|
|
1728
|
-
| 2026-06-03 | claude opus 4.7 [1m] · session `local` (with pwher)
|
|
1729
|
-
| 2026-06-03 | claude opus 4.7 [1m] · session `local` (with pwher)
|
|
1730
|
-
| 2026-06-13 | claude opus 4.8 [1m] · session `local` (with pwher)
|
|
1731
|
-
| 2026-06-23 | Cursor · session `local`
|
|
1732
|
-
| 2026-06-23 | Cursor · session `local`
|
|
1733
|
-
| 2026-07-05 | Claude Sonnet 5 [1m] · session `local` (with pwher)
|
|
1734
|
-
| 2026-07-05 | Claude Sonnet 5 [1m] · session `local` (with pwher)
|
|
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.
|
|
1697
|
+
| Date | Author | Change |
|
|
1698
|
+
| --- | --- | --- |
|
|
1699
|
+
| 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. |
|
|
1700
|
+
| 2026-05-16 | pwher | §`draft`: companion/voice + optional spatial cursor/click hints (uc-voice-ingest-hey-spex §Spatial pointers). |
|
|
1701
|
+
| 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. |
|
|
1702
|
+
| 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. |
|
|
1703
|
+
| 2026-05-17 | pwher | Draft `deliberation_record` (ai-deliberation-gate); task `close_reason` enum + `superseded_by`; archive = filter not folder. |
|
|
1704
|
+
| 2026-05-17 | pwher | Draft `suggestions:` + `review_record:` per HS-EU98-GCGE-TASK-staged-draft-suggestion-schema; omit-when-empty rule. |
|
|
1705
|
+
| 2026-05-17 | pwher | `submission_kind`, `companion_dialogue[]`; companion `capture_channel` per companion-external-media-vs-refined-intent-council. |
|
|
1706
|
+
| 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). |
|
|
1707
|
+
| 2026-05-17 | pwher | `triage_record` scout schema for Review inbox workshop (review-inbox-workshop-scout-overview). |
|
|
1708
|
+
| 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). |
|
|
1709
|
+
| 2026-05-20 | pwher | `canvases/diagrams/` + `canvases/as-built/` for spec diagram dual-surface (spec-diagram-design-vs-as-built-canvas). |
|
|
1710
|
+
| 2026-05-20 | pwher | Added `specs/canvases/` for JSON Canvas design files per adr-0013-canvas-vault-format-and-obsidian-interop. |
|
|
1711
|
+
| 2026-05-20 | pwher | Task/epic ID formats: random alphanumeric suffix for new specs (vault-id-assignment-protocol); legacy `HS-NNNN` migration IDs retained. |
|
|
1712
|
+
| 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). |
|
|
1713
|
+
| 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. |
|
|
1714
|
+
| 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. |
|
|
1715
|
+
| 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). |
|
|
1716
|
+
| 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. |
|
|
1717
|
+
| 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. |
|
|
1718
|
+
| 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). |
|
|
1719
|
+
| 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. |
|
|
1720
|
+
| 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. |
|
|
1721
|
+
| 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). |
|
|
1722
|
+
| 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. |
|
|
1723
|
+
| 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. |
|
|
1724
|
+
| 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. |
|
|
1725
|
+
| 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. |
|
|
1726
|
+
| 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. |
|
|
1727
|
+
| 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. |
|
|
1728
|
+
| 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. |
|