hstack 0.16.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.md +73 -163
  3. package/VERSION +1 -1
  4. package/dist/commands/doctor.js +18 -8
  5. package/dist/commands/doctor.js.map +1 -1
  6. package/dist/commands/init.js +7 -3
  7. package/dist/commands/init.js.map +1 -1
  8. package/dist/commands/update.js +9 -2
  9. package/dist/commands/update.js.map +1 -1
  10. package/dist/lib/descriptions.js +10 -17
  11. package/dist/lib/descriptions.js.map +1 -1
  12. package/dist/lib/wire.js +166 -138
  13. package/dist/lib/wire.js.map +1 -1
  14. package/dist/manifest.js +41 -29
  15. package/dist/manifest.js.map +1 -1
  16. package/package.json +3 -4
  17. package/template/.claude/agents/adversarial-reviewer.md +42 -50
  18. package/template/.claude/agents/app-architect.md +44 -96
  19. package/template/.claude/agents/data-architect.md +46 -89
  20. package/template/.claude/agents/test-strategist.md +39 -68
  21. package/template/.claude/skills/hstack-adr-new/SKILL.md +23 -73
  22. package/template/.claude/skills/hstack-adversarial-review/SKILL.md +46 -152
  23. package/template/.claude/skills/hstack-adversarial-review/references/finding-categories.md +80 -103
  24. package/template/.claude/skills/hstack-app-architecture/SKILL.md +43 -68
  25. package/template/.claude/skills/hstack-commit/SKILL.md +27 -68
  26. package/template/.claude/skills/hstack-data-architecture/SKILL.md +34 -56
  27. package/template/.claude/skills/hstack-promote/SKILL.md +55 -0
  28. package/template/.claude/skills/hstack-story/SKILL.md +58 -0
  29. package/template/.claude/skills/hstack-test-audit/SKILL.md +64 -0
  30. package/template/.claude/skills/hstack-wrap/SKILL.md +48 -0
  31. package/template/.claude/skills/hstack-wrap/references/pr-description.md +45 -0
  32. package/template/KERNEL.md +75 -318
  33. package/template/templates/adr.md +2 -18
  34. package/template/templates/app-architecture.md +38 -50
  35. package/template/templates/data-architecture.md +38 -89
  36. package/template/templates/infrastructure.md +54 -148
  37. package/template/templates/roadmap.md +6 -12
  38. package/template/templates/story.md +7 -13
  39. package/template/templates/tech-debt.md +2 -37
  40. package/template/templates/tech-stack.md +2 -12
  41. package/template/.claude/agents/data-specialist.md +0 -81
  42. package/template/.claude/agents/implementer.md +0 -97
  43. package/template/.claude/agents/kernel-fit-analyst.md +0 -129
  44. package/template/.claude/agents/planner.md +0 -75
  45. package/template/.claude/agents/product-discovery.md +0 -129
  46. package/template/.claude/agents/product-manager.md +0 -76
  47. package/template/.claude/agents/researcher.md +0 -87
  48. package/template/.claude/agents/security-reviewer.md +0 -88
  49. package/template/.claude/agents/spec-author.md +0 -89
  50. package/template/.claude/agents/stack-architect.md +0 -108
  51. package/template/.claude/agents/ui-ux-briefer.md +0 -75
  52. package/template/.claude/agents/verifier.md +0 -81
  53. package/template/.claude/skills/hstack-branch/SKILL.md +0 -76
  54. package/template/.claude/skills/hstack-brownfield-init/SKILL.md +0 -131
  55. package/template/.claude/skills/hstack-change-new/SKILL.md +0 -84
  56. package/template/.claude/skills/hstack-change-plan/SKILL.md +0 -108
  57. package/template/.claude/skills/hstack-configure/SKILL.md +0 -99
  58. package/template/.claude/skills/hstack-coord/SKILL.md +0 -95
  59. package/template/.claude/skills/hstack-data-review/SKILL.md +0 -93
  60. package/template/.claude/skills/hstack-finalize/SKILL.md +0 -140
  61. package/template/.claude/skills/hstack-flag/SKILL.md +0 -99
  62. package/template/.claude/skills/hstack-greenfield-init/SKILL.md +0 -148
  63. package/template/.claude/skills/hstack-help/SKILL.md +0 -153
  64. package/template/.claude/skills/hstack-implement/SKILL.md +0 -155
  65. package/template/.claude/skills/hstack-kernel-fit-promote/SKILL.md +0 -125
  66. package/template/.claude/skills/hstack-kernel-fit-scan/SKILL.md +0 -142
  67. package/template/.claude/skills/hstack-kernel-fit-scan/references/slack-setup.md +0 -42
  68. package/template/.claude/skills/hstack-kernel-fit-triage/SKILL.md +0 -121
  69. package/template/.claude/skills/hstack-module-spec/SKILL.md +0 -78
  70. package/template/.claude/skills/hstack-product-discovery/SKILL.md +0 -75
  71. package/template/.claude/skills/hstack-research/SKILL.md +0 -115
  72. package/template/.claude/skills/hstack-scaffold/SKILL.md +0 -113
  73. package/template/.claude/skills/hstack-security-review/SKILL.md +0 -95
  74. package/template/.claude/skills/hstack-ship/SKILL.md +0 -119
  75. package/template/.claude/skills/hstack-stack-decide/SKILL.md +0 -81
  76. package/template/.claude/skills/hstack-story-draft/SKILL.md +0 -92
  77. package/template/.claude/skills/hstack-tech-debt-new/SKILL.md +0 -95
  78. package/template/.claude/skills/hstack-tech-debt-resolve/SKILL.md +0 -123
  79. package/template/.claude/skills/hstack-tech-debt-stale/SKILL.md +0 -86
  80. package/template/.claude/skills/hstack-tech-debt-wontfix/SKILL.md +0 -77
  81. package/template/.claude/skills/hstack-telemetry/SKILL.md +0 -73
  82. package/template/.claude/skills/hstack-test-plan/SKILL.md +0 -159
  83. package/template/.claude/skills/hstack-ui-brief/SKILL.md +0 -81
  84. package/template/.claude/skills/hstack-verify/SKILL.md +0 -128
  85. package/template/scripts/compute-merge-readiness.mjs +0 -780
  86. package/template/scripts/coord/coord_scan.py +0 -681
  87. package/template/scripts/run-gates.sh +0 -388
  88. package/template/scripts/telemetry/__init__.py +0 -6
  89. package/template/scripts/telemetry/insights/__init__.py +0 -0
  90. package/template/scripts/telemetry/insights/contract_drift.py +0 -137
  91. package/template/scripts/telemetry/insights/kernel_fit.py +0 -438
  92. package/template/scripts/telemetry/insights/overengineering.py +0 -115
  93. package/template/scripts/telemetry/insights/quality_outcomes.py +0 -131
  94. package/template/scripts/telemetry/insights/token_economics.py +0 -302
  95. package/template/scripts/telemetry/insights/workflow_shape.py +0 -198
  96. package/template/scripts/telemetry/parsers/__init__.py +0 -0
  97. package/template/scripts/telemetry/parsers/bodies.py +0 -87
  98. package/template/scripts/telemetry/parsers/commits.py +0 -219
  99. package/template/scripts/telemetry/parsers/frontmatter.py +0 -322
  100. package/template/scripts/telemetry/parsers/sidecars.py +0 -61
  101. package/template/scripts/telemetry/parsers/transcripts.py +0 -294
  102. package/template/scripts/telemetry/render.py +0 -460
  103. package/template/scripts/telemetry/report.py +0 -150
  104. package/template/scripts/telemetry/run_kernel_fit.py +0 -95
  105. package/template/scripts/telemetry/session_id.py +0 -139
  106. package/template/scripts/validate-spec.mjs +0 -3303
  107. package/template/templates/adversarial-review.md +0 -54
  108. package/template/templates/bootstrap.md +0 -105
  109. package/template/templates/change-spec.md +0 -82
  110. package/template/templates/ci-cd.md +0 -41
  111. package/template/templates/coord-message.md +0 -56
  112. package/template/templates/data-review.md +0 -54
  113. package/template/templates/discovery/brainstorm.md +0 -69
  114. package/template/templates/discovery/forcing-questions.md +0 -76
  115. package/template/templates/discovery/project-brief.md +0 -53
  116. package/template/templates/figma-handoff.md +0 -38
  117. package/template/templates/glossary.md +0 -20
  118. package/template/templates/hardening-checklist.md +0 -73
  119. package/template/templates/incident-runbook.md +0 -57
  120. package/template/templates/kernel-fit-finding.md +0 -63
  121. package/template/templates/kernel-fit-flag.md +0 -52
  122. package/template/templates/module-spec.md +0 -49
  123. package/template/templates/persona.md +0 -38
  124. package/template/templates/plan.md +0 -53
  125. package/template/templates/product-brief.md +0 -56
  126. package/template/templates/security-review.md +0 -63
  127. package/template/templates/telemetry-sidecar.md +0 -227
  128. package/template/templates/test-plan.md +0 -119
  129. package/template/templates/threat-model.md +0 -54
  130. package/template/templates/ui-brief.md +0 -49
  131. package/template/templates/verification.md +0 -63
  132. package/template/templates/vision.md +0 -34
