heyspex 0.2.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/bin/hs.mjs +163 -11
- package/dist/cli/hs-check.mjs +88 -46
- package/dist/cli/hs-claim.mjs +84 -39
- package/dist/cli/hs-connect.mjs +583 -129
- package/dist/cli/hs-defer.mjs +251 -30
- package/dist/cli/hs-dev.mjs +20 -8
- package/dist/cli/hs-env.mjs +62 -34
- package/dist/cli/hs-index-rebuild.mjs +288 -83
- package/dist/cli/hs-index-reconcile.mjs +397 -111
- package/dist/cli/hs-init.mjs +2143 -91
- package/dist/cli/hs-install.mjs +628 -106
- package/dist/cli/hs-join.mjs +686 -236
- package/dist/cli/hs-vault-pull.mjs +3189 -179
- package/dist/cli/hs-vault-push.mjs +6433 -0
- package/dist/cli/hs-vault.mjs +396 -178
- package/dist/cli/hs-workspace.mjs +289 -151
- package/dist/cli-templates/harness-commands/claude/hs-backfill.md +28 -28
- package/dist/cli-templates/harness-commands/claude/hs-capture.md +62 -62
- package/dist/cli-templates/harness-commands/claude/hs-defer.md +29 -29
- package/dist/cli-templates/harness-commands/claude/hs-ground.md +30 -28
- package/dist/cli-templates/harness-commands/claude/hs-next.md +29 -29
- package/dist/cli-templates/harness-commands/claude/hs-promote.md +70 -70
- package/dist/cli-templates/harness-commands/claude/hs-push.md +35 -35
- package/dist/cli-templates/harness-commands/claude/hs-qc.md +27 -27
- package/dist/cli-templates/harness-commands/claude/hs-resolve.md +23 -23
- package/dist/cli-templates/harness-commands/claude/hs-review.md +23 -23
- package/dist/cli-templates/harness-commands/claude/hs-view.md +28 -26
- package/dist/cli-templates/harness-commands/claude/kill-ports.md +32 -32
- package/dist/cli-templates/harness-commands/claude/prototype.md +91 -91
- package/dist/cli-templates/harness-commands/cursor/hs-backfill.md +22 -22
- package/dist/cli-templates/harness-commands/cursor/hs-capture.md +56 -56
- package/dist/cli-templates/harness-commands/cursor/hs-defer.md +23 -23
- package/dist/cli-templates/harness-commands/cursor/hs-ground.md +24 -22
- package/dist/cli-templates/harness-commands/cursor/hs-next.md +23 -23
- package/dist/cli-templates/harness-commands/cursor/hs-promote.md +64 -64
- package/dist/cli-templates/harness-commands/cursor/hs-push.md +29 -29
- package/dist/cli-templates/harness-commands/cursor/hs-qc.md +21 -21
- package/dist/cli-templates/harness-commands/cursor/hs-resolve.md +17 -17
- package/dist/cli-templates/harness-commands/cursor/hs-review.md +17 -17
- package/dist/cli-templates/harness-commands/cursor/hs-view.md +24 -22
- package/dist/cli-templates/harness-commands/cursor/kill-ports.md +26 -26
- package/dist/cli-templates/harness-commands/cursor/prototype.md +86 -86
- package/docs/copilot-plugin-install.md +162 -0
- package/docs/driving-heyspex-from-copilot.md +165 -0
- package/package.json +20 -2
- package/plugins/heyspex/.claude-plugin/plugin.json +12 -12
- package/plugins/heyspex/.cursor-plugin/plugin.json +15 -15
- package/plugins/heyspex/README.md +309 -0
- package/plugins/heyspex/bin/run-hook.mjs +20 -2
- package/plugins/heyspex/hooks/cursor-hooks.json +81 -0
- package/plugins/heyspex/hooks/hooks.json +94 -37
- package/scripts/claude-hooks/_intent-classifier-router.mjs +456 -410
- package/scripts/claude-hooks/_intent-classifier-semantic.mjs +5 -0
- package/scripts/claude-hooks/_run.mjs +316 -23
- package/scripts/claude-hooks/capture-execution-gate.mjs +51 -0
- package/scripts/claude-hooks/claim-liveness-shared.mjs +2 -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/inject-communication-style.mjs +20 -0
- package/scripts/claude-hooks/intent-classifier-trigger.mjs +279 -247
- package/scripts/claude-hooks/session-end.mjs +2 -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 +5 -1
- package/scripts/cursor-hooks/manifest.mjs +46 -0
- package/scripts/heyspex-mode.mjs +20 -0
- package/scripts/hs-mode.mjs +1 -1
- package/scripts/hs-view.mjs +180 -17
- package/scripts/install-claude-code-hooks.mjs +3 -1
- package/scripts/lib/console-url-resolver.mjs +3 -2
- package/scripts/lib/customer-kit.mjs +327 -10
- package/scripts/lib/dev-mode.mjs +7 -6
- package/scripts/lib/directive-obligations.mjs +349 -0
- package/scripts/lib/hook-dispositions.mjs +210 -0
- package/scripts/lib/hook-vault-header.mjs +30 -0
- package/scripts/lib/hs-source-branch.mjs +196 -0
- package/scripts/lib/hs-source-log.mjs +2 -1
- package/scripts/lib/hs-source-preflight.mjs +18 -4
- package/scripts/lib/hs-source-push.mjs +386 -356
- package/scripts/lib/window-placement.mjs +109 -0
- package/spexharness/src/adapters/claude-code.mjs +11 -3
- package/spexharness/src/adapters/copilot.mjs +236 -0
- package/spexharness/src/adapters/detect-harness.mjs +34 -0
- package/spexharness/src/gates/_shell-write-targets.mjs +77 -0
- package/spexharness/src/gates/deep-research-cost-gate.mjs +4 -3
- 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/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/intent-classifier.mjs +4 -2
- package/spexharness/src/intent-directive.mjs +626 -541
- package/spexharness/src/rule-table.mjs +31 -1
- package/vendor/heyspex-mcp/account-switch.mjs +6 -5
- package/vendor/heyspex-mcp/capture-buffer-patches.mjs +31 -3
- package/vendor/heyspex-mcp/capture-console-client.mjs +37 -2
- package/vendor/heyspex-mcp/capture-focus.mjs +26 -2
- package/vendor/heyspex-mcp/capture-outbox.mjs +10 -4
- package/vendor/heyspex-mcp/capture-sources.mjs +195 -0
- package/vendor/heyspex-mcp/capture-tools.mjs +56 -11
- package/vendor/heyspex-mcp/claim-tools.mjs +25 -2
- package/vendor/heyspex-mcp/cli-verbs.mjs +19 -21
- package/vendor/heyspex-mcp/cli.mjs +7 -1
- package/vendor/heyspex-mcp/close-branch-report.mjs +102 -0
- package/vendor/heyspex-mcp/cloud-vault-writes.mjs +197 -7
- package/vendor/heyspex-mcp/console-fetch.mjs +192 -28
- package/vendor/heyspex-mcp/console-transport.mjs +7 -1
- package/vendor/heyspex-mcp/credentials.mjs +9 -8
- package/vendor/heyspex-mcp/dev-tools.mjs +7 -0
- package/vendor/heyspex-mcp/filing-tools.mjs +35 -0
- package/vendor/heyspex-mcp/fleet-queue-tools.mjs +2 -1
- package/vendor/heyspex-mcp/folder-trust-store.mjs +2 -1
- package/vendor/heyspex-mcp/http-transport.mjs +2 -0
- package/vendor/heyspex-mcp/list-tools.mjs +1 -1
- package/vendor/heyspex-mcp/mcp-config.mjs +14 -1
- package/vendor/heyspex-mcp/memory-tools.mjs +523 -523
- package/vendor/heyspex-mcp/obligation-backstop.mjs +103 -0
- package/vendor/heyspex-mcp/occupied-keys.mjs +1 -0
- package/vendor/heyspex-mcp/on-deck-brief.mjs +19 -2
- package/vendor/heyspex-mcp/on-deck-scheduler.mjs +1708 -1708
- package/vendor/heyspex-mcp/plan-push.mjs +3 -2
- package/vendor/heyspex-mcp/preflight-gate.mjs +1 -0
- package/vendor/heyspex-mcp/procedure-handlers.mjs +327 -325
- package/vendor/heyspex-mcp/procedure-tools.mjs +1181 -1159
- package/vendor/heyspex-mcp/promote-capture.mjs +2 -0
- package/vendor/heyspex-mcp/promote-research.mjs +6 -0
- package/vendor/heyspex-mcp/read-path.mjs +162 -6
- package/vendor/heyspex-mcp/request-context.mjs +25 -1
- package/vendor/heyspex-mcp/research-handlers.mjs +6 -4
- package/vendor/heyspex-mcp/roadmap-default.mjs +70 -0
- package/vendor/heyspex-mcp/session-owner.mjs +3 -2
- package/vendor/heyspex-mcp/session-tools.mjs +10 -0
- package/vendor/heyspex-mcp/spec-edit-tools.mjs +8 -1
- package/vendor/heyspex-mcp/split-research.mjs +3 -0
- package/vendor/heyspex-mcp/submit-for-review.mjs +18 -1
- package/vendor/heyspex-mcp/summary-write-tools.mjs +5 -1
- package/vendor/heyspex-mcp/test-helpers.mjs +18 -3
- package/vendor/heyspex-mcp/tool-catalog.mjs +7 -1
- package/vendor/heyspex-mcp/tool-dispatch.mjs +18 -0
- package/vendor/heyspex-mcp/vault-io.mjs +720 -724
- package/vendor/heyspex-mcp/vault-resolve.mjs +197 -9
- package/vendor/heyspex-mcp/whoami.mjs +2 -1
- package/vendor/heyspex-mcp/write-outbox.mjs +512 -0
|
@@ -7,59 +7,59 @@ description: Fast brain-offload capture — open/resume a capture, or route a na
|
|
|
7
7
|
|
|
8
8
|
**Usage:** `/hs-capture [HS-CAP-XXXX | HS-IDEA-XXXX] [promote]`
|
|
9
9
|
|
|
10
|
-
> **Platform asymmetry — read this, it is load-bearing.** Claude Code delivers only the **first whitespace token** of an MCP prompt's argument (GitHub [#14210](https://github.com/anthropics/claude-code/issues/14210), closed *not planned*), so the namespaced MCP prompt `/hs-capture` can carry **at most a single capture id** — never an intent word. This **native project command** is the only IDE surface that receives full `$ARGUMENTS`/`$1 $2`, so it is the only place `HS-CAP-1234 promote to research` can be parsed. The two surfaces are intentionally **not** identical; do not try to "make them match" — they cannot. Diagnosis + code anchors: [[HS-UIYC-34KP-RES-hs-capture-arg-routing-capture-id-and-pr]]. Owning epic: [[HS-7IOM-QKEF-EPIC-hs-capture-command-parity-resume-aware-s]].
|
|
11
|
-
|
|
12
|
-
## What to do
|
|
13
|
-
|
|
14
|
-
**1. Parse `$ARGUMENTS`** (both optional, order within the string is: id first, then intent words):
|
|
15
|
-
- Leading token matching `HS-(CAP|IDEA|DRAFT)-[A-Z0-9-]{3,}` (case-insensitive) → `capture_id`. `DRAFT` is tolerated here for a stray/manual `HS-DRAFT-*` id (e.g. pasted by hand) — the auto-launch bridge ([[HS-I6NU]]) resolves every companion draft to a real `HS-CAP-*` id before ever invoking this command, so a `DRAFT` id should not normally reach here.
|
|
16
|
-
- Remaining words containing `promote` (case-insensitive) → **promote intent**.
|
|
17
|
-
- Neither → the no-arg path.
|
|
18
|
-
|
|
19
|
-
If the capture tools are not already available in this session, call `heyspex_load_tools` first so `heyspex_active_capture` / `heyspex_promote_capture` / `heyspex_promote_capture_to_diagnose` are callable.
|
|
20
|
-
|
|
21
|
-
**2. Route on what you parsed:**
|
|
22
|
-
|
|
23
|
-
- **`capture_id` + promote intent** → route **straight to the promote exit**, bypassing the capture loop (do not run capture or ground=expand). Follow `/hs-promote`'s **§A. Capture → research** section verbatim (same tools, same two-phase confirm rule, same bug-fix→diagnose branch) — do **not** re-derive or fork that logic here; this command and `/hs-promote` share one promote implementation, this is just a second entrypoint into it.
|
|
24
|
-
|
|
25
|
-
- **`capture_id`, no promote** → **attach/resume that exact capture**: call `heyspex_active_capture({ spec_id: capture_id })`. The server honors the explicit id (resolves that capture DB-first, disk fallback) and, when it already has a Core Idea + Summary, returns it as a **resume**. Then follow the beats below. A non-existent id returns a clear "no such capture" error — surface it; **never** silently start a fresh capture under a near-miss id.
|
|
26
|
-
|
|
27
|
-
- **No arguments** → call `heyspex_active_capture({})`. It attaches to the capture on deck, or auto-creates a fresh `HS-CAP-*` when none is pinned. Then follow the beats below.
|
|
28
|
-
|
|
29
|
-
**3. Run the beats** (the capture protocol — source of truth is `.cursor/skills/hs-capture/SKILL.md` and the MCP prompt markdown; do not re-derive them). Grounding and expanding are the **same act** — three beats, not four:
|
|
30
|
-
|
|
31
|
-
| # | Action | Confirm? |
|
|
32
|
-
|---|--------|----------|
|
|
33
|
-
| 1 | **Capture** — every turn (including the user's answers to your questions), call `heyspex_update_capture` with `user_quote` = verbatim text. If Core Idea is empty, also pass `core_idea` + `summary` in the same call. | No |
|
|
34
|
-
| 2 | **Ground = Expand + sufficiency check** — chat-only, peer-level grounding (technical co-founder). The grounding output IS the Expanded Concept: write it to `agent_expansion` via `heyspex_update_capture` in the same pass, automatically. No offer, no user confirmation. Every `heyspex_update_capture` response carries a `sufficiency` verdict (the same scorer `heyspex_promote_capture` runs) — while it fails, elicit the listed missing elements (`example` / `done_when` / a considered `kind`) from the user and write them in this same pass. | No |
|
|
35
|
-
| 3 | **Promote** — the only exit, **gated**: only offered once the sufficiency verdict passes AND the owner has confirmed satisfaction with the enhanced capture. `heyspex_promote_capture` (research), or `heyspex_promote_capture_to_diagnose` for `kind: bug-fix`. The promote-time gate stays as defense-in-depth. **`heyspex_promote_capture` creates an outline, not a finished hand-off** — the response's `research_still_stub`/`next_step` fields say so when the research doc still has unfilled `_TBD — fill in this section._` placeholders; run `/hs-res` against it before `heyspex_promote_research` (which refuses stubs with `RESEARCH_STILL_STUB` as a backstop). | Yes |
|
|
36
|
-
|
|
37
|
-
After beat 2, the two choices depend on the sufficiency verdict ([[HS-X8GS-T9T6-EPIC-capture-sufficiency-gate-grounding-time]]):
|
|
38
|
-
- **Verdict fails** → present **iterate** and **enhance to readiness** (elicit the missing elements; never invent content to pass the gate). Do **not** present "promote to research" as a live option — an explicit owner instruction to promote anyway still wins.
|
|
39
|
-
- **Verdict passes** → show the enhanced capture and ask if the owner is satisfied with it; on that yes, present exactly two choices: **promote to research** (or promote-to-diagnose for `kind: bug-fix`) or **iterate**. A promote call is spent only after the owner's confirmation (confirm-before-offer + confirm-before-spend).
|
|
40
|
-
|
|
41
|
-
Never present "do you want to expand" as a choice — expansion already happened.
|
|
42
|
-
|
|
43
|
-
**Open-the-doc offer (agent captures only, owner ruling 2026-08-11):** Companion / Chrome-extension captures auto-open the solo window; agent captures must **not**. When `heyspex_update_capture` returns `offer_open_viewer` (first materialization) — or the first time the capture doc exists on disk — print that offer verbatim alongside promote/iterate (or right after the first "captured" ack):
|
|
44
|
-
|
|
45
|
-
> Want to see `HS-…-CAP`? Say **yes** / **open** / **show** and I'll open the doc.
|
|
46
|
-
|
|
47
|
-
On `yes` / `open` / `show`, immediately run `node bin/hs.mjs view docs <spec_id>` from the repo root. Do not ask twice, do not open unprompted, do not nag on later iterates.
|
|
48
|
-
|
|
49
|
-
**Iterate is the default continuation (owner ruling 2026-07-12).** While the capture sits at that choice, the user's next prose that isn't an explicit "promote" or "discard" IS the iterate move — even when it reads like a new idea or a work order ("please add …"), and even though the user never says "iterate". Append it to the SAME capture: `heyspex_update_capture` with the **explicit `spec_id`** of the capture in flow (never no-arg `heyspex_active_capture({})`, which can mint a fresh capture), re-ground into `agent_expansion`, and re-present the two choices. Only open a new capture when the prose is clearly a separate idea with no thread back — say so in one line first.
|
|
50
|
-
|
|
51
|
-
**Kind suggestion (during beat 2, HS-RZQO):** when the content signals a non-default kind — bug/error/broken/regression language → `bug-fix`; a bare URL/link-only body → `clip`; a pointer to a doc/resource → `reference`; an open question → `question` — offer it in the same reply ("this reads like a bug-fix capture — reclassify?") and on the user's yes pass `kind` in the next `heyspex_update_capture` call. Suggest once, never auto-apply, never nag.
|
|
52
|
-
|
|
53
|
-
**Model routing & thread split/spawn (owner ruling 2026-08-11):** settings at `.heyspex/config.yaml` → `agent_behaviors.capture_on_idea.{default_model, model_switch_mode, thread_split_mode}`; full table in `capture-guardrails.md` §"Capture model routing & thread split/spawn" and `.cursor/skills/hs-capture/SKILL.md`. On a first/only-turn capture, offer or silently delegate a model switch per `model_switch_mode` (`ask`\|`silent_delegate`\|`off`) — never a live silent switch, that's not possible. When new mid-thread prose isn't a continuation, judge whether it benefits from this thread's context: benefits → split (`Agent(subagent_type:"fork")` on a new capture id); doesn't → spawn (fresh `Agent()`); genuinely unsure and `thread_split_mode: ask` → `AskUserQuestion` with exactly those two options.
|
|
54
|
-
|
|
55
|
-
On a **resume** (capture already has Core Idea + Summary), skip re-capturing: greet with what's already there and offer the two resume moves — **iterate** (refine with new verbatim input) or **promote**. Expansion is automatic during grounding, not a menu item — there is **no** separate `/hs-expand` command or skill.
|
|
56
|
-
|
|
57
|
-
## Hard prohibitions
|
|
58
|
-
|
|
59
|
-
- **Never** offer to file epics, tasks, or implementation plans — promote-to-research (or promote-to-diagnose) is the only exit.
|
|
60
|
-
- **Never** implement the captured idea straight from the capture — its only road to code is promote-to-research → `/hs-promote <research-id>` + `/hs-next <resulting-id> [front]`. Milestone/epic/task filing is never skipped; front mode (handheld/assisted/autonomous) controls supervision, never whether that filing happens. The old permission-gated direct-implementation bypass is retired (research-capture-protocol §"From research to code — always through milestone/epic/task (no bypass)").
|
|
61
|
-
- **Never** ask the user whether to expand — Ground=Expand auto-writes `agent_expansion` every time, with no confirmation gate.
|
|
62
|
-
- **Never** auto-open a browser / solo window for an agent-originated capture — offer once (`yes`/`open`/`show`) and only then run `hs view docs <id>`.
|
|
63
|
-
- **Never** alter words inside a `## Notes` quote (format-wrapping is fine; word substitution is not).
|
|
64
|
-
- **Never** create a `type: research` doc without beat-3 (or promote-intent) confirmation.
|
|
65
|
-
- **Never** commit or push.
|
|
10
|
+
> **Platform asymmetry — read this, it is load-bearing.** Claude Code delivers only the **first whitespace token** of an MCP prompt's argument (GitHub [#14210](https://github.com/anthropics/claude-code/issues/14210), closed *not planned*), so the namespaced MCP prompt `/hs-capture` can carry **at most a single capture id** — never an intent word. This **native project command** is the only IDE surface that receives full `$ARGUMENTS`/`$1 $2`, so it is the only place `HS-CAP-1234 promote to research` can be parsed. The two surfaces are intentionally **not** identical; do not try to "make them match" — they cannot. Diagnosis + code anchors: [[HS-UIYC-34KP-RES-hs-capture-arg-routing-capture-id-and-pr]]. Owning epic: [[HS-7IOM-QKEF-EPIC-hs-capture-command-parity-resume-aware-s]].
|
|
11
|
+
|
|
12
|
+
## What to do
|
|
13
|
+
|
|
14
|
+
**1. Parse `$ARGUMENTS`** (both optional, order within the string is: id first, then intent words):
|
|
15
|
+
- Leading token matching `HS-(CAP|IDEA|DRAFT)-[A-Z0-9-]{3,}` (case-insensitive) → `capture_id`. `DRAFT` is tolerated here for a stray/manual `HS-DRAFT-*` id (e.g. pasted by hand) — the auto-launch bridge ([[HS-I6NU]]) resolves every companion draft to a real `HS-CAP-*` id before ever invoking this command, so a `DRAFT` id should not normally reach here.
|
|
16
|
+
- Remaining words containing `promote` (case-insensitive) → **promote intent**.
|
|
17
|
+
- Neither → the no-arg path.
|
|
18
|
+
|
|
19
|
+
If the capture tools are not already available in this session, call `heyspex_load_tools` first so `heyspex_active_capture` / `heyspex_promote_capture` / `heyspex_promote_capture_to_diagnose` are callable.
|
|
20
|
+
|
|
21
|
+
**2. Route on what you parsed:**
|
|
22
|
+
|
|
23
|
+
- **`capture_id` + promote intent** → route **straight to the promote exit**, bypassing the capture loop (do not run capture or ground=expand). Follow `/hs-promote`'s **§A. Capture → research** section verbatim (same tools, same two-phase confirm rule, same bug-fix→diagnose branch) — do **not** re-derive or fork that logic here; this command and `/hs-promote` share one promote implementation, this is just a second entrypoint into it.
|
|
24
|
+
|
|
25
|
+
- **`capture_id`, no promote** → **attach/resume that exact capture**: call `heyspex_active_capture({ spec_id: capture_id })`. The server honors the explicit id (resolves that capture DB-first, disk fallback) and, when it already has a Core Idea + Summary, returns it as a **resume**. Then follow the beats below. A non-existent id returns a clear "no such capture" error — surface it; **never** silently start a fresh capture under a near-miss id.
|
|
26
|
+
|
|
27
|
+
- **No arguments** → call `heyspex_active_capture({})`. It attaches to the capture on deck, or auto-creates a fresh `HS-CAP-*` when none is pinned. Then follow the beats below.
|
|
28
|
+
|
|
29
|
+
**3. Run the beats** (the capture protocol — source of truth is `.cursor/skills/hs-capture/SKILL.md` and the MCP prompt markdown; do not re-derive them). Grounding and expanding are the **same act** — three beats, not four:
|
|
30
|
+
|
|
31
|
+
| # | Action | Confirm? |
|
|
32
|
+
|---|--------|----------|
|
|
33
|
+
| 1 | **Capture** — every turn (including the user's answers to your questions), call `heyspex_update_capture` with `user_quote` = verbatim text. If Core Idea is empty, also pass `core_idea` + `summary` in the same call. | No |
|
|
34
|
+
| 2 | **Ground = Expand + sufficiency check** — chat-only, peer-level grounding (technical co-founder). The grounding output IS the Expanded Concept: write it to `agent_expansion` via `heyspex_update_capture` in the same pass, automatically. No offer, no user confirmation. Every `heyspex_update_capture` response carries a `sufficiency` verdict (the same scorer `heyspex_promote_capture` runs) — while it fails, elicit the listed missing elements (`example` / `done_when` / a considered `kind`) from the user and write them in this same pass. | No |
|
|
35
|
+
| 3 | **Promote** — the only exit, **gated**: only offered once the sufficiency verdict passes AND the owner has confirmed satisfaction with the enhanced capture. `heyspex_promote_capture` (research), or `heyspex_promote_capture_to_diagnose` for `kind: bug-fix`. The promote-time gate stays as defense-in-depth. **`heyspex_promote_capture` creates an outline, not a finished hand-off** — the response's `research_still_stub`/`next_step` fields say so when the research doc still has unfilled `_TBD — fill in this section._` placeholders; run `/hs-res` against it before `heyspex_promote_research` (which refuses stubs with `RESEARCH_STILL_STUB` as a backstop). | Yes |
|
|
36
|
+
|
|
37
|
+
After beat 2, the two choices depend on the sufficiency verdict ([[HS-X8GS-T9T6-EPIC-capture-sufficiency-gate-grounding-time]]):
|
|
38
|
+
- **Verdict fails** → present **iterate** and **enhance to readiness** (elicit the missing elements; never invent content to pass the gate). Do **not** present "promote to research" as a live option — an explicit owner instruction to promote anyway still wins.
|
|
39
|
+
- **Verdict passes** → show the enhanced capture and ask if the owner is satisfied with it; on that yes, present exactly two choices: **promote to research** (or promote-to-diagnose for `kind: bug-fix`) or **iterate**. A promote call is spent only after the owner's confirmation (confirm-before-offer + confirm-before-spend).
|
|
40
|
+
|
|
41
|
+
Never present "do you want to expand" as a choice — expansion already happened.
|
|
42
|
+
|
|
43
|
+
**Open-the-doc offer (agent captures only, owner ruling 2026-08-11):** Companion / Chrome-extension captures auto-open the solo window; agent captures must **not**. When `heyspex_update_capture` returns `offer_open_viewer` (first materialization) — or the first time the capture doc exists on disk — print that offer verbatim alongside promote/iterate (or right after the first "captured" ack):
|
|
44
|
+
|
|
45
|
+
> Want to see `HS-…-CAP`? Say **yes** / **open** / **show** and I'll open the doc.
|
|
46
|
+
|
|
47
|
+
On `yes` / `open` / `show`, immediately run `node bin/hs.mjs view docs <spec_id>` from the repo root. Do not ask twice, do not open unprompted, do not nag on later iterates.
|
|
48
|
+
|
|
49
|
+
**Iterate is the default continuation (owner ruling 2026-07-12).** While the capture sits at that choice, the user's next prose that isn't an explicit "promote" or "discard" IS the iterate move — even when it reads like a new idea or a work order ("please add …"), and even though the user never says "iterate". Append it to the SAME capture: `heyspex_update_capture` with the **explicit `spec_id`** of the capture in flow (never no-arg `heyspex_active_capture({})`, which can mint a fresh capture), re-ground into `agent_expansion`, and re-present the two choices. Only open a new capture when the prose is clearly a separate idea with no thread back — say so in one line first.
|
|
50
|
+
|
|
51
|
+
**Kind suggestion (during beat 2, HS-RZQO):** when the content signals a non-default kind — bug/error/broken/regression language → `bug-fix`; a bare URL/link-only body → `clip`; a pointer to a doc/resource → `reference`; an open question → `question` — offer it in the same reply ("this reads like a bug-fix capture — reclassify?") and on the user's yes pass `kind` in the next `heyspex_update_capture` call. Suggest once, never auto-apply, never nag.
|
|
52
|
+
|
|
53
|
+
**Model routing & thread split/spawn (owner ruling 2026-08-11):** settings at `.heyspex/config.yaml` → `agent_behaviors.capture_on_idea.{default_model, model_switch_mode, thread_split_mode}`; full table in `capture-guardrails.md` §"Capture model routing & thread split/spawn" and `.cursor/skills/hs-capture/SKILL.md`. On a first/only-turn capture, offer or silently delegate a model switch per `model_switch_mode` (`ask`\|`silent_delegate`\|`off`) — never a live silent switch, that's not possible. When new mid-thread prose isn't a continuation, judge whether it benefits from this thread's context: benefits → split (`Agent(subagent_type:"fork")` on a new capture id); doesn't → spawn (fresh `Agent()`); genuinely unsure and `thread_split_mode: ask` → `AskUserQuestion` with exactly those two options.
|
|
54
|
+
|
|
55
|
+
On a **resume** (capture already has Core Idea + Summary), skip re-capturing: greet with what's already there and offer the two resume moves — **iterate** (refine with new verbatim input) or **promote**. Expansion is automatic during grounding, not a menu item — there is **no** separate `/hs-expand` command or skill.
|
|
56
|
+
|
|
57
|
+
## Hard prohibitions
|
|
58
|
+
|
|
59
|
+
- **Never** offer to file epics, tasks, or implementation plans — promote-to-research (or promote-to-diagnose) is the only exit.
|
|
60
|
+
- **Never** implement the captured idea straight from the capture — its only road to code is promote-to-research → `/hs-promote <research-id>` + `/hs-next <resulting-id> [front]`. Milestone/epic/task filing is never skipped; front mode (handheld/assisted/autonomous) controls supervision, never whether that filing happens. The old permission-gated direct-implementation bypass is retired (research-capture-protocol §"From research to code — always through milestone/epic/task (no bypass)").
|
|
61
|
+
- **Never** ask the user whether to expand — Ground=Expand auto-writes `agent_expansion` every time, with no confirmation gate.
|
|
62
|
+
- **Never** auto-open a browser / solo window for an agent-originated capture — offer once (`yes`/`open`/`show`) and only then run `hs view docs <id>`.
|
|
63
|
+
- **Never** alter words inside a `## Notes` quote (format-wrapping is fine; word substitution is not).
|
|
64
|
+
- **Never** create a `type: research` doc without beat-3 (or promote-intent) confirmation.
|
|
65
|
+
- **Never** commit or push.
|
|
@@ -7,26 +7,26 @@ description: Defer remaining work on the claimed task — file a split child wit
|
|
|
7
7
|
|
|
8
8
|
**Usage:** `/hs-defer [HS-XXXX-TASK] (optional — defaults to the task you are working)`
|
|
9
9
|
|
|
10
|
-
> **SaaS-safety note:** orchestration lives in `vendor/heyspex-mcp/cli.mjs` (`heyspex_defer_spec` → `POST /api/specs/:id/defer`). Do not re-implement the defer write path here.
|
|
11
|
-
|
|
12
|
-
## What to do
|
|
13
|
-
|
|
14
|
-
When the user sends `/hs-defer` (optionally with a bare `HS-TASK-*` id):
|
|
15
|
-
|
|
16
|
-
1. **Identify the parent task** — the optional arg, else the spec you currently hold a claim on.
|
|
17
|
-
|
|
18
|
-
2. **Author the handoff envelope** from session context (do not ask the user to paste a handoff prompt):
|
|
19
|
-
- `reason` — why you are deferring (context budget, blocked, lane hand-off, …)
|
|
20
|
-
- `summary_done` — verified work completed this session
|
|
21
|
-
- `remaining` — actionable items for whoever picks it up
|
|
22
|
-
- `success_criteria` — how the reviewer knows the deferred work is done
|
|
23
|
-
|
|
24
|
-
3. **Call** `heyspex_defer_spec` with `{ spec_id, reason, summary_done, remaining, success_criteria }` plus optional `parent_status` (`in_review` default, or `in_progress` when the parent is not independently reviewable), `effort`, `child_name`.
|
|
25
|
-
|
|
26
|
-
4. **Tell the user** the returned `child_id` and that they can open a fresh window and run `/hs-next` to continue. The tool pins the child on-deck, releases the parent claim, and records WIP on the epic.
|
|
27
|
-
|
|
28
|
-
## Not this command
|
|
29
|
-
|
|
30
|
-
- `hs defer` / `hs undefer` — time-shifts a spec via `defer_until` ([[HS-ZZBN]]), not delegation split-child defer.
|
|
31
|
-
|
|
32
|
-
Cross-reference: [[HS-MS3T-1U0Z-TASK-hs-defer-mcp-tool-and-slash-command]], [[HS-DTL1-CX5K-CAP-task-split-handoff-when-context-runs-low]], [[HS-HXE2-YQ5A-EPIC-delegation-defer-work-from-one-agent-to]].
|
|
10
|
+
> **SaaS-safety note:** orchestration lives in `vendor/heyspex-mcp/cli.mjs` (`heyspex_defer_spec` → `POST /api/specs/:id/defer`). Do not re-implement the defer write path here.
|
|
11
|
+
|
|
12
|
+
## What to do
|
|
13
|
+
|
|
14
|
+
When the user sends `/hs-defer` (optionally with a bare `HS-TASK-*` id):
|
|
15
|
+
|
|
16
|
+
1. **Identify the parent task** — the optional arg, else the spec you currently hold a claim on.
|
|
17
|
+
|
|
18
|
+
2. **Author the handoff envelope** from session context (do not ask the user to paste a handoff prompt):
|
|
19
|
+
- `reason` — why you are deferring (context budget, blocked, lane hand-off, …)
|
|
20
|
+
- `summary_done` — verified work completed this session
|
|
21
|
+
- `remaining` — actionable items for whoever picks it up
|
|
22
|
+
- `success_criteria` — how the reviewer knows the deferred work is done
|
|
23
|
+
|
|
24
|
+
3. **Call** `heyspex_defer_spec` with `{ spec_id, reason, summary_done, remaining, success_criteria }` plus optional `parent_status` (`in_review` default, or `in_progress` when the parent is not independently reviewable), `effort`, `child_name`.
|
|
25
|
+
|
|
26
|
+
4. **Tell the user** the returned `child_id` and that they can open a fresh window and run `/hs-next` to continue. The tool pins the child on-deck, releases the parent claim, and records WIP on the epic.
|
|
27
|
+
|
|
28
|
+
## Not this command
|
|
29
|
+
|
|
30
|
+
- `hs defer` / `hs undefer` — time-shifts a spec via `defer_until` ([[HS-ZZBN]]), not delegation split-child defer.
|
|
31
|
+
|
|
32
|
+
Cross-reference: [[HS-MS3T-1U0Z-TASK-hs-defer-mcp-tool-and-slash-command]], [[HS-DTL1-CX5K-CAP-task-split-handoff-when-context-runs-low]], [[HS-HXE2-YQ5A-EPIC-delegation-defer-work-from-one-agent-to]].
|
|
@@ -7,25 +7,27 @@ description: Pre-plan grounding — a single bounded (~2k-token) report (Scope
|
|
|
7
7
|
|
|
8
8
|
**Usage:** `/hs-ground [topic words] [--summary <text>] [--areas a,b] [--tags x,y] [--max-tokens N]`
|
|
9
9
|
|
|
10
|
-
> **Thin trigger.** Retrieval, scoring, conflict detection, caps, and report assembly all live in the MCP server (`vendor/heyspex-mcp/plan-ground.mjs`, `report:true` path). Do not re-implement grounding logic here, and do not turn the report into a vault-reading scaffold — that is the exact failure this command replaces ([[hs-ground-as-built-mcp-failure-modes]], [[HS-BZTV-G7R2-EPIC-hs-ground-three-tier-grounding-report]]).
|
|
11
|
-
|
|
12
|
-
## What to do
|
|
13
|
-
|
|
14
|
-
1. **Parse `$ARGUMENTS`** (topic is required — the bare words are the topic):
|
|
15
|
-
- free text → `topic` (and reuse as `summary` if no `--summary`)
|
|
16
|
-
- `--summary <text>` → `summary`
|
|
17
|
-
- `--areas a,b` → `areas` (subset of: console, companion, mcp, vault, indexer)
|
|
18
|
-
- `--tags x,y` → `tags`
|
|
19
|
-
- `--max-tokens N` → `max_tokens` (default 2000)
|
|
20
|
-
|
|
21
|
-
2. **Call** `heyspex_ground_plan` with **`report: true`** plus the parsed args (and `check_conflicts: true`). The tool returns the bounded report as markdown directly.
|
|
22
|
-
|
|
23
|
-
3. **Output the returned report verbatim.** It is already capped and cited. Then **stop and act on it** — do **NOT** open the discovered specs, run broad `rg`, or read whole files. The report's "Relevant specs" list is a wide lexical-recall window and **you are the reranker**: open *only* the one or two specs you judge directly relevant to the task, if any.
|
|
24
|
-
|
|
25
|
-
4. **If the footer / report shows blocking conflicts** (`conflicts: N (BLOCKING …)`), resolve them via `/hs-resolve` before treating any conflicted spec as authoritative; re-run `/hs-ground` after resolution.
|
|
26
|
-
|
|
27
|
-
5. **Heed the Conflicts caveat.** The conflict detector is claim-level and blind to design-supersession / identifier drift — for substrate/decision questions, check the design-vs-decision axis yourself ([[drift-is-two-axes-as-built-and-design-supersession]]).
|
|
28
|
-
|
|
29
|
-
6. *(Optional)* If the task needs durable context, call `heyspex_recall_memories` with the report's `recall_memories_hint` tags — once, `limit: 10`.
|
|
30
|
-
|
|
31
|
-
Sibling skills: `/hs-next` (build pipeline), `/hs-resolve` (resolution lane), `/hs-review` (review pipeline). Hand off a grounded plan to `/hs-push`.
|
|
10
|
+
> **Thin trigger.** Retrieval, scoring, conflict detection, caps, and report assembly all live in the MCP server (`vendor/heyspex-mcp/plan-ground.mjs`, `report:true` path). Do not re-implement grounding logic here, and do not turn the report into a vault-reading scaffold — that is the exact failure this command replaces ([[hs-ground-as-built-mcp-failure-modes]], [[HS-BZTV-G7R2-EPIC-hs-ground-three-tier-grounding-report]]).
|
|
11
|
+
|
|
12
|
+
## What to do
|
|
13
|
+
|
|
14
|
+
1. **Parse `$ARGUMENTS`** (topic is required — the bare words are the topic):
|
|
15
|
+
- free text → `topic` (and reuse as `summary` if no `--summary`)
|
|
16
|
+
- `--summary <text>` → `summary`
|
|
17
|
+
- `--areas a,b` → `areas` (subset of: console, companion, mcp, vault, indexer)
|
|
18
|
+
- `--tags x,y` → `tags`
|
|
19
|
+
- `--max-tokens N` → `max_tokens` (default 2000)
|
|
20
|
+
|
|
21
|
+
2. **Call** `heyspex_ground_plan` with **`report: true`** plus the parsed args (and `check_conflicts: true`). The tool returns the bounded report as markdown directly.
|
|
22
|
+
|
|
23
|
+
3. **Output the returned report verbatim.** It is already capped and cited. Then **stop and act on it** — do **NOT** open the discovered specs, run broad `rg`, or read whole files. The report's "Relevant specs" list is a wide lexical-recall window and **you are the reranker**: open *only* the one or two specs you judge directly relevant to the task, if any.
|
|
24
|
+
|
|
25
|
+
4. **If the footer / report shows blocking conflicts** (`conflicts: N (BLOCKING …)`), resolve them via `/hs-resolve` before treating any conflicted spec as authoritative; re-run `/hs-ground` after resolution.
|
|
26
|
+
|
|
27
|
+
5. **Heed the Conflicts caveat.** The conflict detector is claim-level and blind to design-supersession / identifier drift — for substrate/decision questions, check the design-vs-decision axis yourself ([[drift-is-two-axes-as-built-and-design-supersession]]).
|
|
28
|
+
|
|
29
|
+
6. *(Optional)* If the task needs durable context, call `heyspex_recall_memories` with the report's `recall_memories_hint` tags — once, `limit: 10`.
|
|
30
|
+
|
|
31
|
+
Sibling skills: `/hs-next` (build pipeline), `/hs-resolve` (resolution lane), `/hs-review` (review pipeline). Hand off a grounded plan to `/hs-push`.
|
|
32
|
+
|
|
33
|
+
7. **When grounding a capture on deck, record it** (HS-KNJ8). Once the report is read and you have judged what is already built / already decided / the owner's own working reference / the residual delta, run `node scripts/record-grounding.mjs --capture <HS-CAP-id> --built "..." --decided "..." --reference "..." --delta "..."`. It writes `.heyspex/research-grounding.json` (the shape the deep-research gate reads) and marks the capture expanded. Until it runs, the capture-execution gate refuses research gathers, paid-model synthesis and routing-edit sub-agents for that capture.
|
|
@@ -7,26 +7,26 @@ description: Pull the next on-deck execution prompt from the HeySpex roadmap (fo
|
|
|
7
7
|
|
|
8
8
|
**Usage:** `/hs-next [handheld|assist|auto] [HS-XXXX-EPIC | HS-XXXX] [--include-horizon] [--ignore-focus] [--claim]`
|
|
9
9
|
|
|
10
|
-
> **SaaS-safety note:** this file is a thin shim — the workflow orchestration (claim question wording, reply→action mapping, failure-mode handling) lives in `vendor/heyspex-mcp/cli.mjs` (`composeAgentOrchestration`) and is delivered to you as the structured `agent_dispatch` object. **Do not add orchestration prose here.** If a workflow detail needs to change, change it in the MCP server so customer workspaces can't corrupt it. See [[HS-CCKM-J6CD-RES-migrate-slash-command-orchestration-from]] and [[workflow-orchestration-belongs-in-mcp-not-claude-commands]].
|
|
11
|
-
|
|
12
|
-
## What to do
|
|
13
|
-
|
|
14
|
-
1. **Parse `$ARGUMENTS`** (all optional, order-flexible):
|
|
15
|
-
- **Run front** (default `handheld`): `handheld` · `assist` | `assisted` · `auto` | `autonomous` → canonical `front` for MCP (`handheld` | `assisted` | `autonomous`; omit when handheld/default)
|
|
16
|
-
- bare token `HS-EPIC-*` or `HS-*` → `spec_id`
|
|
17
|
-
- bare token `HS-ROADMAP-*` → `roadmap_id`
|
|
18
|
-
- `--include-horizon` → `include_horizon: true`
|
|
19
|
-
- `--ignore-focus` → `ignore_focus: true`
|
|
20
|
-
- `--claim` | `--auto-claim` → `auto_claim: true`. Skips the yes/proceed/confirm handshake and claims immediately — same mechanism `autonomous` front already triggers automatically (`shouldAutoClaimOnDeck` in `run-front.mjs`), just usable standalone at any front. `/hs-next HS-IUQO --claim` claims and starts handheld work with no ask; `/hs-next HS-IUQO assisted --claim` does the same at assisted supervision. (Redundant, never conflicting, with `autonomous` front, which already implies it.)
|
|
21
|
-
|
|
22
|
-
2. **Call** `heyspex_next_on_deck` with `summary: true` plus the parsed args (including `front` when not handheld/default, and `auto_claim: true` when `--claim`/`--auto-claim` was passed).
|
|
23
|
-
|
|
24
|
-
3. **Output the `user_prompt_markdown` field verbatim** to the user. Do not summarize, paraphrase, or trim. **Do NOT echo the `agent_dispatch` field** — it is a structured routing object you decode, not prose you print. (The @deprecated `prompt_markdown` field mirrors `user_prompt_markdown`; either is safe to print, but prefer `user_prompt_markdown`.) Schema: `specs/schemas/agent-dispatch.schema.json`.
|
|
25
|
-
|
|
26
|
-
4. **On the user's reply**, decode `agent_dispatch`:
|
|
27
|
-
- Match the reply against each entry's `tokens` array under `on_user_reply` (or `drift_resolution_menu`, when present).
|
|
28
|
-
- If the matching entry has `actions`, invoke each `{ tool, args }` in order. If `execute_after: true`, begin executing the work in the same turn — no second permission ask. All listed tools (`heyspex_claim_spec`, `heyspex_record_alignment`, `heyspex_next_on_deck`, `heyspex_release_spec`) are pre-allowlisted.
|
|
29
|
-
- If the matching entry has `reply`, respond with that string verbatim.
|
|
30
|
-
- If the `default` entry is `"respond_to_user_question"`, treat the reply as a redirect: answer the user's actual question instead of claiming.
|
|
31
|
-
- For any tool error, look up its code in `agent_dispatch.failure_modes` and apply the named `handling` only when that error code was **returned by the tool call** — failure_modes are conditional, not a statement that the console is down. Trust `console_status.reachable` on the brief. Never hand-write vault files when `heyspex_file_spec` fails.
|
|
32
|
-
- On session hand-off, run the `on_handoff` actions (typically `heyspex_release_spec`).
|
|
10
|
+
> **SaaS-safety note:** this file is a thin shim — the workflow orchestration (claim question wording, reply→action mapping, failure-mode handling) lives in `vendor/heyspex-mcp/cli.mjs` (`composeAgentOrchestration`) and is delivered to you as the structured `agent_dispatch` object. **Do not add orchestration prose here.** If a workflow detail needs to change, change it in the MCP server so customer workspaces can't corrupt it. See [[HS-CCKM-J6CD-RES-migrate-slash-command-orchestration-from]] and [[workflow-orchestration-belongs-in-mcp-not-claude-commands]].
|
|
11
|
+
|
|
12
|
+
## What to do
|
|
13
|
+
|
|
14
|
+
1. **Parse `$ARGUMENTS`** (all optional, order-flexible):
|
|
15
|
+
- **Run front** (default `handheld`): `handheld` · `assist` | `assisted` · `auto` | `autonomous` → canonical `front` for MCP (`handheld` | `assisted` | `autonomous`; omit when handheld/default)
|
|
16
|
+
- bare token `HS-EPIC-*` or `HS-*` → `spec_id`
|
|
17
|
+
- bare token `HS-ROADMAP-*` → `roadmap_id`
|
|
18
|
+
- `--include-horizon` → `include_horizon: true`
|
|
19
|
+
- `--ignore-focus` → `ignore_focus: true`
|
|
20
|
+
- `--claim` | `--auto-claim` → `auto_claim: true`. Skips the yes/proceed/confirm handshake and claims immediately — same mechanism `autonomous` front already triggers automatically (`shouldAutoClaimOnDeck` in `run-front.mjs`), just usable standalone at any front. `/hs-next HS-IUQO --claim` claims and starts handheld work with no ask; `/hs-next HS-IUQO assisted --claim` does the same at assisted supervision. (Redundant, never conflicting, with `autonomous` front, which already implies it.)
|
|
21
|
+
|
|
22
|
+
2. **Call** `heyspex_next_on_deck` with `summary: true` plus the parsed args (including `front` when not handheld/default, and `auto_claim: true` when `--claim`/`--auto-claim` was passed).
|
|
23
|
+
|
|
24
|
+
3. **Output the `user_prompt_markdown` field verbatim** to the user. Do not summarize, paraphrase, or trim. **Do NOT echo the `agent_dispatch` field** — it is a structured routing object you decode, not prose you print. (The @deprecated `prompt_markdown` field mirrors `user_prompt_markdown`; either is safe to print, but prefer `user_prompt_markdown`.) Schema: `specs/schemas/agent-dispatch.schema.json`.
|
|
25
|
+
|
|
26
|
+
4. **On the user's reply**, decode `agent_dispatch`:
|
|
27
|
+
- Match the reply against each entry's `tokens` array under `on_user_reply` (or `drift_resolution_menu`, when present).
|
|
28
|
+
- If the matching entry has `actions`, invoke each `{ tool, args }` in order. If `execute_after: true`, begin executing the work in the same turn — no second permission ask. All listed tools (`heyspex_claim_spec`, `heyspex_record_alignment`, `heyspex_next_on_deck`, `heyspex_release_spec`) are pre-allowlisted.
|
|
29
|
+
- If the matching entry has `reply`, respond with that string verbatim.
|
|
30
|
+
- If the `default` entry is `"respond_to_user_question"`, treat the reply as a redirect: answer the user's actual question instead of claiming.
|
|
31
|
+
- For any tool error, look up its code in `agent_dispatch.failure_modes` and apply the named `handling` only when that error code was **returned by the tool call** — failure_modes are conditional, not a statement that the console is down. Trust `console_status.reachable` on the brief. Never hand-write vault files when `heyspex_file_spec` fails.
|
|
32
|
+
- On session hand-off, run the `on_handoff` actions (typically `heyspex_release_spec`).
|
|
@@ -7,67 +7,67 @@ description: Promote whatever doc you hand it to its next stage — a capture (H
|
|
|
7
7
|
|
|
8
8
|
**Usage:** `/hs-promote <HS-CAP-XXXX[,HS-CAP-YYYY...] | HS-RES-XXXX> [rest of args depend on which — see below]`
|
|
9
9
|
|
|
10
|
-
> **Platform asymmetry — read this, it is load-bearing.** Claude Code delivers only the **first whitespace token** of an MCP prompt's argument (GitHub [#14210](https://github.com/anthropics/claude-code/issues/14210), closed *not planned*), so the namespaced MCP prompts (`/hs-promote-capture`, `/hs-promote-research`) can each carry at most a single token. This **native project command** is the only IDE surface that receives full `$ARGUMENTS`.
|
|
11
|
-
>
|
|
12
|
-
> **Why one command instead of two.** `/hs-promote-capture` and `/hs-promote-research` used to be separate commands — which meant typing the word "promote" twice (`/hs-promote-capture HS-CAP-XXXX promote`) when the command name already said what it does. There's exactly one verb here — *promote whatever doc you hand it to its next stage* — so there's one command. The **id prefix alone** tells you which flow applies (`HS-CAP-*` vs `HS-RES-*` are mutually exclusive and mechanical to detect); the two flows underneath are otherwise unrelated (different tools, different payload shapes, different two-phase mechanics) and stay fully separate below — only the entrypoint is shared.
|
|
13
|
-
|
|
14
|
-
## Step 0 — identify the doc
|
|
15
|
-
|
|
16
|
-
Read the **leading token** of `$ARGUMENTS` (case-insensitive; captures may be a comma/whitespace-separated list):
|
|
17
|
-
- Contains `-CAP` as its type label (legacy `HS-CAP-XXXX` or era-3 `HS-<fileKey>-<familyKey>-CAP-<slug>`) → go to **§A. Capture → research**.
|
|
18
|
-
- Contains `-RES` the same way → go to **§A2. Research → milestone**.
|
|
19
|
-
- **Era-3 short/display forms carry NO type label** — `HS-XV4W` (short id) and `HS-XV4W-HV6H` (file key + family key, the form humans see rendered) name a spec without saying its kind. Resolve the kind by fetching it: `heyspex_active_capture({ spec_id })` succeeding → it's a capture, §A. Otherwise treat it as research and try §A2. The tools accept any of these forms and collapse them to the stored short id themselves — never tell the user their id is wrong just because it carries (or lacks) the family key.
|
|
20
|
-
- None of the above → ask the user which doc they mean (don't guess).
|
|
21
|
-
|
|
22
|
-
If the capture tools are not already available in this session, call `heyspex_load_tools` first so `heyspex_active_capture` / `heyspex_promote_capture` / `heyspex_promote_capture_to_diagnose` are callable.
|
|
23
|
-
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
## §A. Capture → research (`HS-CAP-*`)
|
|
27
|
-
|
|
28
|
-
**1. Parse the rest of `$ARGUMENTS`:**
|
|
29
|
-
- Leading token(s) matching `HS-CAP-[A-Z0-9-]{3,}` (comma- and/or whitespace-separated) → `capture_ids` (1 or more).
|
|
30
|
-
- Next token: `HS-RES-[A-Z0-9-]{3,}` → `target_research` = that id. Or the literal word `new`/`NEW` (also the default when this token is omitted entirely) → `target_research = "NEW"`; any remaining words up to an `enhances:` token → `new_research_name`.
|
|
31
|
-
- A token shaped `enhances:HS-MIL-XXXX` anywhere in the string → `enhances`.
|
|
32
|
-
|
|
33
|
-
**2. Route by kind:**
|
|
34
|
-
- For each `capture_id`, read its `kind:` via `heyspex_active_capture({ spec_id: capture_id })`.
|
|
35
|
-
- Exactly one capture_id AND its `kind: bug-fix` → `heyspex_promote_capture_to_diagnose({ capture_id })` (creates `HS-DIAG-*`). Never mix a bug-fix capture into a multi-capture research promote.
|
|
36
|
-
- Otherwise → `heyspex_promote_capture({ capture_ids, target_research, new_research_name?, enhances? })`:
|
|
37
|
-
- `target_research === "NEW"` is **two-phase**: first call **omits** `accepted_outline` — it returns a proposed `{ name, outline, tags, enhances_suggestion }`. **Show it to the user and confirm** before calling again with the same args plus `accepted_outline` (Phase 2 performs the writes). Never skip straight to Phase 2.
|
|
38
|
-
- An existing `target_research` id is single-phase (direct, idempotent append) — no outline confirm needed.
|
|
39
|
-
- A `CAPTURE_INSUFFICIENT` error names the missing elements (core-idea, example, done-criteria, kind, user-stories) — the correct response is to elicit that detail from the user and improve the capture, not to pass `force_promote: true` unless the human explicitly says to promote anyway.
|
|
40
|
-
- **Check the outline against the capture's own Notes before presenting it.** Before showing `proposed_outline` (AI-proposed or agent-authored) to the user, walk every verbatim quote in the capture's `## Notes` and state plainly whether the outline addresses it. If a quote asks for something the outline doesn't cover, add a section for it or say so before asking for confirm — a missed verbatim quote is exactly what got two real items dropped from a milestone in this vault's own history ([[HS-GDT5-F16L-DIAG-promote-flow-drafts-research-and-stubs]]).
|
|
41
|
-
- **Outline confirm ≠ research done.** Phase 2 only writes the research **stub** — every section body is the literal placeholder `_TBD — fill in this section._`. Confirming the outline approves its *shape* (section headings), not its findings. As the very next step after Phase 2 creates the file, fill in every section with real content **by running the `/hs-res` method** (SpexCrawl gather via the Companion + DeepSeek synthesis — see `.claude/commands/hs-res.md`); **never author the research yourself in the main session** — main-session self-research skips the routed research seats and burns the expensive model on work the fleet owns. Do not report the research as complete, and do not move on to `/hs-promote-research`, until the TBD placeholders are gone. (`heyspex_promote_research` mechanically refuses with `RESEARCH_STILL_STUB` while any remain, but don't rely on that gate — write the research because it's the point of the flow, not because a check will otherwise fail.)
|
|
42
|
-
|
|
43
|
-
**3. Report the result** — the research id (created or extended) or diagnose id created, and confirm the capture(s)' `promoted_to` now points at it.
|
|
44
|
-
|
|
45
|
-
---
|
|
46
|
-
|
|
47
|
-
## §A2. Research → milestone (`HS-RES-*`)
|
|
48
|
-
|
|
49
|
-
**1. Parse the rest of `$ARGUMENTS`:**
|
|
50
|
-
- `research_id` is the leading `HS-RES-*` token (already identified in Step 0).
|
|
51
|
-
- Next word matching `spawn|augment|both` → `intent`. Default `spawn` when omitted.
|
|
52
|
-
- Next token: `HS-MIL-[A-Z0-9-]{3,}` → `target_milestone` = that id. Or the literal word `new`/`NEW` (also the default when this token is omitted entirely) → `target_milestone = "NEW"`; remaining words → `new_milestone_name`.
|
|
53
|
-
- If `intent` includes `augment`, any remaining `HS-EPIC-[A-Z0-9-]{3,}` tokens → `augment_epic_ids` (required in that case — ask for them if `augment` was requested but none were given).
|
|
54
|
-
|
|
55
|
-
**2. Default policy:** `target_milestone: "NEW"` unless the user names an **existing `status: open`** milestone that clearly extends the same thesis. Spawning into an `in_progress` milestone is blocked unless the owner explicitly passes `attach_to_in_progress_milestone: true` + `attach_override_reason` (≥40 chars audit trail) — never default to this path or infer the override on the agent's own judgment.
|
|
56
|
-
|
|
57
|
-
**3. Phase 1 — proposal.** Call `heyspex_promote_research({ research_id, target_milestone, new_milestone_name?, intent, spawn_epic_count?, augment_epic_ids? })` **without** `accepted_stubs`. Show the user the returned `proposed_stubs[]` and let them edit/remove/approve.
|
|
58
|
-
- **If `ai_proposal.ok === false` (e.g. `reason: "no_api_key"`), `proposed_stubs` comes back empty — the agent must author the stubs itself.** This is NOT a shortcut to skip the confirm step; it makes the confirm step *more* necessary, not less, because nothing upstream has vetted these stubs yet. Author them from the research doc's actual content, present them to the user exactly as you would an AI proposal (name/kind/effort/rationale per stub), and wait for a real approval turn before calling Phase 2. **Do not call Phase 2 in the same turn you authored the stubs in** — that is precisely the failure this line exists to prevent (observed 2026-08-12: an agent self-authored 3 epic stubs and executed `accepted_stubs` in the same tool-call batch with no human turn in between).
|
|
59
|
-
- **Check the stubs against the SOURCE CAPTURE's own Notes before presenting them.** Before showing `proposed_stubs` (AI-proposed or agent-authored) to the user, walk every verbatim quote in the source capture's `## Notes` — the capture(s) named in the research doc's `sources_captures`, not just the research doc's own prose, since a two-hop drift can lose fidelity the research doc's text won't show — and confirm each is addressed by a stub or explicitly named as out of scope. This check caught two real gaps missed by an agent-authored stub list in this vault's own history ([[HS-GDT5-F16L-DIAG-promote-flow-drafts-research-and-stubs]]).
|
|
60
|
-
|
|
61
|
-
**4. Phase 2 — execute (after human confirms).** Call again with the same args plus `accepted_stubs: [...]` (the confirmed, possibly-edited subset) to perform the transactional write.
|
|
62
|
-
|
|
63
|
-
**5. Report the result** — the milestone id (new or existing) plus spawned epic ids, or the augmented epic ids. Note that research stays `status: open` (research is evergreen) — only its `enhances:`/`spawned_epics:` links change.
|
|
64
|
-
|
|
65
|
-
---
|
|
66
|
-
|
|
67
|
-
## Hard prohibitions
|
|
68
|
-
|
|
69
|
-
- **Never** execute a Phase-2 write (`accepted_outline` or `accepted_stubs`) without the human having seen and confirmed the Phase-1 proposal. For `accepted_stubs` the tool now refuses this mechanically: the proposal turn leaves a marker keyed on the research id, and an execute turn without one returns `STUB_REVIEW_REQUIRED`. If the human replaced every proposed stub, pass `stub_edit_note` (≥40 chars) saying what they changed — otherwise a fully-drifted execute returns `STUB_REVIEW_DRIFT`. As with `RESEARCH_STILL_STUB`, treat the mechanical refusal as the backstop, not the first line of defense.
|
|
70
|
-
- **Never** call `heyspex_promote_research` against a research doc that still carries `_TBD — fill in this section._` placeholders — fill it in via the `/hs-res` method first (§A step 2 above), never by authoring the research yourself in the main session. The tool refuses this mechanically (`RESEARCH_STILL_STUB`) but the agent should never rely on that as the first line of defense.
|
|
71
|
-
- **Never** route a bug-fix capture through `heyspex_promote_capture` — it goes to `heyspex_promote_capture_to_diagnose` instead.
|
|
72
|
-
- **Never** attach a research promote to an `in_progress` milestone without an explicit owner override (`attach_to_in_progress_milestone` + `attach_override_reason`).
|
|
73
|
-
- **Never** commit or push.
|
|
10
|
+
> **Platform asymmetry — read this, it is load-bearing.** Claude Code delivers only the **first whitespace token** of an MCP prompt's argument (GitHub [#14210](https://github.com/anthropics/claude-code/issues/14210), closed *not planned*), so the namespaced MCP prompts (`/hs-promote-capture`, `/hs-promote-research`) can each carry at most a single token. This **native project command** is the only IDE surface that receives full `$ARGUMENTS`.
|
|
11
|
+
>
|
|
12
|
+
> **Why one command instead of two.** `/hs-promote-capture` and `/hs-promote-research` used to be separate commands — which meant typing the word "promote" twice (`/hs-promote-capture HS-CAP-XXXX promote`) when the command name already said what it does. There's exactly one verb here — *promote whatever doc you hand it to its next stage* — so there's one command. The **id prefix alone** tells you which flow applies (`HS-CAP-*` vs `HS-RES-*` are mutually exclusive and mechanical to detect); the two flows underneath are otherwise unrelated (different tools, different payload shapes, different two-phase mechanics) and stay fully separate below — only the entrypoint is shared.
|
|
13
|
+
|
|
14
|
+
## Step 0 — identify the doc
|
|
15
|
+
|
|
16
|
+
Read the **leading token** of `$ARGUMENTS` (case-insensitive; captures may be a comma/whitespace-separated list):
|
|
17
|
+
- Contains `-CAP` as its type label (legacy `HS-CAP-XXXX` or era-3 `HS-<fileKey>-<familyKey>-CAP-<slug>`) → go to **§A. Capture → research**.
|
|
18
|
+
- Contains `-RES` the same way → go to **§A2. Research → milestone**.
|
|
19
|
+
- **Era-3 short/display forms carry NO type label** — `HS-XV4W` (short id) and `HS-XV4W-HV6H` (file key + family key, the form humans see rendered) name a spec without saying its kind. Resolve the kind by fetching it: `heyspex_active_capture({ spec_id })` succeeding → it's a capture, §A. Otherwise treat it as research and try §A2. The tools accept any of these forms and collapse them to the stored short id themselves — never tell the user their id is wrong just because it carries (or lacks) the family key.
|
|
20
|
+
- None of the above → ask the user which doc they mean (don't guess).
|
|
21
|
+
|
|
22
|
+
If the capture tools are not already available in this session, call `heyspex_load_tools` first so `heyspex_active_capture` / `heyspex_promote_capture` / `heyspex_promote_capture_to_diagnose` are callable.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## §A. Capture → research (`HS-CAP-*`)
|
|
27
|
+
|
|
28
|
+
**1. Parse the rest of `$ARGUMENTS`:**
|
|
29
|
+
- Leading token(s) matching `HS-CAP-[A-Z0-9-]{3,}` (comma- and/or whitespace-separated) → `capture_ids` (1 or more).
|
|
30
|
+
- Next token: `HS-RES-[A-Z0-9-]{3,}` → `target_research` = that id. Or the literal word `new`/`NEW` (also the default when this token is omitted entirely) → `target_research = "NEW"`; any remaining words up to an `enhances:` token → `new_research_name`.
|
|
31
|
+
- A token shaped `enhances:HS-MIL-XXXX` anywhere in the string → `enhances`.
|
|
32
|
+
|
|
33
|
+
**2. Route by kind:**
|
|
34
|
+
- For each `capture_id`, read its `kind:` via `heyspex_active_capture({ spec_id: capture_id })`.
|
|
35
|
+
- Exactly one capture_id AND its `kind: bug-fix` → `heyspex_promote_capture_to_diagnose({ capture_id })` (creates `HS-DIAG-*`). Never mix a bug-fix capture into a multi-capture research promote.
|
|
36
|
+
- Otherwise → `heyspex_promote_capture({ capture_ids, target_research, new_research_name?, enhances? })`:
|
|
37
|
+
- `target_research === "NEW"` is **two-phase**: first call **omits** `accepted_outline` — it returns a proposed `{ name, outline, tags, enhances_suggestion }`. **Show it to the user and confirm** before calling again with the same args plus `accepted_outline` (Phase 2 performs the writes). Never skip straight to Phase 2.
|
|
38
|
+
- An existing `target_research` id is single-phase (direct, idempotent append) — no outline confirm needed.
|
|
39
|
+
- A `CAPTURE_INSUFFICIENT` error names the missing elements (core-idea, example, done-criteria, kind, user-stories) — the correct response is to elicit that detail from the user and improve the capture, not to pass `force_promote: true` unless the human explicitly says to promote anyway.
|
|
40
|
+
- **Check the outline against the capture's own Notes before presenting it.** Before showing `proposed_outline` (AI-proposed or agent-authored) to the user, walk every verbatim quote in the capture's `## Notes` and state plainly whether the outline addresses it. If a quote asks for something the outline doesn't cover, add a section for it or say so before asking for confirm — a missed verbatim quote is exactly what got two real items dropped from a milestone in this vault's own history ([[HS-GDT5-F16L-DIAG-promote-flow-drafts-research-and-stubs]]).
|
|
41
|
+
- **Outline confirm ≠ research done.** Phase 2 only writes the research **stub** — every section body is the literal placeholder `_TBD — fill in this section._`. Confirming the outline approves its *shape* (section headings), not its findings. As the very next step after Phase 2 creates the file, fill in every section with real content **by running the `/hs-res` method** (SpexCrawl gather via the Companion + DeepSeek synthesis — see `.claude/commands/hs-res.md`); **never author the research yourself in the main session** — main-session self-research skips the routed research seats and burns the expensive model on work the fleet owns. Do not report the research as complete, and do not move on to `/hs-promote-research`, until the TBD placeholders are gone. (`heyspex_promote_research` mechanically refuses with `RESEARCH_STILL_STUB` while any remain, but don't rely on that gate — write the research because it's the point of the flow, not because a check will otherwise fail.)
|
|
42
|
+
|
|
43
|
+
**3. Report the result** — the research id (created or extended) or diagnose id created, and confirm the capture(s)' `promoted_to` now points at it.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## §A2. Research → milestone (`HS-RES-*`)
|
|
48
|
+
|
|
49
|
+
**1. Parse the rest of `$ARGUMENTS`:**
|
|
50
|
+
- `research_id` is the leading `HS-RES-*` token (already identified in Step 0).
|
|
51
|
+
- Next word matching `spawn|augment|both` → `intent`. Default `spawn` when omitted.
|
|
52
|
+
- Next token: `HS-MIL-[A-Z0-9-]{3,}` → `target_milestone` = that id. Or the literal word `new`/`NEW` (also the default when this token is omitted entirely) → `target_milestone = "NEW"`; remaining words → `new_milestone_name`.
|
|
53
|
+
- If `intent` includes `augment`, any remaining `HS-EPIC-[A-Z0-9-]{3,}` tokens → `augment_epic_ids` (required in that case — ask for them if `augment` was requested but none were given).
|
|
54
|
+
|
|
55
|
+
**2. Default policy:** `target_milestone: "NEW"` unless the user names an **existing `status: open`** milestone that clearly extends the same thesis. Spawning into an `in_progress` milestone is blocked unless the owner explicitly passes `attach_to_in_progress_milestone: true` + `attach_override_reason` (≥40 chars audit trail) — never default to this path or infer the override on the agent's own judgment.
|
|
56
|
+
|
|
57
|
+
**3. Phase 1 — proposal.** Call `heyspex_promote_research({ research_id, target_milestone, new_milestone_name?, intent, spawn_epic_count?, augment_epic_ids? })` **without** `accepted_stubs`. Show the user the returned `proposed_stubs[]` and let them edit/remove/approve.
|
|
58
|
+
- **If `ai_proposal.ok === false` (e.g. `reason: "no_api_key"`), `proposed_stubs` comes back empty — the agent must author the stubs itself.** This is NOT a shortcut to skip the confirm step; it makes the confirm step *more* necessary, not less, because nothing upstream has vetted these stubs yet. Author them from the research doc's actual content, present them to the user exactly as you would an AI proposal (name/kind/effort/rationale per stub), and wait for a real approval turn before calling Phase 2. **Do not call Phase 2 in the same turn you authored the stubs in** — that is precisely the failure this line exists to prevent (observed 2026-08-12: an agent self-authored 3 epic stubs and executed `accepted_stubs` in the same tool-call batch with no human turn in between).
|
|
59
|
+
- **Check the stubs against the SOURCE CAPTURE's own Notes before presenting them.** Before showing `proposed_stubs` (AI-proposed or agent-authored) to the user, walk every verbatim quote in the source capture's `## Notes` — the capture(s) named in the research doc's `sources_captures`, not just the research doc's own prose, since a two-hop drift can lose fidelity the research doc's text won't show — and confirm each is addressed by a stub or explicitly named as out of scope. This check caught two real gaps missed by an agent-authored stub list in this vault's own history ([[HS-GDT5-F16L-DIAG-promote-flow-drafts-research-and-stubs]]).
|
|
60
|
+
|
|
61
|
+
**4. Phase 2 — execute (after human confirms).** Call again with the same args plus `accepted_stubs: [...]` (the confirmed, possibly-edited subset) to perform the transactional write.
|
|
62
|
+
|
|
63
|
+
**5. Report the result** — the milestone id (new or existing) plus spawned epic ids, or the augmented epic ids. Note that research stays `status: open` (research is evergreen) — only its `enhances:`/`spawned_epics:` links change.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Hard prohibitions
|
|
68
|
+
|
|
69
|
+
- **Never** execute a Phase-2 write (`accepted_outline` or `accepted_stubs`) without the human having seen and confirmed the Phase-1 proposal. For `accepted_stubs` the tool now refuses this mechanically: the proposal turn leaves a marker keyed on the research id, and an execute turn without one returns `STUB_REVIEW_REQUIRED`. If the human replaced every proposed stub, pass `stub_edit_note` (≥40 chars) saying what they changed — otherwise a fully-drifted execute returns `STUB_REVIEW_DRIFT`. As with `RESEARCH_STILL_STUB`, treat the mechanical refusal as the backstop, not the first line of defense.
|
|
70
|
+
- **Never** call `heyspex_promote_research` against a research doc that still carries `_TBD — fill in this section._` placeholders — fill it in via the `/hs-res` method first (§A step 2 above), never by authoring the research yourself in the main session. The tool refuses this mechanically (`RESEARCH_STILL_STUB`) but the agent should never rely on that as the first line of defense.
|
|
71
|
+
- **Never** route a bug-fix capture through `heyspex_promote_capture` — it goes to `heyspex_promote_capture_to_diagnose` instead.
|
|
72
|
+
- **Never** attach a research promote to an `in_progress` milestone without an explicit owner override (`attach_to_in_progress_milestone` + `attach_override_reason`).
|
|
73
|
+
- **Never** commit or push.
|
|
@@ -7,32 +7,32 @@ description: Push an epic implementation plan into the HeySpex vault, optionally
|
|
|
7
7
|
|
|
8
8
|
**Usage:** `/hs-push [<epic name>] [--next] [--reason <focus reason>]`
|
|
9
9
|
|
|
10
|
-
> **Platform asymmetry — read this, it is load-bearing.** Claude Code delivers only the **first whitespace token** of an MCP prompt's argument (GitHub [#14210](https://github.com/anthropics/claude-code/issues/14210), closed *not planned*), so the namespaced MCP prompts `/hs-push` / `/hs-push-next` can each carry at most a single token — never an epic name plus a `--next` flag plus a focus reason together. This **native project command** is the only IDE surface that receives full `$ARGUMENTS`. It also **consolidates** the old two-prompt split (`hs-push` vs `hs-push-next`) into one command: both ultimately call the same `heyspex_push_plan` tool with only `on_deck` differing, so there is no behavior lost by merging them here — just one flag instead of two command names.
|
|
11
|
-
|
|
12
|
-
## What to do
|
|
13
|
-
|
|
14
|
-
**1. Parse `$ARGUMENTS`:**
|
|
15
|
-
- `--next` (anywhere, case-insensitive) → `on_deck = true`. Absent → `on_deck = false` (file the epic without pinning focus).
|
|
16
|
-
- `--reason <text>` → `focus_reason` (only meaningful when `on_deck` is true; rest of that flag's value up to the next `--` flag or end of string).
|
|
17
|
-
- Remaining leading, non-flag text → an `epic_name` hint. Optional — if omitted, derive the title from the plan under discussion in chat.
|
|
18
|
-
|
|
19
|
-
**2. Gather the rest of the payload from the conversation** (a Cursor/proprietary `.plan.md` the user pasted or referenced, or a plan already discussed in chat):
|
|
20
|
-
- `summary` — required plain-language frontmatter summary (spec-summary-authoring contract).
|
|
21
|
-
- `plan_markdown` — epic body markdown (goal, phases, acceptance criteria).
|
|
22
|
-
- `milestone` — **required**: the parent `HS-MIL-*` wikilink. Ask the user if it isn't obvious from context; the tool call fails without it.
|
|
23
|
-
- `source_plan_paths` — any `.plan.md` file paths referenced (auto-detected from `plan_markdown` too).
|
|
24
|
-
- `kind` / `effort` / `tags` / `related` — optional scheduler/classification fields.
|
|
25
|
-
|
|
26
|
-
**3. Call** `heyspex_push_plan({ epic_name, summary, plan_markdown, milestone, on_deck, focus_reason?, source_plan_paths?, kind?, effort?, tags?, related? })`. This writes the epic **only** — `children: []`; tasks are never filed here, only later via `/hs-next` breakdown.
|
|
27
|
-
|
|
28
|
-
**4. After the call:**
|
|
29
|
-
- `on_deck: true` → the epic is set `in_progress`, `.heyspex/focus.yaml` is written, and a NEXT STEP block is added. Tell the user to run `/hs-next` next.
|
|
30
|
-
- `on_deck: false` → tell the user to re-run `/hs-push --next` (or `/hs-next <the new epic id>`) when ready to start work.
|
|
31
|
-
|
|
32
|
-
**5. Conflict handling:** if the tool returns a behavioral-conflict block against `related` specs and `on_deck` was requested, the write is blocked by default (no files written, no focus pinned). Surface the conflicts to the user — only pass `skip_conflict_check: true` on their explicit say-so, and note a `conflict_override` should be recorded afterward.
|
|
33
|
-
|
|
34
|
-
## Hard prohibitions
|
|
35
|
-
|
|
36
|
-
- **Never** file tasks here — epics only (`children: []`); tasks are just-in-time via `/hs-next` breakdown.
|
|
37
|
-
- **Never** silently bypass a conflict block — surface it and let the human decide.
|
|
38
|
-
- **Never** commit or push git.
|
|
10
|
+
> **Platform asymmetry — read this, it is load-bearing.** Claude Code delivers only the **first whitespace token** of an MCP prompt's argument (GitHub [#14210](https://github.com/anthropics/claude-code/issues/14210), closed *not planned*), so the namespaced MCP prompts `/hs-push` / `/hs-push-next` can each carry at most a single token — never an epic name plus a `--next` flag plus a focus reason together. This **native project command** is the only IDE surface that receives full `$ARGUMENTS`. It also **consolidates** the old two-prompt split (`hs-push` vs `hs-push-next`) into one command: both ultimately call the same `heyspex_push_plan` tool with only `on_deck` differing, so there is no behavior lost by merging them here — just one flag instead of two command names.
|
|
11
|
+
|
|
12
|
+
## What to do
|
|
13
|
+
|
|
14
|
+
**1. Parse `$ARGUMENTS`:**
|
|
15
|
+
- `--next` (anywhere, case-insensitive) → `on_deck = true`. Absent → `on_deck = false` (file the epic without pinning focus).
|
|
16
|
+
- `--reason <text>` → `focus_reason` (only meaningful when `on_deck` is true; rest of that flag's value up to the next `--` flag or end of string).
|
|
17
|
+
- Remaining leading, non-flag text → an `epic_name` hint. Optional — if omitted, derive the title from the plan under discussion in chat.
|
|
18
|
+
|
|
19
|
+
**2. Gather the rest of the payload from the conversation** (a Cursor/proprietary `.plan.md` the user pasted or referenced, or a plan already discussed in chat):
|
|
20
|
+
- `summary` — required plain-language frontmatter summary (spec-summary-authoring contract).
|
|
21
|
+
- `plan_markdown` — epic body markdown (goal, phases, acceptance criteria).
|
|
22
|
+
- `milestone` — **required**: the parent `HS-MIL-*` wikilink. Ask the user if it isn't obvious from context; the tool call fails without it.
|
|
23
|
+
- `source_plan_paths` — any `.plan.md` file paths referenced (auto-detected from `plan_markdown` too).
|
|
24
|
+
- `kind` / `effort` / `tags` / `related` — optional scheduler/classification fields.
|
|
25
|
+
|
|
26
|
+
**3. Call** `heyspex_push_plan({ epic_name, summary, plan_markdown, milestone, on_deck, focus_reason?, source_plan_paths?, kind?, effort?, tags?, related? })`. This writes the epic **only** — `children: []`; tasks are never filed here, only later via `/hs-next` breakdown.
|
|
27
|
+
|
|
28
|
+
**4. After the call:**
|
|
29
|
+
- `on_deck: true` → the epic is set `in_progress`, `.heyspex/focus.yaml` is written, and a NEXT STEP block is added. Tell the user to run `/hs-next` next.
|
|
30
|
+
- `on_deck: false` → tell the user to re-run `/hs-push --next` (or `/hs-next <the new epic id>`) when ready to start work.
|
|
31
|
+
|
|
32
|
+
**5. Conflict handling:** if the tool returns a behavioral-conflict block against `related` specs and `on_deck` was requested, the write is blocked by default (no files written, no focus pinned). Surface the conflicts to the user — only pass `skip_conflict_check: true` on their explicit say-so, and note a `conflict_override` should be recorded afterward.
|
|
33
|
+
|
|
34
|
+
## Hard prohibitions
|
|
35
|
+
|
|
36
|
+
- **Never** file tasks here — epics only (`children: []`); tasks are just-in-time via `/hs-next` breakdown.
|
|
37
|
+
- **Never** silently bypass a conflict block — surface it and let the human decide.
|
|
38
|
+
- **Never** commit or push git.
|
|
@@ -7,24 +7,24 @@ description: Post-plan QC gut-check — stress-test a drafted plan before execut
|
|
|
7
7
|
|
|
8
8
|
**Usage:** `/hs-qc [--plan <path>] (defaults to the most recent plan)`
|
|
9
9
|
|
|
10
|
-
> **Where this sits.** `/hs-ground` (pre-plan) → draft → `heyspex_plan_review` → **`/hs-qc`** → `ExitPlanMode`. Both plan-review + QC markers required ([[HS-R4OY]]).
|
|
11
|
-
|
|
12
|
-
## What to do
|
|
13
|
-
|
|
14
|
-
**0. Mandatory drift passes** — Axis A (as-built code) + Axis B (design supersession per [[drift-is-two-axes-as-built-and-design-supersession]]). Re-run `heyspex_plan_review`; read `axis_b_drift`. Do not trust parent epic AC over newer memory decisions.
|
|
15
|
-
|
|
16
|
-
**0b. When `axis_b_drift` is non-empty — ask the user before recording QC:**
|
|
17
|
-
|
|
18
|
-
Present each conflict. **Default (Recommended):** re-scope the plan (remove dead work). **Override:** user explicitly confirms proceed anyway → `heyspex_plan_qc({ axis_b_user_confirmed: true, axis_b_confirmation_note: "…" })`. Tool returns `QC_AXIS_B_DRIFT` until resolved or user-confirmed. **The override is currently broken** per [[HS-EP8E-C1L2-DIAG-heyspex-plan-qc-override-path-ignores-ax]] (reproduced twice) — until fixed, `HEYSPEX_PLAN_QC_GATE_OFF=1` is the only working escape, and its use should be reported to the owner.
|
|
19
|
-
|
|
20
|
-
**1. Run the gut-check (verbatim — the owner's standard).**
|
|
21
|
-
|
|
22
|
-
Wonderful work! Can you please do a quality check and a gut-check? … *(full questions unchanged)*
|
|
23
|
-
|
|
24
|
-
**2. Act on what you find.** Fold findings into the plan; re-run `heyspex_plan_review` if material.
|
|
25
|
-
|
|
26
|
-
**3. Record Proof-of-Use.** `heyspex_plan_qc` with substantive `findings_summary` including **`Axis B:`** line.
|
|
27
|
-
|
|
28
|
-
**4. Then `ExitPlanMode`.**
|
|
29
|
-
|
|
30
|
-
(Break-glass: `HEYSPEX_PLAN_QC_GATE_OFF=1`.)
|
|
10
|
+
> **Where this sits.** `/hs-ground` (pre-plan) → draft → `heyspex_plan_review` → **`/hs-qc`** → `ExitPlanMode`. Both plan-review + QC markers required ([[HS-R4OY]]).
|
|
11
|
+
|
|
12
|
+
## What to do
|
|
13
|
+
|
|
14
|
+
**0. Mandatory drift passes** — Axis A (as-built code) + Axis B (design supersession per [[drift-is-two-axes-as-built-and-design-supersession]]). Re-run `heyspex_plan_review`; read `axis_b_drift`. Do not trust parent epic AC over newer memory decisions.
|
|
15
|
+
|
|
16
|
+
**0b. When `axis_b_drift` is non-empty — ask the user before recording QC:**
|
|
17
|
+
|
|
18
|
+
Present each conflict. **Default (Recommended):** re-scope the plan (remove dead work). **Override:** user explicitly confirms proceed anyway → `heyspex_plan_qc({ axis_b_user_confirmed: true, axis_b_confirmation_note: "…" })`. Tool returns `QC_AXIS_B_DRIFT` until resolved or user-confirmed. **The override is currently broken** per [[HS-EP8E-C1L2-DIAG-heyspex-plan-qc-override-path-ignores-ax]] (reproduced twice) — until fixed, `HEYSPEX_PLAN_QC_GATE_OFF=1` is the only working escape, and its use should be reported to the owner.
|
|
19
|
+
|
|
20
|
+
**1. Run the gut-check (verbatim — the owner's standard).**
|
|
21
|
+
|
|
22
|
+
Wonderful work! Can you please do a quality check and a gut-check? … *(full questions unchanged)*
|
|
23
|
+
|
|
24
|
+
**2. Act on what you find.** Fold findings into the plan; re-run `heyspex_plan_review` if material.
|
|
25
|
+
|
|
26
|
+
**3. Record Proof-of-Use.** `heyspex_plan_qc` with substantive `findings_summary` including **`Axis B:`** line.
|
|
27
|
+
|
|
28
|
+
**4. Then `ExitPlanMode`.**
|
|
29
|
+
|
|
30
|
+
(Break-glass: `HEYSPEX_PLAN_QC_GATE_OFF=1`.)
|