hstack 0.7.1 → 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 (131) hide show
  1. package/CHANGELOG.md +308 -0
  2. package/README.md +90 -154
  3. package/VERSION +1 -1
  4. package/dist/commands/doctor.js +69 -9
  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 +17 -4
  9. package/dist/commands/update.js.map +1 -1
  10. package/dist/lib/descriptions.js +160 -0
  11. package/dist/lib/descriptions.js.map +1 -0
  12. package/dist/lib/diff.js +1 -1
  13. package/dist/lib/git.js +16 -0
  14. package/dist/lib/git.js.map +1 -1
  15. package/dist/lib/wire.js +274 -142
  16. package/dist/lib/wire.js.map +1 -1
  17. package/dist/manifest.js +49 -22
  18. package/dist/manifest.js.map +1 -1
  19. package/package.json +4 -3
  20. package/template/.claude/agents/adversarial-reviewer.md +42 -98
  21. package/template/.claude/agents/app-architect.md +44 -133
  22. package/template/.claude/agents/data-architect.md +46 -127
  23. package/template/.claude/agents/test-strategist.md +39 -109
  24. package/template/.claude/skills/hstack-adr-new/SKILL.md +23 -100
  25. package/template/.claude/skills/hstack-adversarial-review/SKILL.md +47 -174
  26. package/template/.claude/skills/hstack-adversarial-review/references/finding-categories.md +134 -0
  27. package/template/.claude/skills/hstack-app-architecture/SKILL.md +43 -95
  28. package/template/.claude/skills/hstack-commit/SKILL.md +28 -97
  29. package/template/.claude/skills/hstack-data-architecture/SKILL.md +34 -82
  30. package/template/.claude/skills/hstack-promote/SKILL.md +55 -0
  31. package/template/.claude/skills/hstack-story/SKILL.md +58 -0
  32. package/template/.claude/skills/hstack-test-audit/SKILL.md +64 -0
  33. package/template/.claude/skills/hstack-wrap/SKILL.md +48 -0
  34. package/template/.claude/skills/hstack-wrap/references/pr-description.md +45 -0
  35. package/template/KERNEL.md +167 -0
  36. package/template/templates/adr.md +9 -18
  37. package/template/templates/app-architecture.md +38 -50
  38. package/template/templates/data-architecture.md +39 -93
  39. package/template/templates/infrastructure.md +54 -148
  40. package/template/templates/roadmap.md +35 -0
  41. package/template/templates/story.md +7 -13
  42. package/template/templates/tech-debt.md +2 -37
  43. package/template/templates/tech-stack.md +2 -12
  44. package/template/.claude/agents/data-specialist.md +0 -126
  45. package/template/.claude/agents/implementer.md +0 -154
  46. package/template/.claude/agents/kernel-fit-analyst.md +0 -190
  47. package/template/.claude/agents/planner.md +0 -110
  48. package/template/.claude/agents/product-discovery.md +0 -165
  49. package/template/.claude/agents/product-manager.md +0 -111
  50. package/template/.claude/agents/researcher.md +0 -123
  51. package/template/.claude/agents/security-reviewer.md +0 -123
  52. package/template/.claude/agents/spec-author.md +0 -123
  53. package/template/.claude/agents/stack-architect.md +0 -137
  54. package/template/.claude/agents/ui-ux-briefer.md +0 -105
  55. package/template/.claude/agents/verifier.md +0 -113
  56. package/template/.claude/skills/hstack-branch/SKILL.md +0 -103
  57. package/template/.claude/skills/hstack-brownfield-init/SKILL.md +0 -158
  58. package/template/.claude/skills/hstack-change-new/SKILL.md +0 -111
  59. package/template/.claude/skills/hstack-change-plan/SKILL.md +0 -119
  60. package/template/.claude/skills/hstack-configure/SKILL.md +0 -126
  61. package/template/.claude/skills/hstack-coord/SKILL.md +0 -131
  62. package/template/.claude/skills/hstack-data-review/SKILL.md +0 -132
  63. package/template/.claude/skills/hstack-finalize/SKILL.md +0 -159
  64. package/template/.claude/skills/hstack-flag/SKILL.md +0 -138
  65. package/template/.claude/skills/hstack-greenfield-init/SKILL.md +0 -175
  66. package/template/.claude/skills/hstack-help/SKILL.md +0 -179
  67. package/template/.claude/skills/hstack-implement/SKILL.md +0 -185
  68. package/template/.claude/skills/hstack-kernel-fit-promote/SKILL.md +0 -164
  69. package/template/.claude/skills/hstack-kernel-fit-scan/SKILL.md +0 -197
  70. package/template/.claude/skills/hstack-kernel-fit-triage/SKILL.md +0 -159
  71. package/template/.claude/skills/hstack-module-spec/SKILL.md +0 -105
  72. package/template/.claude/skills/hstack-product-discovery/SKILL.md +0 -101
  73. package/template/.claude/skills/hstack-research/SKILL.md +0 -145
  74. package/template/.claude/skills/hstack-scaffold/SKILL.md +0 -140
  75. package/template/.claude/skills/hstack-security-review/SKILL.md +0 -133
  76. package/template/.claude/skills/hstack-ship/SKILL.md +0 -129
  77. package/template/.claude/skills/hstack-stack-decide/SKILL.md +0 -108
  78. package/template/.claude/skills/hstack-story-draft/SKILL.md +0 -119
  79. package/template/.claude/skills/hstack-tech-debt-new/SKILL.md +0 -122
  80. package/template/.claude/skills/hstack-tech-debt-resolve/SKILL.md +0 -158
  81. package/template/.claude/skills/hstack-tech-debt-stale/SKILL.md +0 -113
  82. package/template/.claude/skills/hstack-tech-debt-wontfix/SKILL.md +0 -104
  83. package/template/.claude/skills/hstack-telemetry/SKILL.md +0 -98
  84. package/template/.claude/skills/hstack-test-plan/SKILL.md +0 -182
  85. package/template/.claude/skills/hstack-ui-brief/SKILL.md +0 -108
  86. package/template/.claude/skills/hstack-verify/SKILL.md +0 -150
  87. package/template/CLAUDE.md +0 -443
  88. package/template/scripts/coord/coord_scan.py +0 -681
  89. package/template/scripts/telemetry/__init__.py +0 -6
  90. package/template/scripts/telemetry/insights/__init__.py +0 -0
  91. package/template/scripts/telemetry/insights/contract_drift.py +0 -137
  92. package/template/scripts/telemetry/insights/kernel_fit.py +0 -438
  93. package/template/scripts/telemetry/insights/overengineering.py +0 -115
  94. package/template/scripts/telemetry/insights/quality_outcomes.py +0 -131
  95. package/template/scripts/telemetry/insights/token_economics.py +0 -129
  96. package/template/scripts/telemetry/insights/workflow_shape.py +0 -198
  97. package/template/scripts/telemetry/parsers/__init__.py +0 -0
  98. package/template/scripts/telemetry/parsers/bodies.py +0 -87
  99. package/template/scripts/telemetry/parsers/commits.py +0 -219
  100. package/template/scripts/telemetry/parsers/frontmatter.py +0 -322
  101. package/template/scripts/telemetry/parsers/transcripts.py +0 -181
  102. package/template/scripts/telemetry/render.py +0 -395
  103. package/template/scripts/telemetry/report.py +0 -138
  104. package/template/scripts/telemetry/run_kernel_fit.py +0 -91
  105. package/template/templates/adversarial-review.md +0 -54
  106. package/template/templates/bootstrap.md +0 -105
  107. package/template/templates/change-spec.md +0 -82
  108. package/template/templates/ci-cd.md +0 -27
  109. package/template/templates/coord-message.md +0 -55
  110. package/template/templates/data-review.md +0 -54
  111. package/template/templates/discovery/brainstorm.md +0 -69
  112. package/template/templates/discovery/forcing-questions.md +0 -76
  113. package/template/templates/discovery/project-brief.md +0 -53
  114. package/template/templates/figma-handoff.md +0 -38
  115. package/template/templates/glossary.md +0 -20
  116. package/template/templates/hardening-checklist.md +0 -73
  117. package/template/templates/incident-runbook.md +0 -57
  118. package/template/templates/kernel-fit-finding.md +0 -63
  119. package/template/templates/kernel-fit-flag.md +0 -52
  120. package/template/templates/module-spec.md +0 -49
  121. package/template/templates/mvp-scope.md +0 -34
  122. package/template/templates/persona.md +0 -38
  123. package/template/templates/plan.md +0 -49
  124. package/template/templates/product-brief.md +0 -56
  125. package/template/templates/security-review.md +0 -63
  126. package/template/templates/telemetry-sidecar.md +0 -184
  127. package/template/templates/test-plan.md +0 -119
  128. package/template/templates/threat-model.md +0 -54
  129. package/template/templates/ui-brief.md +0 -49
  130. package/template/templates/verification.md +0 -63
  131. package/template/templates/vision.md +0 -34
