heyspex 0.1.0 → 0.2.1
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/.claude-plugin/marketplace.json +14 -0
- package/README.md +21 -0
- package/bin/hs.mjs +1089 -104
- 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 +1127 -103
- package/dist/cli/hs-claim.mjs +981 -63
- package/dist/cli/hs-connect.mjs +10059 -1729
- package/dist/cli/hs-defer.mjs +5507 -3072
- package/dist/cli/hs-dev.mjs +576 -0
- package/dist/cli/hs-env.mjs +416 -302
- package/dist/cli/hs-index-rebuild.mjs +7334 -0
- package/dist/cli/hs-index-reconcile.mjs +8138 -0
- package/dist/cli/hs-init.mjs +2840 -149
- package/dist/cli/hs-install.mjs +7214 -594
- package/dist/cli/hs-join.mjs +10640 -2421
- package/dist/cli/hs-vault-pull.mjs +8157 -6370
- package/dist/cli/hs-vault-push.mjs +6433 -0
- package/dist/cli/hs-vault.mjs +4029 -1555
- package/dist/cli/hs-workspace.mjs +2702 -538
- 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 +30 -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 +28 -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 +33 -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 +32 -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/copilot-plugin-install.md +162 -0
- package/docs/driving-heyspex-from-copilot.md +165 -0
- package/docs/mcp-client-config.md +259 -6
- package/package.json +249 -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/README.md +309 -0
- package/plugins/heyspex/bin/launch-mcp.mjs +95 -0
- package/plugins/heyspex/bin/run-hook.mjs +80 -0
- package/plugins/heyspex/hooks/cursor-hooks.json +308 -0
- package/plugins/heyspex/hooks/hooks.json +418 -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 +456 -0
- package/scripts/claude-hooks/_intent-classifier-semantic.mjs +356 -0
- package/scripts/claude-hooks/_run.mjs +413 -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-execution-gate.mjs +51 -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 +577 -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/diagnose-capture-reminder.mjs +11 -0
- package/scripts/claude-hooks/directive-obligation-gate.mjs +11 -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 +86 -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 +279 -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 +451 -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/vault-mirror-catchup.mjs +11 -0
- package/scripts/claude-hooks/vault-write-tier-guard.mjs +11 -0
- package/scripts/claude-hooks/wip-checkpoint.mjs +302 -0
- package/scripts/cursor-hooks/manifest.mjs +281 -0
- package/scripts/dev-server-status.mjs +34 -13
- package/scripts/dev-server-stop.mjs +313 -0
- package/scripts/heyspex-mode.mjs +288 -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 +496 -0
- package/scripts/hs-worktree.mjs +201 -0
- package/scripts/install-claude-code-hooks.mjs +272 -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 +199 -61
- package/scripts/lib/customer-kit.mjs +1203 -0
- package/scripts/lib/dev-mode.mjs +249 -32
- package/scripts/lib/directive-obligations.mjs +349 -0
- package/scripts/lib/heyspex-home.mjs +72 -0
- package/scripts/lib/hook-dispositions.mjs +210 -0
- package/scripts/lib/hook-vault-header.mjs +30 -0
- package/scripts/lib/hs-command.mjs +277 -0
- package/scripts/lib/hs-companion-settings.mjs +472 -0
- package/scripts/lib/hs-source-branch.mjs +196 -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 +13 -22
- package/scripts/lib/hs-source-preflight.mjs +18 -4
- package/scripts/lib/hs-source-push.mjs +386 -307
- 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/lib/window-placement.mjs +109 -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 +449 -0
- package/spexharness/src/adapters/copilot.mjs +236 -0
- package/spexharness/src/adapters/detect-harness.mjs +34 -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/_shell-write-targets.mjs +77 -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 +275 -0
- package/spexharness/src/gates/diagnose-capture-reminder.mjs +112 -0
- package/spexharness/src/gates/directive-obligation-gate.decide.mjs +132 -0
- package/spexharness/src/gates/directive-obligation-gate.mjs +183 -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/gates/vault-mirror-catchup.mjs +124 -0
- package/spexharness/src/gates/vault-write-tier-guard.decide.mjs +125 -0
- package/spexharness/src/gates/vault-write-tier-guard.mjs +42 -0
- package/spexharness/src/git-reflog-audit.mjs +294 -0
- package/spexharness/src/intent-classifier.mjs +196 -0
- package/spexharness/src/intent-directive.mjs +626 -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 +849 -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 +96 -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 +77 -8
- package/vendor/heyspex-mcp/capture-channel.mjs +55 -5
- package/vendor/heyspex-mcp/capture-console-client.mjs +117 -3
- package/vendor/heyspex-mcp/capture-focus.mjs +1061 -31
- package/vendor/heyspex-mcp/capture-outbox.mjs +15 -5
- package/vendor/heyspex-mcp/capture-sources.mjs +195 -0
- package/vendor/heyspex-mcp/capture-tools.mjs +1264 -0
- package/vendor/heyspex-mcp/claim-tools.mjs +1147 -0
- package/vendor/heyspex-mcp/cli-verbs.mjs +2074 -0
- package/vendor/heyspex-mcp/cli.mjs +207 -15524
- package/vendor/heyspex-mcp/close-branch-report.mjs +102 -0
- package/vendor/heyspex-mcp/cloud-tool-surface.mjs +128 -0
- package/vendor/heyspex-mcp/cloud-vault-writes.mjs +602 -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 +822 -17
- package/vendor/heyspex-mcp/console-transport.mjs +172 -0
- package/vendor/heyspex-mcp/credentials.mjs +585 -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 +131 -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 +723 -0
- package/vendor/heyspex-mcp/fleet-handlers.mjs +37 -0
- package/vendor/heyspex-mcp/fleet-queue-tools.mjs +71 -15
- package/vendor/heyspex-mcp/focus-tools.mjs +190 -0
- package/vendor/heyspex-mcp/folder-trust-store.mjs +60 -0
- package/vendor/heyspex-mcp/http-transport.mjs +302 -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 +107 -0
- package/vendor/heyspex-mcp/memory-tools.mjs +523 -0
- package/vendor/heyspex-mcp/mvp-mode.mjs +53 -6
- package/vendor/heyspex-mcp/obligation-backstop.mjs +103 -0
- package/vendor/heyspex-mcp/occupied-keys.mjs +142 -0
- package/vendor/heyspex-mcp/on-deck-brief.mjs +3377 -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 +908 -22
- 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 +327 -0
- package/vendor/heyspex-mcp/procedure-tools.mjs +1181 -970
- package/vendor/heyspex-mcp/promote-capture.mjs +388 -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 +666 -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 +191 -15
- 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 +83 -0
- package/vendor/heyspex-mcp/research-focus.mjs +207 -4
- package/vendor/heyspex-mcp/research-handlers.mjs +625 -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/roadmap-default.mjs +70 -0
- 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 +109 -0
- package/vendor/heyspex-mcp/session-tools.mjs +162 -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 +453 -0
- package/vendor/heyspex-mcp/spec-id-lib.mjs +93 -17
- package/vendor/heyspex-mcp/split-research.mjs +304 -56
- package/vendor/heyspex-mcp/stdio-rpc.mjs +22 -0
- package/vendor/heyspex-mcp/submit-for-review.mjs +150 -7
- package/vendor/heyspex-mcp/summary-contract.mjs +105 -0
- package/vendor/heyspex-mcp/summary-write-tools.mjs +228 -0
- package/vendor/heyspex-mcp/symptom-query.mjs +146 -0
- package/vendor/heyspex-mcp/test-helpers.mjs +123 -1
- package/vendor/heyspex-mcp/tool-catalog.mjs +2819 -0
- package/vendor/heyspex-mcp/tool-dispatch.mjs +657 -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 +720 -0
- package/vendor/heyspex-mcp/vault-less-endpoints.mjs +52 -0
- package/vendor/heyspex-mcp/vault-resolve.mjs +554 -68
- package/vendor/heyspex-mcp/verify-reproduction.mjs +270 -30
- package/vendor/heyspex-mcp/whoami.mjs +92 -0
- package/vendor/heyspex-mcp/write-outbox.mjs +512 -0
|
@@ -5,11 +5,9 @@ type: protocol
|
|
|
5
5
|
status: draft
|
|
6
6
|
priority: 0
|
|
7
7
|
scope: vault
|
|
8
|
-
owner:
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
created: "2026-05-27"
|
|
12
|
-
updated: "2026-07-04"
|
|
8
|
+
owner: TODO — your name/handle
|
|
9
|
+
created: '2026-05-27'
|
|
10
|
+
updated: '2026-07-04'
|
|
13
11
|
tags:
|
|
14
12
|
- vault
|
|
15
13
|
- specs
|
|
@@ -26,26 +24,16 @@ triggers:
|
|
|
26
24
|
- protocol_edit
|
|
27
25
|
related:
|
|
28
26
|
- "[[entity-model]]"
|
|
29
|
-
- "
|
|
30
|
-
- "session-close-protocol"
|
|
27
|
+
- "[[session-close-protocol]]"
|
|
31
28
|
- "[[memory-protocol]]"
|
|
32
|
-
- "plan-ingest-agent-workflow"
|
|
33
|
-
- "plan-ingest-review-roadmap-workflow"
|
|
34
|
-
- "roadmap-protocol"
|
|
35
|
-
- "HS-VK7C-MILE-EPIC-milestone-entity-type-and-surfacing"
|
|
36
|
-
- "HS-1JC8-HMNJ-MIL-status-and-roadmap-surface-refactor"
|
|
37
|
-
- "HS-RM22-IART-MIL-console-ia-restructure"
|
|
38
|
-
- "HS-VLB8-VQZ8-EPIC-sharpen-alignment-gate-claim-target-clar"
|
|
39
|
-
- "HS-6A4P-MNBD-EPIC-milestone-needs-breakdown-awareness"
|
|
40
|
-
- "pre-execution-alignment-gate"
|
|
41
|
-
- "supersession-protocol"
|
|
42
29
|
summary: |
|
|
43
30
|
Governs the Milestone to Epic to Task hierarchy: filing rules, how acceptance criteria propagate and freeze, the Expected Breakage section, sequencing language constraints, and the change-log review seed close-out steps.
|
|
31
|
+
|
|
44
32
|
---
|
|
45
33
|
|
|
46
34
|
# Spec hierarchy protocol — Milestone → Epic → Task → child tasks
|
|
47
35
|
|
|
48
|
-
The **canonical hierarchy** of trackable work in HeySpex. Every piece of trackable work belongs at exactly one level of this hierarchy. Agents filing new work use this protocol to decide
|
|
36
|
+
The **canonical hierarchy** of trackable work in HeySpex. Every piece of trackable work belongs at exactly one level of this hierarchy. Agents filing new work use this protocol to decide *which level* a new spec belongs at, *what frontmatter* it needs, and *how much autonomy* they have at each level.
|
|
49
37
|
|
|
50
38
|
This protocol exists because the hierarchy was previously implicit — codified in example specs (`HS-HMNJ-MIL`, `HS-84HT-EPIC`) and partially in `entity-model.md`, but never written as a single authoritative procedure an agent can read. Pattern-matching off example files leads to drift; this doc is what agents read **before** filing a milestone, epic, or task.
|
|
51
39
|
|
|
@@ -53,36 +41,35 @@ The Milestone entity type itself is **in-flight**: HS-VK7C-MILE-EPIC-milestone-e
|
|
|
53
41
|
|
|
54
42
|
## The four levels
|
|
55
43
|
|
|
56
|
-
| Level
|
|
57
|
-
|
|
58
|
-
| **Milestone**
|
|
59
|
-
| **Epic**
|
|
60
|
-
| **Task**
|
|
61
|
-
| **Child task** | `specs/tasks/`
|
|
44
|
+
| Level | Folder | ID format | What it is | Status today |
|
|
45
|
+
|---|---|---|---|---|
|
|
46
|
+
| **Milestone** | `specs/milestones/` | `HS-MIL-<suffix>` | A coherent multi-epic ship. Closes when every child epic closes and the milestone's own acceptance gate is met. | Entity exists (4 filed); type formalization in HS-VK7C |
|
|
47
|
+
| **Epic** | `specs/epics/` | `HS-EPIC-<suffix>` | A bounded body of work, typically 1–10 tasks. Has one parent milestone (required after HS-OFR5) and N children tasks. | Stable |
|
|
48
|
+
| **Task** | `specs/tasks/` | `HS-TASK-<suffix>` | An atomic unit of agent-executable work. Has one parent epic. May or may not have child tasks (agent's call — see §Agent autonomy). | Stable |
|
|
49
|
+
| **Child task** | `specs/tasks/` | `HS-TASK-<suffix>` | A task with `parent:` pointing at another task (not an epic). Used when an agent fans out a task during execution. Same shape as a task; differentiated only by parent. | Stable |
|
|
62
50
|
|
|
63
51
|
Suffix format for all four: 4+ uppercase alphanumeric per vault-id-assignment-protocol. Legacy zero-padded epic IDs (`HS-0029-EPIC`) and 4-character mnemonic milestone IDs (`HS-HMNJ-MIL`) both remain valid.
|
|
64
52
|
|
|
65
53
|
**Shared-suffix families:** when a task is filed under an epic, it inherits the epic's 4-char suffix (e.g. epic `HS-D5YF-EPIC-…` → tasks `HS-TASK-D5YF-<slug>.md`). The slug keeps each filename unique; a bare `HS-TASK-<suffix>` alone is a **family token**, not a unique handle — wikilinks must use the full basename. Retroactive re-suffixing of existing tasks is out of scope. Full rules: vault-id-assignment-protocol §Shared-suffix families; decision: bare-hs-task-suffix-is-a-family-token-af.
|
|
66
54
|
|
|
67
|
-
## What each level is
|
|
55
|
+
## What each level is *for*
|
|
68
56
|
|
|
69
|
-
| If the work…
|
|
70
|
-
|
|
71
|
-
| Spans multiple epics, has its own acceptance gate, and represents a coherent ship
|
|
72
|
-
| Is a single bounded ship — one outcome, 1–10 tasks, one DoD
|
|
73
|
-
| Is one atomic unit of agent execution (under one context window, usually)
|
|
74
|
-
| Is sub-work discovered
|
|
75
|
-
| Is a **user-reported bug fix** — executable, but not planned roadmap work that belongs under an epic
|
|
57
|
+
| If the work… | …file it as |
|
|
58
|
+
|---|---|
|
|
59
|
+
| Spans multiple epics, has its own acceptance gate, and represents a coherent ship | Milestone |
|
|
60
|
+
| Is a single bounded ship — one outcome, 1–10 tasks, one DoD | Epic |
|
|
61
|
+
| Is one atomic unit of agent execution (under one context window, usually) | Task |
|
|
62
|
+
| Is sub-work discovered *during* a task that wasn't in the original task's scope but must complete before the parent task can close | Child task |
|
|
63
|
+
| Is a **user-reported bug fix** — executable, but not planned roadmap work that belongs under an epic | Diagnose (see §Diagnose below) |
|
|
76
64
|
|
|
77
65
|
**Anti-patterns** — these are not separate levels and should not be filed as such:
|
|
78
|
-
|
|
79
66
|
- A "phase" or "sprint" inside an epic → those are sections in the epic body or sub-tasks, not a new level.
|
|
80
67
|
- A "follow-up" that's discovered after a task closes → file as a new task under the same epic (not a child of the closed task).
|
|
81
68
|
- A "research" finding that needs implementation → research lives in `specs/research/`; the implementation work is filed as task(s) under an epic, with `discovered_from: [[<research>]]` linking back.
|
|
82
69
|
|
|
83
70
|
### Diagnose — the bug-fix lane (a sibling executable entity, outside the milestone→epic→task chain)
|
|
84
71
|
|
|
85
|
-
A **`diagnose`** (`specs/diagnoses/`, `HS-DIAG-<suffix>`) is a user-reported bug fix as first-class executable work. It is **not** a fifth level of the planning hierarchy — it sits
|
|
72
|
+
A **`diagnose`** (`specs/diagnoses/`, `HS-DIAG-<suffix>`) is a user-reported bug fix as first-class executable work. It is **not** a fifth level of the planning hierarchy — it sits *beside* it:
|
|
86
73
|
|
|
87
74
|
- **Standalone by default.** A diagnose needs **no** parent. It is explicitly **exempt** from the epic→milestone mandatory-parent rule. An optional `parent:` (an `HS-EPIC-*` **or** `HS-MIL-*`) groups related fixes when more organization helps — but absence is the normal, valid state (the same "top-level" allowance [[entity-model]] grants tasks, made intentional and typed).
|
|
88
75
|
- **Claimable like a task — while it is a ONE-FIX bug.** A one-fix diagnose is its own `ClaimTarget` (level `"task"`-equivalent — a leaf), and that is the common path. It is not the only one: a write-up whose own `## Fix` section lists **several separately-verifiable fixes** goes through the **breakdown stage** instead (`heyspex_promote_diagnose` — the same stage `heyspex_promote_research` uses, taking a bug write-up as its second input kind, HS-ALBV-BFIX-EPIC-breakdown-stage-accepts-a-diagnose). Grounding runs first (what open milestone/epic already covers this area?), then placement descends: a matching epic gets **tasks**, a matching milestone with no fitting epic gets **one new epic**, and only when neither exists is a milestone minted — that one asks the owner first. Every epic spawned this way carries a milestone that resolves on disk, with no exemption.
|
|
@@ -93,11 +80,11 @@ A **`diagnose`** (`specs/diagnoses/`, `HS-DIAG-<suffix>`) is a user-reported bug
|
|
|
93
80
|
|
|
94
81
|
**Single-intent test — the deliverable, not the surface count.** When deciding whether work belongs at one level or splits horizontally, the "intent" for SRP-for-plans is the **deliverable** (the milestone's acceptance gate / the epic's DoD / the task's PR), **not** the surface count. A migration epic with N file-tasks is single-intent — the deliverable is "the migration is done." A bundled "platform refresh" milestone whose acceptance gate names three independently-acceptable ships is multi-intent — split it horizontally per §"Milestone sizing — epic cap" below. This is the plan-side counterpart of the doc-side rule in doc-canonicalization-protocol (per evergreen-doc-architecture-srp-and-seo-pillars); both protocols share one principle, applied at different surfaces.
|
|
95
82
|
|
|
96
|
-
**Closed specs are historical record — frozen + immutable.** Trackable plan-side specs (epics / tasks / milestones / reviews) are
|
|
83
|
+
**Closed specs are historical record — frozen + immutable.** Trackable plan-side specs (epics / tasks / milestones / reviews) are *living documents* while their status is `open` / `in_progress` / `in_review`. The moment they close (`status: closed`), the body is **frozen**: no further edits to scope, acceptance criteria, narrative, or `related:` links. The closed spec captures the plan exactly as it was at the moment of close — and that's its job from then on. The actual delivered behavior is the git history of the shipped change; the closed spec is the *plan that closed*, preserved as historical record. Full rule + the four implicit references it generalizes + what you CAN still touch on a closed spec (the close-out change-log row; `status:`; `close_reason:`; `superseded_by:`) + where new information goes instead (new task / new memory / supersession): closed-trackable-specs-are-historical-record-not-living-docs. The Shipped console surface that displays the archive: HS-ZUVY-S1A6-EPIC-shipped-surface-closure-event-archive-wi. The storage convention (archive = filter not folder; closed specs stay in their normal folders): [[entity-model]] §close_reason.
|
|
97
84
|
|
|
98
85
|
### Sequencing language — disambiguate "after X"
|
|
99
86
|
|
|
100
|
-
When a task body or scope item references another spec as a precondition for some piece of work ("land after X," "after X closes," "this happens after X"), the wording must name
|
|
87
|
+
When a task body or scope item references another spec as a precondition for some piece of work ("land after X," "after X closes," "this happens after X"), the wording must name *which signal* the agent should wait for. Pick exactly one:
|
|
101
88
|
|
|
102
89
|
- **"after X's code lands"** — wait until X's implementation is in the working tree, regardless of X's status. Use when the dependent work describes X's final code state (typically: comment rewrites, doc updates, edits that reference X's predicate signature / env var / new column).
|
|
103
90
|
- **"after X closes"** — wait until X's `status: closed` (the reviewer's commit). Use **only** when the trigger is genuinely the close-out event itself — e.g., audit-only timing, archive sweeps, "do this after the reviewer signs off because the next step depends on the sign-off."
|
|
@@ -107,7 +94,7 @@ The bare **"after X"** is banned: in MVP mode where the reviewer is the owner an
|
|
|
107
94
|
|
|
108
95
|
**Reading legacy specs that use bare "after X":** default to "after X's code lands" — it's the cheaper read in MVP mode and matches the spec author's typical intent (they wanted the dependent work to describe X's final semantics, not to wait on the reviewer's clock). Treat the close-out reading as the exception, required only when the surrounding context makes the close-out signal explicit.
|
|
109
96
|
|
|
110
|
-
This rule generalizes the feedback_mvp_mode_after_x_closes_means_after_code_lands incident pattern. The matching enforcement at session close (the **Deferred items audit** subsection in the HS-REV template) catches over-deferral that slipped past this rule — see session-close-protocol §HS-REV companion template §`## Reviewer notes` §`### Deferred items audit`.
|
|
97
|
+
This rule generalizes the feedback_mvp_mode_after_x_closes_means_after_code_lands incident pattern. The matching enforcement at session close (the **Deferred items audit** subsection in the HS-REV template) catches over-deferral that slipped past this rule — see [[session-close-protocol]] §HS-REV companion template §`## Reviewer notes` §`### Deferred items audit`.
|
|
111
98
|
|
|
112
99
|
### Milestone sizing — epic cap
|
|
113
100
|
|
|
@@ -130,37 +117,35 @@ When filing a milestone/epic set from a completed research doc (the `heyspex_pro
|
|
|
130
117
|
|
|
131
118
|
**Decision rule (agents + tools):**
|
|
132
119
|
|
|
133
|
-
| Situation
|
|
134
|
-
|
|
135
|
-
| Research promotion (default)
|
|
136
|
-
| Research clearly extends one open milestone's thesis | May attach — target must be `status: open` only
|
|
137
|
-
| Agent would cram into nearest plausible milestone
|
|
138
|
-
| Research spans multiple milestone theses
|
|
120
|
+
| Situation | Action |
|
|
121
|
+
|-----------|--------|
|
|
122
|
+
| Research promotion (default) | `target_milestone: "NEW"` + `new_milestone_name` |
|
|
123
|
+
| Research clearly extends one open milestone's thesis | May attach — target must be `status: open` only |
|
|
124
|
+
| Agent would cram into nearest plausible milestone | **Stop** — file NEW instead |
|
|
125
|
+
| Research spans multiple milestone theses | Split first (HS-TQQS-GTH9-TASK-hs-split-research-mcp-tool), then promote each child to NEW or its one open best-fit |
|
|
139
126
|
|
|
140
127
|
**Existing-milestone attach gate (enforced in `promote-research.mjs`):**
|
|
141
128
|
|
|
142
|
-
| Target milestone `status:`
|
|
143
|
-
|
|
144
|
-
| `open`
|
|
145
|
-
| `in_progress`
|
|
146
|
-
| `in_review`, `review_pending`, `closed`, `parked`, `deferred`, `hibernated`, … | **Blocked** — use NEW
|
|
129
|
+
| Target milestone `status:` | Spawn epics allowed? |
|
|
130
|
+
|----------------------------|----------------------|
|
|
131
|
+
| `open` | Yes (still requires clear thesis fit — agent judgment) |
|
|
132
|
+
| `in_progress` | **Blocked by default.** Rare owner exception only: `attach_to_in_progress_milestone: true` + `attach_override_reason` (≥40 chars, audit trail) |
|
|
133
|
+
| `in_review`, `review_pending`, `closed`, `parked`, `deferred`, `hibernated`, … | **Blocked** — use NEW |
|
|
147
134
|
|
|
148
|
-
Still check existing milestones first — but as a high-bar gate, not an eager search. Attach to an existing milestone **only** when the research clearly extends that milestone's single thesis and shared infrastructure (best-fit is obvious, not merely that
|
|
135
|
+
Still check existing milestones first — but as a high-bar gate, not an eager search. Attach to an existing milestone **only** when the research clearly extends that milestone's single thesis and shared infrastructure (best-fit is obvious, not merely that *a* fit exists). Absent that clear best-fit, file a new milestone. Filing a new milestone is a strategic decision — confirm it with the owner per the autonomy table below. Rationale: the common case is one research doc → one new milestone; cramming epics into the nearest plausible existing milestone is a helpful-but-wrong habit that over-stuffs milestones and blurs their thesis. Basis: HS-Q7X7-MDHQ-RES-flat-9-epic-milestone-cap-and-research-t.
|
|
149
136
|
|
|
150
137
|
## Frontmatter requirements per level
|
|
151
138
|
|
|
152
139
|
All four levels share the base shape from [[entity-model]]: `id`, `name`, `type`, `status`, `owner`, `created`, `updated`, `tags`, `related`.
|
|
153
140
|
|
|
154
|
-
**Author `summary:` at file time.** A plain-language `summary:` is written as part of the act of filing — the same step as giving the spec a name. **Planning phase (milestone + epic):** summary at plan ingest / research promotion / milestone breakdown — milestones and epics are filed in this wave only, never with tasks. **Execution phase (task):** summary only when filing from What's Next → Launch → `/hs-next` breakdown. Pass `summary` to `heyspex_file_spec` / include it in the `POST /api/specs` body. Full contract: spec-summary-authoring.
|
|
141
|
+
**Author `summary:` at file time.** A plain-language `summary:` is written as part of the act of filing — the same step as giving the spec a name. **Planning phase (milestone + epic):** summary at plan ingest / research promotion / milestone breakdown — milestones and epics are filed in this wave only, never with tasks. **Execution phase (task):** summary only when filing from What's Next → Launch → `/hs-next` breakdown. Pass `summary` to `heyspex_file_spec` / include it in the `POST /api/specs` body. Full contract: [[spec-summary-authoring]].
|
|
155
142
|
|
|
156
143
|
**Milestone-specific** (`type: milestone`):
|
|
157
|
-
|
|
158
144
|
- `epics:` — array of `[[wikilinks]]` to every child epic (mirror of each child epic's `milestone:` pointer)
|
|
159
145
|
- `target_date:` — optional ISO date or empty string
|
|
160
146
|
- Body must include: `## Explain Like I'm 12` **as the first body section** (see below), a `## Intended outcome` re-derived from the source research's outcome (see §Intended outcome — re-derived at every level), rationale ("why this is a milestone, not loose epics"), acceptance gate (numbered closure conditions), suggested landing order (sequencing guidance, not a complete roster or a count), out-of-scope, and `## Expected Breakage & Consequences` (see below). The body must **not** re-list the child epics as a roster or state their count — see §Child rosters live in frontmatter, not prose.
|
|
161
147
|
|
|
162
148
|
**Epic-specific** (`type: epic`):
|
|
163
|
-
|
|
164
149
|
- `milestone:` — `[[wikilink]]` to parent milestone (will be **required** post-HS-OFR5; today recommended)
|
|
165
150
|
- `pillar:` — **required** `[[wikilink]]` to the perpetual `HS-PILR` theme this epic's learning belongs to. **Hard-blocked at filing**: `POST /api/specs` / `heyspex_file_spec` refuse an epic with no resolvable pillar (`400 pillar_required`). When none fits, author a net-new pillar first. Full rules: pillar-assignment-protocol.
|
|
166
151
|
- `children:` — array of `[[wikilinks]]` to every child task
|
|
@@ -169,10 +154,9 @@ All four levels share the base shape from [[entity-model]]: `id`, `name`, `type`
|
|
|
169
154
|
- `requires_user_testing:` — boolean
|
|
170
155
|
- `builder_profile:` — optional at plan ingest: `mechanical` | `architectural` | `mixed` — signals anticipated local builder class for breakdown (builder-fleet-capability-reference).
|
|
171
156
|
- Body must include: `## Explain Like I'm 12` **as the first body section** (see below), a `## Intended outcome` re-derived from the parent milestone's outcome (see §Intended outcome — re-derived at every level), scope, acceptance criteria, out-of-scope, and `## Expected Breakage & Consequences` (see below). Optional at plan ingest: **`## Builder fleet notes`** (cross-file blast radius, expected model/machine class, breakdown constraints — see builder-fleet-capability-reference). The body must **not** enumerate the child tasks as a roster or state their count — see §Child rosters live in frontmatter, not prose.
|
|
172
|
-
- Body must include `## Why this epic exists` — the **substantive priority rationale** the scheduler "Why" surfaces (the mechanical tier/layer order is computed;
|
|
157
|
+
- Body must include `## Why this epic exists` — the **substantive priority rationale** the scheduler "Why" surfaces (the mechanical tier/layer order is computed; *why the work matters* must be authored). See §Why-this-epic-exists rationale below. Auto-scaffolded with prompts (`canonical-frontmatter-templates` §epic / `BODY_SKELETONS.epic`).
|
|
173
158
|
|
|
174
159
|
**Task-specific** (`type: task`):
|
|
175
|
-
|
|
176
160
|
- `parent:` — `[[wikilink]]` to parent epic (or to a parent task, for child-task case)
|
|
177
161
|
- `kind:` — same enum as epic
|
|
178
162
|
- `effort:` — same scale as epic
|
|
@@ -188,11 +172,11 @@ All four levels share the base shape from [[entity-model]]: `id`, `name`, `type`
|
|
|
188
172
|
|
|
189
173
|
## Intended outcome — re-derived at every level (not copied)
|
|
190
174
|
|
|
191
|
-
Every level carries an intended-outcome section — `## Conclusion & intended outcome` on the research doc, `## Intended outcome` on milestone/epic/task. It **cascades by re-derivation, never copy-down** (grounded in HS-K4D4-2I29-RES-outcome-cascade-through-a-requirements-h: GORE/KAOS refine DOWN by asking HOW and justify UP by asking WHY; the OKR rule that copying a parent's wording down the hierarchy is the core failure mode — "the appearance of order while stripping out ownership" — whose cure is
|
|
175
|
+
Every level carries an intended-outcome section — `## Conclusion & intended outcome` on the research doc, `## Intended outcome` on milestone/epic/task. It **cascades by re-derivation, never copy-down** (grounded in HS-K4D4-2I29-RES-outcome-cascade-through-a-requirements-h: GORE/KAOS refine DOWN by asking HOW and justify UP by asking WHY; the OKR rule that copying a parent's wording down the hierarchy is the core failure mode — "the appearance of order while stripping out ownership" — whose cure is *translation*).
|
|
192
176
|
|
|
193
|
-
At each level the section must (a) state the outcome **at that altitude** (the milestone/epic/task's own contribution, not the parent's words), (b) draw an explicit **↑ link** to the parent outcome it moves, and (c) name the **mechanism of contribution** —
|
|
177
|
+
At each level the section must (a) state the outcome **at that altitude** (the milestone/epic/task's own contribution, not the parent's words), (b) draw an explicit **↑ link** to the parent outcome it moves, and (c) name the **mechanism of contribution** — *how* it moves the parent. A child outcome that reads like a paste of its parent is **outcome theater**; rewrite it.
|
|
194
178
|
|
|
195
|
-
**The task level is the verification bridge.** A leaf (task) outcome must be expressed as conditions an agent can **monitor and control** — and those conditions are exactly what the task's `## Acceptance criteria` are, each traceable ↑ to the epic outcome. This is the KAOS leaf-operationalization rule: refinement terminates only when a goal is realizable and testable. So the acceptance criteria are
|
|
179
|
+
**The task level is the verification bridge.** A leaf (task) outcome must be expressed as conditions an agent can **monitor and control** — and those conditions are exactly what the task's `## Acceptance criteria` are, each traceable ↑ to the epic outcome. This is the KAOS leaf-operationalization rule: refinement terminates only when a goal is realizable and testable. So the acceptance criteria are *derived from* the intended outcome, not invented separately.
|
|
196
180
|
|
|
197
181
|
The materializers inject these sections automatically (`promote-capture.mjs` research stub; `promote-research.mjs` milestone + epic; `BODY_SKELETONS` in `spex-console/src/lib/vault.ts` for epic/task/milestone). Hand-authored specs add them per [[canonical-frontmatter-templates]].
|
|
198
182
|
|
|
@@ -212,9 +196,9 @@ Owner ruling 2026-08-15 (HS-KJFZ-Z12C-CAP-every-milestone-and-every-epic-carries
|
|
|
212
196
|
|
|
213
197
|
**Auto-scaffolded at creation.** `spex-console/src/lib/vault.ts` `createSpec` injects the heading, an altitude-appropriate prompt, and the ten properties below as an authoring comment — env-gated by `HEYSPEX_AUTO_ELI12_EMBED`, positioned first in the body. Same dual treatment as `## Memories` and `## Expected Breakage & Consequences`: creation-time embed, author fills it.
|
|
214
198
|
|
|
215
|
-
**Milestone links, epic does not.** A milestone's section links to heyspex-north-star §Explain Like I'm 12 for what the whole product is, and covers only the parts of the product that bear on
|
|
199
|
+
**Milestone links, epic does not.** A milestone's section links to heyspex-north-star §Explain Like I'm 12 for what the whole product is, and covers only the parts of the product that bear on *this* milestone. Owner instruction: "we don't need HeySpex to be re-explained every time. But the important points of HeySpex that are relevant can be helpful." An epic explains its own chunk and carries **no** such link — the parent milestone already covers the wider picture.
|
|
216
200
|
|
|
217
|
-
**Never a paraphrase of `summary:`.** The two do different jobs (spec-summary-authoring). If the summary can be pasted in here, the section is wrong.
|
|
201
|
+
**Never a paraphrase of `summary:`.** The two do different jobs ([[spec-summary-authoring]]). If the summary can be pasted in here, the section is wrong.
|
|
218
202
|
|
|
219
203
|
### Rule 0 — grounding outranks style (read this before the ten)
|
|
220
204
|
|
|
@@ -237,13 +221,13 @@ The ten style rules push toward invention. Read them knowing that:
|
|
|
237
221
|
|
|
238
222
|
Naming an outside product carries **the relationship the source states** — uses it, replaces it, self-hosts it, pays for it. Never read the relationship off the product's name.
|
|
239
223
|
|
|
240
|
-
**Worked failure — 2026-08-15.** A draft section for the SpexCrawl milestone opened:
|
|
224
|
+
**Worked failure — 2026-08-15.** A draft section for the SpexCrawl milestone opened: *"Today HeySpex pays a service called Firecrawl to do that."* Every one of the ten style rules is satisfied by that sentence. It is false. The thing being reproduced is open-source Firecrawl, self-hosted on the owner's own hardware at no cost, and a self-hosted deployment never calls the company at all (spexcrawl-parity-target-is-self-hosted). The word "paying" did appear in the source, in a different sentence about a different thing, and the pull toward plain words moved it onto the wrong subject. A style rule with no grounding rule is a machine for producing well-written falsehoods, at whatever rate you run it.
|
|
241
225
|
|
|
242
226
|
### Written by a machine? Then money, ownership, and scale are off the table
|
|
243
227
|
|
|
244
228
|
A human author writing this section gets Rule 0 and is trusted with it. **Anything writing the section unattended does not get that trust**, because the failure is not decidable by a checker.
|
|
245
229
|
|
|
246
|
-
This was tested, not assumed. A grounding critic was built for exactly this job: it reads the source and each claim, and must quote the sentence that supports it. On 2026-08-15 it was run against both DeepSeek V4 Flash and DeepSeek V4 Pro drafting the SpexCrawl milestone. **Both models wrote that HeySpex pays for page fetching, and the critic passed both** — because "paying to fetch pages in the cloud" does appear in the source, in a sentence about what the new design
|
|
230
|
+
This was tested, not assumed. A grounding critic was built for exactly this job: it reads the source and each claim, and must quote the sentence that supports it. On 2026-08-15 it was run against both DeepSeek V4 Flash and DeepSeek V4 Pro drafting the SpexCrawl milestone. **Both models wrote that HeySpex pays for page fetching, and the critic passed both** — because "paying to fetch pages in the cloud" does appear in the source, in a sentence about what the new design *avoids*. The critic matched the words and missed the subject, which is the same mistake it was hired to catch.
|
|
247
231
|
|
|
248
232
|
So for unattended writing the whole class is refused rather than checked. `lintEli12(..., { strict: true })` in `scripts/eli12-lint.mjs` makes any sentence touching money, ownership, or scale a hard error, and the generator is told the class is out of scope even when the source states it. A spec whose explanation genuinely needs such a claim fails the lint and goes to a human. That is the correct direction to fail.
|
|
249
233
|
|
|
@@ -283,13 +267,13 @@ Same handling as `## Expected Breakage & Consequences` below: an unfilled scaffo
|
|
|
283
267
|
|
|
284
268
|
## Expected Breakage & Consequences (required body section)
|
|
285
269
|
|
|
286
|
-
> **The premise:** to make something better you usually have to break it first. Implementing real work
|
|
270
|
+
> **The premise:** to make something better you usually have to break it first. Implementing real work *raises* the error/failure count before it settles — adding one `surface id` legitimately took a tree from 10 → 17 tsc errors because `layout-panes.ts` needed a resolution entry and a test fixture was now missing a field. Those were **expected consequences**, not regressions. This section makes that anticipation explicit so the executing agent and the reviewer read a transient rise as normal, and so the cascade is enumerated *before* it is hit.
|
|
287
271
|
|
|
288
|
-
Every milestone, epic, and task carries a `## Expected Breakage & Consequences` section. It is **auto-scaffolded at creation** (`spex-console/src/lib/vault.ts` `createSpec`, env-gated by `HEYSPEX_AUTO_BREAKAGE_EMBED`, placed below `## Memories`), **surfaced in the `/hs-next` execution brief** (above NEXT STEP, via `enrichOnDeckWithExpectedBreakage` in `vendor/heyspex-mcp/cli.mjs`), and **reconciled at close** (the HS-REV `### Breakage reconciliation` table — see session-close-protocol). It mirrors the dual-layer (creation-time embed + runtime injection) treatment of `## Memories` per HS-U2M6-IMMF-TASK-memory-recall-hardening-runtime-injectio.
|
|
272
|
+
Every milestone, epic, and task carries a `## Expected Breakage & Consequences` section. It is **auto-scaffolded at creation** (`spex-console/src/lib/vault.ts` `createSpec`, env-gated by `HEYSPEX_AUTO_BREAKAGE_EMBED`, placed below `## Memories`), **surfaced in the `/hs-next` execution brief** (above NEXT STEP, via `enrichOnDeckWithExpectedBreakage` in `vendor/heyspex-mcp/cli.mjs`), and **reconciled at close** (the HS-REV `### Breakage reconciliation` table — see [[session-close-protocol]]). It mirrors the dual-layer (creation-time embed + runtime injection) treatment of `## Memories` per HS-U2M6-IMMF-TASK-memory-recall-hardening-runtime-injectio.
|
|
289
273
|
|
|
290
274
|
The section holds **two distinct halves** — keep them separate, because a non-breaking side-effect is not the same as breakage:
|
|
291
275
|
|
|
292
|
-
1. **Breakage** — things that will
|
|
276
|
+
1. **Breakage** — things that will *error or fail* until fixed in-scope (type/contract consumers, test fixtures/snapshots, call sites). Pair this with a **Baseline → Exit** contract: the tsc/test error count before work starts, and the exit condition (every net-new error resolved before flipping to `in_review`, back to ≤ baseline).
|
|
293
277
|
2. **Consequences / side-effects** — intended ripples that change behavior but do **not** break (a removed field, a changed default, a downstream behavior shift). These are real and worth recording even though nothing "fails."
|
|
294
278
|
|
|
295
279
|
**Altitude-appropriate content:**
|
|
@@ -302,11 +286,11 @@ The scaffold ships with placeholder prompts; the author replaces them (it is **n
|
|
|
302
286
|
|
|
303
287
|
**Expected Breakage cascade (planning → breakdown → execution).** The section **cascades by allocation, not copy-down** — same re-derivation principle as :
|
|
304
288
|
|
|
305
|
-
| Phase
|
|
306
|
-
|
|
307
|
-
| **Milestone** | Plan ingest / research promotion (plan-ingest-agent-workflow) | Cross-epic seams and integration points that may break as the milestone lands | Research scope + milestone thesis
|
|
308
|
-
| **Epic**
|
|
309
|
-
| **Task**
|
|
289
|
+
| Phase | When authored | Altitude | Allocates from |
|
|
290
|
+
|---|---|---|---|
|
|
291
|
+
| **Milestone** | Plan ingest / research promotion (plan-ingest-agent-workflow) | Cross-epic seams and integration points that may break as the milestone lands | Research scope + milestone thesis |
|
|
292
|
+
| **Epic** | Epic filing under the milestone (planning phase) | Subsystems/files this epic's changes ripple into | Parent milestone's breakage (where relevant) |
|
|
293
|
+
| **Task** | `/hs-next` breakdown only (pre-execution-alignment-gate) | Concrete files/fixtures/call sites + baseline→exit contract | Parent epic's blast radius **and** milestone seams surfaced in the decomposition brief |
|
|
310
294
|
|
|
311
295
|
At **task breakdown**, read the parent epic's and milestone's `## Expected Breakage & Consequences` sections first (the `/hs-next` decomposition brief surfaces them verbatim under **Expected Breakage — parent context**). Each task **pre-allocates fix-up scope** from those parent sections — drill down to specifics; do not paste parent prose or invent breakage in isolation. If a parent section is still the unfilled scaffold, fill it before decomposing (or note explicitly in each task why breakage is none).
|
|
312
296
|
|
|
@@ -319,13 +303,11 @@ Implementing this will transiently raise the tsc/test error count — that's exp
|
|
|
319
303
|
Enumerate the cascade so a rise reads as normal, not a regression.
|
|
320
304
|
|
|
321
305
|
**Breakage (will error/fail until fixed in-scope):**
|
|
322
|
-
|
|
323
306
|
- Type/contract consumers: `<files referencing the changed symbol>`
|
|
324
307
|
- Test fixtures/snapshots: `<state literals / snapshots needing the new field>`
|
|
325
308
|
- Call sites: `<…>`
|
|
326
309
|
|
|
327
310
|
**Consequences / side-effects (intended, non-breaking):**
|
|
328
|
-
|
|
329
311
|
- `<changed default / removed field / downstream behavior shift>`
|
|
330
312
|
|
|
331
313
|
**Baseline → Exit:** tsc = `<N>` errors / tests `<green | N failing>` before work.
|
|
@@ -334,13 +316,13 @@ Exit: every net-new error resolved before flipping to `in_review` (back to ≤ `
|
|
|
334
316
|
|
|
335
317
|
## Why-this-epic-exists rationale (substantive priority, not mechanical order)
|
|
336
318
|
|
|
337
|
-
The deterministic scheduler explains **how** a spec ranked — tier, dependency layer, what-matters, criticality (the mechanical "Why"). It cannot explain the **substantive why**:
|
|
319
|
+
The deterministic scheduler explains **how** a spec ranked — tier, dependency layer, what-matters, criticality (the mechanical "Why"). It cannot explain the **substantive why**: *why this work matters and why it belongs at the top now*. That has to be **authored**. Without it, the "Why" is factual but thin. Research + framework grounding: HS-XMSD-W8OZ-RES-authoring-substantive-priority-rationale (Cost of Delay/WSJF, Shape Up appetite, RICE, Definition-of-Ready); the mechanical layer it complements: HS-AVSG-7J97-RES-how-the-scheduler-explains-itself-determ.
|
|
338
320
|
|
|
339
321
|
Every epic's `## Why this epic exists` section carries up to four **plain-language** prompts — no scores, no numeric fields (the scalar-priority anti-pattern HS-141W-PRIO-RES-priority-and-scoring-systems-2026 rejected):
|
|
340
322
|
|
|
341
|
-
- **Problem right now (required at filing):** one sentence — the specific problem this solves
|
|
323
|
+
- **Problem right now (required at filing):** one sentence — the specific problem this solves *and* why now (not next cycle). This is the qualitative minimum Cost of Delay: it names the problem and the time-criticality in one breath.
|
|
342
324
|
- **What this unlocks (required when `kind: infra` or `foundation`):** what future work shipping this makes possible. The authored complement to the scheduler's criticality stage (the graph counts downstream specs; the author says why they matter).
|
|
343
|
-
- **Skip cost (write before pinning this as on-deck):** "If we skip this cycle, we lose: …" — a
|
|
325
|
+
- **Skip cost (write before pinning this as on-deck):** "If we skip this cycle, we lose: …" — a *specific* consequence, not "it's important."
|
|
344
326
|
- **Confidence note (optional):** flag any part of the rationale where confidence is low (RICE's bias-brake; also keeps an agent from treating shaky rationale as ground truth).
|
|
345
327
|
|
|
346
328
|
**Rationale strengthens as a spec rises (progressive elaboration / Definition-of-Ready).** A spec far down the queue needs only the lightweight Problem (+ Unlocks). As it approaches the **top / on-deck pin**, it should also carry the **Skip cost** sentence — the closer to execution, the more specific the justification. This is enforced as a **soft nudge at the pin action** (the pin UI prompts for the skip-cost sentence), **never a hard block** — keep it progressive elaboration, not a phase-gate (HS-XMSD §Definition-of-Ready caveat). The `what_matters` (★/♥) flag remains the coarse value band and always appears in the "Why".
|
|
@@ -349,11 +331,11 @@ Every epic's `## Why this epic exists` section carries up to four **plain-langua
|
|
|
349
331
|
|
|
350
332
|
Linkage is **bidirectional and explicit** — agents MUST update both sides when filing a new spec:
|
|
351
333
|
|
|
352
|
-
| Edge
|
|
353
|
-
|
|
354
|
-
| Milestone → Epic
|
|
355
|
-
| Epic → Task
|
|
356
|
-
| Task → Child task | `children: ["[[HS-TASK-…]]"]` | `parent: "[[HS-TASK-…]]"`
|
|
334
|
+
| Edge | Parent's field | Child's field |
|
|
335
|
+
|---|---|---|
|
|
336
|
+
| Milestone → Epic | `epics: ["[[HS-EPIC-…]]"]` | `milestone: "[[HS-MIL-…]]"` |
|
|
337
|
+
| Epic → Task | `children: ["[[HS-TASK-…]]"]` | `parent: "[[HS-EPIC-…]]"` |
|
|
338
|
+
| Task → Child task | `children: ["[[HS-TASK-…]]"]` | `parent: "[[HS-TASK-…]]"` |
|
|
357
339
|
|
|
358
340
|
**`heyspex_file_spec` does NOT wire the parent's `children[]` back-reference.** It creates the task file and sets the task's own `parent:` field, but the parent epic's `children:` array is a separate write. The signal is the response: if `parent` or `milestone` come back `null`, the back-reference was not written. Always call `heyspex_register_spec(spec_id, parent_id)` immediately after every `heyspex_file_spec` call — it writes both sides atomically and is idempotent (see §Filing procedure step 5).
|
|
359
341
|
|
|
@@ -383,20 +365,20 @@ After filing, run `heyspex_validate_linkage` (MCP) to confirm both sides are pre
|
|
|
383
365
|
|
|
384
366
|
This is the part agents most often get wrong. The default is **ask first** for structural changes, **decide on your own** for execution-level fanout.
|
|
385
367
|
|
|
386
|
-
| Action
|
|
387
|
-
|
|
388
|
-
| **File a new milestone**
|
|
389
|
-
| **File a new epic under an existing milestone**
|
|
390
|
-
| **Fan out tasks under a new epic**
|
|
391
|
-
| **Add a child task during execution of a parent task**
|
|
392
|
-
| **Reorder child tasks within a task**
|
|
393
|
-
| **Add a `related:` link to another spec**
|
|
394
|
-
| **Change a spec's `parent:` or `milestone:` field**
|
|
395
|
-
| **Change a spec's `status:` from anything to `in_review`** | **Decide autonomously** when acceptance criteria are met (per session-close-protocol).
|
|
396
|
-
| **Change a spec's `status:` to `closed`**
|
|
397
|
-
| **Create a memory doc**
|
|
398
|
-
| **Modify a protocol doc (this kind of file)**
|
|
399
|
-
| **File a new diagnose (standalone bug fix)**
|
|
368
|
+
| Action | Agent autonomy |
|
|
369
|
+
|---|---|
|
|
370
|
+
| **File a new milestone** | **Ask the user.** Milestones are strategic decisions; do not file unilaterally. |
|
|
371
|
+
| **File a new epic under an existing milestone** | **Ask the user**, unless the epic clearly maps to a single audit/finding/incident already named by the user. When in doubt, ask. **File the epic with `children: []`** — do not fan out tasks in the same pass (see the next row). **The parent milestone must be open** (non-claim-terminal — `open`/`in_progress`/`draft`/`parked`); filing under an `in_review`/`closed` milestone is hard-blocked with `parent_milestone_not_open` (see §Linkage rules). |
|
|
372
|
+
| **Fan out tasks under a new epic** | **Never at epic-creation / planning time.** Tasks are created **just-in-time at execution**, when the epic becomes the on-deck `ClaimTarget` (via `/hs-next`) — that breakdown is the *first step of executing the epic*, not a planning activity. At doc-creation and during clarification, offer **milestone + epics only**. See the §empty-state grain-split note below and deterministic-priority-scheduler-supersedes-scored-priority. |
|
|
373
|
+
| **Add a child task during execution of a parent task** | **Decide autonomously.** This is the canonical place agents have authority — when executing a task uncovers sub-work, fan out into child tasks without asking. Link via `parent:` to the task you're executing. |
|
|
374
|
+
| **Reorder child tasks within a task** | **Decide autonomously.** Sequence and decomposition of child tasks is the agent's call. |
|
|
375
|
+
| **Add a `related:` link to another spec** | **Decide autonomously.** Cross-linking is low-risk. |
|
|
376
|
+
| **Change a spec's `parent:` or `milestone:` field** | **Ask the user.** Restructuring linkage changes the roadmap rendering and other agents' context. |
|
|
377
|
+
| **Change a spec's `status:` from anything to `in_review`** | **Decide autonomously** when acceptance criteria are met (per [[session-close-protocol]]). |
|
|
378
|
+
| **Change a spec's `status:` to `closed`** | **Never.** Only the reviewer (human) flips to `closed`. Agent terminal action is `in_review`. |
|
|
379
|
+
| **Create a memory doc** | **Decide autonomously** when a lesson/decision/UI pattern emerges (per CLAUDE.md §Automatic knowledge capture). |
|
|
380
|
+
| **Modify a protocol doc (this kind of file)** | **Ask the user.** Protocols are stable contracts; treat changes the same as ADR changes. |
|
|
381
|
+
| **File a new diagnose (standalone bug fix)** | **Decide autonomously** when a bug is reported and the symptom/scope is clear — standalone (no parent) is the default. **Ask the user** before giving it a `parent:` (epic/milestone) or a `blocks:` edge, since both change roadmap/on-deck rendering. |
|
|
400
382
|
|
|
401
383
|
**How the empty-state grain-split is surfaced (2026-06-01).** The two "no children yet" states are NOT the same severity, and the console signals them differently (HS-6A4P On Deck split, pre-execution-alignment-gate):
|
|
402
384
|
|
|
@@ -407,63 +389,63 @@ This is the part agents most often get wrong. The default is **ask first** for s
|
|
|
407
389
|
|
|
408
390
|
## Claim eligibility & `ClaimTarget`
|
|
409
391
|
|
|
410
|
-
**The single eligibility rule:**
|
|
392
|
+
**The single eligibility rule:** *a spec is claimable iff it is its own current `ClaimTarget`*. The console claim endpoint (`POST /api/specs/:id/claim`) enforces this — any POST whose target is not the current `ClaimTarget` returns `409 claim_blocked_by_descendants` with the actual current target's id in the response payload (HS-B0Z7 of HS-VLB8). This is the **vault invariant** that backs the legibility surface in `/hs-next`: the brief always names what is actually claimable, and the claim never silently lands on the wrong level.
|
|
411
393
|
|
|
412
394
|
### `ClaimTarget` type
|
|
413
395
|
|
|
414
396
|
`computeClaimTarget(spec, vaultRoot, alignmentState)` (`vendor/heyspex-mcp/blocker-resolver.mjs`; TypeScript mirror in `spex-console/src/lib/scheduler/claim-eligibility.ts`) returns a 7-field record:
|
|
415
397
|
|
|
416
|
-
| Field
|
|
417
|
-
|
|
418
|
-
| `level`
|
|
419
|
-
| `spec_id`
|
|
420
|
-
| `title`
|
|
421
|
-
| `intent_verb`
|
|
422
|
-
| `tone_token`
|
|
423
|
-
| `hierarchy_breadcrumb` | `string[]`
|
|
424
|
-
| `alignment_state`
|
|
398
|
+
| Field | Shape | Notes |
|
|
399
|
+
|---|---|---|
|
|
400
|
+
| `level` | `"task" \| "epic" \| "milestone"` | What grain the user is actually authorizing. |
|
|
401
|
+
| `spec_id` | `string` | The id the user will claim — **not necessarily the spec id `/hs-next` is currently looking at**. |
|
|
402
|
+
| `title` | `string` | Display title (frontmatter `name:`). |
|
|
403
|
+
| `intent_verb` | plain English | "implement it" / "break it into Tasks" / "break it into Epics" — see §Intent verbs below. |
|
|
404
|
+
| `tone_token` | `--status-neutral \| --status-ready \| --status-pending` | UI tone per HS-6A4P-MNBD-EPIC-milestone-needs-breakdown-awareness. |
|
|
405
|
+
| `hierarchy_breadcrumb` | `string[]` | Root → leaf id chain (e.g. `["HS-AGEX-MIL", "HS-VQZ8-EPIC", "HS-NJPH-TASK"]`). |
|
|
406
|
+
| `alignment_state` | `"fresh" \| "drift_detected" \| "unknown"` | Transparency only — the alignment gate is upstream; this field reports the gate's verdict on the brief, it does not re-decide it. |
|
|
425
407
|
|
|
426
408
|
### The three corollary rules
|
|
427
409
|
|
|
428
|
-
| Spec kind
|
|
429
|
-
|
|
430
|
-
| **Task**
|
|
431
|
-
| **Diagnose (not broken down)**
|
|
432
|
-
| **Diagnose that spawned work**
|
|
433
|
-
| **Epic with open children**
|
|
434
|
-
| **Epic with no open children** (drained or fresh) | Its own `ClaimTarget` — intent depends on child rollup state (see §Rollup states below).
|
|
435
|
-
| **Milestone with open epics**
|
|
436
|
-
| **Milestone with no open epics**
|
|
410
|
+
| Spec kind | Resolution |
|
|
411
|
+
|---|---|
|
|
412
|
+
| **Task** | Always its own `ClaimTarget` (level `"task"`). |
|
|
413
|
+
| **Diagnose (not broken down)** | Its own `ClaimTarget` (a leaf, level `"task"`-equivalent, intent "implement it"). No parent to recurse from; directly claimable. The one-fix case, and the common one. |
|
|
414
|
+
| **Diagnose that spawned work** | NOT claimable — `rollup_state: "tracked_by_work"`, carrying `tracked_by` with the specs it spawned. Claim one of those instead. It is not terminal: the bug is still live, and it closes only when its reproduction stops reproducing (HS-ALBV-BFIX-EPIC-breakdown-stage-accepts-a-diagnose). |
|
|
415
|
+
| **Epic with open children** | Recurses through `children:` in manifest order; returns the first non-terminal-status descendant. The Epic itself is NOT claimable while it has any open Task. |
|
|
416
|
+
| **Epic with no open children** (drained or fresh) | Its own `ClaimTarget` — intent depends on child rollup state (see §Rollup states below). |
|
|
417
|
+
| **Milestone with open epics** | Recurses through `epics:`; returns the first non-terminal descendant (which itself may recurse one more level). |
|
|
418
|
+
| **Milestone with no open epics** | Its own `ClaimTarget` — intent depends on child rollup state (see §Rollup states below). |
|
|
437
419
|
|
|
438
420
|
Terminal statuses that block recursion into a descendant: `closed`, `shipped`, `in_review`, `review_pending`, `archived`, `cancelled`, `duplicate`, `hibernated`, `superseded`.
|
|
439
421
|
|
|
440
|
-
> **A review backlog is never a claim blocker, and never needs owner permission to work past.** `in_review` / `review_pending` are
|
|
422
|
+
> **A review backlog is never a claim blocker, and never needs owner permission to work past.** `in_review` / `review_pending` are *terminal for recursion* precisely because they are build-complete — the code is already in the tree. Specs sitting unreviewed are the expected steady state under a batched review grain (`mvp_mode.review_backlog_never_blocks: true`, owner ruling 2026-08-14), so the `ClaimTarget` is claimed on the normal handshake no matter how deep the review queue is. Never tell the owner to Pass/commit first, never offer to redirect the claim, never ask permission to proceed past pending reviews. Only a **real** dependency blocks — the new work needs code or a decision the other spec has not produced yet; name that dependency specifically and keep going. Full rule: [[session-close-protocol]] §MVP Mode variant item 5. Enforced in `blocker-resolver.mjs` (`STATUS_SEVERITY` → `soft_review`, never `hard`).
|
|
441
423
|
|
|
442
424
|
### Rollup states (HS-Q7IG)
|
|
443
425
|
|
|
444
426
|
When every child is terminal (no `open` / `in_progress` descendant), `computeClaimTarget` classifies the parent instead of defaulting to "break it into Tasks/Epics":
|
|
445
427
|
|
|
446
|
-
| Child rollup
|
|
447
|
-
|
|
448
|
-
| No `children:` / `epics:` entries
|
|
449
|
-
| ≥1 child `in_review` / `review_pending`, rest terminal
|
|
450
|
-
| Every child build-complete below the active review grain (`in_review` / `review_pending` / `closed`, no `open`/`in_progress`) | `ready_for_close`
|
|
451
|
-
| Every child `closed` / cancelled / etc., none awaiting review
|
|
428
|
+
| Child rollup | `rollup_state` | Intent verb | Meaning |
|
|
429
|
+
|---|---|---|---|
|
|
430
|
+
| No `children:` / `epics:` entries | *(absent)* or `no_children` | *break it into Tasks* / *break it into Epics* | Normal just-in-time breakdown — the happy path. |
|
|
431
|
+
| ≥1 child `in_review` / `review_pending`, rest terminal | `reviewer_blocked` | *wait for reviewer* | **Strict (task grain) only:** breakdown/implementation is done but each child still needs its own review before the parent can close. `/hs-next` must **not** offer to claim for breakdown. |
|
|
432
|
+
| Every child build-complete below the active review grain (`in_review` / `review_pending` / `closed`, no `open`/`in_progress`) | `ready_for_close` | *flip to in_review* | **MVP (milestone grain) and Standard (epic grain):** children at `in_review` below the grain are build-complete, not blockers — parent close-out (flip + HS-REV) is claimable. |
|
|
433
|
+
| Every child `closed` / cancelled / etc., none awaiting review | `ready_for_close` | *flip to in_review* | Children are fully terminal; agent close-out is the next write. |
|
|
452
434
|
|
|
453
435
|
### Intent verbs (plain English, per user preference)
|
|
454
436
|
|
|
455
437
|
The on-deck brief uses **plain action verbs** rather than vault jargon ("decompose"). Per feedback_avoid_decompose_in_ux_copy:
|
|
456
438
|
|
|
457
|
-
| Level
|
|
458
|
-
|
|
459
|
-
| Task
|
|
460
|
-
| Epic with no children (fresh)
|
|
461
|
-
| Epic with all children awaiting review
|
|
462
|
-
| Epic with all children build-complete below review grain |
|
|
463
|
-
| Epic with all children closed (none in review)
|
|
464
|
-
| Milestone with no epics (fresh)
|
|
465
|
-
| Milestone with all epics awaiting review
|
|
466
|
-
| Milestone with all epics closed (none in review)
|
|
439
|
+
| Level | Verb |
|
|
440
|
+
|---|---|
|
|
441
|
+
| Task | *implement it* |
|
|
442
|
+
| Epic with no children (fresh) | *break it into Tasks* |
|
|
443
|
+
| Epic with all children awaiting review | *wait for reviewer* | Strict (task grain): children must close before parent. |
|
|
444
|
+
| Epic with all children build-complete below review grain | *flip to in_review* | MVP / Standard: claim for parent close-out even when children are `in_review`. |
|
|
445
|
+
| Epic with all children closed (none in review) | *flip to in_review* |
|
|
446
|
+
| Milestone with no epics (fresh) | *break it into Epics* |
|
|
447
|
+
| Milestone with all epics awaiting review | *wait for reviewer* |
|
|
448
|
+
| Milestone with all epics closed (none in review) | *flip to in_review* |
|
|
467
449
|
|
|
468
450
|
System slugs (`uc-decompose-intent`, `extractDecompositionContext`, etc.) keep their identifiers — only the human-facing copy switches.
|
|
469
451
|
|
|
@@ -485,17 +467,17 @@ A drift-detected brief still names a single claimable target; the user picks `[1
|
|
|
485
467
|
|
|
486
468
|
## Related procedures
|
|
487
469
|
|
|
488
|
-
| Procedure
|
|
489
|
-
|
|
490
|
-
| [[entity-model]]
|
|
491
|
-
| vault-id-assignment-protocol
|
|
492
|
-
| plan-ingest-agent-workflow
|
|
493
|
-
| plan-ingest-review-roadmap-workflow | Same flow with a human review gate
|
|
494
|
-
| roadmap-protocol
|
|
495
|
-
| session-close-protocol
|
|
496
|
-
| [[memory-protocol]]
|
|
497
|
-
| internal-linking-protocol
|
|
498
|
-
| mcp-slash-surface-protocol
|
|
470
|
+
| Procedure | What it covers |
|
|
471
|
+
|---|---|
|
|
472
|
+
| [[entity-model]] | Frontmatter schema, valid status values, valid types, wikilink resolution rules |
|
|
473
|
+
| vault-id-assignment-protocol | Random suffix allocation, ID collision handling |
|
|
474
|
+
| plan-ingest-agent-workflow | Creating specs from implementation plans, manifest registration, linkage validation |
|
|
475
|
+
| plan-ingest-review-roadmap-workflow | Same flow with a human review gate |
|
|
476
|
+
| roadmap-protocol | How the roadmap manifest is structured, what columns specs render in |
|
|
477
|
+
| [[session-close-protocol]] | The `in_review` → `closed` handoff between agent and reviewer |
|
|
478
|
+
| [[memory-protocol]] | When to file memories (lessons / decisions / references / UI patterns) |
|
|
479
|
+
| internal-linking-protocol | Preserve wikilinks + retrieval signal when re-parenting or restructuring trackable specs |
|
|
480
|
+
| mcp-slash-surface-protocol | MCP tools the agent uses to interact with the vault |
|
|
499
481
|
|
|
500
482
|
## Discovery & enforcement
|
|
501
483
|
|
|
@@ -518,31 +500,31 @@ The robust solution — a procedure registry, an MCP `heyspex_get_procedure` too
|
|
|
518
500
|
|
|
519
501
|
## Change log
|
|
520
502
|
|
|
521
|
-
| Date
|
|
522
|
-
|
|
523
|
-
| 2026-05-27 | pwher (with claude opus 4.7)
|
|
524
|
-
| 2026-05-28 | pwher (with claude opus 4.8 [1m])
|
|
525
|
-
| 2026-05-30 | claude opus 4.7 [1m] · session `local`
|
|
526
|
-
| 2026-06-03 | claude opus 4.7 [1m] · session `local` (with pwher)
|
|
527
|
-
| 2026-06-03 | claude opus 4.7 [1m] · session `local` (with pwher)
|
|
528
|
-
| 2026-06-04 | claude opus 4.7 [1m] · session `local` (with pwher)
|
|
529
|
-
| 2026-06-05 | claude opus 4.7 [1m] · session `local`
|
|
530
|
-
| 2026-06-07 | claude opus 4.7 [1m] · session `local` (with pwher)
|
|
531
|
-
| 2026-06-18 | claude opus 4.8 [1m] · session `local` (with pwher)
|
|
532
|
-
| 2026-06-07 | claude opus 4.7 [1m] · session `local` (with pwher)
|
|
533
|
-
| 2026-06-13 | claude opus 4.8 [1m] · session `local` (with pwher)
|
|
534
|
-
| 2026-06-20 | claude opus 4.8 [1m] · session `local` (with pwher)
|
|
535
|
-
| 2026-06-20 | claude opus 4.8 [1m] · session `local` (with pwher)
|
|
536
|
-
| 2026-06-21 | claude opus 4.8 [1m] · session `local` (with pwher)
|
|
537
|
-
| 2026-06-22 | Cursor · Composer (with pwher)
|
|
538
|
-
| 2026-06-24 | Claude Code · session `2a8cade3` (with pwher)
|
|
539
|
-
| 2026-06-24 | Cursor · local
|
|
540
|
-
| 2026-06-24 | Cursor · local
|
|
541
|
-
| 2026-06-25 | claude opus 4.8 [1m] · session `0b396d62` (with pwher) | **(A)** Collapsed §"Milestone sizing — epic cap" from the soft-8 / at-cap-9–10 / hard-10 ladder to a **flat hard cap of 9 epics**, owner-override only; rewrote the rationale to lead with the console Milestone-card **3×3 grid** (scheduler + chip-budget now secondary). **(B)** Added §"Research → milestone/epic filing — default to a new milestone": on the `heyspex_promote_research` path the default is a NEW milestone; attaching to an existing one is a high-bar exception (clear best-fit only). Cross-referenced from research-capture-protocol and plan-ingest-agent-workflow. Both implemented directly off research HS-Q7X7-MDHQ-RES-flat-9-epic-milestone-cap-and-research-t (prose-only, owner-approved).
|
|
542
|
-
| 2026-07-07 | Cursor
|
|
543
|
-
| 2026-07-04 | Claude Code (HS-I949-TASK)
|
|
544
|
-
| 2026-07-07 | Cursor · Composer (with pwher)
|
|
545
|
-
| 2026-08-14 | Claude Code (Opus 5) · with pwher
|
|
546
|
-
| 2026-08-15 | Claude Code (Opus 5) · with pwher
|
|
547
|
-
| 2026-08-15 | Claude Code (Opus 5) · with pwher
|
|
548
|
-
| 2026-08-22 | Claude Code · session `45051d11` (with pwher)
|
|
503
|
+
| Date | Author | Change |
|
|
504
|
+
|---|---|---|
|
|
505
|
+
| 2026-05-27 | pwher (with claude opus 4.7) | Initial draft. Codifies the Milestone → Epic → Task → child task hierarchy that was previously implicit. Filed alongside the agent-procedure-discovery planning epic. Status `draft` until reviewed; flip to `open` after first cross-agent use confirms it answers the questions agents actually have. |
|
|
506
|
+
| 2026-05-28 | pwher (with claude opus 4.8 [1m]) | Conflict fix (Builder-approved protocol edit): `kind:` enum corrected from `feature\|bug\|spike\|story\|polish` to the scheduler tier vocabulary `infra\|foundation\|feature\|polish` actually read by HS-78E7-Y9OJ-EPIC-deterministic-priority-scheduler and used by every real epic (MILE=infra, M2J3/Y9OJ=foundation). Surfaced during the HS-SSOT-MIL conflict check. |
|
|
507
|
+
| 2026-05-30 | claude opus 4.7 [1m] · session `local` | Added `### Milestone sizing — epic cap` subsection under §What each level is *for*: soft cap 8, at-cap 9–10, hard cap 10, owner-override exception with inline `## Exception — over-cap rationale` requirement, and a filing flow for over-cap proposals. Codifies the previously informal cap surfaced at HS-QOAL-JN9H-TASK-manifest-schema-v3-and-horizon-retirement close-out (PFAG=9, CMCH=11, IART=11). Filed under HS-SP9M-MCAP-TASK-over-cap-milestone-splits-pfag-cmch-iart per HS-OFR5-M2J3-EPIC-introduce-milestones-as-highest-entity; owner permitted the three current over-cap milestones to remain unsplit under the new exception clause. |
|
|
508
|
+
| 2026-06-03 | claude opus 4.7 [1m] · session `local` (with pwher) | Added the **"Single-intent test — the deliverable, not the surface count"** clarification under §"What each level is *for*" §Anti-patterns. Per HS-UEF3-S1HX-RES-seo-style-information-architecture-for-t §Q9 findings: a migration epic with N file-tasks is single-intent; a bundled milestone whose acceptance gate names three independently-acceptable ships is multi-intent. Cross-links to doc-canonicalization-protocol + evergreen-doc-architecture-srp-and-seo-pillars so plan-side and doc-side SRP share one principle. One-sentence amendment — explicitly NOT a new plan-side protocol; SSOT for plan-side questions stays in this protocol. |
|
|
509
|
+
| 2026-06-03 | claude opus 4.7 [1m] · session `local` (with pwher) | Added the **"Closed specs are historical record — frozen + immutable"** clarification under §"What each level is *for*" §Anti-patterns. User flagged the principle as foundational and previously undocumented: *"Epics are stale once implemented — by design. Immediately locked and frozen and never updated again."* The principle existed implicitly across four references (supersession-protocol, this protocol's prior anti-pattern about post-close follow-ups, edit-protocol-in-place-with-version-preamble, spec-literal-is-intent-not-literal-update-on-rename); now named explicitly in the foundational memory-decision closed-trackable-specs-are-historical-record-not-living-docs under HS-PILR-pillars. Cross-links to HS-ZUVY-S1A6-EPIC-shipped-surface-closure-event-archive-wi (the console surface that displays the historical record) and to [[entity-model]] §close_reason (the storage convention: archive = filter not folder). |
|
|
510
|
+
| 2026-06-04 | claude opus 4.7 [1m] · session `local` (with pwher) | Reconciled stale "milestones cannot be created via `POST /api/specs`" directive in §Filing procedure (and removed the matching §Open questions / in-flight bullet) after verifying HS-VK7C-MILE-EPIC-milestone-entity-type-and-surfacing and HS-Y855-1AX3-TASK-recognize-milestone-in-console-type-regi both closed 2026-05-31 — `TYPE_TO_FOLDER` now has `milestone: "milestones"` and `createSpec()` handles `type: "milestone"` (`spex-console/src/lib/vault.ts:1263, 1605-1614`). The prior line cited a now-nonexistent `vault.ts:897`, a tell that no agent re-grepped after the implementation moved. Surfaced by the user flagging the directive as a memory candidate for review; rejected the memory because the corrected truth is derivable from current code. |
|
|
511
|
+
| 2026-06-05 | claude opus 4.7 [1m] · session `local` | **T5 added §Claim eligibility & `ClaimTarget`** (HS-VLB8 / HS-IYD8). Codifies the vault invariant *a spec is claimable iff it is its own current `ClaimTarget`*, the 7-field type, three corollary rules (Task / Epic-with-open-children / Epic-empty / Milestone-with-open-epics / Milestone-empty), plain-English intent verbs ("implement it" / "break it into Tasks" / "break it into Epics" — per feedback_avoid_decompose_in_ux_copy), tone tokens linking HS-6A4P, the two SSOT invariants (structural truth from disk; time truth from git), and the upstream/downstream relationship with pre-execution-alignment-gate. Implementation references: `vendor/heyspex-mcp/blocker-resolver.mjs` (HS-USOP), `spex-console/src/lib/scheduler/claim-eligibility.ts` (HS-B0Z7). Also upgraded `heyspex_preflight({ intent: "claim_spec" })` to return this protocol as `required`. |
|
|
512
|
+
| 2026-06-07 | claude opus 4.7 [1m] · session `local` (with pwher) | **Added §"Sequencing language — disambiguate 'after X'"** under §What each level is *for*. Bans bare "after X" wording in task bodies; requires one of three explicit phrasings ("after X's code lands" / "after X closes" / a behavioral marker). Sets the default-read rule for legacy bare-"after-X" specs to "after X's code lands" (cheapest read in MVP mode where close-out is a reviewer formality). Companion enforcement on the close side (the `### Deferred items audit` subsection in the HS-REV template): [[session-close-protocol]]. Driven by the feedback_mvp_mode_after_x_closes_means_after_code_lands incident during HS-7FOD where bare "after DV1T" in the task body led an agent to defer six in-tree edits to a future session for no real gate. |
|
|
513
|
+
| 2026-06-18 | claude opus 4.8 [1m] · session `local` (with pwher) | **Added §"Child rosters live in frontmatter, not prose (single source of truth)"** and amended the milestone/epic §Frontmatter-requirements body lines: a parent's prose body must **not** re-list the child set or hard-code a count (no "## The N epics" roster table, no "all six child epics" wording); the `epics:`/`children:` frontmatter array is the single source of truth, rendered live by the console. Landing order stays allowed as sequencing guidance, not a roster. Owner-approved (option A) fix for HS-FMRH-SVCZ-DIAG-parent-spec-prose-body-drifts-from-its-f — the write path patches the parent's frontmatter array but never re-syncs its body, so any prose roster/count silently drifts (HS-4PTZ-MVMD-MIL-mvp-mode-relax-review-commit-pre-launch body said "six" while its array held nine). |
|
|
514
|
+
| 2026-06-07 | claude opus 4.7 [1m] · session `local` (with pwher) | **Added `## Memories` body-convention note** to §Frontmatter requirements per level → Task-specific. Tasks should include a `## Memories` section as the first body section (auto-populated by `POST /api/specs` when filed under an epic parent; hand-authored manually otherwise). Companion of the new step 1c in plan-ingest-agent-workflow and the runtime-injection enricher in HS-U2M6-IMMF-TASK-memory-recall-hardening-runtime-injectio. The two surfaces together (creation-time embedding + runtime injection) cover each other's failure modes — see feedback_creation_time_memory_embedding_complements_runtime_recall. |
|
|
515
|
+
| 2026-06-13 | claude opus 4.8 [1m] · session `local` (with pwher) | **Added §"Diagnose — the bug-fix lane"** plus a "What each level is for" row, an Agent-autonomy row ("File a new diagnose"), and a Claim-eligibility corollary row. A `diagnose` (`specs/diagnoses/`, `HS-DIAG-*`) is a user-reported bug fix as a sibling executable entity *outside* the milestone→epic→task chain: standalone-by-default (exempt from the epic→milestone parent rule), optional epic/milestone `parent:`, always its own leaf `ClaimTarget`, advising the scheduler via `severity:` + `blocks:` (resolution-advises-scheduler-via-severity-and-gating). Ratified by introduction lineage HS-OXBS. Per HS-AO2F-1KZK-RES-bug-fix-resolution-task-entity-model-and. |
|
|
516
|
+
| 2026-06-20 | claude opus 4.8 [1m] · session `local` (with pwher) | **Added the "parent milestone must still be accepting work" rule** to §Linkage rules (new paragraph after the bidirectional table) and a clause to the §Agent-autonomy "File a new epic under an existing milestone" row. An epic may only be filed under a milestone that is **not claim-terminal** (`open`/`in_progress`/`draft`/`parked`); filing under an `in_review`/`closed`/… milestone is hard-blocked at `POST /api/specs` / `heyspex_file_spec` with `400 parent_milestone_not_open`, plus a defense-in-depth throw in `createSpec` — back-linking the child would otherwise mutate a frozen parent's `epics:` array (closed-trackable-specs-are-historical-record-not-living-docs). Reuses `CLAIM_TERMINAL_STATUSES` (now exported from `spex-console/src/lib/scheduler/claim-eligibility.ts`) so claim-terminality and child-acceptance are one rule. Owner-approved fix for HS-05ND-2DMM-DIAG-epic-can-be-filed-under-a-non-open-in-re (from capture HS-R22Q-OBO9-CAP-filing-an-epic-under-a-milestone-that-is); scope is prevention-only (existing in-review milestones left as-is) and epic→milestone only. |
|
|
517
|
+
| 2026-06-20 | claude opus 4.8 [1m] · session `local` (with pwher) | **Made `summary:` an authoring step of filing** — added "Author `summary:` at file time" to §Frontmatter requirements (after the base-shape line) and a clause to §Filing procedure step 4. A plain-language `summary:` is now written as part of creating every milestone/epic/task, not deferred to claim time (the `/hs-next` claim flow was the only checkpoint, so specs created-but-not-claimed — e.g. the HS-QYXP-PI91-MIL-capture-workflow-v3-fast-brain-offload-h family — slipped through bare). Authoring expectation only, **not** a blocking gate: refuse-to-commit-without-one stays rejected per HS-G7OW-Q3HK-EPIC-spec-frontmatter-summary-field-policy-an. Owner-requested. |
|
|
518
|
+
| 2026-06-21 | claude opus 4.8 [1m] · session `local` (with pwher) | **Added §"Why-this-epic-exists rationale"** + an §Epic-specific body bullet. Every epic's `## Why this epic exists` section now carries four plain-language prompts (Problem-right-now, What-this-unlocks, Skip-cost, Confidence) so the scheduler "Why" can surface the *substantive* priority rationale, not just the mechanical tier/layer order. Rationale **strengthens as a spec rises** (progressive elaboration / Definition-of-Ready): Problem(+Unlocks) at filing, Skip-cost before the on-deck pin — enforced as a **soft pin nudge, never a hard gate**. No numeric scores / no `value`/`time_criticality` frontmatter (the scalar anti-pattern HS-141W-PRIO-RES-priority-and-scoring-systems-2026 rejected); `what_matters` (★/♥) stays the coarse value band and always shows in the Why (`buildWhyNow`). Mirrored in `canonical-frontmatter-templates` §epic + `BODY_SKELETONS.epic` (`spex-console/src/lib/vault.ts`). Research: HS-XMSD-W8OZ-RES-authoring-substantive-priority-rationale; mechanical layer it complements: HS-AVSG-7J97-RES-how-the-scheduler-explains-itself-determ. Owner-approved (soft-nudge option). |
|
|
519
|
+
| 2026-06-22 | Cursor · Composer (with pwher) | §Filing procedure step 2: split ID allocation into planning (milestone/epic) vs execution (task at `/hs-next` only). Authoring-phase parity sweep with plan-ingest, skills, and agent contracts. |
|
|
520
|
+
| 2026-06-24 | Claude Code · session `2a8cade3` (with pwher) | **Hardened §Linkage rules + §Filing procedure step 5** to make `heyspex_register_spec` a mandatory post-file step. `heyspex_file_spec` does NOT auto-wire `children[]` on the parent; the filed task is invisible in the UI until `heyspex_register_spec(spec_id, parent_id)` writes both sides. Removed the stale "planned, not shipped" note (both tools now ship). Incident: HS-8XZA-LJUP-DIAG-heyspex-file-spec-does-not-auto-wire-chi. |
|
|
521
|
+
| 2026-06-24 | Cursor · local | **Added shared-suffix family note** under §The four levels (inherits epic suffix; bare `HS-TASK-<suffix>` is a family token; basename required). Cross-links vault-id-assignment-protocol §Shared-suffix families and bare-hs-task-suffix-is-a-family-token-af. (HS-M96C). |
|
|
522
|
+
| 2026-06-24 | Cursor · local | Cross-linked internal-linking-protocol in §Related procedures + §Linkage rules (re-parent / restructure moves). Implements HS-CGJ6-XPGV-RES-internal-linking-and-wikilink-best-pract. |
|
|
523
|
+
| 2026-06-25 | claude opus 4.8 [1m] · session `0b396d62` (with pwher) | **(A)** Collapsed §"Milestone sizing — epic cap" from the soft-8 / at-cap-9–10 / hard-10 ladder to a **flat hard cap of 9 epics**, owner-override only; rewrote the rationale to lead with the console Milestone-card **3×3 grid** (scheduler + chip-budget now secondary). **(B)** Added §"Research → milestone/epic filing — default to a new milestone": on the `heyspex_promote_research` path the default is a NEW milestone; attaching to an existing one is a high-bar exception (clear best-fit only). Cross-referenced from research-capture-protocol and plan-ingest-agent-workflow. Both implemented directly off research HS-Q7X7-MDHQ-RES-flat-9-epic-milestone-cap-and-research-t (prose-only, owner-approved). |
|
|
524
|
+
| 2026-07-07 | Cursor | **Mandatory NEW-milestone default on research promotion** — expanded §"Research → milestone/epic filing" with decision table + `promote-research.mjs` enforcement (open-only attach; in_progress owner-gated via `attach_to_in_progress_milestone` + `attach_override_reason`). Cross-linked from research-capture-protocol. | Every level carries an intended-outcome section that **cascades by re-derivation, not copy-down**: state the outcome at that altitude, draw an explicit ↑ link to the parent outcome, and name the **mechanism of contribution** (a paste of the parent is "outcome theater"). The **task** outcome must be stated as **monitorable + controllable conditions that seed the `## Acceptance criteria`** — the KAOS leaf-operationalization rule, so acceptance criteria are *derived from* the outcome, not invented separately. Materializers: `promote-capture.mjs` / `promote-research.mjs` / `BODY_SKELETONS` (epic/task/milestone) in `spex-console/src/lib/vault.ts`. Grounded in HS-K4D4-2I29-RES-outcome-cascade-through-a-requirements-h (GORE/KAOS HOW-down/WHY-up + OKR translate-not-cascade). Companion edits: `research-capture-protocol`, `plan-ingest-agent-workflow`, `canonical-frontmatter-templates`. Owner-directed. |
|
|
525
|
+
| 2026-07-04 | Claude Code (HS-I949-TASK) | Added a one-line pointer next to the grain-split empty-state note ("How the empty-state grain-split is surfaced"): breakdown must resolve inbound `amends:` first before decomposing an epic or milestone. See pre-execution-alignment-gate §"Resolve inbound amendments before decomposing" and supersession-protocol §Amends. |
|
|
526
|
+
| 2026-07-07 | Cursor · Composer (with pwher) | **Added §Expected Breakage cascade** under §Expected Breakage & Consequences: milestone (plan ingest) → epic (planning) → task (`/hs-next` breakdown) allocates by altitude; task breakdown must read parent epic + milestone sections (plan-ingest-agent-workflow, pre-execution-alignment-gate; `alignment-gate.mjs` **Expected Breakage — parent context** block). Owner-directed. |
|
|
527
|
+
| 2026-08-14 | Claude Code (Opus 5) · with pwher | **§Claim eligibility: added the "review backlog is never a claim blocker" callout.** `in_review` / `review_pending` are terminal-for-recursion because they are build-complete; an unreviewed queue never gates the next claim and never needs owner permission to work past. Mirrors [[session-close-protocol]] §MVP Mode variant item 5 and `mvp_mode.review_backlog_never_blocks`. Owner ruling. |
|
|
528
|
+
| 2026-08-15 | Claude Code (Opus 5) · with pwher | **Added §Explain Like I'm 12 (required body section — milestone + epic)**, and added the section to the milestone + epic "Body must include" rows as the FIRST body section. Ten checkable writing properties observed from the approved example held verbatim in heyspex-north-star; milestone links there, epic does not; creation-time only (owner ruled **no backfill** of the ~3,400 existing specs); unfilled scaffold handled at breakdown like `## Expected Breakage & Consequences`, filing is not gated. Classification: template-shape. Owner ruling via HS-KJFZ-Z12C-CAP-every-milestone-and-every-epic-carries-a → HS-W5O3-K8AG-RES-explain-like-i-m-12-as-a-required. |
|
|
529
|
+
| 2026-08-15 | Claude Code (Opus 5) · with pwher | **Added §Rule 0 — grounding outranks style**, after the owner caught a drafted section claiming "HeySpex pays a service called Firecrawl". Every one of the ten style properties passed that sentence and it is false. Several style rules actively push toward invention, so Rule 0 now outranks them: every sentence is a rewrite of something the source says, and money / ownership / scale are never inferred. Added §"Written by a machine?" — a grounding critic was built for this and DOES NOT WORK (both DeepSeek V4 Flash and Pro reproduced the same false claim through it), so unattended writing refuses the whole class instead. Revised §Backfill: the no-backfill ruling was widened the same day to open + in_progress milestones and epics, generated sections carry a "not written by the author" marker, and a spec that cannot clear the strict lint is skipped rather than written. |
|
|
530
|
+
| 2026-08-22 | Claude Code · session `45051d11` (with pwher) | **§Diagnose rewritten: the leaf claim is the ONE-FIX case, not the only case.** The old bullet said a diagnose is *always* its own `ClaimTarget`, which left a bug needing several separate fixes with nowhere to put them. It now says a one-fix write-up is the claimable leaf and a multi-fix one goes through the breakdown stage (`heyspex_promote_diagnose` — the same stage as `heyspex_promote_research`, second input kind), with grounding before sizing, placement descending (epic gets tasks, milestone gets one epic, milestone minted last and owner-confirmed), and a resolvable milestone on everything spawned with no exemption. Two bullets added: **links, not parenting** (`spawned_epics:`/`spawned_tasks:` <-> `derived_from:`; the diagnose's own `parent:` keeps its bug-grouping job and is never touched, because an epic parented to a bug report does not render on the roadmap) and **closes on its reproduction, not on its children**. The claim-eligibility corollary row split in two: a not-broken-down diagnose is the claimable leaf; one that spawned work returns `rollup_state: "tracked_by_work"` and is not claimable. Per HS-ALBV-BFIX-EPIC-breakdown-stage-accepts-a-diagnose. |
|