@@ -1,142 +0,0 @@
1
- ---
2
- name: hstack-kernel-fit-scan
3
- description: Use to detect kernel-fit gaps — patterns in shipped practice suggesting the kernel itself needs revision — and synthesize one finding file per fired pattern. The first step of the kernel-fit loop; triage and promotion are separate Skills.
4
- tools:
5
- - Read
6
- - Write
7
- - Edit
8
- - Grep
9
- - Glob
10
- - Bash
11
- - Task
12
- - "{{TODO-MCP: Slack — mcp__claude_ai_Slack__slack_send_message — required for kernel-fit notifications. Without it, findings still land on disk; the Skill logs to stderr and exits 0 (deliberate carve-out from the kernel's general MCP-unreachable stop condition — Slack is a side-channel pointer, not authoritative state).}}"
13
- - "node hstack/scripts/validate-spec.mjs — validates kernel-fit-finding frontmatter and KF-01 through KF-05"
14
- ---
15
-
16
- ## Purpose
17
-
18
- `hstack-kernel-fit-scan` is the entry point to the kernel-fit closed-loop system. The Skill orchestrates four steps: detection (Python script, pure read), synthesis (`kernel-fit-analyst` subagent, one file per fired pattern), notification (Slack, best-effort), and the atomic commit. Promotion to a kernel change is a separate, human-invoked Skill (`/hstack:kernel-fit-promote`).
19
-
20
- The Skill is the only path by which the `kernel-fit-analyst` subagent runs. The kernel's "AI writes, humans confirm" contract is preserved at the kernel-modification layer because the analyst writes findings only — never ADRs, never change-specs, never kernel edits.
21
-
22
- ## When to invoke
23
-
24
- Common cadence:
25
-
26
- - Weekly for active engineering — catches kernel-vs-practice drift early.
27
- - After every ~5 shipped changes — surfaces patterns single-change inspection cannot.
28
- - After a kernel edit lands — confirm the edit moved the relevant pattern off the fired list (or did not introduce a new one).
29
- - Whenever a `kernel-fit-analyst` finding is restated or superseded by triage, to let the analyst write the supersession edit atomically.
30
-
31
- The Skill is opt-in. There is no cron, no automatic invocation, no event-driven trigger in v1.
32
-
33
- ## Inputs
34
-
35
- - `--window <N>` (optional): limit detector history to the last N days. Default 30. `--window 0` means all-history.
36
- - `--no-slack` (optional): skip the Slack notification step even if MCP is wired. Useful for dry-runs or for replaying a scan when the engineer has already been notified manually.
37
-
38
- ## Preconditions
39
-
40
- - `hstack/config.yaml` exists at `init-status: complete`. If init is incomplete, halt with `HSTACK-HALT: reason=missing-context`.
41
- - The wrapper script `hstack/scripts/telemetry/run_kernel_fit.py` exists. If missing, halt with `HSTACK-HALT: reason=missing-context` and the recommendation "re-vendor hstack or run `/hstack:configure`".
42
- - The repo contains at least 3 shipped change-specs (count by `status: shipped` across `hstack/specs/changes/*/spec.md`). Below this threshold, the corpus is too small for cross-correlation; the Skill halts with a one-line note: "kernel-fit scan needs ≥3 shipped changes; corpus is too small to produce honest evidence."
43
- - Python 3.10+ is available on PATH (matches `hstack-telemetry`).
44
- - The git repository is intact (`.git/` present).
45
-
46
- ## Orchestration steps
47
-
48
- 1. **Verify preconditions.** Walk the checks above; halt with the named reason if any fail. Print "kernel-fit-scan: preconditions OK, N shipped changes in corpus, M-day window" to stderr.
49
-
50
- 2. **Run detection.** Shell out: `python3 hstack/scripts/telemetry/run_kernel_fit.py --repo <repo-root> --window <N>`. Capture stdout as JSON; capture stderr as the diagnostic log. On non-zero exit, surface the traceback and halt with `HSTACK-HALT: reason=missing-context`.
51
-
52
- 3. **Enumerate pending engineer flags.** Glob `hstack/kernel-fit/flags/pending/*.md`. Capture the list (may be empty). The analyst processes these per ADR-0005's Pending Flags Processing loop documented in `template/.claude/agents/kernel-fit-analyst.md`; this Skill is responsible for surfacing the list to the analyst and for the post-analyst pin-file moves at step 5.
53
-
54
- 4. **Decide whether to invoke the subagent.** Parse the detector JSON. If every pattern has `fired: false` **and** no pending flags exist, exit clean: print "kernel-fit-scan: no patterns fired in window, no pending flags — kernel is consistent with shipped practice in current corpus" to stdout, write nothing, do not invoke the subagent, do not nudge Slack, do not commit. If patterns fired OR pending flags exist (or both), proceed to step 5.
55
-
56
- 5. **Invoke `kernel-fit-analyst`.** Invoke via Task tool with `subagent_type: kernel-fit-analyst`. The prompt includes (a) the JSON evidence blob verbatim, (b) the list of pending flag paths from step 3 (or "no pending flags" when empty), (c) the canonical reminder of session-isolation (no implementer transcripts loaded), (d) the explicit instruction "one file per fired pattern; mandatory two-bullet counter-explanation; never write outside `hstack/kernel-fit/findings/`; process pending flags per the Pending Flags Processing section of the analyst prompt". The subagent's writes land in the working tree before the subagent returns. The analyst's response object reports the flag-processing counts (`processed`, `folded`, `emitted`, `not_actionable`, `transcript_truncated`).
57
-
58
- 6. **Move processed pin files.** For each pin the analyst updated to `status: processed`, `git mv hstack/kernel-fit/flags/pending/<pin>.md hstack/kernel-fit/flags/processed/<pin>.md`. Create the `processed/` directory if missing. This move lands in the same commit as the finding writes at step 7 — the analyst's pin frontmatter updates (classification, classification-rationale, folded-into, emitted-as, status) plus the file move must be atomic from git's perspective. **Note**: pin files are gitignored per ADR-0005, so `git mv` operates only on the filesystem (git will not stage either side). The "atomicity" here is filesystem-only — the analyst's in-place frontmatter update and the directory move complete together before stdout reports flag-processing counts. If the gitignore is later relaxed (would require an ADR amendment), this step's `git mv` becomes a real staged operation.
59
-
60
- 7. **Stage and commit findings.** Compute the set of newly-written or modified finding files (analyst may have superseded a prior finding atomically with a new one, or appended evidence rows to existing findings via fold). Print the proposed diff for engineer confirmation (per the kernel's "AI writes, humans confirm" mechanical-operations adaptation). On Y/n confirmation `Y` (default Yes), `git add` the finding files and commit with message `kernel-fit: <N> finding(s) detected` (or `kernel-fit: <N> finding(s) detected, <M> superseded` when supersession edits landed; or `kernel-fit: <N> finding(s) detected (<F> from flags), <M> superseded` when flag-emit landed). One commit per scan run, atomic across all new/edited findings. When patterns did not fire and only pending flags were processed, the commit message reads `kernel-fit: <F> flag(s) processed (<E> emit, <FF> fold, <NA> not-actionable, <TT> transcript-truncated)`.
61
-
62
- 8. **Notification — Slack nudge (best-effort).** Compute the notification set:
63
-
64
- ```
65
- notify = [f for f in newly_written_findings
66
- if f.confidence in ("high", "medium")
67
- and not _open_finding_exists_for_pattern_in_window(f.pattern, days=14)]
68
- ```
69
-
70
- For each finding in `notify`, send a Slack message via `mcp__claude_ai_Slack__slack_send_message` with the canonical body:
71
-
72
- ```
73
- hstack kernel-fit: <N> new finding(s)
74
-
75
- • KF-NNNN — <title> [confidence: high|medium] [via: detector|flag]
76
- Pattern: <KF-P1|KF-P2|KF-P3|KF-FLAG-NNNN>
77
- Kernel surface: <one-line>
78
- hstack/kernel-fit/findings/KF-NNNN-<slug>.md
79
-
80
- Triage: /hstack:kernel-fit-triage KF-NNNN --action acknowledge
81
- Dismiss: /hstack:kernel-fit-triage KF-NNNN --action dismiss --reason "..."
82
- Promote: /hstack:kernel-fit-promote KF-NNNN --slug <adr-slug>
83
- ```
84
-
85
- Bundle multiple findings into a single message when more than one fires in this scan — one scan, one message, never carried across runs. When flag-processing occurred, append the **flag tail summary** as the last line of the same Slack message:
86
-
87
- ```
88
- Flags processed: <P> total — <FF> folded, <E> emitted, <NA> not-actionable, <TT> transcript-truncated.
89
- ```
90
-
91
- The tail is included only when at least one pin was processed AND at least one of `folded` or `emitted` is non-zero, OR when `transcript_truncated > 0` (the transcript-truncated count is operationally interesting because it surfaces v1-heuristic edge cases the engineer should know about). When every processed pin was classified `not-actionable` the tail is suppressed — it would otherwise be pure noise. When the scan produces zero detector findings AND only `not-actionable` pin processing, the Slack message is suppressed entirely (no findings, no tail-worthy signal).
92
-
93
- 9. **Graceful degradation when Slack is unreachable.** If the MCP call raises (tool not configured, network failure, channel-not-found, etc.), log to stderr: `kernel-fit: Slack MCP unreachable; <N> finding(s) written to disk without notification. <P> flag(s) processed; triage via /hstack:help to discover open findings.` Exit 0. The disk write from step 7 is the load-bearing action; Slack is a side-channel pointer. This is a deliberate carve-out from the kernel's general MCP-unreachable stop condition — Slack is not load-bearing for kernel-fit (the canonical state lives on disk and is reachable via `/hstack:help`). The carve-out is documented here and in the kernel's `## How hstack improves itself` section.
94
-
95
- 10. **Report.** Print to stdout: the count of patterns fired, the count of new findings written, the count of supersessions, the count of flags processed broken down by classification (`folded`, `emitted`, `not-actionable`, `transcript-truncated`), and the count of Slack notifications fired (or "skipped — Slack unreachable" / "skipped — within dedup window for all findings" / "skipped — no signal worth surfacing"). Done.
96
-
97
- ## Outputs
98
-
99
- - Zero or more files at `hstack/kernel-fit/findings/KF-NNNN-<slug>.md` at `status: open`.
100
- - Zero or more supersession edits (status flip + `superseded-by` set) on prior finding files.
101
- - Zero or more evidence-row appends to existing findings (from flag fold).
102
- - Zero or more pin transitions from `hstack/kernel-fit/flags/pending/` to `hstack/kernel-fit/flags/processed/` with `status: processed` and the analyst-owned classification fields populated. Pins are gitignored per ADR-0005, so the moves are filesystem-only — not staged in git.
103
- - Zero or one git commits (covering finding writes only; pin moves are not staged).
104
- - Zero or one Slack messages (bundled when multiple findings notify, with the flag tail summary appended when applicable).
105
-
106
- ## Auto-commit triggers
107
-
108
- - One commit at the writing of finding files (per the kernel's auto-commit-at-status-transition rule applied at the artifact-creation moment). No commit when no patterns fire AND no flag-emit or flag-fold landed (i.e., only `not-actionable` / `transcript-truncated` flag processing occurred). Pin file moves are filesystem-only (pins are gitignored) and do not require a commit.
109
-
110
- ## Idempotency contract
111
-
112
- - Re-running the Skill when no patterns fire AND no pending flags exist: zero new disk artifacts, no commit, no Slack message. Pure no-op.
113
- - Re-running when no patterns fire but pending flags exist: the analyst is invoked to process flags only. Outcomes depend on classification — fold/emit may produce finding writes and a commit; not-actionable/transcript-truncated produce only pin moves (no commit).
114
- - Re-running when patterns fire that already have open findings within the dedup window: the analyst is invoked, sees existing findings, and may skip-write or supersede; Slack notification is suppressed by the dedup gate.
115
- - Re-running when the same patterns fire with new evidence: the analyst may produce supersession edits; the dedup gate still suppresses Slack (already-notified within the window).
116
- - Re-running with `--no-slack`: identical to a run with Slack unreachable — findings land on disk, flags are processed normally, no Slack message.
117
- - Re-running after pending flags were processed in a prior scan: the prior pins are now in `processed/` and the analyst is forbidden from re-processing them (per the kernel-fit-analyst's discipline rules). Only newly-flagged pins (added to `pending/` since the last scan) are processed this run.
118
-
119
- ## Stop conditions
120
-
121
- Beyond the kernel's general stop conditions:
122
-
123
- - Init is incomplete or `run_kernel_fit.py` is missing (`HSTACK-HALT: reason=missing-context`).
124
- - Corpus is below the 3-shipped-changes floor — halt with the one-line note above.
125
- - Detector script exits non-zero or produces malformed JSON — halt with the traceback and `HSTACK-HALT: reason=missing-context`.
126
- - The `kernel-fit-analyst` subagent halts mid-run — propagate the halt sentinel; do not commit partial output (the analyst's writes-so-far remain unstaged on disk; the engineer can either delete them or re-invoke the Skill which will see them on next run).
127
- - The proposed-diff confirmation at step 5 is declined — abort the commit; the analyst's writes-so-far remain in the working tree. Re-invoke to continue.
128
-
129
- Slack-MCP-unreachable is NOT a stop condition. See step 7.
130
-
131
- ## Failure modes
132
-
133
- - **Detector raises on malformed frontmatter in a shipped change-spec.** The detector is read-only and tolerant of missing fields; the parser falls back to a degraded YAML reader. If a corrupted frontmatter file genuinely crashes the parser, the traceback names the offending file — fix it and re-run.
134
- - **Subagent produces a finding without two counter-explanations.** The analyst auto-downgrades `confidence: low` per KF-03; the finding still lands on disk but does not nudge Slack. No remediation needed — this is the designed behavior.
135
- - **Subagent writes a finding outside `hstack/kernel-fit/findings/`.** Scope-lock violation. The subagent's prompt forbids this at every Write call. If observed, surface as a kernel-fit-analyst contract violation and do not commit; report the offending path for diagnosis.
136
- - **Slack message rejected by the MCP server (rate limit, channel-not-found, auth error).** Same as MCP unreachable — log to stderr, exit 0, the engineer triages via `/hstack:help` on next session.
137
-
138
- ## Configuring Slack notifications (consumer-side)
139
-
140
- One-time consumer setup, not scan-time reading. The full procedure — MCP wiring and the `chat:write` scope, the `kernel-fit` block in `hstack/config.yaml` (`slack-channel`, `slack-fallback`), and the `--no-slack` dry-run — lives in `references/slack-setup.md` alongside this file.
141
-
142
- Read that file only when the engineer is wiring Slack for the first time, or when a run reported a Slack auth / channel / destination problem. Do not read it on a normal scan: Slack is opt-in, the disk artifact is canonical, and an unwired or unreachable Slack is not a stop condition (step 7).
@@ -1,42 +0,0 @@
1
- # Configuring Slack notifications for `/hstack:kernel-fit-scan` (consumer-side)
2
-
3
- Reference file for `hstack-kernel-fit-scan`. Read it **only** when the engineer is
4
- wiring Slack for the first time, or when a scan run reported a Slack auth /
5
- channel / destination problem. It is not needed on a normal scan: the disk
6
- artifact is canonical, and an unwired or unreachable Slack degrades gracefully
7
- (log to stderr, exit 0).
8
-
9
- Slack notifications are opt-in per consumer. Without wiring, the Skill still
10
- works — findings land on disk and the engineer discovers them via
11
- `/hstack:help`. To enable Slack nudges on `medium` / `high` confidence findings:
12
-
13
- 1. **Wire the MCP server.** Add the Slack MCP to your Claude Code MCP
14
- configuration so `mcp__claude_ai_Slack__slack_send_message` is callable from
15
- the session that runs `/hstack:kernel-fit-scan`. Follow Anthropic's Slack MCP
16
- install docs; the auth scope `chat:write` is required.
17
-
18
- 2. **Configure the destination channel.** Add a `kernel-fit` block to
19
- `hstack/config.yaml`:
20
-
21
- ```yaml
22
- kernel-fit:
23
- slack-channel: "#hstack-kernel-fit" # public channel id or name; the bot must be invited
24
- slack-fallback: "dm" # "dm" | "off" — behavior when slack-channel is absent or unreachable
25
- ```
26
-
27
- `slack-channel` is optional. When absent and `slack-fallback: "dm"`, the Skill
28
- sends to the invoking engineer's DM via the bot. When `slack-fallback: "off"`,
29
- a missing channel behaves identically to an unreachable MCP (log to stderr,
30
- exit 0).
31
-
32
- 3. **Verify with a dry-run.** Run `/hstack:kernel-fit-scan --no-slack` first to
33
- confirm the detection layer produces output on your corpus, then re-run
34
- without the flag once Slack is wired. The first non-`--no-slack` run will
35
- surface any auth or channel issues as the documented graceful-degradation log
36
- line.
37
-
38
- What you do NOT need to do: no code to write, no hook to install. The Skill is
39
- prose-driven; the runtime LLM agent invokes the MCP when the tool is available in
40
- the session and the config names a destination. The `{{TODO-MCP}}` placeholder in
41
- the Skill's `tools` array is the framework convention naming the contract — the
42
- consumer's MCP wiring satisfies it.
@@ -1,121 +0,0 @@
1
- ---
2
- name: hstack-kernel-fit-triage
3
- description: Use to acknowledge or dismiss an open kernel-fit finding. The second step of the kernel-fit loop — it only flips status and records a rationale; elevating a finding to an ADR is `/hstack:kernel-fit-promote`.
4
- tools:
5
- - Read
6
- - Write
7
- - Edit
8
- - Grep
9
- - Glob
10
- - Bash
11
- - "node hstack/scripts/validate-spec.mjs — validates the finding frontmatter flip and KF-05 (dismissed-reason non-null when status: dismissed)"
12
- ---
13
-
14
- ## Purpose
15
-
16
- `hstack-kernel-fit-triage` is the mechanical status-flip Skill for kernel-fit findings. It moves a finding from `status: open` to either `acknowledged` (intent to promote, not yet) or `dismissed` (won't pursue, with mandatory rationale). Per ADR-0001, the Skill performs the `Edit` writes directly in the main session — no subagent invocation; the value to write is fully determined by the engineer's invocation arguments.
17
-
18
- This Skill does not promote findings to ADRs. Promotion is a separate Skill (`/hstack:kernel-fit-promote`) with its own structured flow. This Skill also does not edit ADRs, change-specs, or any artifact outside `hstack/kernel-fit/findings/`.
19
-
20
- ## When to invoke
21
-
22
- Invoke when a finding is at `status: open` and the engineer wants to:
23
-
24
- - **Acknowledge** (`--action acknowledge`): record intent to act on the finding without committing to an ADR yet. Useful when the finding is real but the team needs more thinking time, or when the right kernel-change shape is unclear.
25
- - **Dismiss** (`--action dismiss --reason <text>`): close the finding without pursuing a kernel change. The reason is mandatory (KF-05) and becomes part of the audit trail.
26
-
27
- For findings already at `acknowledged`, re-invoking with `--action acknowledge` is a no-op; re-invoking with `--action dismiss --reason <text>` is permitted (acknowledged → dismissed is a valid transition when the engineer reconsiders). Findings at terminal status (`dismissed`, `promoted`, `superseded`, `archived`) are immutable from this Skill's perspective — the Skill halts.
28
-
29
- ## Inputs
30
-
31
- - `<finding-id>` (required, positional): the finding id, e.g. `KF-0001-category-a-claim-spans-production` or the short form `KF-0001` (the Skill resolves the latter to the matching file via glob).
32
- - `--action <acknowledge | dismiss>` (required): the triage action.
33
- - `--reason <text>` (required when `--action dismiss`; forbidden when `--action acknowledge`): the dismissal rationale. It has to say what about the finding is wrong or not worth acting on, specifically enough that a reader six months from now can tell whether the dismissal still holds. "Not relevant" gives them nothing to check; "the kernel gives a norm here, not a bound" gives them everything, in forty-one characters. Length is not the test and is not checked (ADR-0014).
34
-
35
- ## Preconditions
36
-
37
- - `hstack/kernel-fit/findings/<finding-id>*.md` exists. If missing, halt.
38
- - The finding is at `status: open` (or `acknowledged` when transitioning to `dismissed`). If at any other status, halt with the current status named and the explanation that the status is terminal.
39
- - `--action` is one of `acknowledge | dismiss` (controlled enum).
40
- - When `--action dismiss`, `--reason` is non-empty and re-evaluable by a later reader per the Inputs section. When it is not — the reason restates the finding, or asserts a preference with no referent — say so and ask for the specific claim; do not write the dismissal.
41
- - When `--action acknowledge`, `--reason` is absent (the Skill rejects redundant reasons to keep the audit signal clean — acknowledge reasons live in the next promote / dismiss invocation if needed).
42
-
43
- ## Orchestration steps
44
-
45
- 1. **Resolve the finding file.** Glob `hstack/kernel-fit/findings/<finding-id>*.md`. If zero matches, halt. If multiple matches (shouldn't happen with the immutable-id rule, but defense in depth), halt and ask the engineer to disambiguate.
46
-
47
- 2. **Validate inputs against preconditions.** Walk the precondition checks above. On any failure, halt with the named reason. When the failure is the `--reason` (`dismiss`), quote the reason back and name what is missing from it — the claim it makes, or the referent it lacks — so the engineer knows what to write rather than how long to write.
48
-
49
- 3. **Print the finding in full.** Read the resolved file and print its full body to the conversation. The engineer should re-read before committing to the triage action.
50
-
51
- 4. **Compose the frontmatter edit.** These fields, and only these, are triage's to write — `pattern`, `evidence-rows`, `evidence-row-count` and `confidence` are the analyst's domain and are never edited here. Compute the exact frontmatter changes:
52
-
53
- For `--action acknowledge`:
54
- - `status: open → acknowledged`
55
- - `owner: <git-handle>` (read from git config; fall back to the engineer's hstack config owner)
56
- - `updated: <today>` (ISO date)
57
-
58
- For `--action dismiss`:
59
- - `status: open → dismissed` (or `acknowledged → dismissed`)
60
- - `dismissed-reason: <text>` (the engineer's `--reason` verbatim)
61
- - `owner: <git-handle>`
62
- - `updated: <today>`
63
-
64
- 5. **Compose the Triage Log append.** Compute the entry to append to the `## Triage Log` section:
65
-
66
- For acknowledge:
67
- ```
68
- - `status: open → acknowledged` on <today> by <owner>. Triggered by `/hstack:kernel-fit-triage <id> --action acknowledge`.
69
- ```
70
-
71
- For dismiss:
72
- ```
73
- - `status: <prev> → dismissed` on <today> by <owner>. Reason: <dismissed-reason>.
74
- ```
75
-
76
- Defensive log-header check per the kernel: if `## Triage Log` is absent, append it before writing the entry.
77
-
78
- 6. **Print the proposed diff.** Show the engineer the exact frontmatter changes and the exact Triage Log entry that will land. This is the kernel's mechanical-operations confirmation gate: the engineer sees what will land before it lands. The validator run in step 7 is the mechanical half of the same check.
79
-
80
- 7. **Confirm.** Print "Apply triage to <finding-id>? (Y/n)". Default Yes. On `n`, abort without writing.
81
-
82
- 8. **Edit + validate + commit.** On `Y`:
83
- - `Edit` the file: frontmatter changes + Triage Log append.
84
- - Run `node hstack/scripts/validate-spec.mjs <path>` against the file. KF-01 through KF-05 must pass; specifically KF-05 (`dismissed-reason` non-null when `status: dismissed`) gates dismissal.
85
- - On validation pass: `git add` the file and commit with message `kernel-fit(<finding-id>): <action>` (e.g. `kernel-fit(KF-0001): acknowledge`).
86
- - On validation failure: halt; revert via `git checkout -- <finding-file>`. Report the failing rule to the engineer.
87
-
88
- 9. **Confirm completion.** Print "Triage applied: <finding-id> is now `<new-status>`. Next steps: `/hstack:kernel-fit-promote <finding-id> --slug <adr-slug>` to elevate to an ADR; or leave at <new-status> and let the next `/hstack:kernel-fit-scan` re-evaluate."
89
-
90
- ## Outputs
91
-
92
- - One edit to `hstack/kernel-fit/findings/<finding-id>*.md` — frontmatter flip + Triage Log append.
93
- - One commit. Message: `kernel-fit(<finding-id>): <action>`.
94
-
95
- ## Auto-commit triggers
96
-
97
- - One commit at the status flip. The kernel's auto-commit-at-status-transition rule applies.
98
-
99
- ## Idempotency contract
100
-
101
- - Re-running with `--action acknowledge` on a finding already at `acknowledged`: no-op. The Skill prints "already acknowledged" and exits without writing.
102
- - Re-running with `--action dismiss` on a finding already at `dismissed`: no-op. The Skill prints "already dismissed" + the existing `dismissed-reason` and exits without writing.
103
- - Re-running with `--action dismiss` on a finding at `acknowledged`: permitted — the `acknowledged → dismissed` transition is valid. The Triage Log entry uses the `<prev> → dismissed` shape.
104
- - Re-running on a finding at `promoted`, `superseded`, or `archived`: halt with the status named. These are terminal from this Skill's perspective.
105
-
106
- ## Stop conditions
107
-
108
- Beyond the kernel's general stop conditions:
109
-
110
- - The finding does not exist or is at a terminal-from-triage status (`dismissed`, `promoted`, `superseded`, `archived`). Halt with the status named.
111
- - `--action` is missing or not in the enum. Halt with usage.
112
- - `--action dismiss` without `--reason`, or with a `--reason` that restates the finding instead of answering it. Halt, quote it back, and name what is missing.
113
- - `--action acknowledge` with `--reason` present. Halt — acknowledge does not take a reason.
114
- - The engineer declines confirmation at step 7. Abort cleanly.
115
- - Validator fails at step 8 — halt with the failing rule; revert the unstaged edit.
116
-
117
- ## Failure modes
118
-
119
- - **Edit fails (filesystem, validator, git).** The frontmatter flip and the Triage Log append must land together in a single auto-commit. If `Edit` succeeds but `git add` or `git commit` fails, the working tree carries the unstaged change — revert via `git checkout -- <finding-file>` and re-invoke.
120
- - **Drive-by dismissal attempt.** The re-evaluability judgment at step 2 is the v1 defense: the reason is read against the finding the Skill just resolved, and one that gives a later reader nothing to check is quoted back before any write occurs.
121
- - **Stale finding (post-scan supersession in flight).** If a concurrent `/hstack:kernel-fit-scan` has just superseded the finding the engineer is triaging, the post-edit validator would catch the inconsistent state (superseded finding cannot be re-triaged). Halt and let the engineer re-fetch the working tree.
@@ -1,78 +0,0 @@
1
- ---
2
- name: hstack-module-spec
3
- description: Use to reverse-engineer or refresh the baseline `hstack/specs/<module>/spec.md` for one module. Required before any change-spec whose `area` names that module can validate.
4
- tools:
5
- - Read
6
- - Write
7
- - Edit
8
- - Grep
9
- - Glob
10
- - Bash
11
- - Task
12
- - "{{TODO-TOOL: RepoMix — packs the module slice (paths from hstack/config.yaml) into a single context bundle for spec-author}}"
13
- - "node hstack/scripts/validate-spec.mjs — validates module-spec frontmatter and MS-01/MS-02/MS-03"
14
- ---
15
-
16
- ## Purpose
17
-
18
- `hstack-module-spec` produces a baseline `hstack/specs/<module>/spec.md` for one named module by orchestrating the `spec-author` subagent against a packed module slice. It is the one Skill where `spec-author` is permitted to grep the code in service of authorship — reading it, never modifying it. The module-spec is the system's anchor between its `area` controlled enum and the actual codebase, and a module-spec disconnected from real paths is worthless.
19
-
20
- ## When to invoke
21
-
22
- Invoke once per critical module after `hstack-init` completes, before any change-spec in that module's `area` can validate. Re-invoke when the 60-day `needs-refresh` cron flags the spec, when the module's shape materially changes (new owned table, new public surface, new dependency), or on demand when the engineer wants a refresh.
23
-
24
- ## Inputs
25
-
26
- - `<module>` (required, positional): the module key as declared in `hstack/config.yaml`'s module-to-area mapping. Must match an existing entry.
27
-
28
- ## Preconditions
29
-
30
- Before any work:
31
-
32
- - Verify `hstack/config.yaml` exists at `init-status: complete`. If not, halt and direct the engineer to `hstack-init`.
33
- - Verify the named module exists in the config's module-to-area mapping. If not, halt and ask the engineer to add it via `hstack-configure` first.
34
- - Read the module's declared `paths` globs from config and verify at least one path resolves to existing files. If none resolve, halt — the module-to-paths mapping is stale.
35
- - Check whether `hstack/specs/<module>/spec.md` already exists. If yes and at `status: current`, ask the engineer whether this is a refresh (proceed with the existing spec as the proposal layer) or a re-author (archive the existing spec first).
36
- - Read `hstack/context/glossary.md` and `hstack/context/tech-stack.md` (required by `spec-author`'s session-start protocol).
37
-
38
- ## Orchestration steps
39
-
40
- 1. **Pack the module slice.** Run `{{TODO-TOOL: RepoMix}}` over the module's `paths` globs and write the packed bundle to a temporary location. If RepoMix is unavailable, fall back to having `spec-author` grep the paths directly; flag the degraded read in the conversation.
41
-
42
- 2. **Invoke `spec-author`.** Use the Task tool with `subagent_type: spec-author` and context = [kernel, `hstack/templates/module-spec.md`, glossary, tech-stack, packed module bundle, existing module-spec instance if refresh]. The subagent reads the bundle, walks the seven module-spec sections — Purpose, Public Surface, Data Owned, External Dependencies, Invariants, Known Tech-Debt and ADRs, Refresh Policy — with confirmation gates per field.
43
-
44
- 3. **Exercise the Invariants challenge prompt.** Per the `spec-author` contract and MS-03, the Invariants section requires a minimum of three bullets, elicited via the challenge "What would a careless refactor in this module break that the tests would not catch?" The Skill does not bypass this even on refresh.
45
-
46
- 4. **Validate.** After each confirmed field write, the subagent runs `node hstack/scripts/validate-spec.mjs <path>` against the in-progress file. The Skill verifies MS-01 (paths non-empty and resolve), MS-02 (no overlap with other module-specs' paths — important to surface mis-aligned module-to-paths mapping), MS-03 (Invariants ≥ 3 bullets).
47
-
48
- 5. **Transition to `status: current`.** When every section is confirmed and the validator passes, `spec-author` advances status from `drafted` to `current` and updates `last-refreshed` to today. Auto-commit fires.
49
-
50
- ## Outputs
51
-
52
- - `hstack/specs/<module>/spec.md` at `status: current`, with frontmatter including the module's `paths` array mirrored from `hstack/config.yaml`. The Skill mirrors those globs; it never edits, substitutes, or invents them — `paths` are config's to change.
53
-
54
- ## Auto-commit triggers
55
-
56
- - Status moves from absent to `drafted` after the first section is confirmed (so partial work survives).
57
- - Status moves from `drafted` to `current` when the full spec lands. Commit message: `module-spec(<module>): draft baseline` or `module-spec(<module>): refresh` depending on prior state.
58
-
59
- ## Idempotency contract
60
-
61
- - Re-running on a `current` module-spec without specifying refresh intent: the Skill detects the existing spec and asks the engineer whether to refresh.
62
- - Re-running mid-authoring after a halt: `spec-author` reads the partial file, identifies the first un-confirmed section, and resumes the interview there.
63
- - Re-running on a refresh where the engineer accepts every section unchanged: a no-op diff body with only the `updated` and `last-refreshed` timestamps changing.
64
-
65
- ## Stop conditions
66
-
67
- Beyond the kernel's general stop conditions:
68
-
69
- - The module's `paths` globs resolve to zero existing files. Halt; the module-to-paths mapping in config is wrong.
70
- - MS-02 fails — the module's paths overlap with another module's paths. Halt and ask the engineer to reconcile the mapping via `hstack-configure`.
71
- - The Invariants challenge prompt cannot produce three bullets after honest interview. Halt; either the module is too small to merit its own spec (fold into a parent module via `hstack-configure`) or the engineer needs more time to think.
72
- - `spec-author` halts because a referenced glossary term cannot be reconciled. Halt and surface; the engineer either updates the glossary via `hstack-configure --interview glossary` or rephrases.
73
-
74
- ## Failure modes
75
-
76
- - **RepoMix unavailable.** Degraded mode — flag in the conversation, fall back to direct grep, continue.
77
- - **Existing module-spec frontmatter does not match config's paths.** Halt; the engineer reconciles before the refresh can proceed.
78
- - **Validator failure on a partial write.** `spec-author` halts at the field; the Skill surfaces the validator's message and waits.
@@ -1,75 +0,0 @@
1
- ---
2
- name: hstack-product-discovery
3
- description: Use to produce or refresh `hstack/context/product/product-brief.md` through one of three discovery techniques. Greenfield Phase 1, optional brownfield enrichment when source docs are thin, or standalone retroactive authoring.
4
- tools:
5
- - Read
6
- - Write
7
- - Edit
8
- - Grep
9
- - Glob
10
- - Bash
11
- - Task
12
- - "node hstack/scripts/validate-spec.mjs — frontmatter validator"
13
- ---
14
-
15
- ## Purpose
16
-
17
- `hstack-product-discovery` is the atom that produces `hstack/context/product/product-brief.md` via the `product-discovery` subagent. It is the canonical authoring path for the brief; the brief never lands via a generic spec-author interview.
18
-
19
- ## When to invoke
20
-
21
- - Phase 1 of `/hstack:greenfield-init` (elicit mode, no source).
22
- - Optional enrichment within `/hstack:brownfield-init` when existing product docs are thin and the engineer wants the deeper reframe-style brief.
23
- - Standalone via `/hstack:product-discovery [--mode extract|elicit] [--section <name>]` for retroactive brief authoring on any repo.
24
-
25
- ## Inputs
26
-
27
- - `--mode extract | elicit` — defaults: `elicit` if no source docs are reachable; `extract` if a `product-brief.md` exists or the engineer points at source documents.
28
- - `--section <name>` — optional, fast-jumps to a specific section for refresh. Re-runs the end-of-atom check across all sections before commit.
29
-
30
- ## Preconditions
31
-
32
- - `hstack/config.yaml` exists and `init-status` is at least `minimal-complete` — the atom does not run standalone until config exists.
33
- - `hstack/KERNEL.md` and `hstack/templates/product-brief.md` are present.
34
- - `hstack/templates/discovery/{brainstorm,forcing-questions,project-brief}.md` are present.
35
- - In extract mode, at least one source document must be reachable; otherwise halt and ask the engineer to either supply source pointers or fall back to elicit mode.
36
-
37
- ## Orchestration steps
38
-
39
- 1. **Detect mode.** Read disk state. If `hstack/context/product/product-brief.md` exists at `status: current` and no `--section` flag, this is a refresh confirmation — print summary and exit unless engineer opts into full re-interview.
40
- 2. **Pick technique** (elicit mode only). Prompt the engineer to choose Brainstorm / Forcing-Questions / Project-Brief. Persist the choice as `technique-used` in the brief frontmatter.
41
- 3. **Invoke `product-discovery` subagent.** Via the Task tool with `subagent_type: product-discovery`. Pass mode, technique, optional section, and the canonical session-start context (kernel, template, technique script, source docs in extract mode).
42
- 4. **Walk sections.** The subagent runs the chosen technique's script and walks the brief sections with confirmation gates. Each confirmed section writes to disk and auto-commits.
43
- 5. **Run forcing prompts.** The three required reframes (Who pays? What's the wedge? What would falsify this?) fire before terminal state regardless of technique.
44
- 6. **Auto-route at terminal state.** When the brief reaches `status: current`, the Skill prints the auto-route message (with alternative-path commands) and hands off to `product-manager` via the Task tool with `subagent_type: product-manager` to refresh `vision.md`, `roadmap.md`, `personas/`, `glossary.md`. If the engineer types `skip-routing`, the Skill commits the brief and exits cleanly — downstream Skills will halt on missing context docs.
45
-
46
- ## Outputs
47
-
48
- - `hstack/context/product/product-brief.md` at `status: current`.
49
- - `hstack/.session-state/<session-id>.yaml` (transient).
50
- - Via auto-route: `vision.md`, `roadmap.md`, `personas/*`, `glossary.md` refreshed (unless skip-routing).
51
-
52
- ## Auto-commit triggers
53
-
54
- - Each confirmed section writes immediately and auto-commits.
55
- - Brief reaches `status: current` → final commit with the auto-route message in the body.
56
- - Downstream refreshes by `product-manager` each auto-commit per the product-manager subagent's contract.
57
-
58
- ## Idempotency contract
59
-
60
- - Brief at `current` + no `--section` + no `--force`: print summary, exit no-op.
61
- - Brief at `draft` or partial: read disk + session-state, resume at next non-confirmed section.
62
- - Brief at `needs-refresh` (flipped by `/hstack:configure` because upstream changed): walk all sections in confirm-or-revise mode.
63
-
64
- ## Stop conditions
65
-
66
- - A required source document in extract mode is unreachable.
67
- - Forcing-prompt answer is too vague after one re-ask. The subagent halts with `HSTACK-HALT: reason=ambiguous-spec` or `missing-context`.
68
- - Mid-technique switch requested.
69
- - Engineer signals end-of-session.
70
- - Downstream auto-route fails (e.g., `product-manager` cannot reach the configured personas store). The Skill surfaces the failure; the brief stays at `current`, downstream context docs stay at their prior status until the engineer resolves.
71
-
72
- ## Failure modes
73
-
74
- - **Subagent unreachable.** Persist session state; retry later.
75
- - **Auto-route partial failure.** If `product-manager` succeeds on vision but fails on personas (e.g., Notion MCP unreachable), the partial state is on disk; re-running auto-route via `/hstack:configure personas --from-brief` recovers.
@@ -1,115 +0,0 @@
1
- ---
2
- name: hstack-research
3
- description: Use when a decision needs grounded external information — API behavior, competitive scans, canonical docs, security CVEs, AI-native patterns — written to a transient research session. `--promote` elevates a session to an ADR, tech-debt, or durable note.
4
- tools:
5
- - Read
6
- - Write
7
- - Edit
8
- - Grep
9
- - Glob
10
- - Bash
11
- - Task
12
- - WebSearch
13
- - WebFetch
14
- - "{{TODO-MCP: Notion MCP — optional; useful when research must include prior team decisions in Notion}}"
15
- - "{{TODO-MCP: GitHub MCP — optional; useful for searching issues and PRs on third-party SDK repos}}"
16
- - "node hstack/scripts/validate-spec.mjs — validates research session frontmatter"
17
- - "{{TODO-SCRIPT: hstack/scripts/garbage-collect-research.sh — clears sessions past their garbage-collect-after date; promoted sessions exempt}}"
18
- ---
19
-
20
- ## Purpose
21
-
22
- `hstack-research` produces grounded research outputs via the `researcher` subagent and routes explicit promotion to durable artifacts. The Skill has two modes:
23
-
24
- - **Default mode.** Invoke the researcher with a query; classify into one of five modes; write a transient session artifact under `hstack/research/sessions/` with sources, confidence markers, and proposed promotion targets.
25
- - **`--promote <session-id>` mode.** Elevate an existing session to a durable artifact: ADR (route through `hstack-adr-new`), tech-debt (route through `hstack-tech-debt-new`), or a durable note under `hstack/research/promoted/` (the researcher writes this directly).
26
-
27
- ## When to invoke
28
-
29
- Invoke when the engineer wants to ground a decision or implementation choice in current external information rather than speculation. Common triggers: third-party API integration choices, competitive scans before an ADR, security-CVE checks against pinned dependencies, AI-native pattern lookups (prompt-caching, retrieval, orchestration).
30
-
31
- ## Inputs
32
-
33
- Default mode:
34
- - `<query>` (required, positional): the research question, in natural language. The Skill does not require a pre-classified mode — the researcher classifies during the session.
35
-
36
- Promote mode:
37
- - `--promote <session-id>` (required): the session to elevate.
38
- - `--target adr | tech-debt | note` (optional): the promotion target. When omitted, the Skill asks the engineer based on the session's proposed promotion targets.
39
-
40
- ## Preconditions
41
-
42
- Before any work:
43
-
44
- - Verify `hstack/config.yaml` exists at `init-status: complete`.
45
- - Default mode: verify `hstack/research/sessions/` exists; create if absent.
46
- - Promote mode: verify the named session exists at `hstack/research/sessions/<session-id>.md` and is at `status: current`. Verify the session is not already promoted.
47
-
48
- ## Orchestration steps
49
-
50
- ### Default mode
51
-
52
- 1. **Invoke `researcher`.** Use the Task tool with `subagent_type: researcher` and context = [kernel, query, mode-relevant context docs per the researcher's contract — tech-stack for API/documentation modes, vision/roadmap for competitive/AI-native modes, threat-model/hardening-checklist for security-CVE mode]. The subagent classifies the query, applies the mode's source bias, and writes findings incrementally.
53
-
54
- 2. **Source discipline.** Per the `researcher` contract:
55
- - API-lookup: canonical vendor docs over tutorials; 12-month recency window.
56
- - Competitive-scan: engineering-side sources over marketing pages; vendors named explicitly.
57
- - Documentation: canonical sources only; contradictions surfaced rather than papered.
58
- - Security-CVE: CVE databases and vendor advisories; recency window open; cross-checked against `tech-stack.md` pins.
59
- - AI-native best practices: 6-month recency bias; engineering blogs and tooling repos over vendor marketing.
60
- Every source is named with URL and access timestamp. Single-source claims marked explicitly.
61
-
62
- 3. **Confidence markers.** Each finding lands with `high | medium | low` confidence per the researcher's contract.
63
-
64
- 4. **Proposed promotion targets.** The session artifact closes with a Promotion Targets section: "Promote to ADR / tech-debt / research-note? Engineer decides." The Skill does not promote unilaterally.
65
-
66
- 5. **Session artifact frontmatter.** Includes `garbage-collect-after: <today + 30 days>` per the architecture's retention rule. Promoted sessions are exempt; the `--promote` operation sets a flag that the garbage-collector honors.
67
-
68
- ### Promote mode
69
-
70
- 1. **Read the session.** Surface the proposed promotion targets to the engineer.
71
-
72
- 2. **Route by `--target` value:**
73
- - `--target adr`: invoke `hstack-adr-new` with `--from-research <session-id>` and a slug supplied by the engineer. The ADR's Context section is seeded from the session findings; `spec-author` walks the remaining Nygard sections via its conversational interview, exercising the Consequences challenge prompt.
74
- - `--target tech-debt`: invoke `hstack-tech-debt-new` with the engineer-supplied slug and any `--origin <change-spec-id>` when applicable. `spec-author` walks the six tech-debt sections.
75
- - `--target note`: the `researcher` writes a durable note at `hstack/research/promoted/<topic>.md` directly. Free-form structure; no template constraint. This is the only target where the researcher writes the promoted artifact directly — the kernel's promotion-routing rule explicitly permits this for free-form notes.
76
-
77
- 3. **Mark the session as promoted.** Update the session's frontmatter with `promoted-to: adr:<ADR-NNNN>` (or `tech-debt:<TD-NNNN>` or `note:<path>`). Exempt from garbage collection.
78
-
79
- ## Outputs
80
-
81
- Default mode:
82
- - `hstack/research/sessions/<YYYY-MM-DD>-<topic-slug>.md` at `status: current`, with query, classified mode(s), sources, findings, options, and proposed promotion targets.
83
-
84
- Promote mode (depending on `--target`):
85
- - A new ADR at `hstack/adr/ADR-NNNN-<slug>.md` (via `hstack-adr-new`).
86
- - A new tech-debt item at `hstack/tech-debt/TD-NNNN-<slug>.md` (via `hstack-tech-debt-new`).
87
- - A new durable note at `hstack/research/promoted/<topic>.md` (written by the researcher).
88
- - An edit to the source session marking it `promoted-to: ...`.
89
-
90
- ## Auto-commit triggers
91
-
92
- - Default mode: one commit when the session artifact lands. Commit message: `research(<topic>): drafted`.
93
- - Promote mode: the destination Skill's auto-commit fires (ADR or tech-debt). For `--target note`, one commit when the note lands plus the session's `promoted-to` edit.
94
-
95
- ## Idempotency contract
96
-
97
- - Default mode: re-running with an identical query produces a new session file with today's date in the filename — research is recency-sensitive and re-running is intentional. The engineer may delete the prior session manually, or let the garbage collector handle it after 30 days.
98
- - Promote mode: re-running on an already-promoted session is a no-op; the Skill detects the `promoted-to` field and exits.
99
-
100
- ## Stop conditions
101
-
102
- Beyond the kernel's general stop conditions:
103
-
104
- - Query is too vague to classify into a mode. Ask for clarification.
105
- - A load-bearing context document is unreachable.
106
- - Sources are contradictory and the resolution requires a human call.
107
- - Promote mode: target is unspecified and the engineer has not chosen.
108
- - Promote mode: the named session does not exist or is already promoted.
109
- - Promote mode with `--target adr` or `--target tech-debt`: the routed Skill halts; surface the halt message.
110
-
111
- ## Failure modes
112
-
113
- - **WebSearch / WebFetch rate-limited or unavailable.** Surface the limitation; the researcher proceeds with cached or partial results, naming confidence as `low` for affected findings.
114
- - **A vendor's docs have moved and the canonical URL no longer resolves.** Note the broken canonical source explicitly; do not silently switch to a tutorial.
115
- - **Promote-to-ADR or promote-to-tech-debt halts inside `spec-author`'s interview.** The session's `promoted-to` field is not written until the destination artifact is at terminal state. Resume by re-running the destination Skill directly.