hstack 0.16.0 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/README.md +76 -163
  3. package/VERSION +1 -1
  4. package/dist/commands/doctor.js +18 -8
  5. package/dist/commands/doctor.js.map +1 -1
  6. package/dist/commands/init.js +7 -3
  7. package/dist/commands/init.js.map +1 -1
  8. package/dist/commands/update.js +9 -2
  9. package/dist/commands/update.js.map +1 -1
  10. package/dist/lib/descriptions.js +10 -17
  11. package/dist/lib/descriptions.js.map +1 -1
  12. package/dist/lib/wire.js +166 -138
  13. package/dist/lib/wire.js.map +1 -1
  14. package/dist/manifest.js +41 -29
  15. package/dist/manifest.js.map +1 -1
  16. package/package.json +3 -4
  17. package/template/.claude/agents/adversarial-reviewer.md +44 -50
  18. package/template/.claude/agents/app-architect.md +44 -96
  19. package/template/.claude/agents/data-architect.md +46 -89
  20. package/template/.claude/agents/test-strategist.md +39 -68
  21. package/template/.claude/skills/hstack-adr-new/SKILL.md +23 -73
  22. package/template/.claude/skills/hstack-adversarial-review/SKILL.md +46 -152
  23. package/template/.claude/skills/hstack-adversarial-review/references/finding-categories.md +89 -103
  24. package/template/.claude/skills/hstack-app-architecture/SKILL.md +43 -68
  25. package/template/.claude/skills/hstack-commit/SKILL.md +27 -68
  26. package/template/.claude/skills/hstack-data-architecture/SKILL.md +34 -56
  27. package/template/.claude/skills/hstack-promote/SKILL.md +55 -0
  28. package/template/.claude/skills/hstack-story/SKILL.md +58 -0
  29. package/template/.claude/skills/hstack-test-audit/SKILL.md +64 -0
  30. package/template/.claude/skills/hstack-wrap/SKILL.md +50 -0
  31. package/template/.claude/skills/hstack-wrap/references/pr-description.md +45 -0
  32. package/template/KERNEL.md +75 -318
  33. package/template/templates/adr.md +2 -18
  34. package/template/templates/app-architecture.md +38 -50
  35. package/template/templates/code-standards.md +107 -0
  36. package/template/templates/data-architecture.md +38 -89
  37. package/template/templates/eslint-clean-code.mjs +322 -0
  38. package/template/templates/infrastructure.md +54 -148
  39. package/template/templates/roadmap.md +6 -12
  40. package/template/templates/story.md +7 -13
  41. package/template/templates/tech-debt.md +2 -37
  42. package/template/templates/tech-stack.md +2 -12
  43. package/template/.claude/agents/data-specialist.md +0 -81
  44. package/template/.claude/agents/implementer.md +0 -97
  45. package/template/.claude/agents/kernel-fit-analyst.md +0 -129
  46. package/template/.claude/agents/planner.md +0 -75
  47. package/template/.claude/agents/product-discovery.md +0 -129
  48. package/template/.claude/agents/product-manager.md +0 -76
  49. package/template/.claude/agents/researcher.md +0 -87
  50. package/template/.claude/agents/security-reviewer.md +0 -88
  51. package/template/.claude/agents/spec-author.md +0 -89
  52. package/template/.claude/agents/stack-architect.md +0 -108
  53. package/template/.claude/agents/ui-ux-briefer.md +0 -75
  54. package/template/.claude/agents/verifier.md +0 -81
  55. package/template/.claude/skills/hstack-branch/SKILL.md +0 -76
  56. package/template/.claude/skills/hstack-brownfield-init/SKILL.md +0 -131
  57. package/template/.claude/skills/hstack-change-new/SKILL.md +0 -84
  58. package/template/.claude/skills/hstack-change-plan/SKILL.md +0 -108
  59. package/template/.claude/skills/hstack-configure/SKILL.md +0 -99
  60. package/template/.claude/skills/hstack-coord/SKILL.md +0 -95
  61. package/template/.claude/skills/hstack-data-review/SKILL.md +0 -93
  62. package/template/.claude/skills/hstack-finalize/SKILL.md +0 -140
  63. package/template/.claude/skills/hstack-flag/SKILL.md +0 -99
  64. package/template/.claude/skills/hstack-greenfield-init/SKILL.md +0 -148
  65. package/template/.claude/skills/hstack-help/SKILL.md +0 -153
  66. package/template/.claude/skills/hstack-implement/SKILL.md +0 -155
  67. package/template/.claude/skills/hstack-kernel-fit-promote/SKILL.md +0 -125
  68. package/template/.claude/skills/hstack-kernel-fit-scan/SKILL.md +0 -142
  69. package/template/.claude/skills/hstack-kernel-fit-scan/references/slack-setup.md +0 -42
  70. package/template/.claude/skills/hstack-kernel-fit-triage/SKILL.md +0 -121
  71. package/template/.claude/skills/hstack-module-spec/SKILL.md +0 -78
  72. package/template/.claude/skills/hstack-product-discovery/SKILL.md +0 -75
  73. package/template/.claude/skills/hstack-research/SKILL.md +0 -115
  74. package/template/.claude/skills/hstack-scaffold/SKILL.md +0 -113
  75. package/template/.claude/skills/hstack-security-review/SKILL.md +0 -95
  76. package/template/.claude/skills/hstack-ship/SKILL.md +0 -119
  77. package/template/.claude/skills/hstack-stack-decide/SKILL.md +0 -81
  78. package/template/.claude/skills/hstack-story-draft/SKILL.md +0 -92
  79. package/template/.claude/skills/hstack-tech-debt-new/SKILL.md +0 -95
  80. package/template/.claude/skills/hstack-tech-debt-resolve/SKILL.md +0 -123
  81. package/template/.claude/skills/hstack-tech-debt-stale/SKILL.md +0 -86
  82. package/template/.claude/skills/hstack-tech-debt-wontfix/SKILL.md +0 -77
  83. package/template/.claude/skills/hstack-telemetry/SKILL.md +0 -73
  84. package/template/.claude/skills/hstack-test-plan/SKILL.md +0 -159
  85. package/template/.claude/skills/hstack-ui-brief/SKILL.md +0 -81
  86. package/template/.claude/skills/hstack-verify/SKILL.md +0 -128
  87. package/template/scripts/compute-merge-readiness.mjs +0 -780
  88. package/template/scripts/coord/coord_scan.py +0 -681
  89. package/template/scripts/run-gates.sh +0 -388
  90. package/template/scripts/telemetry/__init__.py +0 -6
  91. package/template/scripts/telemetry/insights/__init__.py +0 -0
  92. package/template/scripts/telemetry/insights/contract_drift.py +0 -137
  93. package/template/scripts/telemetry/insights/kernel_fit.py +0 -438
  94. package/template/scripts/telemetry/insights/overengineering.py +0 -115
  95. package/template/scripts/telemetry/insights/quality_outcomes.py +0 -131
  96. package/template/scripts/telemetry/insights/token_economics.py +0 -302
  97. package/template/scripts/telemetry/insights/workflow_shape.py +0 -198
  98. package/template/scripts/telemetry/parsers/__init__.py +0 -0
  99. package/template/scripts/telemetry/parsers/bodies.py +0 -87
  100. package/template/scripts/telemetry/parsers/commits.py +0 -219
  101. package/template/scripts/telemetry/parsers/frontmatter.py +0 -322
  102. package/template/scripts/telemetry/parsers/sidecars.py +0 -61
  103. package/template/scripts/telemetry/parsers/transcripts.py +0 -294
  104. package/template/scripts/telemetry/render.py +0 -460
  105. package/template/scripts/telemetry/report.py +0 -150
  106. package/template/scripts/telemetry/run_kernel_fit.py +0 -95
  107. package/template/scripts/telemetry/session_id.py +0 -139
  108. package/template/scripts/validate-spec.mjs +0 -3303
  109. package/template/templates/adversarial-review.md +0 -54
  110. package/template/templates/bootstrap.md +0 -105
  111. package/template/templates/change-spec.md +0 -82
  112. package/template/templates/ci-cd.md +0 -41
  113. package/template/templates/coord-message.md +0 -56
  114. package/template/templates/data-review.md +0 -54
  115. package/template/templates/discovery/brainstorm.md +0 -69
  116. package/template/templates/discovery/forcing-questions.md +0 -76
  117. package/template/templates/discovery/project-brief.md +0 -53
  118. package/template/templates/figma-handoff.md +0 -38
  119. package/template/templates/glossary.md +0 -20
  120. package/template/templates/hardening-checklist.md +0 -73
  121. package/template/templates/incident-runbook.md +0 -57
  122. package/template/templates/kernel-fit-finding.md +0 -63
  123. package/template/templates/kernel-fit-flag.md +0 -52
  124. package/template/templates/module-spec.md +0 -49
  125. package/template/templates/persona.md +0 -38
  126. package/template/templates/plan.md +0 -53
  127. package/template/templates/product-brief.md +0 -56
  128. package/template/templates/security-review.md +0 -63
  129. package/template/templates/telemetry-sidecar.md +0 -227
  130. package/template/templates/test-plan.md +0 -119
  131. package/template/templates/threat-model.md +0 -54
  132. package/template/templates/ui-brief.md +0 -49
  133. package/template/templates/verification.md +0 -63
  134. package/template/templates/vision.md +0 -34