@@ -1,133 +0,0 @@
1
- ---
2
- name: hstack-security-review
3
- description: |
4
- Use this skill when a change-spec is at `status: ready-to-plan` or later and needs `security-review.md` produced before the implementer can start. The Skill orchestrates the `security-reviewer` subagent. In v1 the output is an LLM-scored structured judgment (`scoring-mode: llm-scored`), not an executable test result — the Skill enforces this framing on every output. Examples:
5
-
6
- <example>
7
- Context: A change-spec introduces a new public-schema table with RLS and is at ready-to-plan.
8
- user: "/hstack:security-review 2026-05-billing-overage-warning"
9
- assistant: "I'll invoke security-reviewer. Surfaces is [ui, db], so the threat-model-delta section is mandatory. Scoring biases toward CONCERNS over PASS when evidence is thin; the three challenge prompts run regardless of what surfaces declares."
10
- <commentary>
11
- The Skill is the only authoring path for security-review.md. It enforces SR-03 (threat-model-delta required when surfaces touches agent/auth/api/db) and SR-02 (three challenge prompts mandatory). v1 framing is enforced on every rationale.
12
- </commentary>
13
- </example>
14
-
15
- <example>
16
- Context: A change touches the agent surface — new orchestrator prompt and a new tool boundary — and the threat-model.md has not been touched in eight weeks.
17
- user: "/hstack:security-review 2026-06-playbook-runner-prompt"
18
- assistant: "I'll invoke security-reviewer. The threat-model-delta is mandatory because surfaces includes agent; I'll halt if the delta can't be produced from the current threat-model. Findings will frame as structured judgment, not verified by test execution."
19
- <commentary>
20
- Agent-surface changes are exactly where the v1 honesty clause matters most. The Skill ensures the subagent does not claim test-backed evidence for prompt-injection resistance — that is v2 substrate work.
21
- </commentary>
22
- </example>
23
-
24
- <example>
25
- Context: A change is a small refactor with no declared security-sensitive surface, but the diff touches authentication-adjacent code.
26
- user: "/hstack:security-review 2026-05-auth-helper-rename"
27
- assistant: "I'll invoke security-reviewer. Even on a refactor, the three challenge prompts run — attack vector not covered by checklist, tenant-isolation citation, malicious-payload behavior — to surface anything the surface declaration may have missed."
28
- <commentary>
29
- Refactors near auth are exactly the place where the surface declaration may understate the risk. The challenge-prompt machinery is the v1 mitigation for humans missing what's missing.
30
- </commentary>
31
- </example>
32
- tools:
33
- - Read
34
- - Write
35
- - Edit
36
- - Grep
37
- - Glob
38
- - Bash
39
- - Task
40
- - "{{TODO-SCRIPT: hstack/scripts/score-security-review.ts — computes overall status from the scores map}}"
41
- - "{{TODO-SCRIPT: hstack/scripts/validate-spec.ts — validates security-review frontmatter and SR-01..SR-05}}"
42
- - "{{TODO-MCP: Supabase MCP — optional in v1 for live RLS introspection; v2 substrate will hard-fail when unreachable for db-surface changes}}"
43
- ---
44
-
45
- ## Purpose
46
-
47
- `hstack-security-review` produces `security-review.md` for a change-spec by orchestrating the `security-reviewer` subagent. In hstack v1, the artifact is a structured LLM judgment against the hardening checklist plus three mandatory challenge prompts. It is not an executable test artifact; v2 substrate replaces the scoring with real probe outcomes (prompt-injection corpora, RLS bypass attempts, tenant_id fuzzing, secret-redaction probes). This Skill enforces the v1 honesty framing on every output.
48
-
49
- ## When to invoke
50
-
51
- Invoke when a change-spec reaches `status: ready-to-plan` or later. Security-review can run before, after, or concurrently with `hstack-change-plan` and `hstack-data-review` — none of those gate one another. The implementer refuses to start unless this artifact is at `status: passed` or `concerns-acknowledged`.
52
-
53
- ## Inputs
54
-
55
- - `<change-id>` (required, positional): the change-spec id.
56
-
57
- ## Preconditions
58
-
59
- Before any work:
60
-
61
- - Verify the change-spec exists and is at `status: ready-to-plan` or later.
62
- - Verify `hstack/context/threat-model.md` is at `status: current` (not `needs-refresh` or absent). Halt otherwise — the subagent refuses to score against a stale or missing threat model.
63
- - Verify `hstack/context/hardening-checklist.md` is at `status: current`.
64
- - Read `hstack/context/tech-stack.md` and `ci-cd.md` (loaded by `security-reviewer` for grounding).
65
- - Determine whether `surfaces` includes any of `agent`, `auth`, `api`, `db`. If yes, set `threat-model-delta-required: true` for the subagent's session.
66
- - Note whether the Supabase MCP is wired up. If `surfaces` includes `db` and the MCP is unreachable, the Skill proceeds in v1 degraded mode (flagged in rationale) per the v1/v2 split; v2 substrate hard-fails here.
67
-
68
- ## Orchestration steps
69
-
70
- 1. **Invoke `security-reviewer`.** Use the Task tool with `subagent_type: security-reviewer` and context = [kernel, `hstack/templates/security-review.md`, change-spec, threat-model, hardening-checklist, tech-stack, ci-cd]. The subagent scores each applicable hardening item against PASS / CONCERNS / FAIL / not-applicable, with a one-paragraph rationale per item.
71
-
72
- 2. **Threat-model delta.** When `threat-model-delta-required: true`, the subagent writes section 3 with a non-empty delta against the current threat-model.md. SR-03 enforces this at validation.
73
-
74
- 3. **Three challenge prompts (mandatory).** Per SR-02 and the subagent's contract, the subagent answers all three challenge prompts verbatim:
75
- - "What attack vector did the In-Scope diff create that is NOT covered by the hardening checklist? If none, justify."
76
- - "Which tenant_isolation guarantee does this change depend on? Cite the line of code that enforces it."
77
- - "What part of this change would behave incorrectly under a malicious payload that the test suite does not cover?"
78
- Each answer is at least one paragraph. The Skill verifies `challenge-prompts-answered: 3` in frontmatter.
79
-
80
- 4. **Scoring discipline.** Per the subagent's contract, scoring biases toward CONCERNS when evidence is thin. The Skill does not override this bias. Tenant-isolation citations reference real lines of code; the subagent greps to verify.
81
-
82
- 5. **v1 framing.** Every rationale paragraph uses language like "based on the diff, RLS policy mirrors X" rather than "verified". The Skill rejects any rationale that asserts test-backed evidence — that is v2 substrate territory.
83
-
84
- 6. **Status transitions.** When every applicable score is `pass` or `not-applicable`, the subagent transitions to `status: passed`. When any score is `concerns`, the subagent transitions to `concerns-acknowledged` only when `concerns-acknowledged-by` is non-null (a human handle the owner has explicitly provided) and section 5 enumerates each open concern. Per SR-05, `passed` is impossible if any score is `concerns` or `fail`.
85
-
86
- 7. **Tech-debt for deferred concerns.** When a CONCERNS finding is being deferred rather than fixed, the subagent prompts the engineer to invoke `hstack-tech-debt-new` to create the paper trail. The Skill does not file the tech-debt itself; it surfaces the recommendation.
87
-
88
- 8. **Validate.** Run `{{TODO-SCRIPT: hstack/scripts/validate-spec.ts}}` and `{{TODO-SCRIPT: hstack/scripts/score-security-review.ts}}` — SR-01 through SR-05.
89
-
90
- ## Outputs
91
-
92
- - `hstack/specs/changes/<change-id>/security-review.md` at `status: passed` or `concerns-acknowledged`.
93
- - Optional surfaced recommendation to file tech-debt for any deferred CONCERNS.
94
-
95
- ## Auto-commit triggers
96
-
97
- - Status transition to `in-progress` after the first scores land.
98
- - Status transition to terminal (`passed` or `concerns-acknowledged`). Commit message: `security-review(<change-id>): passed` or `concerns-acknowledged`.
99
- - Edits to the `scores` map (because SR-05's terminal-gating depends on it).
100
- - Edits to `concerns-acknowledged-by` (because it gates SR-04).
101
-
102
- ## Idempotency contract
103
-
104
- - Re-running on a terminal security-review without diff changes: the subagent reads the existing artifact and produces a no-op diff aside from `updated` timestamps.
105
- - Re-running after the change-spec's `in-scope` has expanded: the subagent re-scopes the diff read and may produce new scores; the engineer confirms or amends.
106
- - Re-running mid-authoring after a halt: the subagent reads the partial artifact and resumes at the next un-scored item or unanswered challenge prompt.
107
-
108
- ## Stop conditions
109
-
110
- Beyond the kernel's general stop conditions:
111
-
112
- - `threat-model.md` or `hardening-checklist.md` at `needs-refresh` or absent. Halt.
113
- - Supabase MCP unreachable and `surfaces` includes `db` in a high-stakes context (new schema, new RLS). Halt in v1 if the change is high-stakes; v2 always hard-fails here.
114
- - A score would require evidence (a test result, runtime check) that does not yet exist. The subagent marks CONCERNS with the missing evidence named; does not synthesize a PASS.
115
- - `concerns-acknowledged-by` would be written without the owner's explicit acknowledgement. Halt.
116
- - A forbidden surface is touched (service_role Supabase key in agent code, raw shell against production, Pipedream Connect against live customer accounts). Halt — kernel-level stop condition.
117
-
118
- ## Failure modes
119
-
120
- - **Threat-model stale.** Halt; refresh via `hstack-configure --interview threat-model`.
121
- - **Tenant-isolation citation cannot be produced because the In-Scope diff drops tenant context.** Halt and surface — the change introduces a tenant-isolation bug.
122
- - **Validator fails SR-02 (fewer than 3 challenge prompts answered).** Halt; the subagent re-runs the missing prompt.
123
- - **v1 framing slips in a rationale.** The Skill detects "verified by test" language in any rationale paragraph and halts; the subagent re-words.
124
-
125
- ## Anti-patterns
126
-
127
- - Never produce a PASS when evidence is thin. Default to CONCERNS and let the human acknowledge.
128
- - Never skip or paraphrase a challenge prompt. The three are verbatim and mandatory.
129
- - Never claim test-backed evidence in v1. The honesty clause is load-bearing.
130
- - Never write `concerns-acknowledged-by` without the owner's explicit acknowledgement.
131
- - Never silently fall back to `data-architecture.md` when the live-schema MCP is unreachable on a db-surface change — flag the degradation in the rationale and (in v1) continue if the change is low-stakes, halt if high-stakes.
132
- - Never fabricate line numbers in tenant_isolation citations.
133
- - Never file tech-debt from this Skill; surface the recommendation for the engineer to invoke `hstack-tech-debt-new`.
@@ -1,129 +0,0 @@
1
- ---
2
- name: hstack-ship
3
- description: |
4
- Use this skill when every artifact for a change is at terminal status and the engineer wants the final merge-readiness scorecard and a generated PR description. The Skill is the merge gate's prelude — it checks that every CI gate's preconditions are met, computes the scorecard, and produces the PR description body. It does not perform the merge; the engineer opens or marks the PR ready-for-review themselves. Examples:
5
-
6
- <example>
7
- Context: Every artifact for the billing-overage change is at terminal status and the engineer wants to open the PR.
8
- user: "/hstack:ship 2026-05-billing-overage-warning"
9
- assistant: "I'll compute the scorecard: spec at ready-to-ship, test-plan passed, plan completed, security-review passed, ui-brief drafted, figma-handoff ready, data-review passed, verification passed, adversarial-review findings-resolved, resolves-tech-debt items at in-progress (GT-11). PR description will land in hstack/specs/changes/<id>/pr-body.md for you to paste; after merge, run /hstack:finalize to flip the TD to resolved."
10
- <commentary>
11
- The Skill is mechanical — it reads frontmatter and computes the gate result. No subagent is invoked. If any gate fails, the Skill names the failing artifact and halts.
12
- </commentary>
13
- </example>
14
-
15
- <example>
16
- Context: The engineer tries to ship a change whose adversarial-review is still at findings-open.
17
- user: "/hstack:ship 2026-06-knowledge-citations"
18
- assistant: "I'll halt — adversarial-review is at findings-open. Three findings still at status: open with no resolution. Resolve those via the existing adversarial-review.md before re-running ship."
19
- <commentary>
20
- The Skill names the exact blocker and the exact remediation path. It does not advance any status itself; ship is read-only across the artifact set.
21
- </commentary>
22
- </example>
23
- tools:
24
- - Read
25
- - Write
26
- - Grep
27
- - Glob
28
- - Bash
29
- - "{{TODO-SCRIPT: hstack/scripts/validate-spec.ts — validates every artifact's frontmatter}}"
30
- - "{{TODO-SCRIPT: hstack/scripts/compute-merge-readiness.ts — computes the nine-gate scorecard from artifact frontmatter}}"
31
- ---
32
-
33
- ## Purpose
34
-
35
- `hstack-ship` is the final merge-readiness Skill. It reads every artifact's frontmatter for the change, computes the nine-gate scorecard from `hstack-gates.yml`, and generates a PR description body. It does not invoke any subagent and does not write to any artifact — `ship` is read-only across the change-spec, plan, reviews, and verification.
36
-
37
- ## When to invoke
38
-
39
- Invoke when every per-change artifact is at terminal status and the engineer is ready to open or mark the PR ready-for-review. May be invoked multiple times — the Skill is idempotent and is often used as a "what's left?" diagnostic before the final pass.
40
-
41
- ## Inputs
42
-
43
- - `<change-id>` (required, positional): the change-spec id.
44
-
45
- ## Preconditions
46
-
47
- Before any work:
48
-
49
- - Verify the change folder `hstack/specs/changes/<change-id>/` exists.
50
- - Verify the change-spec exists. Read its `surfaces`, `internal-tooling`, `enables`, `enabled-by`, `trivial` flags to know which conditional gates apply.
51
-
52
- The Skill does not pre-halt on artifact non-terminal status — that is what the scorecard reports. It halts only on missing artifacts or unreadable frontmatter.
53
-
54
- ## Orchestration steps
55
-
56
- 1. **Read every change artifact.** Read `spec.md`, `plan.md`, `test-plan.md`, `security-review.md`, `data-review.md` (when surfaces includes db), `ui-brief.md` and `figma-handoff.md` (when surfaces includes ui), `verification.md`, `adversarial-review.md`. Capture each artifact's `status` and key gating fields.
57
-
58
- 2. **Compute the twelve-gate scorecard.** Run `{{TODO-SCRIPT: hstack/scripts/compute-merge-readiness.ts}}` against the artifact set, or inline the equivalent logic:
59
- - GT-01: spec presence — change folder exists with non-draft change-spec, or PR carries `trivial: true`.
60
- - GT-02: diff within scope — every file in the PR diff (against the merge target) is a subset of `change-spec.in-scope`.
61
- - GT-03: pattern lints — every `hstack/lints/*.yaml` rule passes (the Skill runs `{{TODO-SCRIPT: hstack/scripts/run-gates.sh}}` for this and reads the exit code).
62
- - GT-04: adversarial-review at `findings-resolved`.
63
- - GT-05: security-review at `passed` or `concerns-acknowledged`.
64
- - GT-06: data-review at `passed` or `concerns-acknowledged` (when applicable).
65
- - GT-07: ui-brief at `drafted` and figma-handoff at `ready` (when applicable).
66
- - GT-08: `user-stories` non-empty UNLESS `internal-tooling: true` (Category A) UNLESS `enables` non-empty (Category B). The audit-chain assumption: a Category-B spec's user value lives in one of the change-specs named in `enables`; this gate does not transitively verify that downstream spec has `user-stories` non-empty — that's the downstream's GT-08 check, run at its own ship time.
67
- - GT-09: every cross-reference rule (CG-01..CG-04) passes.
68
- - GT-10: test-plan at `passed` or `concerns-acknowledged`, and `verification.test-plan-coverage` shows no missing tenant-isolation tests and no out-of-budget performance assertions.
69
- - GT-11: When `change-spec.resolves-tech-debt` is non-empty: (a) every referenced tech-debt must exist and be at `status: in-progress` with `resolution-attempted-at` set; (b) the adversarial-review must contain the AR-07 Acceptance-satisfied confirmation enumerating each TD's Acceptance bullets against the diff; (c) no referenced tech-debt may have a non-null `resolved-by` already (that would indicate a double-resolution attempt). When `resolves-tech-debt` is empty, GT-11 is `not-applicable`.
70
- - GT-12 (SP-13 mutual exclusion): `internal-tooling: true` AND `enables` non-empty is forbidden. Hard FAIL. Reciprocity (SP-14): for every id in `enables`, the named downstream spec must exist on disk and must list this change-id in its `enabled-by` array. Missing downstream specs are a FAIL (forward references are only legal at authoring time — by ship time, the downstream must be scaffolded so reciprocity holds). The reverse direction (`enabled-by` entries that point at non-existent or non-listing upstream specs) is also FAIL.
71
-
72
- 3. **Frontmatter validation.** Run `{{TODO-SCRIPT: hstack/scripts/validate-spec.ts}}` across every artifact. Any FM-* or per-type validation failure blocks ship.
73
-
74
- 4. **Generate the PR description body.** Write `hstack/specs/changes/<change-id>/pr-body.md` containing:
75
- - Title: the change-spec's `Problem` first sentence, prefixed with the change id.
76
- - Summary section: pull the Target Behavior bullets from the change-spec.
77
- - Surfaces touched: from frontmatter.
78
- - Linked artifacts: pointers to spec, plan, test-plan, reviews, verification, adversarial-review.
79
- - Tech-debt created: pointers from `change-spec.creates-tech-debt`.
80
- - Test plan: pulled from `test-plan.md` — pyramid summary, tenant-isolation tests, and performance budgets — cross-referenced with `verification.test-plan-coverage` to show observed-vs-promised.
81
- - Tech-debt resolved: pointers from `change-spec.resolves-tech-debt` with each TD's Title and Acceptance summary. When non-empty, the body explicitly notes that `/hstack:finalize <change-id>` must be run post-merge to flip each TD to `resolved`.
82
- - Scorecard summary: the twelve-gate table from step 2.
83
-
84
- The pr-body.md is for the engineer to copy into the actual PR description — the Skill does not call `gh pr create` or otherwise open the PR.
85
-
86
- 5. **Advance change-spec status.** When every gate passes, the Skill emits the recommended status transition: `ready-for-review` → `ready-to-ship`. The Skill does not write this transition itself — the engineer either confirms (in which case the engineer can advance via direct edit, or `spec-author` is invoked separately) or addresses any remaining issues. This separation preserves the kernel's rule that humans confirm status transitions to ship-readiness.
87
-
88
- 6. **Surface finalize handoff.** When every gate passes AND `change-spec.resolves-tech-debt` is non-empty, the Skill emits a clear directive: "After this PR merges, run `/hstack:finalize <change-id>` to advance the change-spec to `shipped` and flip [TD-NNNN, TD-MMMM] to `resolved` with `resolved-by` set." When `resolves-tech-debt` is empty, the Skill still notes: "After merge, run `/hstack:finalize <change-id>` to advance the change-spec to `shipped`." The finalize handoff is informational at ship time — the actual writes happen in `/hstack:finalize`, never here.
89
-
90
- ## Outputs
91
-
92
- - `hstack/specs/changes/<change-id>/pr-body.md` (new or updated) — the PR description body.
93
- - A scorecard printed to the conversation: per-gate pass/fail summary with the failing artifact and field named for any FAIL.
94
- - A recommended next action: either "open / mark the PR ready-for-review and advance status to `ready-to-ship`" or a list of failing gates.
95
-
96
- The Skill does not auto-commit any artifact status transitions. `pr-body.md` is committed when written.
97
-
98
- ## Auto-commit triggers
99
-
100
- - One commit when `pr-body.md` is written or updated. Commit message: `ship(<change-id>): pr-body`.
101
-
102
- ## Idempotency contract
103
-
104
- - Re-running on the same change: re-reads every artifact and recomputes the scorecard. `pr-body.md` is rewritten if any artifact has changed since the prior run; otherwise a no-op.
105
- - Re-running after fixing a failing gate: the scorecard reports the new state.
106
-
107
- ## Stop conditions
108
-
109
- Beyond the kernel's general stop conditions:
110
-
111
- - A required artifact is missing on disk.
112
- - Any artifact's frontmatter cannot be parsed.
113
- - GT-02 (diff within scope) fails — this is a hard halt with a clear message naming the out-of-scope files; the engineer either reshapes the change-spec via `spec-author` or splits via the multi-module pattern.
114
-
115
- ## Failure modes
116
-
117
- - **Trivial PRs.** When the change-spec carries `trivial: true`, several gates are skipped per the kernel. The Skill still computes the diff-within-scope and pattern-lint gates (GT-02 and GT-03 remain mandatory even for trivial PRs).
118
- - **Parent-change (multi-module) records.** When the change-spec is a coordination record (`children` non-empty), the Skill computes scorecards for every child and produces a parent-level summary. The parent reaches ready-to-ship only when every child does.
119
- - **Pattern-lint failure.** Surface the failing rule and the offending lines. The fix is via a new `hstack-implement` invocation against an appropriate phase (or a scope amendment if the lint surfaced new in-scope needs).
120
-
121
- ## Anti-patterns
122
-
123
- - Never write status transitions on any artifact from this Skill. Ship is read-only across the artifact set.
124
- - Never call `gh pr create` or perform the merge. The engineer opens the PR.
125
- - Never silently pass a gate. Every FAIL names the artifact and field.
126
- - Never collapse the twelve gates into a single PASS / FAIL. The scorecard is per-gate.
127
- - Never flip a tech-debt status from this Skill. That is `/hstack:finalize`'s job and only runs post-merge. Ship surfaces the directive; it does not perform the write.
128
- - Never extend `change-spec.in-scope` to make GT-02 pass — the scope amendment goes through `spec-author`, not this Skill.
129
- - Never overwrite `pr-body.md` content the engineer has hand-edited without confirmation. If the file exists with edits beyond the template, surface a diff and ask before rewriting.
@@ -1,108 +0,0 @@
1
- ---
2
- name: hstack-stack-decide
3
- description: |
4
- Use this skill when the engineer wants to decide stack choices and capture each as an ADR. The Skill is Phase 4 of `/hstack:greenfield-init`, the stack-decision step of `/hstack:brownfield-init` when stack ADRs are missing, or a standalone atom for mid-project layer swaps (replacing auth, switching the database, rotating the hosting provider). It invokes the `stack-architect` subagent for the technical-discovery interview, then routes each layer's decision through `/hstack:adr-new` (which invokes `spec-author`) with pre-populated Context / Decision / Alternatives. The Consequences challenge prompt fires fresh on every ADR regardless of pre-population. Examples:
5
-
6
- <example>
7
- Context: Phase 4 of greenfield-init opens after app-architecture is current. hstack/config.yaml's default-stack declaration is set.
8
- user: "/hstack:stack-decide"
9
- assistant: "Loading brief, data-architecture, app-architecture, default-stack declaration. Defaults cover framework / database / hosting / auth — I'll fast-path those to a single rollup ADR. Observability is undeclared in config; I'll deep-dive on that layer. Expected: 2 ADRs (rollup + observability) routed through spec-author."
10
- <commentary>
11
- Default-stack fast-path collapses 80% of the interview when defaults match. Only layers explicitly flagged for deep-dive or undeclared in config get the full constraint interview.
12
- </commentary>
13
- </example>
14
-
15
- <example>
16
- Context: Mid-project, the team decides to replace Supabase Auth with Clerk.
17
- user: "/hstack:stack-decide --layer auth"
18
- assistant: "Standalone mode. Loading the existing auth ADR, threat-model, hardening-checklist. Constraint interview first (engineering capacity, scale horizon, compliance posture), then surfacing 2–3 Clerk alternatives, then routing to spec-author for the new ADR with supersedes: [<predecessor>]. The predecessor's reciprocal superseded-by writes atomically with the new ADR."
19
- <commentary>
20
- Standalone mode runs against a single layer. The supersedes / superseded-by reciprocal pair is mandatory; spec-author handles both halves atomically per the kernel's reciprocal-pair atomicity rule.
21
- </commentary>
22
- </example>
23
- tools:
24
- - Read
25
- - Write
26
- - Edit
27
- - Grep
28
- - Glob
29
- - Bash
30
- - Task
31
- - "{{TODO-SKILL: /hstack:adr-new — invoked via spec-author handoff for ADR authoring}}"
32
- - "{{TODO-SKILL: /hstack:research — invoked for unfamiliar-territory deep-dives}}"
33
- - "{{TODO-SCRIPT: hstack/scripts/validate-spec.ts — frontmatter validator}}"
34
- ---
35
-
36
- ## Purpose
37
-
38
- `hstack-stack-decide` is the atom that produces stack ADRs via the `stack-architect` subagent. It does NOT write to `hstack/adr/` directly; the kernel rule reserves ADR authoring for `spec-author`. Stack-architect produces pre-populated Context / Decision / Alternatives content; spec-author runs the Nygard interview in confirm-or-revise mode with the Consequences challenge firing fresh.
39
-
40
- ## When to invoke
41
-
42
- - Phase 4 of `/hstack:greenfield-init`.
43
- - The stack-decision step of `/hstack:brownfield-init` when no stack ADRs exist.
44
- - Standalone via `/hstack:stack-decide [--layer <name>]` for mid-project layer swaps.
45
-
46
- ## Inputs
47
-
48
- - `--layer <name>` — optional, standalone mode. Runs against a single declared layer (`framework | database | auth | hosting | observability | <custom>`). In greenfield/brownfield mode, the Skill walks all declared layers.
49
-
50
- ## Preconditions
51
-
52
- - `hstack/config.yaml` at `init-status: minimal-complete` or later, with the default-stack declaration present (set in greenfield-init Phase 0 or via `/hstack:configure default-stack`).
53
- - `hstack/context/app-architecture.md` at `status: current` (greenfield/brownfield mode). In standalone mode, the atom may run without app-architecture only if the layer being swapped doesn't depend on architecture decisions (rare).
54
- - `hstack/templates/adr.md` present.
55
- - Existing ADRs read at session start to set the next sequential ADR id and detect supersession candidates.
56
-
57
- ## Orchestration steps
58
-
59
- 1. **Detect mode.** Greenfield/brownfield: walk all declared layers. Standalone: run against the named `--layer`.
60
- 2. **Invoke `stack-architect` subagent.** Via the Task tool with `subagent_type: stack-architect`. Pass mode, layer scope, the canonical session-start context.
61
- 3. **For each layer (greenfield/brownfield mode):**
62
- - **Default check.** stack-architect reads `hstack/config.yaml`'s declared default for this layer.
63
- - **Fast-path confirmation.** If the engineer accepts the default, the layer is added to a pending rollup ADR.
64
- - **Deep-dive.** If the engineer chooses to deep-dive, stack-architect runs the constraint interview (scale, ops capacity, compliance, AI-native specifics), surfaces 2–3 candidate options with tradeoff axes, and lets the engineer choose.
65
- - **ADR handoff.** stack-architect prepares the Context / Decision / Alternatives sections, then invokes `/hstack:adr-new` via the Task tool (which invokes `spec-author`). spec-author runs confirm-or-revise on the prepared content. The Consequences challenge prompt fires fresh per the kernel's Nygard challenge rule.
66
- 4. **Rollup ADR (greenfield/brownfield mode).** After per-layer ADRs land, the Skill produces one rollup ADR via `/hstack:adr-new` naming every defaulted layer with the constraint check that confirmed each.
67
- 5. **Standalone mode** runs the same constraint interview + spec-author handoff for the single `--layer`. The new ADR carries `supersedes: [<predecessor>]`; the predecessor gets the reciprocal `superseded-by` written atomically by spec-author.
68
- 6. **Config update (optional).** After ADRs land, the Skill asks the engineer whether any layer's choice diverged from the prior default in a way they want project-wide. If yes, the Skill proposes a `hstack/config.yaml` update via the proposed-diff preview + Y/n gate, then commits the config update as a mechanical operation.
69
-
70
- ## Outputs
71
-
72
- - One rollup ADR plus N per-layer ADRs (greenfield/brownfield mode), or one new ADR with `supersedes` (standalone mode), all at `status: accepted`.
73
- - Updated `hstack/config.yaml` default-stack declaration (optional, only if changed).
74
- - `hstack/.session-state/<session-id>.yaml` (transient).
75
-
76
- ## Auto-commit triggers
77
-
78
- - Each ADR commits via `/hstack:adr-new`'s standard pattern (single auto-commit per ADR).
79
- - Standalone mode's supersedes / superseded-by reciprocal pair commits atomically in one git commit per the kernel.
80
- - Config update (if any) commits as a separate mechanical operation.
81
-
82
- ## Idempotency contract
83
-
84
- - If a layer's current ADR is at `accepted` and the engineer's constraints + default-stack haven't changed: skip the layer.
85
- - If a deep-dive interview was started but no ADR landed (engineer parked mid-interview): resume the interview from session-state.
86
- - Re-running standalone mode for a layer whose ADR is already at `accepted` and no supersession is requested: print summary, exit no-op.
87
-
88
- ## Stop conditions
89
-
90
- - App-architecture at non-terminal status (greenfield/brownfield mode).
91
- - A chosen option contradicts an upstream invariant (e.g., DB without RLS conflicts with `data-architecture.md`'s tenant-scoped posture). Halt with `HSTACK-HALT: reason=upstream-drift`.
92
- - A research session is needed (unfamiliar territory) but the engineer has not authorized `/hstack:research`.
93
- - Standalone mode supersedes an ADR at a non-accepted status.
94
- - The Postgres assumption in `data-architecture.md` is being contradicted. Halt and surface.
95
-
96
- ## Failure modes
97
-
98
- - **spec-author handoff fails partway** (e.g., Consequences challenge produces a finding the engineer doesn't accept). The pending ADR sits at `draft`; the engineer either revises or routes through `/hstack:configure adr-author <id>` per spec-author's recovery path.
99
- - **Research subagent unavailable when needed.** Persist constraint interview state; resume later.
100
-
101
- ## Anti-patterns
102
-
103
- - Never write to `hstack/adr/` from this Skill directly. ADR authoring is `spec-author`'s exclusive ownership per kernel rule.
104
- - Never let pre-population skip the Consequences challenge prompt. Pre-population covers Context / Decision / Alternatives; Consequences fires fresh.
105
- - Never propose stack options before constraints are concrete.
106
- - Never bypass the upstream check (app-architecture must be `current` in greenfield/brownfield mode).
107
- - Never silently honor a non-Postgres DB choice when `data-architecture.md`'s `assumes-database: postgres` says otherwise. Halt and surface.
108
- - Never split the supersedes / superseded-by reciprocal pair across two commits in standalone mode.
@@ -1,119 +0,0 @@
1
- ---
2
- name: hstack-story-draft
3
- description: |
4
- Use this skill when a user-facing change needs a story drafted or refined, anchored on an existing persona, with a concrete success metric and the user-visible edge cases enumerated. The Skill orchestrates the `product-manager` subagent and is conditional — it does not run when the parent change-spec is Category A (`internal-tooling: true`) or Category B (`enables` non-empty), since both carve-outs satisfy SP-09 without a story. Examples:
5
-
6
- <example>
7
- Context: The engineer just scaffolded a billing-overage change-spec and needs a linked user story before SP-09 lets the spec advance past draft.
8
- user: "Draft a story for the billing overage warning, anchored on the growth-marketer persona."
9
- assistant: "I'll invoke product-manager to walk the five story sections with the growth-marketer persona as the anchor. The story id will land in the configured story store; the change-spec's user-stories array updates reciprocally."
10
- <commentary>
11
- Stories are gated by SP-09 (`user-stories` non-empty UNLESS `internal-tooling: true` UNLESS `enables` non-empty). The Skill produces the story before the change-spec can advance, and writes the reciprocal `linked-change-specs` entry on the story.
12
- </commentary>
13
- </example>
14
-
15
- <example>
16
- Context: A story exists but the engineer wants to refine the success metric, which the product-manager flagged as too vague.
17
- user: "Refine STORY-2026-05-014 — sharpen the success metric."
18
- assistant: "I'll invoke product-manager with the existing story as the proposal layer. The other sections are accept-or-correct; the success-metric field gets the full interview treatment."
19
- <commentary>
20
- Refinement reuses the same orchestration with the existing story as the proposal context. The Skill does not re-walk every field; the subagent reads the existing content and targets the field the engineer named.
21
- </commentary>
22
- </example>
23
- tools:
24
- - Read
25
- - Write
26
- - Edit
27
- - Grep
28
- - Glob
29
- - Bash
30
- - Task
31
- - "{{TODO-MCP: Notion MCP — required when configured story store is Notion}}"
32
- - "{{TODO-MCP: Linear MCP — required when configured story store is Linear}}"
33
- - "{{TODO-MCP: GitHub MCP — required when configured story store is GitHub Issues}}"
34
- - "{{TODO-SCRIPT: hstack/scripts/validate-spec.ts — validates story frontmatter and ST-01/ST-02/ST-03}}"
35
- ---
36
-
37
- ## Purpose
38
-
39
- `hstack-story-draft` produces or refines one user story by orchestrating the `product-manager` subagent. It maintains the reciprocal `user-stories` ↔ `linked-change-specs` linkage between the story and its parent change-spec. It is conditional — skipped automatically for changes marked Category A (`internal-tooling: true`) or Category B (`enables` non-empty). For Category B, the user value lives in the downstream change-spec(s) named in `enables`; the story (if any) is drafted against that downstream spec, not this one.
40
-
41
- ## When to invoke
42
-
43
- Invoke when the engineer wants a story for a user-facing change before SP-09 / GT-08 require it, or to refine an existing story whose fields the team is reworking. Run after `hstack-change-new` so the parent change-spec already exists and can receive the reciprocal link.
44
-
45
- ## Inputs
46
-
47
- - `--change <id>` (optional): the parent change-spec id. If omitted, the Skill asks the engineer interactively.
48
- - `--story <id>` (optional): an existing story id to refine. If omitted, the Skill drafts a new story.
49
- - `--persona <id>` (optional): the persona to anchor on. If omitted, `product-manager` interviews the engineer for the anchor.
50
-
51
- ## Preconditions
52
-
53
- Before any work:
54
-
55
- - Verify `hstack/config.yaml` exists at `init-status: complete`.
56
- - Verify the parent change-spec exists when `--change` is provided or when context implies it.
57
- - Verify `hstack/context/personas/` (or the configured personas store) contains at least one persona at `status: current`.
58
- - Verify the configured story store's MCP is reachable when the store is Notion / Linear / GitHub. If unreachable, halt — the kernel forbids silent fallback to a different store.
59
- - If the parent change-spec carries `internal-tooling: true`, halt and surface: "Story not required — change is Category A (internal tooling, never on a user path)."
60
- - If the parent change-spec carries `enables` non-empty, halt and surface: "Story not required — change is Category B (foundational prerequisite; user value lives in <enables-ids>). Draft a story against the downstream spec instead."
61
- - If the parent change-spec carries BOTH `internal-tooling: true` AND `enables` non-empty, halt with SP-13 violation: "Categories A and B are mutually exclusive. Pick one via `spec-author`."
62
- - Read `hstack/context/vision.md`, `mvp-scope.md`, and the personas index (required by `product-manager`'s session-start protocol).
63
-
64
- ## Orchestration steps
65
-
66
- 1. **Determine mode.** Draft a new story (no `--story` argument) or refine an existing one (`--story <id>` argument). Read the existing story when refining.
67
-
68
- 2. **Invoke `product-manager`.** Use the Task tool with `subagent_type: product-manager` and context = [kernel, `hstack/templates/story.md`, vision, mvp-scope, personas store, parent change-spec when known, existing story when refining]. The subagent runs the five-section interview — Who and Why, What Shipping Looks Like, Success Metric, Edge Cases the User Cares About, Out of Scope for This Story — with confirmation gates.
69
-
70
- 3. **Verify the persona anchor exists.** Per ST-01, the story's `persona` field must reference an existing persona at `current`. If the engineer names a persona that does not exist, `product-manager` halts and runs a sub-interview to author it first (or the engineer chooses an existing one).
71
-
72
- 4. **Exercise the Edge Cases challenge.** Per the `product-manager` contract, the Edge Cases section uses the challenge prompt "What does the user notice if this ships but is slightly broken?" with a minimum of two bullets. The Skill does not bypass this on refinement.
73
-
74
- 5. **Reciprocity.** When the story reaches `status: in-flight` (i.e., its `linked-change-specs` is non-empty), the Skill confirms the parent change-spec's `user-stories` array contains the story id and writes it if absent. The reciprocal write is performed by `product-manager` per its contract (the spec-author handles change-spec field writes generally, but for the `user-stories` array specifically, `product-manager`'s contract permits the reciprocal write).
75
-
76
- 6. **Persist.** When the story store is external (Notion/Linear/GitHub), `product-manager` writes via the MCP and produces a local sync stub at `hstack/stories/<id>.md` referencing the external record. When the store is `hstack/stories/`, the file is written directly.
77
-
78
- 7. **Validate.** Run `{{TODO-SCRIPT: hstack/scripts/validate-spec.ts}}` against the story — ST-01 (persona references existing), ST-02 (linked-change-specs non-empty at `in-flight`), ST-03 (success metric non-empty string).
79
-
80
- ## Outputs
81
-
82
- - A new or updated story at the configured store, at `status: drafted`, `ready`, or `in-flight` per the engineer's intent.
83
- - Reciprocal `user-stories: [<story-id>]` entry on the parent change-spec.
84
- - When the store is external: a sync stub at `hstack/stories/<id>.md`.
85
-
86
- ## Auto-commit triggers
87
-
88
- - Status transition of the story to `drafted` after the first sections land.
89
- - Status transition to `ready` or `in-flight` at the end of the interview.
90
- - Reciprocal write to the parent change-spec's `user-stories` array (commits the parent change-spec file).
91
-
92
- ## Idempotency contract
93
-
94
- - Re-running with the same `--story` id and identical engineer answers is a no-op aside from `updated` timestamps.
95
- - Re-running mid-interview after a halt: `product-manager` reads the partial story and resumes at the next un-confirmed field.
96
- - Re-running to refine: existing values are the proposal layer; accepting all current values is a no-op.
97
-
98
- ## Stop conditions
99
-
100
- Beyond the kernel's general stop conditions:
101
-
102
- - The configured story-store MCP is unreachable. Halt.
103
- - The named persona does not exist and the engineer declines the sub-interview to author it.
104
- - The success metric the engineer offers is not concretely measurable. `product-manager` re-prompts; the Skill halts after a reasonable number of re-prompts.
105
- - The story would drift outside `mvp-scope.md`. `product-manager` flags; the Skill asks whether to update mvp-scope (via `hstack-configure --interview mvp-scope`) or defer the story.
106
-
107
- ## Failure modes
108
-
109
- - **Parent change-spec is `internal-tooling: true` (Category A) or `enables` non-empty (Category B).** Halt early; the story is unnecessary. For Category B, redirect the engineer to draft a story against the downstream change-spec named in `enables`.
110
- - **Reciprocal write to the parent change-spec would advance its status.** It should not — the reciprocal write only touches the `user-stories` array. If the validator detects a status change, halt and ask.
111
- - **Validator fails.** Halt and surface; the engineer rewords the failing field.
112
-
113
- ## Anti-patterns
114
-
115
- - Never anchor a story on an invented persona. The persona either exists at `current` or is authored first via a sub-interview.
116
- - Never bypass the Edge Cases challenge prompt, even on refinement.
117
- - Never write a story without a concretely measurable success metric.
118
- - Never silently fall back to a local story file when the configured external store's MCP is unreachable.
119
- - Never write reciprocal `user-stories` entries to a change-spec at a non-draft status without going through the `spec-author`'s field-change machinery — except for the array-append case explicitly carved out by `product-manager`'s contract.
@@ -1,122 +0,0 @@
1
- ---
2
- name: hstack-tech-debt-new
3
- description: |
4
- Use this skill when the engineer needs to capture a tech-debt item — a known compromise the team agreed to live with for now. The Skill orchestrates the `spec-author` subagent through a six-section interview for the TD body (genuine open-ended authoring); the reciprocal `creates-tech-debt` write on the originating change-spec is performed by the Skill directly per ADR-0001 (no second spec-author invocation). Both halves of the reciprocal pair (TD-01) land in a single atomic commit; spec-author defers its terminal-state auto-commit when invoked under this Skill so the Skill can include both files in one commit. Examples:
5
-
6
- <example>
7
- Context: The billing-overage change shipped with a one-off Tailwind class for warning-yellow because the design token isn't yet exposed; the engineer wants to log it.
8
- user: "/hstack:tech-debt-new --origin 2026-05-billing-overage-warning overage-banner-tailwind-class"
9
- assistant: "I'll invoke spec-author for the tech-debt interview. The six sections cover Title, Why we took the shortcut, What it costs us, Fix sketch, Pre-conditions for fixing, Acceptance. Reciprocally, I'll add this tech-debt id to the change-spec's creates-tech-debt array."
10
- <commentary>
11
- Reciprocity per TD-01 is load-bearing. Without the back-reference, audit queries cannot answer "who put this here?" without grepping every change-spec. Per ADR-0001, the TD body is authored by spec-author (interview) and the reciprocal `creates-tech-debt` write on the change-spec is performed by the Skill directly; both files land in one atomic commit.
12
- </commentary>
13
- </example>
14
-
15
- <example>
16
- Context: The adversarial-reviewer surfaced a deliberate trade-off that should be tracked as tech-debt rather than fixed in the change.
17
- user: "F-03 routes to tech-debt. /hstack:tech-debt-new --origin 2026-06-knowledge-citations cookie-samesite-attributes"
18
- assistant: "I'll invoke spec-author. The reciprocal write lands on the change-spec; the adversarial-review's finding gets resolution: tech-debt:<this-td-id> once the artifact is created."
19
- <commentary>
20
- This is the routing the adversarial-review's resolution discipline assumes. The tech-debt is created here, then referenced from the adversarial-review's `findings[].resolution`. The Skill is the only path because spec-author owns reciprocal writes.
21
- </commentary>
22
- </example>
23
- tools:
24
- - Read
25
- - Write
26
- - Edit
27
- - Grep
28
- - Glob
29
- - Bash
30
- - Task
31
- - "{{TODO-SCRIPT: hstack/scripts/validate-spec.ts — validates tech-debt frontmatter and TD-01..TD-03}}"
32
- ---
33
-
34
- ## Purpose
35
-
36
- `hstack-tech-debt-new` captures a tech-debt item via the `spec-author` subagent. Tech-debt artifacts live at `hstack/tech-debt/TD-NNNN-<slug>.md`, are append-only, and maintain a reciprocal back-reference to the originating change-spec via the `introduced-by` ↔ `creates-tech-debt` pair (TD-01).
37
-
38
- ## When to invoke
39
-
40
- Invoke when:
41
- - The engineer ships a deliberate compromise (a hack-now-fix-later) and wants it logged.
42
- - The `adversarial-reviewer` surfaces a finding routed to `tech-debt:<id>` and the artifact does not yet exist.
43
- - A retrospective surfaces accumulated debt that was not captured at the time it landed (origin: `found-later`).
44
-
45
- ## Inputs
46
-
47
- - `<slug>` (required, positional): kebab-case slug. Examples: `overage-banner-tailwind-class`, `stripe-webhook-idempotency-buffer`.
48
- - `--origin <change-spec-id>` (optional): the change-spec that introduced this debt. When set, reciprocal writes apply. When omitted, origin defaults to `found-later`.
49
-
50
- ## Preconditions
51
-
52
- Before any work:
53
-
54
- - Verify `hstack/config.yaml` exists at `init-status: complete`.
55
- - Read every existing tech-debt item under `hstack/tech-debt/` to determine the next sequential id.
56
- - Verify the `<slug>` matches `^[a-z][a-z0-9-]*$` and is not already used.
57
- - When `--origin <change-spec-id>` is provided: verify the change-spec exists.
58
- - Scan existing tech-debt for a near-duplicate (same module, similar slug). Surface any candidates to the engineer; if the new debt is genuinely a duplicate, the Skill halts and directs the engineer to update the existing item instead.
59
-
60
- ## Orchestration steps
61
-
62
- 1. **Compute the next id.** `TD-NNNN-<slug>`.
63
-
64
- 2. **Invoke `spec-author` with explicit deferred-commit instruction.** Use the Task tool with `subagent_type: spec-author` and context = [kernel, `hstack/templates/tech-debt.md`, glossary, the originating change-spec when `--origin`]. The subagent walks the six sections — Title, Why we took the shortcut, What it costs us, Fix sketch, Pre-conditions for fixing, Acceptance — with confirmation gates. **Critical instruction to spec-author**: do NOT auto-commit at terminal author-state (`status: open`) when invoked under `/hstack:tech-debt-new`. The Skill will perform the atomic commit after the reciprocal change-spec write in step 7. Spec-author should leave the new TD file staged-but-uncommitted (or unstaged) so the Skill can include both halves of the reciprocal pair in a single commit. This deviation from spec-author's normal auto-commit-at-status-transition behavior is mandated by the kernel's atomicity rule for reciprocal pairs.
65
-
66
- 3. **Severity.** The subagent elicits severity (critical | high | medium | low). For `severity: critical`, a `target-resolve-by` date is required per TD-02 (this is a future field — surface in the conversation that v1 does not yet enforce it via the validator).
67
-
68
- 4. **Cost and fix-sketch-effort.** Both are controlled enums (`small | medium | large`).
69
-
70
- 5. **Reciprocity.** When `--origin <change-spec-id>` is set:
71
- - **Authoring half (spec-author).** `spec-author` writes `introduced-by: <change-spec-id>` on the new tech-debt frontmatter during its interview (this field is part of the artifact being authored, so it lands inside the spec-author session). Per the deferred-commit instruction in step 2, spec-author does NOT auto-commit on terminal author-state under this Skill — it leaves the TD file written but uncommitted.
72
- - **Reciprocal half (direct write by this Skill).** After `spec-author` finishes the interview and returns, this Skill performs the reciprocal write itself via the `Edit` tool — no second `spec-author` invocation. Edit `hstack/specs/changes/<change-spec-id>/spec.md`:
73
- - Append the new tech-debt id to the frontmatter `creates-tech-debt` array (idempotent — if already present, no-op).
74
- - Update frontmatter `updated: <today>`.
75
- - Per the kernel's Mechanical operations section, this reciprocal write is mechanical: the value to append is fully determined by the just-authored TD's id. No interview is required.
76
- - TD-01 enforces this at validation. Both files land in a single auto-commit (step 7 below) so the reciprocal pair is atomic.
77
-
78
- 6. **Proposed-diff preview (confirmation gate).** Per the kernel's AI-writes-humans-confirm contract for mechanical operations, print the proposed reciprocal-write diff (the `creates-tech-debt` array append on the change-spec, the `updated` bump) and ask "Proceed with these writes? (Y/n)". Default Yes. On `n`, halt without staging the change-spec edit; the TD file remains unstaged so the engineer can `git checkout -- <td-file>` to discard.
79
-
80
- 7. **Validate and atomic-commit both files.** Run `{{TODO-SCRIPT: hstack/scripts/validate-spec.ts}}` against the new TD and (when `--origin` is set) the modified change-spec. TD-01 (reciprocity), TD-02 (severity:critical requires target-resolve-by — v1 surfaces only), TD-03 (no field rewrites once resolved; v1 informational) all checked. On validation pass, `git add` both files and commit with message `tech-debt(TD-NNNN): open` (with `(introduced-by: <change-spec-id>)` appended when applicable). The reciprocal pair (TD `introduced-by` ↔ change-spec `creates-tech-debt`) lands in this single atomic commit. On validation failure, halt; both files remain unstaged for the engineer to inspect or discard.
81
-
82
- 8. **Status note.** The new artifact lands at `status: open`. Advancing to `in-progress` or `resolved` is a separate later operation, not this Skill's domain.
83
-
84
- ## Outputs
85
-
86
- - `hstack/tech-debt/TD-NNNN-<slug>.md` at `status: open`.
87
- - When `--origin` is set: an edit to the originating change-spec's `creates-tech-debt` array.
88
-
89
- The tech-debt item lands at `status: open`. To begin resolution work, invoke `/hstack:tech-debt-resolve TD-NNNN`. To close without a fix, invoke `/hstack:tech-debt-wontfix TD-NNNN`. The new fields `resolved-by`, `resolution-attempted-at`, `wontfix-reason`, `wontfix-accepted-alternative` are left as their template defaults (`null`) at creation time — they are written by the corresponding resolution Skill.
90
-
91
- ## Auto-commit triggers
92
-
93
- - One commit at terminal author-state (`status: open`). When reciprocity writes are involved, both files are included in the commit. Commit message: `tech-debt(TD-NNNN): open` (with the origin change-spec in parentheses when applicable).
94
-
95
- ## Idempotency contract
96
-
97
- - Re-running with the same `<slug>` halts because the slug would not be unique.
98
- - Re-running mid-interview after a halt: `spec-author` reads the partial tech-debt file and resumes.
99
- - Reciprocal writes are idempotent: if the change-spec's `creates-tech-debt` already contains the tech-debt id, the Skill does not duplicate.
100
-
101
- ## Stop conditions
102
-
103
- Beyond the kernel's general stop conditions:
104
-
105
- - The `<slug>` collides with an existing tech-debt item.
106
- - `--origin` references a change-spec that does not exist.
107
- - A near-duplicate tech-debt item already exists and the engineer should update it instead.
108
- - The Why-we-took-the-shortcut field is empty — every tech-debt item must explain its origin, not just enumerate the cost.
109
-
110
- ## Failure modes
111
-
112
- - **Reciprocal write to the change-spec fails (e.g., the change-spec's frontmatter is broken).** Halt before commit; the TD authoring half also rolls back unstaged. The engineer fixes the change-spec frontmatter manually (broken YAML is hand-fixed and validated; if the change-spec body needs prose authoring corrections, `spec-author` can resume the change-spec since change-spec body editing is interview-driven, but `spec-author` cannot touch the `creates-tech-debt` reciprocal field per kernel — the Skill performs that append on the re-run). Then re-run `/hstack:tech-debt-new` — the Skill is idempotent on the TD half (spec-author resumes the existing partial file) and idempotent on the reciprocal append (a no-op if the TD id is already in the array).
113
- - **The change-spec is at `shipped` or `archived` status.** TD-03 forbids rewrites on resolved items, but the change-spec at `shipped` may still accept `creates-tech-debt` array appends — surface and confirm with the engineer before writing.
114
- - **Validator fails TD-01.** Halt before commit; the partial state on disk is unstaged. The engineer reconciles by running the Skill again — the reciprocal half is idempotent and the TD half resumes from the existing file.
115
-
116
- ## Anti-patterns
117
-
118
- - Never invent a tech-debt id. Sequential per the implicit rule.
119
- - Never write a tech-debt item without the Why-we-took-the-shortcut section. Debt without context is paperwork.
120
- - Never write `origin: <change-spec-id>` without the reciprocal `creates-tech-debt` write on that change-spec.
121
- - Never advance status past `open` from this Skill. Status transitions happen on the fix side, not the capture side.
122
- - Never overwrite an existing tech-debt item from this Skill. Updates happen via direct `spec-author` invocation when the item is being actively worked on.