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,182 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hstack-test-plan
|
|
3
|
+
description: |
|
|
4
|
+
Use this skill when a change-spec is at `status: ready-to-plan` and needs `test-plan.md` produced before the planner can sequence implementation phases. The Skill orchestrates the `test-strategist` subagent. In v1 the output is an LLM-strategized judgment (`scoring-mode: llm-strategized`), not coverage-instrumented or mutation-tested — the Skill enforces this framing on every output. Examples:
|
|
5
|
+
|
|
6
|
+
<example>
|
|
7
|
+
Context: A change-spec adds a new RLS-protected table and a tenant-scoped RPC; it is at ready-to-plan.
|
|
8
|
+
user: "/hstack:test-plan 2026-06-knowledge-citations"
|
|
9
|
+
assistant: "I'll invoke test-strategist. Surfaces is [db, api] so tenant-isolation tests are mandatory and non-empty. The plan will name a negative cross-tenant RPC test, declare the fixture strategy, and answer the three challenge prompts before status can advance."
|
|
10
|
+
<commentary>
|
|
11
|
+
The Skill is the only authoring path for test-plan.md. It enforces TS-03 (tenant-isolation-tests non-empty when surfaces includes db/api/agent) and TS-02 (three challenge prompts mandatory). v1 framing is enforced on every rationale paragraph.
|
|
12
|
+
</commentary>
|
|
13
|
+
</example>
|
|
14
|
+
|
|
15
|
+
<example>
|
|
16
|
+
Context: A change touches a hot-path retrieval endpoint that other services depend on for latency.
|
|
17
|
+
user: "/hstack:test-plan 2026-05-retrieval-rpc-rewrite"
|
|
18
|
+
assistant: "I'll invoke test-strategist with performance-budgets-required: true. Each row in the budgets table pairs a numeric threshold with an asserting test; budgets without tests are refused."
|
|
19
|
+
<commentary>
|
|
20
|
+
The performance-budget contract is the v1 mitigation for "we said it had to be fast" promises that never get enforced. The Skill verifies every populated budget row has both a numeric threshold and a named asserting test before terminal status.
|
|
21
|
+
</commentary>
|
|
22
|
+
</example>
|
|
23
|
+
|
|
24
|
+
<example>
|
|
25
|
+
Context: A small refactor with no behavior change but adjacent to authentication code.
|
|
26
|
+
user: "/hstack:test-plan 2026-05-auth-helper-rename"
|
|
27
|
+
assistant: "I'll invoke test-strategist. Even on a refactor, the three challenge prompts run — silent-pass-but-break behavior, invariant without mapped test, untested failure scenario. Refactors near auth are exactly where strategy surfaces hidden risk."
|
|
28
|
+
<commentary>
|
|
29
|
+
Refactors are not exempt from the challenge prompts. The v1 honesty clause forbids skipping them. A refactor near auth that ships without these prompts answered is a regression risk that no other artifact will catch.
|
|
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 test-plan frontmatter and TS-01..TS-06}}"
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Purpose
|
|
44
|
+
|
|
45
|
+
`hstack-test-plan` produces `test-plan.md` for a change-spec by orchestrating the `test-strategist` subagent. In hstack v1, the artifact is a structured LLM judgment about test pyramid layering, edge cases, tenant-isolation tests, fixture strategy, and performance budgets, plus three mandatory challenge prompts. It is not a coverage-instrumented or mutation-tested artifact; v2 substrate replaces the strategist's claims with measured coverage runs and benchmark-asserted budgets. This Skill enforces the v1 honesty framing on every output.
|
|
46
|
+
|
|
47
|
+
The test-plan runs **upstream of the planner**. It is the first per-change artifact authored after the change-spec reaches `ready-to-plan`. The planner reads it; the implementer reads it; the verifier later checks observed tests against both the planner's per-phase Verifier Expectations and the test-plan's pyramid and budgets.
|
|
48
|
+
|
|
49
|
+
## When to invoke
|
|
50
|
+
|
|
51
|
+
Invoke when a change-spec reaches `status: ready-to-plan`. The test-plan must reach terminal status (`passed` or `concerns-acknowledged`) before `hstack-change-plan` can run — the planner refuses to start without it. Security-review and data-review can run in parallel with the test-plan; none of those three gate one another.
|
|
52
|
+
|
|
53
|
+
Trivial changes (`trivial: true` on the change-spec) bypass this Skill per the kernel's trivial-changes carve-out.
|
|
54
|
+
|
|
55
|
+
## Inputs
|
|
56
|
+
|
|
57
|
+
- `<change-id>` (required, positional): the change-spec id.
|
|
58
|
+
|
|
59
|
+
## Preconditions
|
|
60
|
+
|
|
61
|
+
Before any work:
|
|
62
|
+
|
|
63
|
+
- Verify the change-spec exists and is at `status: ready-to-plan` or later. If at `draft`, halt — the strategist cannot work against a draft spec.
|
|
64
|
+
- Verify the change-spec is **not** `trivial: true`. If trivial, halt and surface that the test-plan is not required.
|
|
65
|
+
- Verify the change-spec's `Invariants` section has ≥ 3 bullets (SP-04). The strategist maps tests to invariant ids; without invariants, mapping is impossible.
|
|
66
|
+
- Verify `hstack/context/tech-stack.md` and `hstack/context/ci-cd.md` are at `status: current`. The strategist relies on these for framework conventions and canonical command names.
|
|
67
|
+
- When `surfaces` includes `db`: verify `hstack/context/data-architecture.md` is at `status: current`.
|
|
68
|
+
- Verify the relevant module-spec at `status: current`.
|
|
69
|
+
- Determine whether `surfaces` includes `db`, `api`, or `agent`. If yes, the strategist will be required to produce a non-empty `tenant-isolation-tests` array (TS-03).
|
|
70
|
+
- Determine whether the change touches a hot path or high-traffic surface. If yes, set `performance-budgets-required: true` for the subagent's session and require the Budgets table to be populated.
|
|
71
|
+
|
|
72
|
+
## Orchestration steps
|
|
73
|
+
|
|
74
|
+
1. **Invoke `test-strategist`.** Use the Task tool with `subagent_type: test-strategist` and context = [kernel, `hstack/templates/test-plan.md`, change-spec, module-spec, tech-stack, ci-cd, data-architecture when applicable]. The subagent walks the eight sections — Surfaces and Risk Profile, Test Pyramid, Edge Cases, Tenant Isolation Tests, Test Data and Fixture Strategy, Performance and Regression Budgets, Challenge Prompts, Open Concerns.
|
|
75
|
+
|
|
76
|
+
2. **Pyramid bias.** Per the subagent's contract, bias is unit-for-pure-functions, integration-for-multi-module-behavior, e2e-only-for-user-journeys-that-span-the-stack. The Skill rejects any pyramid where the bulk of behavior coverage lands in e2e — that is the slow-and-flaky failure mode the strategist exists to prevent.
|
|
77
|
+
|
|
78
|
+
3. **Edge case enumeration.** Minimum three bullets unless the change-spec carries `trivial: true`. Each bullet maps to a named test file and test name. The Skill rejects edge cases that name a test without a path.
|
|
79
|
+
|
|
80
|
+
4. **Tenant-isolation tests (TS-03 enforcement).** When `surfaces` includes `db`, `api`, or `agent`, the `tenant-isolation-tests` array must be non-empty and every entry must cite a real surface (table, RPC, tool boundary) and a real planned test. The subagent grep-verifies surface identifiers; making them up is forbidden.
|
|
81
|
+
|
|
82
|
+
5. **Fixture strategy.** The Test Data and Fixture Strategy section must be non-empty before status can advance. `fixture-strategy-declared: true` is required for terminal status (TS-05).
|
|
83
|
+
|
|
84
|
+
6. **Performance budgets.** When `performance-budgets-required: true`, every row in the Budgets table must pair a numeric threshold with an asserting test. The Skill deletes any unbacked row and surfaces it as a coverage gap rather than letting an unenforceable budget ship.
|
|
85
|
+
|
|
86
|
+
7. **Three challenge prompts (mandatory).** Per TS-02 and the subagent's contract, the subagent answers all three challenge prompts verbatim:
|
|
87
|
+
- "What behavior in this change would silently pass the test suite but break in production? Name the test that would catch it, or declare that no such test is planned and justify."
|
|
88
|
+
- "Which invariant from the change-spec has no corresponding negative or regression test? If every invariant has a mapped test, cite the test for each invariant by id."
|
|
89
|
+
- "What concurrent, multi-tenant, or failure-mode scenario is not exercised by the planned tests? If none is plausibly relevant, justify why this change has no such scenario."
|
|
90
|
+
Each answer is at least one paragraph. The Skill verifies `challenge-prompts-answered: 3` in frontmatter.
|
|
91
|
+
|
|
92
|
+
8. **Invariant mapping (TS-06).** Every invariant id declared in the change-spec must be referenced at least once in section 3, section 4, or in the (b) challenge prompt. The `invariants-mapped` frontmatter array enumerates the covered ids. The validator fails if any invariant is unmapped.
|
|
93
|
+
|
|
94
|
+
9. **v1 framing.** Every rationale paragraph uses language like "the planned test asserts X" rather than "we verified X" or "we measured X". The Skill rejects any rationale that asserts coverage-measured evidence — that is v2 substrate territory.
|
|
95
|
+
|
|
96
|
+
10. **Status transitions.** When every coverage layer is `addressed` or `not-applicable` with justification, every required section is populated, every invariant is mapped, every applicable budget has an asserting test, and all three challenge prompts are answered, the subagent transitions to `status: passed`. When any layer is `partial`, the subagent can only transition to `concerns-acknowledged`, and only when `concerns-acknowledged-by` is non-null (a human handle the owner has explicitly provided) and the Open Concerns section enumerates each partial layer with a tech-debt id. Per TS-04, `passed` is impossible if any layer is `partial`.
|
|
97
|
+
|
|
98
|
+
11. **Tech-debt for deferred coverage.** When a coverage layer is being deferred rather than addressed, 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.
|
|
99
|
+
|
|
100
|
+
12. **Validate.** Run `{{TODO-SCRIPT: hstack/scripts/validate-spec.ts}}` — TS-01 (parent-change matches), TS-02 (challenge-prompts-answered == 3), TS-03 (tenant-isolation-tests non-empty when surfaces includes db/api/agent), TS-04 (status gating on partial layers), TS-05 (fixture-strategy-declared == true before passed), TS-06 (every invariant id is in `invariants-mapped`).
|
|
101
|
+
|
|
102
|
+
## Outputs
|
|
103
|
+
|
|
104
|
+
- `hstack/specs/changes/<change-id>/test-plan.md` at `status: passed` or `concerns-acknowledged`.
|
|
105
|
+
- Optional surfaced recommendation to file tech-debt for any deferred `partial` coverage layer.
|
|
106
|
+
|
|
107
|
+
## Auto-commit triggers
|
|
108
|
+
|
|
109
|
+
- Status transition to `in-progress` after the Test Pyramid section lands.
|
|
110
|
+
- Status transition to terminal (`passed` or `concerns-acknowledged`). Commit message: `test-plan(<change-id>): passed` or `concerns-acknowledged`.
|
|
111
|
+
- Edits to the `coverage-layers` map (because TS-04's terminal-gating depends on it).
|
|
112
|
+
- Edits to `tenant-isolation-tests` (because TS-03's gating depends on it).
|
|
113
|
+
- Edits to `concerns-acknowledged-by` (because it gates the partial-layer path).
|
|
114
|
+
|
|
115
|
+
## Telemetry sidecar
|
|
116
|
+
|
|
117
|
+
At the terminal-status auto-commit above (`test-plan(<change-id>): passed` or `concerns-acknowledged`), write `hstack/specs/changes/<change-id>/.telemetry/test-plan.json` in the same `git add && git commit` as the canonical write. The sidecar is derivative of git + frontmatter (see `hstack/templates/telemetry-sidecar.md`). Schema:
|
|
118
|
+
|
|
119
|
+
```json
|
|
120
|
+
{
|
|
121
|
+
"schema_version": 1,
|
|
122
|
+
"skill": "hstack-test-plan",
|
|
123
|
+
"change_id": "<change-id>",
|
|
124
|
+
"completed_at": "<ISO-8601, when terminal status reached>",
|
|
125
|
+
"status": "passed | concerns-acknowledged",
|
|
126
|
+
"coverage_layers": {<mirror of frontmatter coverage-layers map>},
|
|
127
|
+
"tenant_isolation_tests_count": <int, length of tenant-isolation-tests array>,
|
|
128
|
+
"tenant_isolation_required": <bool, true when surfaces includes db/api/agent>,
|
|
129
|
+
"performance_budgets_required": <bool>,
|
|
130
|
+
"performance_budgets_count": <int, rows in the Budgets table>,
|
|
131
|
+
"challenge_prompts_answered": <int, frontmatter field; must be 3 at terminal>,
|
|
132
|
+
"invariants_mapped_count": <int, length of invariants-mapped array>,
|
|
133
|
+
"invariants_declared_count": <int, count of bullets in change-spec Invariants>,
|
|
134
|
+
"edge_cases_count": <int, bullets in Edge Cases section>,
|
|
135
|
+
"test_files_named_count": <int, distinct test file paths referenced>,
|
|
136
|
+
"fixture_strategy_declared": <bool>,
|
|
137
|
+
"halt_reasons": [<kernel halt-sentinel enum values, if any>]
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Reason this sidecar matters: it makes the test-strategist's rubber-stamp signal cheap. A `passed` test-plan with `tenant_isolation_tests_count: 0` despite `tenant_isolation_required: true`, or `challenge_prompts_answered: 3` paired with zero invariants-mapped diff against declared, are the cases the telemetry layer's WS-2 and QO-1 metrics exist to surface. `.telemetry/` is git-ignored. If the sidecar write fails, log and continue; the canonical commit must still land.
|
|
142
|
+
|
|
143
|
+
## Idempotency contract
|
|
144
|
+
|
|
145
|
+
- Re-running on a terminal test-plan without spec changes: the subagent reads the existing artifact and produces a no-op aside from `updated` timestamps.
|
|
146
|
+
- Re-running after the change-spec's Invariants have been amended: the subagent re-verifies `invariants-mapped` covers every id and adds new entries where needed; halts if an amended invariant has no mappable test.
|
|
147
|
+
- Re-running mid-authoring after a halt: the subagent reads the partial file and resumes at the next un-confirmed section or un-answered challenge prompt.
|
|
148
|
+
|
|
149
|
+
## Stop conditions
|
|
150
|
+
|
|
151
|
+
Beyond the kernel's general stop conditions:
|
|
152
|
+
|
|
153
|
+
- Change-spec at `draft` rather than `ready-to-plan`. Halt.
|
|
154
|
+
- Change-spec carries `trivial: true`. Halt and inform — test-plan is not required.
|
|
155
|
+
- Change-spec `Invariants` empty or fewer than three bullets. Halt; the strategist cannot map tests to invariants that do not exist.
|
|
156
|
+
- `tech-stack.md`, `ci-cd.md`, or (when applicable) `data-architecture.md` at `needs-refresh` or absent. Halt.
|
|
157
|
+
- `surfaces` includes `db`/`api`/`agent` but the change-spec does not name a tenant-isolation invariant. Halt and ask the engineer to amend via `spec-author`.
|
|
158
|
+
- A performance budget is being declared but the consuming repo has no test pattern that can assert it. Halt; file tech-debt for the missing test infrastructure or drop the budget.
|
|
159
|
+
- A coverage layer would be marked `addressed` without concrete test file paths. The Skill rejects and the subagent bias-falls to `partial`.
|
|
160
|
+
- `concerns-acknowledged-by` would be written without the owner's explicit acknowledgement. Halt.
|
|
161
|
+
- The test-plan would name more than fifteen test files — halt and ask whether the change-spec should split per the kernel's multi-module rule.
|
|
162
|
+
|
|
163
|
+
## Failure modes
|
|
164
|
+
|
|
165
|
+
- **Module-spec missing or `needs-refresh`.** Halt; refresh via `hstack-module-spec` first.
|
|
166
|
+
- **Change-spec Invariants are present but generic ("no regressions").** Halt; the strategist cannot map tests to non-specific invariants. Ask the engineer to amend via `spec-author`.
|
|
167
|
+
- **Validator fails TS-02 (fewer than three challenge prompts answered).** Halt; the subagent re-runs the missing prompt.
|
|
168
|
+
- **Validator fails TS-03 (empty tenant-isolation-tests on a db/api/agent surface).** Halt; the subagent re-walks every new tenant-scoped surface and names a negative test.
|
|
169
|
+
- **Validator fails TS-06 (an invariant is unmapped).** Halt; the subagent either adds a test for the unmapped invariant, surfaces it in the (b) challenge prompt with a defended rationale, or escalates to amend the invariant via `spec-author`.
|
|
170
|
+
- **v1 framing slips in a rationale.** The Skill detects "verified by test execution" or "measured coverage" language and halts; the subagent re-words.
|
|
171
|
+
|
|
172
|
+
## Anti-patterns
|
|
173
|
+
|
|
174
|
+
- Never plan a behavior coverage strategy that depends primarily on e2e. The pyramid bias is load-bearing.
|
|
175
|
+
- Never write a performance budget without a paired asserting test. Budgets without tests are wishes.
|
|
176
|
+
- Never mark a coverage layer `addressed` without concrete test file paths.
|
|
177
|
+
- Never claim coverage-measured or mutation-tested evidence in v1. The honesty clause is load-bearing.
|
|
178
|
+
- Never skip or paraphrase a challenge prompt. The three are verbatim and mandatory.
|
|
179
|
+
- Never produce a test-plan whose `tenant-isolation-tests` array is empty when surfaces includes db/api/agent.
|
|
180
|
+
- Never fabricate test file paths, factory module names, or surface identifiers.
|
|
181
|
+
- Never write `concerns-acknowledged-by` without the owner's confirmed acknowledgement.
|
|
182
|
+
- Never file tech-debt from this Skill; surface the recommendation for the engineer to invoke `hstack-tech-debt-new`.
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hstack-ui-brief
|
|
3
|
+
description: |
|
|
4
|
+
Use this skill when a change-spec at `ready-to-plan` or later has `ui` in its surfaces and needs `ui-brief.md` drafted before the cofounder produces Figma frames and before `hstack-change-plan` runs. The Skill orchestrates the `ui-ux-briefer` subagent against the configured design system docs. Examples:
|
|
5
|
+
|
|
6
|
+
<example>
|
|
7
|
+
Context: The billing-overage change-spec is at ready-to-plan with surfaces: [ui, db]; the cofounder is about to start Figma work and needs the brief first.
|
|
8
|
+
user: "/hstack:ui-brief 2026-05-billing-overage-warning"
|
|
9
|
+
assistant: "I'll invoke ui-ux-briefer with the design system docs, the change-spec, the linked story, and the growth-marketer persona. Reused components first; any new component carries a justification per UI-01."
|
|
10
|
+
<commentary>
|
|
11
|
+
The Skill is the only entry point for ui-brief production. It enforces the reuse-bias by relying on the subagent's challenge prompt and the validator's UI-01 rule. Skipping the Skill and letting the cofounder freelance in Figma erodes the design system.
|
|
12
|
+
</commentary>
|
|
13
|
+
</example>
|
|
14
|
+
|
|
15
|
+
<example>
|
|
16
|
+
Context: A change-spec without `ui` in surfaces is mistakenly passed to this Skill.
|
|
17
|
+
user: "/hstack:ui-brief 2026-05-internal-cron-rebuild"
|
|
18
|
+
assistant: "I'll halt — surfaces on that change-spec is [api, infra], no ui. The ui-brief is conditional and is not produced for changes without ui surfaces."
|
|
19
|
+
<commentary>
|
|
20
|
+
The surface-conditional gate is hard. Producing a ui-brief for a non-ui change inflates the artifact count and slows the merge without value.
|
|
21
|
+
</commentary>
|
|
22
|
+
</example>
|
|
23
|
+
tools:
|
|
24
|
+
- Read
|
|
25
|
+
- Write
|
|
26
|
+
- Edit
|
|
27
|
+
- Grep
|
|
28
|
+
- Glob
|
|
29
|
+
- Bash
|
|
30
|
+
- Task
|
|
31
|
+
- "{{TODO-MCP: Figma MCP — optional; enables richer reuse hints when present, falls back to URL-only references when absent}}"
|
|
32
|
+
- "{{TODO-SCRIPT: hstack/scripts/validate-spec.ts — validates ui-brief frontmatter and UI-01/UI-02}}"
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Purpose
|
|
36
|
+
|
|
37
|
+
`hstack-ui-brief` produces `ui-brief.md` for a change touching the `ui` surface by orchestrating the `ui-ux-briefer` subagent. It is the upstream artifact for the cofounder's Figma work and a co-input for the implementer alongside `figma-handoff.md`. It is conditional on `surfaces` including `ui` and halts otherwise.
|
|
38
|
+
|
|
39
|
+
## When to invoke
|
|
40
|
+
|
|
41
|
+
Invoke after the change-spec reaches `status: ready-to-plan` and before `hstack-change-plan` runs, when the change-spec's `surfaces` includes `ui`. Re-invoke when the spec changes shape in ways the existing brief no longer reflects.
|
|
42
|
+
|
|
43
|
+
## Inputs
|
|
44
|
+
|
|
45
|
+
- `<change-id>` (required, positional): the change-spec id.
|
|
46
|
+
|
|
47
|
+
## Preconditions
|
|
48
|
+
|
|
49
|
+
Before any work:
|
|
50
|
+
|
|
51
|
+
- Verify the change-spec exists at `hstack/specs/changes/<id>/spec.md` and is at `status: ready-to-plan` or later.
|
|
52
|
+
- Verify `surfaces` includes `ui`. If not, halt with the surface-conditional message.
|
|
53
|
+
- Verify the configured design-system resources are reachable per their declared source in `hstack/config.yaml` (`design-system.components.source`, `tokens.source`, `brand-guidelines.source`). For each resource the brief will need: `in-repo` paths must resolve; `figma-mcp` / `notion-mcp` sources require the corresponding MCP to be wired and reachable (UI-surface changes are high-stakes — graceful degradation is not safe here); `submodule` / `npm` / `external-other` must fetch. A resource at `source: none` is treated as "not yet captured" — halt if the brief genuinely needs it, otherwise proceed against the resources that ARE configured.
|
|
54
|
+
- Verify the `design-system-version` declared in `hstack/config.yaml` is current and is what the brief will reference. Halt on drift.
|
|
55
|
+
- Read the change-spec's `user-stories` array; verify each story is reachable in the configured store and read it. Halt if any linked story or its persona is missing.
|
|
56
|
+
|
|
57
|
+
## Orchestration steps
|
|
58
|
+
|
|
59
|
+
1. **Invoke `ui-ux-briefer`.** Use the Task tool with `subagent_type: ui-ux-briefer` and context = [kernel, `hstack/templates/ui-brief.md`, change-spec, linked stories, referenced personas, design-system components / tokens / brand-guidelines at the configured paths]. The subagent walks the six sections — Goal, Layouts and States, Reused Components, New Components, Copy, Accessibility Notes — with confirmation gates.
|
|
60
|
+
|
|
61
|
+
2. **Exercise the new-component challenge.** Per the `ui-ux-briefer` contract, every entry in `new-components` carries a justification paragraph in section 4, elicited via the challenge "Why is this new and not a reuse?" The Skill does not bypass this.
|
|
62
|
+
|
|
63
|
+
3. **Token-gap surfacing.** When the brief requires a value not in the design system's current token set, `ui-ux-briefer` names the gap and notes that a tech-debt item should be filed via `hstack-tech-debt-new` before implementation begins. The Skill does not file the tech-debt itself; it surfaces the recommendation and waits for the engineer to act.
|
|
64
|
+
|
|
65
|
+
4. **Validate.** Run `{{TODO-SCRIPT: hstack/scripts/validate-spec.ts}}` against the in-progress brief — UI-01 (every `new-components` entry has a section-4 justification paragraph), UI-02 (`design-system-version` matches config).
|
|
66
|
+
|
|
67
|
+
5. **Transition.** When every section is confirmed and the validator passes, `ui-ux-briefer` advances status from `draft` to `drafted`. Auto-commit fires.
|
|
68
|
+
|
|
69
|
+
## Outputs
|
|
70
|
+
|
|
71
|
+
- `hstack/specs/changes/<change-id>/ui-brief.md` at `status: drafted`.
|
|
72
|
+
- Optional surfaced recommendation to author a tech-debt item for any design-token gap.
|
|
73
|
+
|
|
74
|
+
## Auto-commit triggers
|
|
75
|
+
|
|
76
|
+
- Status transition to `draft` after the first section confirms.
|
|
77
|
+
- Status transition to `drafted` at the end. Commit message: `ui-brief(<change-id>): drafted`.
|
|
78
|
+
- Edits to `new-components` array (because UI-01 enforcement depends on it).
|
|
79
|
+
|
|
80
|
+
## Idempotency contract
|
|
81
|
+
|
|
82
|
+
- Re-running on an existing `drafted` brief without changes: the subagent reads the existing instance as the proposal layer; identical re-confirmation is a no-op.
|
|
83
|
+
- Re-running after a halt mid-brief: `ui-ux-briefer` reads the partial file and resumes at the next un-confirmed section.
|
|
84
|
+
- Re-running after the change-spec's `surfaces` has been amended to drop `ui`: halt with the surface-conditional message; the existing brief is archived only on explicit engineer action.
|
|
85
|
+
|
|
86
|
+
## Stop conditions
|
|
87
|
+
|
|
88
|
+
Beyond the kernel's general stop conditions:
|
|
89
|
+
|
|
90
|
+
- The change-spec's `surfaces` does not include `ui`.
|
|
91
|
+
- The configured design system docs are unreachable.
|
|
92
|
+
- `design-system-version` in config has drifted from what the brief would target.
|
|
93
|
+
- A new component's justification cannot be articulated under the challenge prompt — the signal that an existing component should be reused.
|
|
94
|
+
- The brief requires a new design-system token and no tech-debt item exists or is filed concurrently.
|
|
95
|
+
|
|
96
|
+
## Failure modes
|
|
97
|
+
|
|
98
|
+
- **Linked story unreachable.** Halt; reconcile via `hstack-story-draft` or fix the change-spec's `user-stories` array.
|
|
99
|
+
- **Figma MCP absent.** Degraded mode — `ui-ux-briefer` produces the brief without frame-content hints, flags in the conversation, continues.
|
|
100
|
+
- **Validator fails UI-01 because a `new-components` entry has no body justification.** Halt; the subagent re-runs the challenge prompt for that component.
|
|
101
|
+
|
|
102
|
+
## Anti-patterns
|
|
103
|
+
|
|
104
|
+
- Never invent a new component when composition of existing primitives would work. The challenge prompt exists to force this discipline.
|
|
105
|
+
- Never paste design-token values inline. Use named tokens; gaps are flagged for tech-debt.
|
|
106
|
+
- Never produce a ui-brief for a non-ui change. The conditional is hard.
|
|
107
|
+
- Never write Figma frame URLs in the ui-brief — that is `figma-handoff.md`'s domain (the cofounder's deliverable).
|
|
108
|
+
- Never silently brief against a stale design-system version.
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hstack-verify
|
|
3
|
+
description: |
|
|
4
|
+
Use this skill after the implementer has completed every phase of the plan and the engineer wants `verification.md` produced from test, lint, and typecheck outcomes. The Skill orchestrates the `verifier` subagent — a mechanical role that runs the canonical commands from `ci-cd.md`, captures the output, and compares observed outcomes against each phase's Verifier Expectations. Examples:
|
|
5
|
+
|
|
6
|
+
<example>
|
|
7
|
+
Context: The implementer just finished phase-5 of the billing-overage plan and the engineer wants verification before adversarial review.
|
|
8
|
+
user: "/hstack:verify 2026-05-billing-overage-warning"
|
|
9
|
+
assistant: "I'll invoke verifier. It will run the canonical test/lint/typecheck commands from ci-cd.md, capture stdout/stderr to a pointer file, and write phase-coverage mirroring plan.steps-completed."
|
|
10
|
+
<commentary>
|
|
11
|
+
The verifier is mechanical and conservative. Any `failed` test result blocks status `passed` (V-02); discrepancies between predicted and observed test behavior land in section 4 with recommended actions.
|
|
12
|
+
</commentary>
|
|
13
|
+
</example>
|
|
14
|
+
|
|
15
|
+
<example>
|
|
16
|
+
Context: The test suite passed locally but the verifier observes that a Playwright test the plan promised actually skipped.
|
|
17
|
+
user: "/hstack:verify 2026-06-knowledge-citations"
|
|
18
|
+
assistant: "I'll invoke verifier. If a phase's Verifier Expectations name a test that skipped or is absent, the Discrepancies section captures it and the Skill refuses to mark status passed."
|
|
19
|
+
<commentary>
|
|
20
|
+
Discrepancies between predicted and observed behavior are exactly what section 4 exists to capture. Marking `passed` over a discrepancy would defeat the purpose of the gate.
|
|
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/run-gates.sh — runs the consuming repo's test/lint/typecheck suite and captures output}}"
|
|
32
|
+
- "{{TODO-SCRIPT: hstack/scripts/validate-spec.ts — validates verification.md frontmatter and V-01/V-02}}"
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Purpose
|
|
36
|
+
|
|
37
|
+
`hstack-verify` produces `verification.md` for a change by orchestrating the `verifier` subagent. The verifier is the mechanical reader of test, lint, and typecheck output. It does not score security or data; it does not produce findings; it does not interpret failing tests as flaky. It compares observed outcomes against each phase's Verifier Expectations as set by the planner.
|
|
38
|
+
|
|
39
|
+
## When to invoke
|
|
40
|
+
|
|
41
|
+
Invoke after `plan.steps-completed` covers every phase id in the plan body (the implementer is done with every phase). The Skill halts when `steps-completed` is incomplete — a partial verification run is meaningless.
|
|
42
|
+
|
|
43
|
+
## Inputs
|
|
44
|
+
|
|
45
|
+
- `<change-id>` (required, positional): the change-spec id.
|
|
46
|
+
|
|
47
|
+
## Preconditions
|
|
48
|
+
|
|
49
|
+
Before any work:
|
|
50
|
+
|
|
51
|
+
- Verify `hstack/specs/changes/<change-id>/spec.md`, `plan.md`, and `test-plan.md` all exist.
|
|
52
|
+
- Verify `plan.steps-completed` covers every phase id in the plan body. If not, halt — implementation is not complete.
|
|
53
|
+
- Verify `test-plan.md` is at `passed` or `concerns-acknowledged`. The verifier needs the test-plan to check observed tests against promised coverage.
|
|
54
|
+
- Verify `hstack/context/ci-cd.md` exists at `status: current` and names the canonical test, lint, and typecheck commands the consuming repo expects.
|
|
55
|
+
- Verify the consuming repo's local environment can run the canonical commands (dependencies installed, env vars present). If a command fails to execute due to environment misconfiguration, halt before invoking the subagent.
|
|
56
|
+
|
|
57
|
+
## Orchestration steps
|
|
58
|
+
|
|
59
|
+
1. **Invoke `verifier`.** Use the Task tool with `subagent_type: verifier` and context = [kernel, `hstack/templates/verification.md`, change-spec, plan, test-plan, ci-cd]. The subagent runs the canonical commands declared in `ci-cd.md` (or orchestrates `{{TODO-SCRIPT: hstack/scripts/run-gates.sh}}`).
|
|
60
|
+
|
|
61
|
+
2. **Capture output.** The subagent writes captured stdout/stderr to a pointer file at `hstack/specs/changes/<change-id>/test-output.txt` and references it from `verification.artifacts.test-output`.
|
|
62
|
+
|
|
63
|
+
3. **Phase coverage mapping.** For each phase in `plan.steps-completed`, the subagent emits an entry in `phase-coverage` with a PASS / FAIL value computed from whether the phase's Verifier Expectations are met. Per V-01, `phase-coverage` keys must equal `plan.steps-completed`.
|
|
64
|
+
|
|
65
|
+
4. **Test-results map.** The subagent writes the top-level `test-results` map covering `unit`, `integration`, `e2e`, `lint`, `typecheck`. Per V-02, any `failed` value blocks `status: passed`.
|
|
66
|
+
|
|
67
|
+
5. **Test-plan coverage check.** The subagent walks the test-plan's Edge Cases bullets, Tenant Isolation Tests array, and Performance Budgets table, and confirms each observed in the test run. `test-plan-coverage` frontmatter map captures the three subsections. Per V-03, any tenant-isolation test absent or skipped blocks `status: passed` and is escalated to adversarial-review via Discrepancies. Per V-04, any performance-budget assertion that did not execute or that observed values outside the declared budget blocks `status: passed`.
|
|
68
|
+
|
|
69
|
+
6. **Discrepancies.** Anything the subagent observed that the plan or test-plan did not predict — a test that ran but no artifact promised, a test the plan or test-plan promised that did not exist, flakiness, environment-dependent behavior — lands in the Discrepancies section with a recommended action (file an issue, escalate to adversarial-review, or note as benign with reason).
|
|
70
|
+
|
|
71
|
+
7. **Status transition.** When every `phase-coverage` entry is PASS, every `test-results` entry is `pass`, every `test-plan-coverage` value is `all-observed` / `all-within-budget` / `not-applicable`, the subagent advances status to `passed`. When any test result is `failed`, when a tenant-isolation test is missing, or when a performance-budget regressed or did not execute, status moves to `ran` (not `passed`) and the Skill halts.
|
|
72
|
+
|
|
73
|
+
8. **Change-spec advance (mechanical, only on `passed`, Skill-orchestrator write per ADR-0002).** When and only when the subagent returned with `verification.md` at `status: passed`, read `hstack/specs/changes/<change-id>/spec.md` and inspect its `status` frontmatter. If `status: ready-for-implementation`, print a proposed-diff preview of the change-spec edit (`status: ready-for-implementation → ready-for-review`; `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-for-review`. This is a separate commit from the `verification(<change-id>): passed` commit — one commit per status transition, matching the finalize precedent. If the change-spec is already at `ready-for-review` or any downstream status, this step is a no-op (idempotent on re-runs). When verification status is `ran` or `failed`, this step does not run — the change-spec remains at `ready-for-implementation` until a subsequent re-run lands `passed`. Do NOT invoke `spec-author` for this write; per the kernel's Mechanical operations section, the value to write is fully determined by the verification postcondition and the change-spec's current status, so the Skill writes directly.
|
|
74
|
+
|
|
75
|
+
9. **Validate.** Run `{{TODO-SCRIPT: hstack/scripts/validate-spec.ts}}` — V-01, V-02, V-03, V-04.
|
|
76
|
+
|
|
77
|
+
## Outputs
|
|
78
|
+
|
|
79
|
+
- `hstack/specs/changes/<change-id>/verification.md` at `status: passed`, `ran`, or `failed`.
|
|
80
|
+
- `hstack/specs/changes/<change-id>/test-output.txt` capturing the canonical commands' output.
|
|
81
|
+
- When `verification.md` lands at `passed` and the change-spec was at `ready-for-implementation`: an edit to `hstack/specs/changes/<change-id>/spec.md` advancing `status: ready-for-implementation → ready-for-review` and bumping `updated:` (per ADR-0002).
|
|
82
|
+
|
|
83
|
+
## Auto-commit triggers
|
|
84
|
+
|
|
85
|
+
- Status transition to `ran` after the commands execute.
|
|
86
|
+
- Status transition to `passed` (or `failed`). Commit message: `verification(<change-id>): passed` / `failed`.
|
|
87
|
+
- **Change-spec status transition `ready-for-implementation → ready-for-review`** (per ADR-0002). Lands as a separate commit after the `verification(<change-id>): passed` commit. Commit message: `change-spec(<change-id>): ready-for-review`. Skipped when verification status is not `passed`, or when the change-spec was already at `ready-for-review` or any downstream status.
|
|
88
|
+
|
|
89
|
+
## Telemetry sidecar
|
|
90
|
+
|
|
91
|
+
At the change-spec advance commit (only when verification status is `passed`), write `hstack/specs/changes/<change-id>/.telemetry/verify.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:
|
|
92
|
+
|
|
93
|
+
```json
|
|
94
|
+
{
|
|
95
|
+
"schema_version": 1,
|
|
96
|
+
"skill": "hstack-verify",
|
|
97
|
+
"change_id": "<change-id>",
|
|
98
|
+
"ran_at": "<ISO-8601, when canonical commands started>",
|
|
99
|
+
"test_suite_runtime_s": <float seconds, wall clock across canonical commands>,
|
|
100
|
+
"phase_coverage": {<mirror of verification.md frontmatter>},
|
|
101
|
+
"test_plan_coverage": {<mirror of verification.md frontmatter>},
|
|
102
|
+
"discrepancies_count": <int, bullet count under verification.md § Discrepancies>,
|
|
103
|
+
"status": "passed"
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
When verification ends at `ran` or `failed`, the sidecar still lands with `status` reflecting the canonical artifact status; the change-spec advance commit does not happen, so the sidecar piggybacks on the `verification(<change-id>): ran` (or `failed`) commit instead. `.telemetry/` is git-ignored. If the sidecar write fails, log and continue; the canonical commit must still land.
|
|
108
|
+
|
|
109
|
+
## Idempotency contract
|
|
110
|
+
|
|
111
|
+
- Re-running on a `passed` verification: the subagent re-runs the canonical commands; identical outcomes produce a no-op aside from `updated` timestamps; different outcomes (newly failing test on a flake) update the artifact accordingly.
|
|
112
|
+
- Re-running after a `failed`: same — the subagent re-runs and updates.
|
|
113
|
+
- The verifier does not write a PASS to avoid re-running. The canonical commands run on every invocation.
|
|
114
|
+
- The change-spec advance step (step 8) is idempotent: a re-run against a change-spec already at `ready-for-review` (or any downstream status) produces a no-op for that step. The Skill does not re-advance a change-spec past `ready-for-review` and does not regress one if a later phase has moved it forward.
|
|
115
|
+
|
|
116
|
+
## Stop conditions
|
|
117
|
+
|
|
118
|
+
Beyond the kernel's general stop conditions:
|
|
119
|
+
|
|
120
|
+
- `plan.steps-completed` is incomplete relative to the plan body's phase ids.
|
|
121
|
+
- A canonical command in `ci-cd.md` is missing or cannot execute (missing dependency, missing env var).
|
|
122
|
+
- A phase's Verifier Expectations cannot be evaluated because the relevant test file is missing.
|
|
123
|
+
- A test failure blocks `status: passed`. The Skill halts at `status: ran` (or `failed`) until the implementer fixes the failing test via a new `hstack-implement` invocation.
|
|
124
|
+
|
|
125
|
+
## Failure modes
|
|
126
|
+
|
|
127
|
+
- **Environment misconfiguration prevents a canonical command from running.** Halt before invoking the subagent; surface the issue and the resolution.
|
|
128
|
+
- **A test file the plan promised does not exist.** Halt; this is a discrepancy between plan and reality — surface as a Discrepancy and refuse `status: passed`.
|
|
129
|
+
- **The subagent's test runner produces a runtime error (not a test failure).** Surface in Discrepancies; do not record as a PASS or FAIL on the affected suite.
|
|
130
|
+
|
|
131
|
+
## Anti-patterns
|
|
132
|
+
|
|
133
|
+
- Never invent a PASS. If tests are not green, status is `ran` or `failed`, not `passed`.
|
|
134
|
+
- Never skip a canonical command. The consuming repo's commands in `ci-cd.md` are mandatory.
|
|
135
|
+
- Never silently drop a discrepancy. Even benign discrepancies get a one-line note.
|
|
136
|
+
- Never score security or data. Stay in the mechanical-verification lane.
|
|
137
|
+
- Never modify code or tests to make verification pass. That requires a new `hstack-implement` invocation.
|
|
138
|
+
- Never claim phase coverage for phases not in `plan.steps-completed`.
|
|
139
|
+
- Never run any command not declared in `ci-cd.md`. Extending the canonical command set requires `hstack-configure --interview ci-cd`.
|