hstack 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +31 -0
- package/LICENSE +21 -0
- package/README.md +169 -0
- package/VERSION +1 -0
- package/dist/cli.js +55 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/doctor.js +155 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/init.js +87 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/update.js +118 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/lib/diff.js +120 -0
- package/dist/lib/diff.js.map +1 -0
- package/dist/lib/git.js +26 -0
- package/dist/lib/git.js.map +1 -0
- package/dist/lib/paths.js +35 -0
- package/dist/lib/paths.js.map +1 -0
- package/dist/lib/wire.js +314 -0
- package/dist/lib/wire.js.map +1 -0
- package/dist/manifest.js +53 -0
- package/dist/manifest.js.map +1 -0
- package/package.json +54 -0
- package/template/.claude/agents/adversarial-reviewer.md +123 -0
- package/template/.claude/agents/data-specialist.md +126 -0
- package/template/.claude/agents/implementer.md +154 -0
- package/template/.claude/agents/planner.md +110 -0
- package/template/.claude/agents/product-manager.md +111 -0
- package/template/.claude/agents/researcher.md +123 -0
- package/template/.claude/agents/security-reviewer.md +123 -0
- package/template/.claude/agents/spec-author.md +118 -0
- package/template/.claude/agents/test-strategist.md +129 -0
- package/template/.claude/agents/ui-ux-briefer.md +105 -0
- package/template/.claude/agents/verifier.md +109 -0
- package/template/.claude/skills/hstack-adr-new/SKILL.md +118 -0
- package/template/.claude/skills/hstack-adversarial-review/SKILL.md +187 -0
- package/template/.claude/skills/hstack-branch/SKILL.md +103 -0
- package/template/.claude/skills/hstack-change-new/SKILL.md +109 -0
- package/template/.claude/skills/hstack-change-plan/SKILL.md +119 -0
- package/template/.claude/skills/hstack-commit/SKILL.md +122 -0
- package/template/.claude/skills/hstack-configure/SKILL.md +126 -0
- package/template/.claude/skills/hstack-data-review/SKILL.md +132 -0
- package/template/.claude/skills/hstack-finalize/SKILL.md +159 -0
- package/template/.claude/skills/hstack-help/SKILL.md +174 -0
- package/template/.claude/skills/hstack-implement/SKILL.md +185 -0
- package/template/.claude/skills/hstack-init/SKILL.md +152 -0
- package/template/.claude/skills/hstack-module-spec/SKILL.md +105 -0
- package/template/.claude/skills/hstack-research/SKILL.md +145 -0
- package/template/.claude/skills/hstack-security-review/SKILL.md +133 -0
- package/template/.claude/skills/hstack-ship/SKILL.md +128 -0
- package/template/.claude/skills/hstack-story-draft/SKILL.md +117 -0
- package/template/.claude/skills/hstack-tech-debt-new/SKILL.md +122 -0
- package/template/.claude/skills/hstack-tech-debt-resolve/SKILL.md +158 -0
- package/template/.claude/skills/hstack-tech-debt-stale/SKILL.md +113 -0
- package/template/.claude/skills/hstack-tech-debt-wontfix/SKILL.md +104 -0
- package/template/.claude/skills/hstack-telemetry/SKILL.md +96 -0
- package/template/.claude/skills/hstack-test-plan/SKILL.md +182 -0
- package/template/.claude/skills/hstack-ui-brief/SKILL.md +108 -0
- package/template/.claude/skills/hstack-verify/SKILL.md +139 -0
- package/template/CLAUDE.md +390 -0
- package/template/scripts/telemetry/__init__.py +6 -0
- package/template/scripts/telemetry/insights/__init__.py +0 -0
- package/template/scripts/telemetry/insights/contract_drift.py +137 -0
- package/template/scripts/telemetry/insights/overengineering.py +115 -0
- package/template/scripts/telemetry/insights/quality_outcomes.py +131 -0
- package/template/scripts/telemetry/insights/token_economics.py +129 -0
- package/template/scripts/telemetry/insights/workflow_shape.py +198 -0
- package/template/scripts/telemetry/parsers/__init__.py +0 -0
- package/template/scripts/telemetry/parsers/bodies.py +87 -0
- package/template/scripts/telemetry/parsers/commits.py +219 -0
- package/template/scripts/telemetry/parsers/frontmatter.py +322 -0
- package/template/scripts/telemetry/parsers/transcripts.py +181 -0
- package/template/scripts/telemetry/render.py +311 -0
- package/template/scripts/telemetry/report.py +112 -0
- package/template/templates/adr.md +38 -0
- package/template/templates/adversarial-review.md +54 -0
- package/template/templates/change-spec.md +80 -0
- package/template/templates/ci-cd.md +27 -0
- package/template/templates/data-architecture.md +35 -0
- package/template/templates/data-review.md +54 -0
- package/template/templates/figma-handoff.md +38 -0
- package/template/templates/glossary.md +20 -0
- package/template/templates/hardening-checklist.md +73 -0
- package/template/templates/incident-runbook.md +57 -0
- package/template/templates/infrastructure.md +190 -0
- package/template/templates/module-spec.md +49 -0
- package/template/templates/mvp-scope.md +34 -0
- package/template/templates/persona.md +38 -0
- package/template/templates/plan.md +49 -0
- package/template/templates/security-review.md +63 -0
- package/template/templates/story.md +37 -0
- package/template/templates/tech-debt.md +61 -0
- package/template/templates/tech-stack.md +41 -0
- package/template/templates/telemetry-sidecar.md +184 -0
- package/template/templates/test-plan.md +119 -0
- package/template/templates/threat-model.md +54 -0
- package/template/templates/ui-brief.md +49 -0
- package/template/templates/verification.md +63 -0
- package/template/templates/vision.md +34 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hstack-adversarial-review
|
|
3
|
+
description: |
|
|
4
|
+
Use this skill only in a fresh Claude Code session — separate from the session that ran the implementer — after verification has landed at `status: passed` and the change is at `ready-for-review`. The Skill orchestrates the `adversarial-reviewer` subagent to produce a quota-driven critique. v1 fresh-session enforcement is honor-system; the Skill emits a clear instruction reminding the engineer that the v2 substrate will verify via session-id comparison. Examples:
|
|
5
|
+
|
|
6
|
+
<example>
|
|
7
|
+
Context: The implementer finished the last phase of a billing change; verification passed; the engineer has opened a fresh session for adversarial review.
|
|
8
|
+
user: "I've opened a new session. /hstack:adversarial-review 2026-05-billing-overage-warning"
|
|
9
|
+
assistant: "I'll invoke adversarial-reviewer. Findings floor is 5 because area=billing. I'll load every change artifact and the full diff; no implementer transcripts. Minimum 5 findings or a defended sub-floor justification — 'no issues found' is not a terminal state."
|
|
10
|
+
<commentary>
|
|
11
|
+
AR-06 raises the findings floor to 5 for changes in {agent, auth, billing}. The reviewer must spread findings across categories — clustering all findings in one category is a smell unless flagged in Methodology.
|
|
12
|
+
</commentary>
|
|
13
|
+
</example>
|
|
14
|
+
|
|
15
|
+
<example>
|
|
16
|
+
Context: A small copy-fix change has been verified and the reviewer can only honestly produce two findings.
|
|
17
|
+
user: "/hstack:adversarial-review 2026-05-billing-copy-tweak"
|
|
18
|
+
assistant: "I'll invoke adversarial-reviewer. If I can only honestly produce two findings, I'll set findings-fewer-than-floor: true and write a defended justification in section 4 — enumerate every category considered and explain why each produced no honest finding."
|
|
19
|
+
<commentary>
|
|
20
|
+
The sub-floor path is explicit and rare. AR-01 demands `findings` length ≥ `findings-floor` OR `findings-fewer-than-floor: true` plus non-empty `justification-when-fewer`. "The change is small" alone is insufficient.
|
|
21
|
+
</commentary>
|
|
22
|
+
</example>
|
|
23
|
+
|
|
24
|
+
<example>
|
|
25
|
+
Context: The adversarial reviewer finds a high-severity tenant-isolation issue the security review missed.
|
|
26
|
+
user: "/hstack:adversarial-review 2026-06-retrieval-rpc-rewrite"
|
|
27
|
+
assistant: "I'll invoke adversarial-reviewer with the new pgvector RPC under scrutiny. If a severity:high tenant-isolation finding lands, the resolution must be commit:<hash> or tech-debt:<id> — not justified-in-prose. High-severity security routed to justified-in-prose is a smell and I'll halt."
|
|
28
|
+
<commentary>
|
|
29
|
+
Resolution discipline matters: `commit:<hash>` for code fixes, `tech-debt:<id>` for deliberate deferral, `justified-in-prose` only for low-severity findings where in-prose reasoning is genuinely right. High-severity security via justified-in-prose is a halt condition.
|
|
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/validate-spec.ts — validates adversarial-review frontmatter and AR-01..AR-06}}"
|
|
41
|
+
- "{{TODO-OTHER: fresh-session-attestation — in v1, the subagent self-attests the session is fresh; v2 substrate captures and compares Claude Code session ids automatically}}"
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Purpose
|
|
45
|
+
|
|
46
|
+
`hstack-adversarial-review` produces `adversarial-review.md` by orchestrating the `adversarial-reviewer` subagent in a Claude Code session separate from the one that ran the implementer. The output is structurally biased against "looks good" — the reviewer must produce at least the findings floor across the six categories or defend a smaller count with explicit rationale. In v1, fresh-session separation is honor-system; the Skill's first job is to remind the engineer of that.
|
|
47
|
+
|
|
48
|
+
## When to invoke
|
|
49
|
+
|
|
50
|
+
Invoke after `verification.md` reaches `status: passed`, in a **fresh Claude Code session**. The Skill opens with a clear instruction to the engineer naming the requirement. If the engineer reports they are in the same session as the implementer, halt and ask them to start a new session.
|
|
51
|
+
|
|
52
|
+
## Inputs
|
|
53
|
+
|
|
54
|
+
- `<change-id>` (required, positional): the change-spec id.
|
|
55
|
+
|
|
56
|
+
## Preconditions
|
|
57
|
+
|
|
58
|
+
Before any work:
|
|
59
|
+
|
|
60
|
+
- **Fresh-session attestation.** The Skill's first action is to print: "This Skill must run in a Claude Code session separate from the one that ran `hstack-implement`. The kernel's authoring-and-review-never-share-a-session principle is honor-system in v1; v2 substrate will verify via session-id comparison. Confirm you are in a fresh session before I proceed." Halt until the engineer confirms.
|
|
61
|
+
- Verify the change-spec exists and is at `status: ready-for-review`.
|
|
62
|
+
- Verify every required upstream artifact is at terminal status:
|
|
63
|
+
- test-plan at `passed` or `concerns-acknowledged`
|
|
64
|
+
- plan at `completed`
|
|
65
|
+
- security-review at `passed` or `concerns-acknowledged`
|
|
66
|
+
- data-review at `passed` or `concerns-acknowledged` when applicable
|
|
67
|
+
- ui-brief at `drafted` and figma-handoff at `ready` when applicable
|
|
68
|
+
- verification at `passed`
|
|
69
|
+
- Determine the findings floor: 3 default; 5 when `change-spec.area` is in {agent, auth, billing} per AR-06.
|
|
70
|
+
|
|
71
|
+
## Orchestration steps
|
|
72
|
+
|
|
73
|
+
1. **Open with the fresh-session reminder.** Print the message verbatim; wait for the engineer's confirmation.
|
|
74
|
+
|
|
75
|
+
2. **Invoke `adversarial-reviewer`.** Use the Task tool with `subagent_type: adversarial-reviewer` and context = [kernel, `hstack/templates/adversarial-review.md`, change-spec, plan, test-plan, ui-brief and figma-handoff when present, security-review, data-review when present, verification, full diff, module-spec, threat-model, hardening-checklist, data-architecture, tech-stack]. Explicitly NOT included: any implementer conversation transcript or scratchpad.
|
|
76
|
+
|
|
77
|
+
3. **Findings generation across six categories.** The subagent produces findings in security, scope-drift, invariant-breach, spec-compliance, data-integrity, and code-quality. Clustering in one category is a smell — when it happens, the subagent flags the clustering in Methodology and explains why the change genuinely lives in one risk dimension. Test-plan adherence is a first-class lens: missing edge-case tests surface as spec-compliance findings; missing tenant-isolation tests surface as data-integrity findings; unmet performance budgets surface as code-quality or data-integrity findings depending on cause; unmapped invariants in `verification.test-plan-coverage` surface as spec-compliance findings. **Test-immutability audit:** the subagent diffs every pre-existing test file against the branch base; any modification, deletion, or snapshot update without a matching `Ok to change/delete/update/refresh ...` authorization echo in a commit message is a mandatory finding under spec-compliance at minimum `severity: high`. Bulk snapshot-update flags visible in the diff or in CI logs escalate to `severity: critical`. These findings are filed even when they push the total over the findings-floor.
|
|
78
|
+
|
|
79
|
+
4. **Findings-floor compliance.** Per AR-01, `findings` length must be ≥ `findings-floor`. If the subagent honestly cannot produce the floor, it sets `findings-fewer-than-floor: true` and writes a defended `justification-when-fewer` enumerating every category considered and why each produced no honest finding. "The change is small" alone is insufficient.
|
|
80
|
+
|
|
81
|
+
5. **Resolution discipline.** Each finding's `resolution` is one of:
|
|
82
|
+
- `commit:<hash>` — must reference an existing commit on the change's branch (AR-04).
|
|
83
|
+
- `tech-debt:<id>` — must reference an existing tech-debt artifact at `open` or `in-progress` (AR-05). When the engineer chooses this path, they invoke `hstack-tech-debt-new` to create the tech-debt artifact before this review terminates.
|
|
84
|
+
- `justified-in-prose` — reserved for low-severity findings only. High-severity findings routed to `justified-in-prose` halt the Skill.
|
|
85
|
+
|
|
86
|
+
6. **Fresh-session attestation in frontmatter.** The subagent writes `fresh-session-attestation: "session <id>; opened <timestamp>; no prior implementer context loaded"`. v1 records this as honor-system text; v2 substrate captures the actual session id from Claude Code's session file.
|
|
87
|
+
|
|
88
|
+
7. **Findings-open is non-terminal.** The subagent does not advance `status: findings-resolved` until every finding has `status: resolved` and a `resolution` value.
|
|
89
|
+
|
|
90
|
+
8. **Owner response loop.** For each finding, the engineer (the change owner) responds with a resolution. The Resolution Log section records each response. The Skill walks the engineer through every finding sequentially.
|
|
91
|
+
|
|
92
|
+
9. **Validate.** Run `{{TODO-SCRIPT: hstack/scripts/validate-spec.ts}}` — AR-01 through AR-06.
|
|
93
|
+
|
|
94
|
+
10. **Change-spec advance (mechanical, only on `findings-resolved`, Skill-orchestrator write per ADR-0002).** When and only when the subagent returned with `adversarial-review.md` at `status: findings-resolved`, read `hstack/specs/changes/<change-id>/spec.md` and inspect its `status` frontmatter. If `status: ready-for-review`, print a proposed-diff preview of the change-spec edit (`status: ready-for-review → ready-to-ship`; `updated: <today>`) and prompt "Proceed with this change-spec advance? (Y/n)". Default Yes. On confirmation, perform the edit via the `Edit` tool, run `{{TODO-SCRIPT: hstack/scripts/validate-spec.ts}}` against the change-spec, then `git add` and commit with message `change-spec(<change-id>): ready-to-ship`. This is a separate commit from the adversarial-review transition commits, matching the verify and finalize precedents. If the change-spec is already at `ready-to-ship` or any downstream status (`shipped`, `archived`), this step is a no-op (idempotent on re-runs). When adversarial-review status is `findings-open` or `in-progress`, this step does not run — the change-spec remains at `ready-for-review` until every finding is resolved. Do NOT invoke `spec-author` and do NOT delegate the write to the `adversarial-reviewer` subagent; per the kernel's Mechanical operations section and ADR-0002, the value to write is fully determined by the adversarial-review postcondition and the change-spec's current status, so the Skill orchestrator writes directly. The `adversarial-reviewer` subagent retains its critique-only lane and writes only `adversarial-review.md`.
|
|
95
|
+
|
|
96
|
+
## Outputs
|
|
97
|
+
|
|
98
|
+
- `hstack/specs/changes/<change-id>/adversarial-review.md` at `status: findings-resolved`.
|
|
99
|
+
- When `adversarial-review.md` lands at `findings-resolved` and the change-spec was at `ready-for-review`: an edit to `hstack/specs/changes/<change-id>/spec.md` advancing `status: ready-for-review → ready-to-ship` and bumping `updated:` (per ADR-0002, written by the Skill orchestrator).
|
|
100
|
+
- Optional new tech-debt artifacts produced via `hstack-tech-debt-new` invocations when findings route to `tech-debt:<id>`.
|
|
101
|
+
- Optional new commits on the change's branch when findings route to `commit:<hash>` and the implementer is re-invoked (separately, via `hstack-implement`) to make the fix.
|
|
102
|
+
|
|
103
|
+
## Auto-commit triggers
|
|
104
|
+
|
|
105
|
+
- Status transition to `in-progress` after Methodology lands.
|
|
106
|
+
- Status transition to `findings-open` after all findings are written.
|
|
107
|
+
- Status transition to `findings-resolved` when every finding has `status: resolved`.
|
|
108
|
+
- Edits to the `findings` array.
|
|
109
|
+
- Edits to any finding's `resolution`.
|
|
110
|
+
- **Change-spec status transition `ready-for-review` → `ready-to-ship`** (per ADR-0002, Skill-orchestrator write). When `adversarial-review.md` reaches `findings-resolved`, the Skill orchestrator performs the change-spec advance directly via `Edit` (orchestration step 10), in a separate auto-commit with message `change-spec(<change-id>): ready-to-ship`. The change-spec becomes eligible for `hstack-ship` only after this commit lands. `hstack-ship` itself remains read-only across artifact statuses — it reads the already-written `ready-to-ship` and computes the merge-readiness scorecard. The `adversarial-reviewer` subagent does not write this transition; it stays in its critique-only lane.
|
|
111
|
+
|
|
112
|
+
## Telemetry sidecar
|
|
113
|
+
|
|
114
|
+
At the change-spec advance commit (only when adversarial-review status is `findings-resolved`), write `hstack/specs/changes/<change-id>/.telemetry/adversarial-review.json` in the same `git add && git commit` as the change-spec advance. The sidecar is derivative of git + frontmatter (see `hstack/templates/telemetry-sidecar.md`). Schema:
|
|
115
|
+
|
|
116
|
+
```json
|
|
117
|
+
{
|
|
118
|
+
"schema_version": 1,
|
|
119
|
+
"skill": "hstack-adversarial-review",
|
|
120
|
+
"change_id": "<change-id>",
|
|
121
|
+
"reviewed_at": "<ISO-8601, when status reached findings-resolved>",
|
|
122
|
+
"findings_floor": <int, 3 or 5 per AR-06>,
|
|
123
|
+
"findings_count": <int, length of frontmatter findings array>,
|
|
124
|
+
"findings_fewer_than_floor": <bool>,
|
|
125
|
+
"category_counts": {
|
|
126
|
+
"security": <int>,
|
|
127
|
+
"scope-drift": <int>,
|
|
128
|
+
"invariant-breach": <int>,
|
|
129
|
+
"spec-compliance": <int>,
|
|
130
|
+
"data-integrity": <int>,
|
|
131
|
+
"code-quality": <int>
|
|
132
|
+
},
|
|
133
|
+
"severity_counts": {
|
|
134
|
+
"critical": <int>,
|
|
135
|
+
"high": <int>,
|
|
136
|
+
"medium": <int>,
|
|
137
|
+
"low": <int>
|
|
138
|
+
},
|
|
139
|
+
"resolution_mix": {
|
|
140
|
+
"commit": <int>,
|
|
141
|
+
"tech-debt": <int>,
|
|
142
|
+
"justified-in-prose": <int>
|
|
143
|
+
},
|
|
144
|
+
"fresh_session_attestation": "<verbatim copy of frontmatter field>",
|
|
145
|
+
"halt_reasons": [<kernel halt-sentinel enum values, if any>]
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
When the review ends at `findings-open` or `in-progress` (no change-spec advance), the sidecar still lands with the same shape on whichever transition commit terminates the current run; `findings_fewer_than_floor` reflects the current value. `.telemetry/` is git-ignored. If the sidecar write fails, log and continue; the canonical commit must still land. This is the most directly Goodhart-resistant of the five v1 sidecars — `category_counts` + `severity_counts` + `resolution_mix` jointly surface findings-quota-gaming patterns no single field could detect.
|
|
150
|
+
|
|
151
|
+
## Idempotency contract
|
|
152
|
+
|
|
153
|
+
- Re-running on a `findings-resolved` review: the subagent reads the existing artifact and produces a no-op aside from `updated` timestamps, unless new code or artifacts have landed since the prior run (in which case new findings may be generated and the status drops back to `findings-open`).
|
|
154
|
+
- Re-running mid-resolution after a halt: the subagent reads the partial artifact and resumes with the first finding still at `status: open`.
|
|
155
|
+
- The change-spec advance step (step 10) is idempotent: a re-run against a change-spec already at `ready-to-ship` (or `shipped`, `archived`) produces a no-op for that step. The Skill does not re-advance and does not regress.
|
|
156
|
+
|
|
157
|
+
## Stop conditions
|
|
158
|
+
|
|
159
|
+
Beyond the kernel's general stop conditions:
|
|
160
|
+
|
|
161
|
+
- Engineer has not confirmed they are in a fresh Claude Code session.
|
|
162
|
+
- A required upstream artifact is non-terminal.
|
|
163
|
+
- A high-severity security or tenant-isolation finding would route to `justified-in-prose`. Halt.
|
|
164
|
+
- A `commit:<hash>` resolution would reference a commit not on the change's branch.
|
|
165
|
+
- A `tech-debt:<id>` resolution would reference a non-existent tech-debt artifact (the engineer must invoke `hstack-tech-debt-new` first).
|
|
166
|
+
- The findings floor cannot honestly be met and the sub-floor justification cannot be defended.
|
|
167
|
+
- The diff includes changes outside `change-spec.in-scope` that CI did not catch — surface a scope-drift finding and halt the CI gap as a separate concern.
|
|
168
|
+
- An implementer transcript or scratchpad is visible in the session.
|
|
169
|
+
|
|
170
|
+
## Failure modes
|
|
171
|
+
|
|
172
|
+
- **Engineer claims fresh session but conversation shows prior implementer transcripts.** Halt; ask the engineer to truly start a new session.
|
|
173
|
+
- **Reviewer cannot produce honest findings to meet the floor and the sub-floor justification feels thin.** Re-prompt for each category; if still under floor, the engineer must defend the sub-floor explicitly.
|
|
174
|
+
- **A finding routes to `tech-debt:<id>` but the engineer hasn't created the tech-debt artifact.** The Skill prompts to invoke `hstack-tech-debt-new`; the review does not terminate until the artifact exists.
|
|
175
|
+
- **A commit hash named in `resolution` does not exist on the change's branch.** Halt — the engineer either re-references the correct commit or the resolution is reconsidered.
|
|
176
|
+
|
|
177
|
+
## Anti-patterns
|
|
178
|
+
|
|
179
|
+
- Never return "no issues found" without a defended sub-floor justification.
|
|
180
|
+
- Never run in the same Claude Code session as `hstack-implement`. Honor-system in v1; CI-verified in v2.
|
|
181
|
+
- Never cluster all findings in one category without flagging in Methodology.
|
|
182
|
+
- Never use `justified-in-prose` for a high-severity finding.
|
|
183
|
+
- Never propose code changes directly — the reviewer surfaces findings; the owner or implementer (via `hstack-implement`) resolves them.
|
|
184
|
+
- Never invent a tech-debt id. The artifact must exist or be authored before the review terminates.
|
|
185
|
+
- Never accept a `commit:<hash>` that does not exist on the change's branch.
|
|
186
|
+
- Never advance status to `findings-resolved` while any finding has `status: open`.
|
|
187
|
+
- Never load implementer transcripts. If visible, halt.
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hstack-branch
|
|
3
|
+
description: |
|
|
4
|
+
Use this skill when the engineer needs to check out or create the conventional `change/<change-id>` branch for a specific change-spec — typically because they realized mid-flow that they're on the wrong branch, or because they declined the branch offer at `/hstack:change-new` and want to switch later. One-shot, single-purpose, no subagent invoked. Examples:
|
|
5
|
+
|
|
6
|
+
<example>
|
|
7
|
+
Context: The engineer scaffolded the billing-overage change earlier, declined the branch offer at the time, and has since drafted the spec and ui-brief on main. Now they want to switch before implementing.
|
|
8
|
+
user: "/hstack:branch 2026-05-billing-overage-warning"
|
|
9
|
+
assistant: "I'll check whether `change/2026-05-billing-overage-warning` already exists. If yes, check out. If no, create from the current branch and check out. Any uncommitted work is preserved."
|
|
10
|
+
<commentary>
|
|
11
|
+
Idempotent: existing branch → checkout; missing branch → create-and-checkout. The Skill never force-deletes, never resets, never loses local work. If there are uncommitted changes that conflict with the target branch, the engineer is warned before the switch.
|
|
12
|
+
</commentary>
|
|
13
|
+
</example>
|
|
14
|
+
|
|
15
|
+
<example>
|
|
16
|
+
Context: The engineer wants the branch for whatever the most recently scaffolded change is and doesn't want to type the id.
|
|
17
|
+
user: "/hstack:branch"
|
|
18
|
+
assistant: "No id given. I'll detect the most recently scaffolded in-flight change-spec from hstack/specs/changes/, propose its expected branch name, and ask for confirmation before checking out."
|
|
19
|
+
<commentary>
|
|
20
|
+
No-arg mode defaults to the latest in-flight change for convenience. The Skill confirms before acting — the default is a guess, not a command.
|
|
21
|
+
</commentary>
|
|
22
|
+
</example>
|
|
23
|
+
tools:
|
|
24
|
+
- Bash
|
|
25
|
+
- Read
|
|
26
|
+
- Glob
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Purpose
|
|
30
|
+
|
|
31
|
+
`hstack-branch` is the explicit branch-switching Skill. It honors the kernel's branch-hygiene rule: one branch per change-spec, named `change/<change-id>`. It exists for the mid-flow case where the engineer needs to switch branches outside the `/hstack:change-new` offer moment. No subagent invoked; no artifact writes; just `git checkout`.
|
|
32
|
+
|
|
33
|
+
## When to invoke
|
|
34
|
+
|
|
35
|
+
Invoke when:
|
|
36
|
+
- You declined the branch offer at `/hstack:change-new` earlier and now want to switch.
|
|
37
|
+
- You realized you're on the wrong branch several commits into a change.
|
|
38
|
+
- You're picking up a teammate's change-spec and need to be on the right branch before implementing.
|
|
39
|
+
- `/hstack:help` flagged a branch mismatch and you want to fix it.
|
|
40
|
+
|
|
41
|
+
## Inputs
|
|
42
|
+
|
|
43
|
+
- `<change-id>` (optional, positional): the change-spec id whose branch you want to check out. If omitted, the Skill detects the most recently scaffolded in-flight change-spec and proposes its branch.
|
|
44
|
+
- `--from <base-branch>` (optional): the branch to create from when the target branch doesn't exist yet. Defaults to `main` (or the configured default).
|
|
45
|
+
|
|
46
|
+
## Preconditions
|
|
47
|
+
|
|
48
|
+
Before any work:
|
|
49
|
+
|
|
50
|
+
- Verify the working directory is a git repository.
|
|
51
|
+
- When `<change-id>` is provided: verify `hstack/specs/changes/<change-id>/spec.md` exists. If not, halt — there's nothing to branch for.
|
|
52
|
+
- When `<change-id>` is omitted: glob `hstack/specs/changes/*/spec.md`, filter to non-terminal status, sort by `created` descending, take the first. If none exist, halt with "no in-flight change-specs; nothing to branch for."
|
|
53
|
+
- Inspect uncommitted work via `git status --short`. If the working tree is dirty AND switching branches would lose context, warn the engineer before proceeding.
|
|
54
|
+
|
|
55
|
+
## Orchestration steps
|
|
56
|
+
|
|
57
|
+
1. **Resolve the change-id.** Either the positional argument or the auto-detected most-recent in-flight change. When auto-detected, surface the detection and ask for confirmation before proceeding.
|
|
58
|
+
|
|
59
|
+
2. **Compute the target branch.** `change/<change-id>`.
|
|
60
|
+
|
|
61
|
+
3. **Check whether the target branch exists.** Run `git rev-parse --verify --quiet refs/heads/<target>`.
|
|
62
|
+
- Exists → run `git checkout <target>`. Report the switch.
|
|
63
|
+
- Does not exist → run `git checkout -b <target> <base>` where `<base>` is `--from`'s value or the configured default. Report the create-and-switch.
|
|
64
|
+
|
|
65
|
+
4. **Verify post-switch state.** Run `git branch --show-current` and `git status --short`. Surface the new state to the engineer.
|
|
66
|
+
|
|
67
|
+
5. **Suggest the next action.** Read the change-spec's `status`. Based on the status, suggest the natural next Skill (e.g., status `ready-to-plan` → "Next: `/hstack:change-plan <id>`"). Same logic as `/hstack:help`'s next-action computation, scoped to this one change.
|
|
68
|
+
|
|
69
|
+
## Outputs
|
|
70
|
+
|
|
71
|
+
- A git branch checkout (existing) or create-and-checkout (new). No artifact writes. No commits.
|
|
72
|
+
|
|
73
|
+
## Auto-commit triggers
|
|
74
|
+
|
|
75
|
+
None. Branch operations do not create commits.
|
|
76
|
+
|
|
77
|
+
## Idempotency contract
|
|
78
|
+
|
|
79
|
+
- Re-running with the same `<change-id>` when already on the target branch: no-op. Report "already on `change/<id>`" and exit cleanly.
|
|
80
|
+
- Re-running with a target branch that already exists: plain checkout, no creation.
|
|
81
|
+
|
|
82
|
+
## Stop conditions
|
|
83
|
+
|
|
84
|
+
Beyond the kernel's general stop conditions:
|
|
85
|
+
|
|
86
|
+
- The named `<change-id>` does not correspond to an existing change-spec.
|
|
87
|
+
- The working tree has uncommitted changes that would be lost or conflict on switch. Halt and ask: "Uncommitted changes detected — stash, commit, or discard before switching?" (recommend `/hstack:commit` for the commit path; never auto-stash; never auto-discard).
|
|
88
|
+
- The engineer requested a `<base-branch>` that does not exist.
|
|
89
|
+
- The current branch is already the target branch — exit cleanly with the no-op message.
|
|
90
|
+
|
|
91
|
+
## Failure modes
|
|
92
|
+
|
|
93
|
+
- **`git checkout` fails due to conflicting local changes.** Surface the git error; do not retry. The engineer resolves manually.
|
|
94
|
+
- **Branch name collision with an unrelated existing branch.** If `change/<change-id>` exists but points at unrelated history (someone created it manually for another purpose), warn the engineer; do not silently overwrite. Engineer renames the unrelated branch or uses `--from` to specify their intent.
|
|
95
|
+
|
|
96
|
+
## Anti-patterns
|
|
97
|
+
|
|
98
|
+
- Never use `git checkout -B` (force-create). Use `git checkout -b` (create or fail) and let the engineer resolve collisions.
|
|
99
|
+
- Never auto-stash. Stash policy is the engineer's call.
|
|
100
|
+
- Never `git checkout -- <files>` or any path-discarding form.
|
|
101
|
+
- Never force-delete a branch. Cleanup of obsolete `change/*` branches is post-ship hygiene, not this Skill's domain.
|
|
102
|
+
- Never push the new branch automatically. Push is hard-to-reverse; the engineer pushes when ready.
|
|
103
|
+
- Never branch from anywhere other than the configured default (typically `main`) unless `--from` is explicit. The kernel's branching convention starts every change from `main`.
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hstack-change-new
|
|
3
|
+
description: |
|
|
4
|
+
Use this skill when an engineer wants to start a new change and needs the `hstack/specs/changes/<id>/` folder scaffolded with templates pre-populated, before any spec-author or planner work begins. The Skill validates that the affected module has a current module-spec, derives the change id from the area and slug, scaffolds the folder, and seeds `spec.md` with the canonical template. Examples:
|
|
5
|
+
|
|
6
|
+
<example>
|
|
7
|
+
Context: The engineer is about to start work on the billing overage warning feature and needs the change folder before drafting the spec.
|
|
8
|
+
user: "/hstack:change-new billing overage-warning"
|
|
9
|
+
assistant: "I'll scaffold hstack/specs/changes/2026-05-billing-overage-warning/ with spec.md pre-populated from the template. spec-author runs separately when you're ready to fill the fields."
|
|
10
|
+
<commentary>
|
|
11
|
+
This Skill does not author content; it produces the empty folder shape so spec-author has a target to write into. Scaffold-only separation keeps the Skill cheap to re-run and idempotent on partial state.
|
|
12
|
+
</commentary>
|
|
13
|
+
</example>
|
|
14
|
+
|
|
15
|
+
<example>
|
|
16
|
+
Context: The engineer tries to scaffold a change in an area that has no module-spec yet.
|
|
17
|
+
user: "/hstack:change-new playbook-runner inline-mode"
|
|
18
|
+
assistant: "I'll halt — there's no hstack/specs/playbook-runner/spec.md at status current. Run /hstack:module-spec playbook-runner first."
|
|
19
|
+
<commentary>
|
|
20
|
+
Scaffolding refuses when the module's baseline doesn't exist. This is a deliberate gate: a change-spec whose `area` points at a nonexistent module-spec fails SP-01 anyway, so the Skill halts before any folder is created rather than producing dead scaffolding.
|
|
21
|
+
</commentary>
|
|
22
|
+
</example>
|
|
23
|
+
tools:
|
|
24
|
+
- Read
|
|
25
|
+
- Write
|
|
26
|
+
- Edit
|
|
27
|
+
- Grep
|
|
28
|
+
- Glob
|
|
29
|
+
- Bash
|
|
30
|
+
- "{{TODO-SCRIPT: hstack/scripts/validate-spec.ts — validates the seeded change-spec frontmatter}}"
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Purpose
|
|
34
|
+
|
|
35
|
+
`hstack-change-new` scaffolds the per-change folder under `hstack/specs/changes/<id>/` and seeds `spec.md` from the canonical template. It does no authoring — `spec-author` is invoked separately by the engineer once the folder exists. This Skill exists to keep id-generation, folder layout, and template seeding consistent across changes, and to enforce the module-spec precondition before any change work begins.
|
|
36
|
+
|
|
37
|
+
## When to invoke
|
|
38
|
+
|
|
39
|
+
Invoke at the start of any new change. The Skill is the conventional first step of the per-change workflow, run before `hstack-story-draft`, `hstack-change-plan`, or any other per-change Skill. Trivial changes (typo fixes, dependency bumps) that the engineer intends to tag with `trivial: true` may skip this Skill, though most engineers run it anyway for consistency.
|
|
40
|
+
|
|
41
|
+
## Inputs
|
|
42
|
+
|
|
43
|
+
- `<area>` (required, positional): the module key, must match an existing module-spec at `status: current`. Examples: `billing`, `orchestrator`, `knowledge-base`.
|
|
44
|
+
- `<slug>` (required, positional): kebab-case short name for the change. Examples: `overage-warning`, `inline-mode`. The Skill validates the slug shape (kebab-case, no spaces, no leading numerics).
|
|
45
|
+
|
|
46
|
+
The change `id` is derived as `YYYY-MM-<area>-<slug>` using the current month from `today`'s ISO date.
|
|
47
|
+
|
|
48
|
+
## Preconditions
|
|
49
|
+
|
|
50
|
+
Before any work:
|
|
51
|
+
|
|
52
|
+
- Verify `hstack/config.yaml` exists at `init-status: complete`. If not, halt and direct the engineer to `hstack-init`.
|
|
53
|
+
- Verify `hstack/specs/<area>/spec.md` exists at `status: current`. If absent or non-terminal, halt and direct the engineer to `hstack-module-spec <area>`.
|
|
54
|
+
- Verify `hstack/specs/changes/<derived-id>/` does not already exist. If it does, halt and surface the existing folder — the engineer is either resuming (in which case no scaffold is needed) or has a slug collision (in which case they pick a different slug).
|
|
55
|
+
- Verify the slug matches `^[a-z][a-z0-9-]*$`.
|
|
56
|
+
|
|
57
|
+
## Orchestration steps
|
|
58
|
+
|
|
59
|
+
1. **Derive the id.** Compute `<YYYY-MM>-<area>-<slug>` from today's date and the inputs. Surface the derived id to the engineer for confirmation before writing.
|
|
60
|
+
|
|
61
|
+
2. **Create the folder.** `mkdir -p hstack/specs/changes/<id>/` via Bash.
|
|
62
|
+
|
|
63
|
+
3. **Seed `spec.md`.** Read `hstack/templates/change-spec.md`, instantiate the frontmatter with `id`, `type: change-spec`, `status: draft`, `owner` (from `git config user.name` or `hstack/config.yaml`'s default owner), `area: <area>`, `related-spec: <area>`, `created` and `updated` set to today, `schema-version: 1`. Leave `surfaces`, `user-stories`, `in-scope`, `out-of-scope`, `related-adrs`, `creates-tech-debt`, `parent-change`, `threat-model-delta`, `internal-tooling`, `trivial` as their template defaults (typically empty arrays or `null`). Leave every prose section empty, with the template's interview-prompt comments intact for `spec-author` to consume.
|
|
64
|
+
|
|
65
|
+
4. **Validate.** Run `{{TODO-SCRIPT: hstack/scripts/validate-spec.ts}}` against the seeded file. Validation at `status: draft` is permissive — empty arrays and empty prose are allowed at draft — but the universal floor (FM-01) must pass.
|
|
66
|
+
|
|
67
|
+
5. **Offer branch creation.** Run `git branch --show-current`. If the current branch is `main` (or the configured default), ask the engineer: "You're on `<current-branch>`. Convention is one branch per change-spec — create `change/<id>` from here and check out before the scaffold commits? [Y/n/type-different-name]". Default Yes. On confirmation, run `git checkout -b change/<id>` BEFORE step 6 so the scaffold commit lands on the correct branch from the start. If the engineer declines or names a different branch, honor the choice and continue on the chosen branch. If the current branch is anything other than the configured default (i.e., already on a feature branch), do nothing — the engineer has a deliberate branching strategy and the Skill respects it.
|
|
68
|
+
|
|
69
|
+
6. **Auto-commit.** Commit message: `chore(change-new): scaffold <id>`.
|
|
70
|
+
|
|
71
|
+
7. **Surface next steps.** Print a one-line instruction directing the engineer to invoke `spec-author` (or `hstack-story-draft` first if the change is user-facing and no story exists yet).
|
|
72
|
+
|
|
73
|
+
The Skill does not invoke any subagent. Scaffolding is mechanical and the engineer's subsequent moves vary by change.
|
|
74
|
+
|
|
75
|
+
## Outputs
|
|
76
|
+
|
|
77
|
+
- New directory `hstack/specs/changes/<id>/`.
|
|
78
|
+
- New file `hstack/specs/changes/<id>/spec.md` at `status: draft`, with frontmatter populated to the floor and prose sections empty.
|
|
79
|
+
|
|
80
|
+
## Auto-commit triggers
|
|
81
|
+
|
|
82
|
+
- One commit at scaffold completion. No further commits from this Skill.
|
|
83
|
+
|
|
84
|
+
## Idempotency contract
|
|
85
|
+
|
|
86
|
+
- Re-running with the same `<area>` and `<slug>` when the derived folder exists is a no-op; the Skill detects the existing folder, surfaces it, and exits without writes.
|
|
87
|
+
- Re-running with a different month (e.g., the engineer scaffolded in May, returns in June, and re-runs the same slug) produces a different id and a new folder; this is intentional — month-prefixed ids prevent slug-collision across long-running work.
|
|
88
|
+
- If the folder exists but `spec.md` is absent (rare, indicates an interrupted scaffold), the Skill re-seeds `spec.md` only.
|
|
89
|
+
|
|
90
|
+
## Stop conditions
|
|
91
|
+
|
|
92
|
+
Beyond the kernel's general stop conditions:
|
|
93
|
+
|
|
94
|
+
- The `<area>` does not correspond to an existing module-spec at `status: current`. Halt.
|
|
95
|
+
- The `<slug>` violates kebab-case shape. Halt.
|
|
96
|
+
- The derived folder already exists with content. Halt and ask.
|
|
97
|
+
|
|
98
|
+
## Failure modes
|
|
99
|
+
|
|
100
|
+
- **Validator fails on the seeded spec.** The template itself is broken — halt and surface as a hstack installation issue.
|
|
101
|
+
- **`git config user.name` returns empty and `hstack/config.yaml` has no default owner.** Halt and ask the engineer for their owner handle.
|
|
102
|
+
|
|
103
|
+
## Anti-patterns
|
|
104
|
+
|
|
105
|
+
- Never write prose content into the seeded `spec.md` beyond the template's existing prompts. The Skill scaffolds; `spec-author` authors.
|
|
106
|
+
- Never derive the id from anything other than the current month, the area, and the slug. Hand-rolled ids break the kebab-case + chronological-prefix convention that other Skills depend on.
|
|
107
|
+
- Never scaffold under an area whose module-spec is absent. The precondition is hard.
|
|
108
|
+
- Never modify an existing change folder. Reruns are no-ops or refusals, never overwrites.
|
|
109
|
+
- Never advance `status` past `draft` from this Skill. Subsequent transitions are owned by the authoring subagents.
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hstack-change-plan
|
|
3
|
+
description: |
|
|
4
|
+
Use this skill when a change-spec is at `status: ready-to-plan` (with its conditional upstream artifacts also at terminal status) and needs `plan.md` drafted as atomic phases. The Skill orchestrates the `planner` subagent. Examples:
|
|
5
|
+
|
|
6
|
+
<example>
|
|
7
|
+
Context: The billing-overage change-spec is at ready-to-plan, the ui-brief is drafted, the figma-handoff is ready, and the engineer is about to start implementation.
|
|
8
|
+
user: "/hstack:change-plan 2026-05-billing-overage-warning"
|
|
9
|
+
assistant: "I'll invoke planner with the change-spec, ui-brief, figma-handoff. Atomic phases with per-phase verifier expectations and a rollback strategy."
|
|
10
|
+
<commentary>
|
|
11
|
+
The planner is the only authoring path for plan.md. The Skill enforces that upstream conditional artifacts (ui-brief, figma-handoff for ui; data-review for db) are at terminal status before invoking — otherwise the planner halts.
|
|
12
|
+
</commentary>
|
|
13
|
+
</example>
|
|
14
|
+
|
|
15
|
+
<example>
|
|
16
|
+
Context: A change touching ui and db is at ready-to-plan but data-review has not been run yet.
|
|
17
|
+
user: "/hstack:change-plan 2026-06-knowledge-citations"
|
|
18
|
+
assistant: "I'll halt — surfaces includes db and data-review.md is missing. Run /hstack:data-review first."
|
|
19
|
+
<commentary>
|
|
20
|
+
The conditional upstream gate is hard. Skipping the data-review and producing a plan against an unscored data layer produces a plan that the implementer would refuse to act on anyway.
|
|
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 plan frontmatter and PL-01..PL-05}}"
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Purpose
|
|
35
|
+
|
|
36
|
+
`hstack-change-plan` produces `plan.md` for a change-spec by orchestrating the `planner` subagent. The plan decomposes the change into atomic phases with per-phase verifier expectations, names cross-phase risks, and articulates a rollback strategy. It is the artifact the implementer executes one phase at a time and the verifier checks phase-by-phase.
|
|
37
|
+
|
|
38
|
+
## When to invoke
|
|
39
|
+
|
|
40
|
+
Invoke when the change-spec reaches `status: ready-to-plan`, `test-plan.md` is at terminal status, and any conditional upstream artifacts required by the spec's `surfaces` are at terminal status. Re-invoke when the change-spec, the test-plan, or any conditional upstream artifact changes shape in ways that invalidate the existing plan.
|
|
41
|
+
|
|
42
|
+
## Inputs
|
|
43
|
+
|
|
44
|
+
- `<change-id>` (required, positional): the change-spec id.
|
|
45
|
+
|
|
46
|
+
## Preconditions
|
|
47
|
+
|
|
48
|
+
Before any work:
|
|
49
|
+
|
|
50
|
+
- Verify the change-spec exists at `hstack/specs/changes/<id>/spec.md` and is at `status: ready-to-plan` or later.
|
|
51
|
+
- Verify the change-spec's `Invariants` section has ≥ 3 bullets (SP-04) and `Scope Boundaries` is non-empty (SP-05/SP-06). If empty, halt — the planner refuses.
|
|
52
|
+
- **Verify `test-plan.md` is at `status: passed` or `concerns-acknowledged`.** This is the hard upstream gate; the planner refuses to sequence phases without a terminal test strategy. Halt otherwise and direct the engineer to `/hstack:test-plan`.
|
|
53
|
+
- When `surfaces` includes `ui`: verify `ui-brief.md` at `status: drafted` and `figma-handoff.md` at `status: ready`. Halt otherwise.
|
|
54
|
+
- When `surfaces` includes `db`: verify `data-review.md` at `status: passed` or `concerns-acknowledged`. Halt otherwise.
|
|
55
|
+
- Verify the relevant module-spec at `status: current`.
|
|
56
|
+
- Read `hstack/context/tech-stack.md` (loaded by `planner` for pinned runtime constraints).
|
|
57
|
+
|
|
58
|
+
The security-review is not a planner precondition — security-review and the plan can be produced in either order, since neither depends on the other's content (the implementer reads both at session start). The test-plan, by contrast, IS a planner precondition: the planner's phase ordering and per-phase Test Strategy entries reference test-plan sections, so the test-plan must already be terminal.
|
|
59
|
+
|
|
60
|
+
## Orchestration steps
|
|
61
|
+
|
|
62
|
+
1. **Invoke `planner`.** Use the Task tool with `subagent_type: planner` and context = [kernel, `hstack/templates/plan.md`, change-spec, test-plan, ui-brief and figma-handoff if applicable, data-review if applicable, module-spec, tech-stack]. The subagent walks the four plan sections — Phase Overview, Per-Phase Detail, Cross-Phase Risks, Rollback. Per-phase Test Strategy entries point at test-plan sections rather than re-stating tests inline.
|
|
63
|
+
|
|
64
|
+
2. **Phase decomposition.** Per the `planner` contract, typical plans hold 4–8 phases; > 12 phases requires an `oversized-plan-justification` frontmatter field. Each phase has a `step-id`, one-line summary, `depends-on` list, Files Touched (subset of `change-spec.in-scope`), Test Strategy, Risk sentence, and Verifier Expectations.
|
|
65
|
+
|
|
66
|
+
3. **Scope subset enforcement.** Per PL-04, every "Files Touched" entry across the plan must be a subset of `change-spec.in-scope`. The subagent verifies during authoring; the Skill verifies post-write via the validator. If a phase requires a file outside `in-scope`, the planner halts with a scope-amendment request.
|
|
67
|
+
|
|
68
|
+
4. **Exercise the Cross-Phase Risks challenge.** Per the `planner` contract, the Cross-Phase Risks section uses the challenge prompt "What could go wrong across phase boundaries that no single phase catches?" Minimum one bullet for multi-phase plans.
|
|
69
|
+
|
|
70
|
+
5. **Rollback discipline.** Section 4 names what to flip, revert, or feature-gate if a partial rollout breaks something. If the engineer cannot answer, the planner halts rather than writing a plausible default.
|
|
71
|
+
|
|
72
|
+
6. **Leave `steps-completed: []`.** Per architecture amendment A3 and the planner's contract, `steps-completed` is owned by the implementer; the planner never populates it.
|
|
73
|
+
|
|
74
|
+
7. **Validate.** Run `{{TODO-SCRIPT: hstack/scripts/validate-spec.ts}}` — PL-01 (parent-change matches), PL-02 (phase count), PL-03 (steps-completed entries match plan phase ids), PL-04 (Files Touched is subset of in-scope), PL-05 (status advance gating).
|
|
75
|
+
|
|
76
|
+
8. **Transition.** When the validator passes, `planner` advances status from `draft` to `ready`. Auto-commit fires.
|
|
77
|
+
|
|
78
|
+
## Outputs
|
|
79
|
+
|
|
80
|
+
- `hstack/specs/changes/<change-id>/plan.md` at `status: ready`.
|
|
81
|
+
|
|
82
|
+
## Auto-commit triggers
|
|
83
|
+
|
|
84
|
+
- Status transition to `draft` after the Phase Overview table lands.
|
|
85
|
+
- Status transition to `ready` at end of authoring. Commit message: `plan(<change-id>): ready`.
|
|
86
|
+
|
|
87
|
+
## Idempotency contract
|
|
88
|
+
|
|
89
|
+
- Re-running on an existing `ready` plan without spec changes: the subagent reads the existing plan as the proposal layer; identical re-confirmation is a no-op.
|
|
90
|
+
- Re-running mid-authoring after a halt: `planner` reads the partial file and resumes at the next un-confirmed section.
|
|
91
|
+
- Re-running after the change-spec's `in-scope` has been amended: the planner re-validates every Files Touched entry against the new in-scope, halts if any phase drifted, and prompts the engineer to reshape phases.
|
|
92
|
+
|
|
93
|
+
## Stop conditions
|
|
94
|
+
|
|
95
|
+
Beyond the kernel's general stop conditions:
|
|
96
|
+
|
|
97
|
+
- Change-spec Invariants empty (< 3 bullets) or Scope Boundaries empty.
|
|
98
|
+
- `test-plan.md` missing or non-terminal. Halt and direct the engineer to `/hstack:test-plan`.
|
|
99
|
+
- Conditional upstream artifact missing or non-terminal.
|
|
100
|
+
- A Files Touched entry would drift outside `in-scope`. Halt and request a scope amendment via `spec-author`.
|
|
101
|
+
- > 12 phases without `oversized-plan-justification` in frontmatter.
|
|
102
|
+
- The Cross-Phase Risks challenge prompt cannot be answered with at least one bullet on a multi-phase change.
|
|
103
|
+
- The engineer cannot answer the rollback prompt.
|
|
104
|
+
|
|
105
|
+
## Failure modes
|
|
106
|
+
|
|
107
|
+
- **Module-spec missing or `needs-refresh`.** Halt; refresh via `hstack-module-spec` first.
|
|
108
|
+
- **`ui-brief.md` exists at `draft` rather than `drafted`.** Halt; the brief is incomplete.
|
|
109
|
+
- **Validator fails PL-04.** The planner halts immediately at the offending phase; the engineer either reshapes the phase or amends in-scope.
|
|
110
|
+
- **`planner` halts on cross-phase risk surfacing an invariant gap.** Halt; the engineer amends the change-spec via `spec-author`, then re-runs this Skill.
|
|
111
|
+
|
|
112
|
+
## Anti-patterns
|
|
113
|
+
|
|
114
|
+
- Never write code. Plans are prose plus YAML.
|
|
115
|
+
- Never silently accept a non-terminal upstream artifact.
|
|
116
|
+
- Never invent invariants or modify the change-spec's Invariants section — that is `spec-author`'s domain.
|
|
117
|
+
- Never write `steps-completed` values; the field belongs to the implementer.
|
|
118
|
+
- Never produce a multi-phase plan with empty Cross-Phase Risks without exercising the challenge prompt.
|
|
119
|
+
- Never write a rollback section with a plausible-sounding default the engineer did not endorse.
|