@@ -1,227 +0,0 @@
1
- # Telemetry sidecar — schema and discipline
2
-
3
- This document describes the JSON sidecar files five hstack Skills emit alongside their canonical artifact writes, to make per-change telemetry attribution cheap. Sidecars are **derivative** of git + frontmatter + transcripts — re-runnable from source, never authoritative. The kernel's "no parallel tracker" rule is preserved by this derivative property.
4
-
5
- This file is the canonical schema and the only place the field rules are stated. The five emitting Skills reference it: each carries its own JSON schema block (its Skill-specific payload) and the executable step that opens the phase window, and points here for everything else. Per ADR-0012 they do not restate the rules below.
6
-
7
- ## Where sidecars live
8
-
9
- ```
10
- hstack/specs/changes/<change-id>/.telemetry/
11
- test-plan.json # one per test-plan terminal status
12
- implement-<phase-id>.json # one per implement phase
13
- verify.json # one per verify pass
14
- adversarial-review.json # one per adversarial-review terminal status
15
- finalize.json # one per ship
16
- ```
17
-
18
- The `.telemetry/` directory is **git-ignored** at the consuming-repo level. Sidecars are transient; the canonical truth lives in the artifact frontmatter and git history.
19
-
20
- ## When sidecars are written
21
-
22
- | Skill | Trigger | File |
23
- | --- | --- | --- |
24
- | `hstack-test-plan` | At the test-plan terminal-status commit (`passed` or `concerns-acknowledged`) | `test-plan.json` |
25
- | `hstack-implement` | At each phase-completion auto-commit (the same `git add && git commit` that lands `plan.steps-completed`) | `implement-<phase-id>.json` |
26
- | `hstack-verify` | At the change-spec advance commit when `verification.md` lands at `status: passed` (per ADR-0002); on `ran`/`failed`, piggybacks on the verification status commit | `verify.json` |
27
- | `hstack-adversarial-review` | At the change-spec advance commit when `adversarial-review.md` lands at `findings-resolved` (per ADR-0002 follow-up); on `findings-open`/`in-progress`, piggybacks on the transition commit | `adversarial-review.json` |
28
- | `hstack-finalize` | At the change-spec advance commit when status moves `ready-to-ship → shipped` | `finalize.json` |
29
-
30
- The other 22 Skills do **not** emit sidecars in v1. Their data is reconstructible from git + frontmatter + transcripts; the five emissions above target the highest-signal events across the change lifecycle: test discipline up front (`test-plan`), per-phase scope-locked execution (`implement`), promised-vs-observed (`verify`), gate-firing critique (`adversarial-review`), lifecycle close (`finalize`).
31
-
32
- ## The phase window — every sidecar, every Skill (schema_version 2)
33
-
34
- Every sidecar carries three fields on top of its Skill-specific payload. They exist so the telemetry parser can answer "what did this phase cost?" — see ADR-0009.
35
-
36
- ```json
37
- {
38
- "session_id": "062b8fe8-649f-4d73-b4fb-b0a28a800552",
39
- "phase_opened_at": "2026-08-15T09:12:44Z",
40
- "phase_closed_at": "2026-08-15T11:03:07Z"
41
- }
42
- ```
43
-
44
- Field rules — one statement, applying identically to all five Skills:
45
-
46
- - `session_id` — the active Claude Code session, resolved by `hstack/scripts/telemetry/session_id.py` (the most recently modified `*.jsonl` under `~/.claude/projects/<encoded-cwd>/`). One shared resolver, not a per-Skill heuristic. Unresolvable → `null`.
47
- - `phase_opened_at` — stamped when the Skill's preconditions pass, **before any subagent invocation**. Same script call as `session_id`, so both come from one read. The script is read-only, takes milliseconds, and never halts; if it fails or reports `"session_id": null`, the Skill holds `null` for both and continues.
48
- - `phase_closed_at` — stamped at the Skill's terminal state, in the same write that lands the sidecar.
49
- - All three are **best-effort by contract**. Any of them `null`, unparseable, or inverted makes the phase *unmeasured*: `parsers/transcripts.py:phase_usage` returns `null`, and TE-4/TE-5 print `unmeasured`. **Never zero** — a phase whose window cannot be honoured still spent tokens, and a zero would fold it into the averages as if it were free.
50
- - A sidecar write failure never blocks the canonical commit, and the window is never a halt condition. Measurement never gates the workflow.
51
- - ISO-8601, UTC, second precision, `Z` suffix — the format `session_id.py` emits.
52
-
53
- Sidecars at `schema_version: 1` (written before ADR-0009) carry no window and read as unmeasured. Nothing migrates them: the transcript timestamps they would need were never recorded.
54
-
55
- The window measures *what the session spent while the phase was open* — not what the phase required. A detour taken between `phase_opened_at` and `phase_closed_at` is counted, and subagent spend lands in its host's window (`isSidechain: false` throughout the transcripts). Narrow, not exact.
56
-
57
- ## Schema — `test-plan.json`
58
-
59
- ```json
60
- {
61
- "schema_version": 2,
62
- "skill": "hstack-test-plan",
63
- "session_id": "<session id, or null>",
64
- "phase_opened_at": "<ISO-8601 at precondition pass, or null>",
65
- "phase_closed_at": "<ISO-8601 at terminal state, or null>",
66
- "change_id": "2026-05-billing-overage-warning",
67
- "completed_at": "2026-05-22T11:14:00Z",
68
- "status": "passed",
69
- "coverage_layers": {"unit": "addressed", "integration": "addressed", "e2e": "not-applicable"},
70
- "tenant_isolation_tests_count": 0,
71
- "tenant_isolation_required": false,
72
- "performance_budgets_required": false,
73
- "performance_budgets_count": 0,
74
- "challenge_prompts_answered": 3,
75
- "invariants_mapped_count": 4,
76
- "invariants_declared_count": 4,
77
- "edge_cases_count": 5,
78
- "test_files_named_count": 7,
79
- "fixture_strategy_declared": true,
80
- "halt_reasons": []
81
- }
82
- ```
83
-
84
- Field rules:
85
-
86
- - `tenant_isolation_tests_count` paired with `tenant_isolation_required` is the rubber-stamp tell. `required: true` with `count: 0` at terminal status is a TS-03 contract violation that should have halted the Skill — its presence in a `passed` sidecar is a high-severity signal.
87
- - `challenge_prompts_answered` must be exactly `3` for `passed`. Lower values at `passed` indicate either a validator gap or a Skill bypass.
88
- - `invariants_mapped_count` lower than `invariants_declared_count` at `passed` is a TS-06 violation. Same signal-handling as above.
89
-
90
- ## Schema — `implement-<phase-id>.json`
91
-
92
- ```json
93
- {
94
- "schema_version": 2,
95
- "skill": "hstack-implement",
96
- "session_id": "062b8fe8-649f-4d73-b4fb-b0a28a800552",
97
- "phase_opened_at": "2026-05-22T13:58:12Z",
98
- "phase_closed_at": "2026-05-22T14:18:42Z",
99
- "change_id": "2026-05-billing-overage-warning",
100
- "phase_id": "phase-3-component",
101
- "started_at": "2026-05-22T14:00:00Z",
102
- "completed_at": "2026-05-22T14:18:42Z",
103
- "files_touched_count": 4,
104
- "tests_written_count": 2,
105
- "scope_amendment_emitted": false,
106
- "halt_reasons": [],
107
- "test_immutability_authorizations": []
108
- }
109
- ```
110
-
111
- Field rules:
112
-
113
- - `started_at`, `completed_at` — ISO-8601. The implementer records them from session timestamps. They describe the phase; `phase_opened_at` / `phase_closed_at` bound the *measurement window* and come from the shared resolver. They will usually be within seconds of each other; when they disagree, the window fields are the ones the parser reads.
114
- - `files_touched_count` — count of distinct files modified by the phase's commit. Computed mechanically; not a judgment.
115
- - `tests_written_count` — count of test files newly created in the phase (kernel test-immutability rule allows new tests without authorization).
116
- - `scope_amendment_emitted` — `true` only when the implementer halted and surfaced a scope-amendment request during this phase.
117
- - `halt_reasons` — array of enum values from the kernel halt sentinel (see KERNEL.md § Halt sentinel).
118
- - `test_immutability_authorizations` — array of canonical authorization phrases echoed during this phase (e.g., `"Ok to change test foo"`).
119
-
120
- ## Schema — `verify.json`
121
-
122
- ```json
123
- {
124
- "schema_version": 2,
125
- "skill": "hstack-verify",
126
- "session_id": "062b8fe8-649f-4d73-b4fb-b0a28a800552",
127
- "phase_opened_at": "2026-05-22T15:19:41Z",
128
- "phase_closed_at": "2026-05-22T15:32:00Z",
129
- "change_id": "2026-05-billing-overage-warning",
130
- "ran_at": "2026-05-22T15:32:00Z",
131
- "test_suite_runtime_s": 187.4,
132
- "phase_coverage": {"phase-1-types": "pass", "phase-2-component": "pass"},
133
- "test_plan_coverage": {
134
- "edge-cases": "all-observed",
135
- "tenant-isolation": "not-applicable",
136
- "performance-budgets": "not-applicable"
137
- },
138
- "discrepancies_count": 0,
139
- "status": "passed"
140
- }
141
- ```
142
-
143
- Field rules:
144
-
145
- - `test_suite_runtime_s` — float seconds. Wall-clock elapsed across all canonical commands.
146
- - `phase_coverage`, `test_plan_coverage` — mirror `verification.md` frontmatter for cheap downstream parsing. When verification fails, the sidecar still lands at the corresponding `ran` or `failed` status; the canonical artifact is the source of truth for any discrepancy.
147
- - `discrepancies_count` — count of bullet points under `verification.md § Discrepancies`. A non-zero value should always pair with a non-empty Discrepancies section in the canonical artifact.
148
-
149
- ## Schema — `adversarial-review.json`
150
-
151
- ```json
152
- {
153
- "schema_version": 2,
154
- "skill": "hstack-adversarial-review",
155
- "session_id": "9f41c0aa-2f5e-4c31-9a77-6d0b1b0e2c14",
156
- "phase_opened_at": "2026-05-22T16:40:03Z",
157
- "phase_closed_at": "2026-05-22T16:42:00Z",
158
- "change_id": "2026-05-billing-overage-warning",
159
- "reviewed_at": "2026-05-22T16:42:00Z",
160
- "findings_floor": 5,
161
- "findings_count": 6,
162
- "findings_fewer_than_floor": false,
163
- "category_counts": {
164
- "security": 1,
165
- "scope-drift": 0,
166
- "invariant-breach": 1,
167
- "spec-compliance": 2,
168
- "data-integrity": 1,
169
- "code-quality": 1
170
- },
171
- "severity_counts": {"critical": 0, "high": 1, "medium": 3, "low": 2},
172
- "resolution_mix": {"commit": 4, "tech-debt": 1, "justified-in-prose": 1},
173
- "fresh_session_attestation": "session abc-123; opened 2026-05-22T16:40Z; no implementer transcripts loaded",
174
- "halt_reasons": []
175
- }
176
- ```
177
-
178
- Field rules:
179
-
180
- - `findings_floor` is `3` by default, `5` when `change-spec.area` is in `{agent, auth, billing}` per AR-06. Since ADR-0014 it is the area's *expected* finding count and gates nothing — it is carried here so `findings_count` has a denominator to be read against.
181
- - `findings_count` below `findings_floor` is an ordinary outcome, not a violation. The one count the canonical artifact must argue for is zero: AR-01 requires `findings_fewer_than_floor: true` with a defended justification when `findings` is empty. Aggregating across changes: the `findings_count / findings_floor` distribution is the primary read, and a rate of empty reviews that climbs while `severity_counts` stays flat is the signal worth acting on.
182
- - `category_counts` clustering — e.g., 5 of 5 findings in `code-quality` — is a description of where a change carried its risk, not a smell in itself. It is worth reading against the change's `surfaces`: a `db`-surface change with every finding in `code-quality` is a review that did not look where the risk was. Surfaced via OE-7.
183
- - `severity_counts.high + critical` paired with `resolution_mix.justified-in-prose > 0` is a high-severity-in-prose smell flagged by QO-2. The Skill's stop condition should have caught it before terminal status; sidecar presence indicates a bypass.
184
-
185
- ## Schema — `finalize.json`
186
-
187
- ```json
188
- {
189
- "schema_version": 2,
190
- "skill": "hstack-finalize",
191
- "session_id": "c7d2e5b1-88a4-4f0d-b3ce-51a9f7d6e8b2",
192
- "phase_opened_at": "2026-05-23T10:11:26Z",
193
- "phase_closed_at": "2026-05-23T10:14:00Z",
194
- "change_id": "2026-05-billing-overage-warning",
195
- "shipped_at": "2026-05-23T10:14:00Z",
196
- "merge_commit_sha": "abc1234567890",
197
- "change_duration_days": 4,
198
- "tds_resolved": ["TD-0042-overage-banner-tailwind-class"]
199
- }
200
- ```
201
-
202
- Field rules:
203
-
204
- - `merge_commit_sha` — full SHA of the merge commit on the default branch.
205
- - `change_duration_days` — integer days from `change-spec.created` to the merge commit's author date.
206
- - `tds_resolved` — list of TD ids; mirrors `change-spec.resolves-tech-debt`. Empty array on changes that resolve no debt.
207
-
208
- ## Discipline preserved
209
-
210
- Per the kernel § Mechanical operations § Discipline preserved:
211
-
212
- - **Atomic with the canonical commit.** Each sidecar is written and `git add`-ed in the same commit as the canonical artifact write. No separate commit. The sidecar piggybacks on a commit that was happening anyway — zero new LLM turns, zero new confirmation gates.
213
- - **Idempotency.** Re-running a Skill on a phase that already landed produces a no-op on the sidecar (file already present, content unchanged aside from `schema_version` bumps if any).
214
- - **Derivative property.** Every value in every sidecar is reconstructible from git + frontmatter + transcripts. The sidecar is a cache, not a source. Deleting a sidecar is harmless — the next `/hstack:telemetry` run will compute the same metrics from the slower path. The phase window is the one field group with a shelf life: it points at a transcript that `cleanupPeriodDays` will eventually sweep (365 days on some machines, 30 by default), after which the phase reads as unmeasured. Deleting the sidecar loses the window for good, since nothing else records it.
215
- - **Schema versioning.** `schema_version: 2` since ADR-0009 (the phase window). The bump is additive: every v1 field keeps its name and meaning, and a v1 sidecar still parses — it simply reports as unmeasured. No migration exists or is planned.
216
- - **No local identifiers in git.** `session_id` is a local machine identifier. `.telemetry/` is gitignored in the consuming repo, so it never lands in history — but the discipline now depends on that gitignore line holding. A consumer that commits `.telemetry/` publishes its session ids.
217
-
218
- ## What sidecars are NOT
219
-
220
- - Not authoritative. The artifact frontmatter and git history are. If a sidecar disagrees with the artifact, the artifact wins.
221
- - Not an audit trail. The kernel reserves "agent-ledger" naming for the v2 substrate when it ships with cryptographic guarantees.
222
- - Not blocking. A sidecar write failure is logged but does not block the canonical commit.
223
- - Not a parallel tracker. The kernel forbids parallel trackers; sidecars survive that rule only because they are derivative.
224
-
225
- ## Adding sidecar emission to a new Skill
226
-
227
- The v1 emission list is fixed at five Skills (`test-plan`, `implement`, `verify`, `adversarial-review`, `finalize`). Adding a sixth is a follow-up change-spec, not a unilateral Skill edit. The cost-benefit threshold: a Skill is sidecar-eligible when its terminal event is per-change (not per-session), the data the sidecar would carry is non-trivial to reconstruct from git alone, and the Skill already auto-commits at the terminal event (no new commit needed). The "tier 2" candidates already evaluated and held back are `hstack-security-review` and `hstack-data-review`; both pass the criteria but their data is already first-class in frontmatter, so the sidecar's only value is parse-cost reduction. Promote them when WS-2 body parsing becomes a felt bottleneck.
@@ -1,119 +0,0 @@
1
- ---
2
- id: <parent-change-id>-test-plan
3
- type: test-plan
4
- status: draft # draft | in-progress | passed | concerns-acknowledged | failed | superseded
5
- owner: <git-handle>
6
- parent-change: <change-spec-id>
7
- scoring-mode: llm-strategized # v1; v2 introduces 'executed' once mutation/coverage tooling is wired
8
- coverage-layers:
9
- unit: not-applicable # addressed | partial | not-applicable
10
- integration: not-applicable
11
- e2e: not-applicable
12
- tenant-isolation-tests: [] # required non-empty when surfaces includes db | api | agent
13
- fixture-strategy-declared: false # must be true before status: passed
14
- performance-budgets-required: false # true when change touches hot paths or high-traffic surfaces
15
- challenge-prompts-answered: 0 # must equal 3
16
- concerns-acknowledged-by: null # handle required when any coverage layer is `partial` and deferred
17
- invariants-mapped: [] # change-spec invariant ids that have a mapped test in this plan
18
- created: <YYYY-MM-DD>
19
- updated: <YYYY-MM-DD>
20
- schema-version: 1
21
- ---
22
-
23
- ## Surfaces and Risk Profile
24
-
25
- _Pointer to change-spec `surfaces`. One sentence per surface naming the dominant test-risk layer it adds (e.g., "ui — interaction state regressions; db — RLS bypass risk on new table")._
26
-
27
- ## Test Pyramid
28
-
29
- _Per-layer decisions: which behaviors land at which layer and why. Bias toward integration over end-to-end for behavior coverage; bias toward unit for pure functions and reducers. Name the test files that will exist; estimate count roughly. If a layer is `not-applicable`, justify in one sentence._
30
-
31
- ### unit
32
-
33
- **Coverage status.** _addressed | partial | not-applicable._
34
-
35
- **Files.** _Test files in scope (relative paths)._
36
-
37
- -
38
-
39
- **What's covered.** _Behaviors validated at this layer. 2–4 bullets._
40
-
41
- -
42
-
43
- **Rationale.** _Why this layer is the right home for these behaviors._
44
-
45
- ### integration
46
-
47
- **Coverage status.**
48
-
49
- **Files.**
50
-
51
- -
52
-
53
- **What's covered.**
54
-
55
- -
56
-
57
- **Rationale.**
58
-
59
- ### e2e
60
-
61
- **Coverage status.**
62
-
63
- **Files.**
64
-
65
- -
66
-
67
- **What's covered.**
68
-
69
- -
70
-
71
- **Rationale.**
72
-
73
- ## Edge Cases
74
-
75
- _Enumerate the edge cases the change must handle, and name the test that catches each. Bias toward cases the change-spec's Target Behavior does not explicitly name — empty inputs, max-length inputs, concurrent writes, partial failure, retries, idempotency, time-zone boundaries, off-by-one on pagination, NULL vs empty-string, locale-sensitive formatting. Minimum three bullets unless the change is genuinely trivial. Format: `case → test file::test name`._
76
-
77
- -
78
- -
79
- -
80
-
81
- ## Tenant Isolation Tests
82
-
83
- _Required non-empty section when `surfaces` includes `db`, `api`, or `agent`. For every new RLS-protected table, new tenant-scoped RPC, new tool boundary, or new cross-tenant data path: name an explicit negative test that proves cross-tenant reads/writes are refused. The change-spec's `tenant_isolation` invariants must each map to at least one test here. Format: `surface → test file::test name → what it proves`._
84
-
85
- -
86
-
87
- ## Test Data and Fixture Strategy
88
-
89
- _Required section. How test data is seeded, what factories or fixtures are reused, how tests are isolated from each other, and how multi-tenant data is partitioned in test runs. Name the factory module or fixture file. State whether tests share a database between runs (transactional rollback per test, full reset per suite, in-memory mock) and why._
90
-
91
- **Seed strategy.**
92
-
93
- **Factory / fixture module.**
94
-
95
- **Isolation between tests.**
96
-
97
- **Multi-tenant partitioning.**
98
-
99
- ## Performance and Regression Budgets
100
-
101
- _Required when `performance-budgets-required: true`. For each hot path the change touches, declare a numeric budget (p50/p95 latency, throughput, payload size, query count) and the test that asserts the budget. Budgets without an asserting test are not budgets; they are wishes._
102
-
103
- | path | budget | asserting test |
104
- | --- | --- | --- |
105
- | | | |
106
-
107
- ## Challenge Prompts
108
-
109
- _All three required. Each answer must be at least one paragraph. These exist because the v1 mitigation for "humans miss what's missing" is to force the strategist to name gaps the planner and the implementer will not. The questions below are the canonical wording — adapt one to the change when the adaptation probes harder, and record what was actually asked in the heading. Keep the `(a)` / `(b)` / `(c)` prefixes: TS-02 locates the answers by them._
110
-
111
- ### (a) 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.
112
-
113
- ### (b) 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.
114
-
115
- ### (c) 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.
116
-
117
- ## Open Concerns
118
-
119
- _When any coverage layer is `partial` and being deferred rather than addressed: enumerate what is uncovered, why it is acceptable to defer, who is acknowledging, and what tech-debt id captures the deferral. Ack must be human-confirmed by `owner` before status: concerns-acknowledged. Empty when every layer is `addressed` or `not-applicable`._
@@ -1,54 +0,0 @@
1
- ---
2
- id: threat-model
3
- type: threat-model
4
- status: drafted # drafted | current | needs-refresh | archived
5
- owner: <git-handle>
6
- last-quarterly-review: <YYYY-MM-DD>
7
- surfaces-covered: [ui, api, db, infra, agent]
8
- created: <YYYY-MM-DD>
9
- updated: <YYYY-MM-DD>
10
- schema-version: 1
11
- ---
12
-
13
- _One section per surface in `surfaces-covered` (validator rule TM-01). Each section enumerates concrete threats with: threat description, affected assets, mitigation, mitigation evidence (pointer to code, ADR, or hardening-checklist item). Length cap: 8 threats per surface._
14
-
15
- ## ui
16
-
17
- ### Threat: <name>
18
- **Affected assets.**
19
- **Mitigation.**
20
- **Evidence.**
21
-
22
- ## api
23
-
24
- ### Threat: <name>
25
- **Affected assets.**
26
- **Mitigation.**
27
- **Evidence.**
28
-
29
- ## db
30
-
31
- ### Threat: <name>
32
- **Affected assets.**
33
- **Mitigation.**
34
- **Evidence.**
35
-
36
- ## infra
37
-
38
- ### Threat: <name>
39
- **Affected assets.**
40
- **Mitigation.**
41
- **Evidence.**
42
-
43
- ## agent
44
-
45
- ### Threat: <name>
46
- **Affected assets.**
47
- **Mitigation.**
48
- **Evidence.**
49
-
50
- ## Unknowns
51
-
52
- _Challenge prompt: what threat to our multi-tenant boundary do you not yet have a mitigation for? This section must be present even when empty, to make the absence explicit (validator rule TM-02)._
53
-
54
- -
@@ -1,49 +0,0 @@
1
- ---
2
- id: <parent-change-id>-ui-brief
3
- type: ui-brief
4
- status: draft # draft | drafted | superseded
5
- owner: <git-handle>
6
- parent-change: <change-spec-id>
7
- reused-components: [] # design-system component ids
8
- new-components: [] # any non-empty entry requires a justification subsection
9
- design-system-version: <version> # must match hstack/config.yaml
10
- created: <YYYY-MM-DD>
11
- updated: <YYYY-MM-DD>
12
- schema-version: 1
13
- ---
14
-
15
- ## Goal
16
-
17
- _One paragraph. What the UI must achieve from the user's POV._
18
-
19
- ## Layouts and States
20
-
21
- _For every visible state of every new or modified surface: layout, content, interaction. Paragraph or bullets per state._
22
-
23
- ## Reused Components
24
-
25
- _Bullets pointing to existing components by design-system id._
26
-
27
- -
28
-
29
- ## New Components
30
-
31
- _For each: name, props, justification for not reusing. Challenge prompt: why is this new and not a reuse?_
32
-
33
- ### <ComponentName>
34
-
35
- **Props.** `{ ... }`
36
-
37
- **Justification.**
38
-
39
- ## Copy
40
-
41
- _Exact strings the user sees. Reviewed by cofounder. Bullets._
42
-
43
- -
44
-
45
- ## Accessibility Notes
46
-
47
- _Anything that requires non-default handling (focus order, screen reader copy, contrast deviation). Bullets._
48
-
49
- -
@@ -1,63 +0,0 @@
1
- ---
2
- id: <parent-change-id>-verification
3
- type: verification
4
- status: draft # draft | ran | passed | failed | superseded
5
- owner: <git-handle>
6
- parent-change: <change-spec-id>
7
- test-results:
8
- unit: pending # pass | fail | pending | not-run
9
- integration: pending
10
- e2e: pending
11
- lint: pending
12
- typecheck: pending
13
- phase-coverage: {} # mirror of plan.steps-completed; { <phase-id>: pass | fail }
14
- test-plan-coverage: # observed-vs-promised against test-plan.md
15
- edge-cases: pending # all-observed | partial | missing
16
- tenant-isolation: pending # all-observed | partial | missing | not-applicable
17
- performance-budgets: pending # all-within-budget | regressed | missing | not-applicable
18
- artifacts:
19
- test-output: <path>
20
- created: <YYYY-MM-DD>
21
- updated: <YYYY-MM-DD>
22
- schema-version: 1
23
- ---
24
-
25
- ## Summary
26
-
27
- _Single-sentence verdict._
28
-
29
- ## Per-Phase Outcomes
30
-
31
- _Table of phase id, verifier expectations met (yes/no), notes. Three columns max._
32
-
33
- | phase-id | met | notes |
34
- | --- | --- | --- |
35
- | | | |
36
-
37
- ## Test-Plan Coverage
38
-
39
- _Observed-vs-promised against `test-plan.md`. Three subsections; populate only those that apply to this change._
40
-
41
- ### Edge Cases
42
-
43
- _Every bullet in the test-plan's Edge Cases section maps to an observed test. Absent or skipped tests are listed with a recommended action._
44
-
45
- ### Tenant Isolation
46
-
47
- _Every entry in the test-plan's `tenant-isolation-tests` array maps to an observed negative test. Absences here are high-severity and escalate to adversarial-review (V-03)._
48
-
49
- ### Performance Budgets
50
-
51
- _Every row in the test-plan's Budgets table maps to an observed assertion within budget. Regressions and absences block `status: passed` (V-04)._
52
-
53
- | path | budget | observed | within budget |
54
- | --- | --- | --- | --- |
55
- | | | | |
56
-
57
- ## Test Suite Output
58
-
59
- _Pointer to the captured stdout/stderr blob (`artifacts.test-output`)._
60
-
61
- ## Discrepancies
62
-
63
- _Anything the verifier observed that the plan did not predict, with an action (file an issue, escalate to adversarial-review)._
@@ -1,34 +0,0 @@
1
- ---
2
- id: vision
3
- type: vision
4
- status: drafted # drafted | current | needs-refresh | archived
5
- owner: <git-handle>
6
- reviewed-quarterly-on: <YYYY-MM-DD>
7
- created: <YYYY-MM-DD>
8
- updated: <YYYY-MM-DD>
9
- schema-version: 1
10
- ---
11
-
12
- ## What this product is
13
-
14
- _Two or three sentences naming the product and category._
15
-
16
- ## What it does
17
-
18
- _Top 3–5 user-visible capabilities. Bullets._
19
-
20
- -
21
-
22
- ## What it explicitly is not
23
-
24
- _Boundaries we are committing not to cross. Bullets._
25
-
26
- -
27
-
28
- ## Who it is for
29
-
30
- _Pointer to personas. Not a duplication of persona content._
31
-
32
- ## Why now
33
-
34
- _The timing thesis. Two or three sentences._