hstack 0.7.0 → 0.16.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 (99) hide show
  1. package/CHANGELOG.md +277 -0
  2. package/README.md +39 -13
  3. package/VERSION +1 -1
  4. package/dist/commands/doctor.js +51 -1
  5. package/dist/commands/doctor.js.map +1 -1
  6. package/dist/commands/update.js +8 -2
  7. package/dist/commands/update.js.map +1 -1
  8. package/dist/lib/descriptions.js +167 -0
  9. package/dist/lib/descriptions.js.map +1 -0
  10. package/dist/lib/diff.js +1 -1
  11. package/dist/lib/git.js +16 -0
  12. package/dist/lib/git.js.map +1 -1
  13. package/dist/lib/wire.js +108 -4
  14. package/dist/lib/wire.js.map +1 -1
  15. package/dist/manifest.js +17 -2
  16. package/dist/manifest.js.map +1 -1
  17. package/package.json +3 -1
  18. package/template/.claude/agents/adversarial-reviewer.md +16 -64
  19. package/template/.claude/agents/app-architect.md +12 -49
  20. package/template/.claude/agents/data-architect.md +13 -51
  21. package/template/.claude/agents/data-specialist.md +5 -50
  22. package/template/.claude/agents/implementer.md +8 -65
  23. package/template/.claude/agents/kernel-fit-analyst.md +7 -68
  24. package/template/.claude/agents/planner.md +7 -42
  25. package/template/.claude/agents/product-discovery.md +12 -48
  26. package/template/.claude/agents/product-manager.md +8 -43
  27. package/template/.claude/agents/researcher.md +5 -41
  28. package/template/.claude/agents/security-reviewer.md +19 -54
  29. package/template/.claude/agents/spec-author.md +18 -52
  30. package/template/.claude/agents/stack-architect.md +14 -43
  31. package/template/.claude/agents/test-strategist.md +16 -57
  32. package/template/.claude/agents/ui-ux-briefer.md +6 -36
  33. package/template/.claude/agents/verifier.md +13 -45
  34. package/template/.claude/skills/hstack-adr-new/SKILL.md +6 -33
  35. package/template/.claude/skills/hstack-adversarial-review/SKILL.md +31 -52
  36. package/template/.claude/skills/hstack-adversarial-review/references/finding-categories.md +157 -0
  37. package/template/.claude/skills/hstack-app-architecture/SKILL.md +2 -29
  38. package/template/.claude/skills/hstack-branch/SKILL.md +4 -31
  39. package/template/.claude/skills/hstack-brownfield-init/SKILL.md +10 -37
  40. package/template/.claude/skills/hstack-change-new/SKILL.md +4 -31
  41. package/template/.claude/skills/hstack-change-plan/SKILL.md +21 -32
  42. package/template/.claude/skills/hstack-commit/SKILL.md +7 -35
  43. package/template/.claude/skills/hstack-configure/SKILL.md +7 -34
  44. package/template/.claude/skills/hstack-coord/SKILL.md +3 -39
  45. package/template/.claude/skills/hstack-data-architecture/SKILL.md +4 -30
  46. package/template/.claude/skills/hstack-data-review/SKILL.md +3 -42
  47. package/template/.claude/skills/hstack-finalize/SKILL.md +30 -49
  48. package/template/.claude/skills/hstack-flag/SKILL.md +9 -48
  49. package/template/.claude/skills/hstack-greenfield-init/SKILL.md +9 -36
  50. package/template/.claude/skills/hstack-help/SKILL.md +11 -37
  51. package/template/.claude/skills/hstack-implement/SKILL.md +28 -58
  52. package/template/.claude/skills/hstack-kernel-fit-promote/SKILL.md +7 -46
  53. package/template/.claude/skills/hstack-kernel-fit-scan/SKILL.md +5 -60
  54. package/template/.claude/skills/hstack-kernel-fit-scan/references/slack-setup.md +42 -0
  55. package/template/.claude/skills/hstack-kernel-fit-triage/SKILL.md +12 -50
  56. package/template/.claude/skills/hstack-module-spec/SKILL.md +5 -32
  57. package/template/.claude/skills/hstack-product-discovery/SKILL.md +5 -31
  58. package/template/.claude/skills/hstack-research/SKILL.md +3 -33
  59. package/template/.claude/skills/hstack-scaffold/SKILL.md +2 -29
  60. package/template/.claude/skills/hstack-security-review/SKILL.md +5 -43
  61. package/template/.claude/skills/hstack-ship/SKILL.md +43 -53
  62. package/template/.claude/skills/hstack-stack-decide/SKILL.md +3 -30
  63. package/template/.claude/skills/hstack-story-draft/SKILL.md +6 -33
  64. package/template/.claude/skills/hstack-tech-debt-new/SKILL.md +4 -31
  65. package/template/.claude/skills/hstack-tech-debt-resolve/SKILL.md +9 -44
  66. package/template/.claude/skills/hstack-tech-debt-stale/SKILL.md +10 -37
  67. package/template/.claude/skills/hstack-tech-debt-wontfix/SKILL.md +8 -35
  68. package/template/.claude/skills/hstack-telemetry/SKILL.md +5 -30
  69. package/template/.claude/skills/hstack-test-plan/SKILL.md +23 -46
  70. package/template/.claude/skills/hstack-ui-brief/SKILL.md +3 -30
  71. package/template/.claude/skills/hstack-verify/SKILL.md +26 -48
  72. package/template/KERNEL.md +410 -0
  73. package/template/scripts/compute-merge-readiness.mjs +780 -0
  74. package/template/scripts/coord/coord_scan.py +121 -22
  75. package/template/scripts/run-gates.sh +388 -0
  76. package/template/scripts/telemetry/insights/kernel_fit.py +1 -1
  77. package/template/scripts/telemetry/insights/token_economics.py +181 -8
  78. package/template/scripts/telemetry/parsers/sidecars.py +61 -0
  79. package/template/scripts/telemetry/parsers/transcripts.py +135 -22
  80. package/template/scripts/telemetry/render.py +68 -3
  81. package/template/scripts/telemetry/report.py +16 -4
  82. package/template/scripts/telemetry/run_kernel_fit.py +6 -2
  83. package/template/scripts/telemetry/session_id.py +139 -0
  84. package/template/scripts/validate-spec.mjs +3303 -0
  85. package/template/templates/adr.md +7 -0
  86. package/template/templates/adversarial-review.md +5 -5
  87. package/template/templates/ci-cd.md +14 -0
  88. package/template/templates/coord-message.md +3 -2
  89. package/template/templates/data-architecture.md +3 -6
  90. package/template/templates/kernel-fit-finding.md +2 -2
  91. package/template/templates/kernel-fit-flag.md +2 -2
  92. package/template/templates/plan.md +4 -0
  93. package/template/templates/product-brief.md +2 -2
  94. package/template/templates/roadmap.md +41 -0
  95. package/template/templates/security-review.md +1 -1
  96. package/template/templates/telemetry-sidecar.md +56 -13
  97. package/template/templates/test-plan.md +1 -1
  98. package/template/CLAUDE.md +0 -443
  99. package/template/templates/mvp-scope.md +0 -34
@@ -1,25 +1,6 @@
1
1
  ---
2
2
  name: hstack-tech-debt-wontfix
3
- description: |
4
- Use this skill when a tech-debt item is being closed without a fix because the team has decided the cost of resolving exceeds the cost of living with it. The Skill runs a brief two-question interview (a structured-elicitation loop per the kernel's Mechanical operations section), captures the rationale into the TD's frontmatter, and performs direct mechanical writes (per ADR-0001, no spec-author invocation): writes `wontfix-reason` and `wontfix-accepted-alternative`, flips status `open → wontfix`, appends a Resolution Log entry, all in a single atomic commit. Wontfix is a terminal status — per TD-03, no field rewrites are permitted afterwards. Examples:
5
-
6
- <example>
7
- Context: TD-0017 captured a deliberate compromise that no longer matters — the surrounding code has been rewritten and the original compromise no longer exists.
8
- user: "/hstack:tech-debt-wontfix TD-0017-prompt-template-string-concat"
9
- assistant: "I'll ask two questions: (a) why won't this be fixed; (b) what we're accepting as the alternative. Both answers are required and become non-null wontfix-reason and wontfix-accepted-alternative frontmatter fields (TD-06). On confirmation, the Skill writes both fields and flips status to wontfix directly (per ADR-0001, no spec-author invocation) in a single auto-commit. Wontfix is terminal — no further edits."
10
- <commentary>
11
- Wontfix is the controlled escape valve for tech-debt that no longer warrants a fix. The kernel requires both fields because "we don't care anymore" without a recorded alternative is the kind of decision that comes back to bite the team six months later. Future engineers reading the TD see the explicit reasoning rather than a silent closure.
12
- </commentary>
13
- </example>
14
-
15
- <example>
16
- Context: An engineer wants to wontfix a tech-debt because they don't want to deal with it right now, not because the cost-benefit has actually flipped.
17
- user: "/hstack:tech-debt-wontfix TD-0042-overage-banner-tailwind-class"
18
- assistant: "I'll ask the two questions. If your answer to (a) is 'we don't have time' or 'we'll get to it later', I'll halt and surface that the right path is to leave the TD at `open` and re-prioritize, not to mark it wontfix. Wontfix is for compromises we've decided to live with permanently, not for deferrals."
19
- <commentary>
20
- The Skill applies a deliberate friction at the prose level: if the wontfix-reason reads like a deferral ("later", "not a priority", "we don't have bandwidth"), the Skill halts and asks the engineer to either commit to a real wontfix reason or leave the TD at `open`. Deferrals belong in the backlog, not in the wontfix log.
21
- </commentary>
22
- </example>
3
+ description: Use to close a tech-debt item the team has decided to live with permanently, recording the reason and the accepted alternative. Wontfix describes a choice; `/hstack:tech-debt-stale` describes a claim that no longer reproduces.
23
4
  tools:
24
5
  - Read
25
6
  - Write
@@ -28,7 +9,7 @@ tools:
28
9
  - Glob
29
10
  - Bash
30
11
  - Task
31
- - "{{TODO-SCRIPT: hstack/scripts/validate-spec.ts — validates the TD frontmatter flip and TD-06 (wontfix-reason and wontfix-accepted-alternative both non-null)}}"
12
+ - "node hstack/scripts/validate-spec.mjs — validates the TD frontmatter flip and TD-06 (wontfix-reason and wontfix-accepted-alternative both non-null)"
32
13
  ---
33
14
 
34
15
  ## Purpose
@@ -45,26 +26,26 @@ Invoke when a tech-debt item at `status: open` will not be fixed and the team ha
45
26
 
46
27
  ## Preconditions
47
28
 
48
- - Verify `hstack/tech-debt/<td-id>.md` exists and is at `status: open`. If at `in-progress`, halt — work is already underway. Concrete recovery: locate the resolution change-spec via the TD's Resolution Log (most recent entry names the resolving change-spec id) and either complete that change normally or abandon it by direct frontmatter edit (`git checkout HEAD -- hstack/tech-debt/<td-id>.md` to revert the TD to `open`, then archive the resolution change folder manually). Do not invoke `spec-author` for the rollback — the kernel forbids it for status flips. If at any terminal status, halt with the status named.
29
+ - Verify `hstack/tech-debt/<td-id>.md` exists and is at `status: open`. If at `in-progress`, halt — work is already underway. Concrete recovery: locate the resolution change-spec via the TD's Resolution Log (most recent entry names the resolving change-spec id) and either complete that change normally or abandon it by direct frontmatter edit (`git checkout HEAD -- hstack/tech-debt/<td-id>.md` to revert the TD to `open`, then archive the resolution change folder manually). If at any terminal status, halt with the status named.
49
30
 
50
31
  ## Orchestration steps
51
32
 
52
33
  1. **Print the TD in full.** Read `hstack/tech-debt/<td-id>.md` and print Title, Why we took the shortcut, What it costs us, Fix sketch, Pre-conditions, Acceptance to the conversation. The engineer should re-read before committing to wontfix.
53
34
 
54
- 2. **Ask the first question.** "Why won't this tech-debt be fixed? (one sentence, 200 characters)". Capture the answer.
35
+ 2. **Ask the first question.** "Why won't this tech-debt be fixed?" The answer names the compromise and why living with it is the right call, in a form that survives being read back in a year without the surrounding context. No length bound — the artifact was just printed in full, so the engineer is answering with it on screen.
55
36
 
56
- 3. **Deferral check.** If the answer contains deferral indicators ("later", "not a priority", "no time", "we'll come back", "next quarter", "after X ships"), halt with: "That reads like a deferral, not a wontfix. Wontfix is for compromises we've decided to live with permanently. Leave the TD at `open` if this is a deferral; only re-invoke when the cost-benefit has actually flipped." The Skill does not write anything in this case.
37
+ 3. **Deferral check.** Wontfix means the problem is real and we are choosing to live with it. If the answer describes a future in which we fix it, it is a deferral and the item stays `open`. Judge the sentence, not its vocabulary: "we accept the 50ms until the v2 substrate lands next quarter, which removes it as a side effect" is a real acceptance with a date in it, while "the cost-benefit does not favour action" is a deferral with no giveaway words at all. When it reads as a deferral, halt with: "That reads like a deferral, not a wontfix. Wontfix is for compromises we've decided to live with permanently. Leave the TD at `open` if this is a deferral; only re-invoke when the cost-benefit has actually flipped." The Skill does not write anything in this case.
57
38
 
58
39
  4. **Ask the second question.** "What are we accepting as the alternative to fixing this? (one sentence)". This is the on-record acknowledgement of the cost the team is choosing to live with. Examples: "We accept the manual workaround documented in the runbook", "We accept the 50ms latency overhead until v2 substrate lands", "The surrounding code has been rewritten and the original compromise no longer exists".
59
40
 
60
41
  5. **Confirm.** Print both answers and ask "Mark TD-NNNN as wontfix with this rationale? (Y/n)". Default Yes.
61
42
 
62
43
  6. **Write the wontfix transition (direct write).** Per the kernel's Mechanical operations section, this Skill performs the writes itself via the `Edit` tool — no `spec-author` invocation. Edit `hstack/tech-debt/<td-id>.md`:
63
- - **Defensive Resolution Log check.** If `## Resolution Log` is not present in the file (legacy TDs authored before the template included this section), append `\n## Resolution Log\n` to the end of the file first.
44
+ - Defensive log-header check per the kernel: if `## Resolution Log` is absent, append it before writing the entry.
64
45
  - Edit frontmatter: `wontfix-reason: <answer-a>`, `wontfix-accepted-alternative: <answer-b>`, `status: open → wontfix`, `updated: <today>`.
65
46
  - Append to the Resolution Log section: `status: open → wontfix on <today> by <owner>. Reason: <answer-a>. Accepted alternative: <answer-b>.`
66
47
 
67
- Run `{{TODO-SCRIPT: hstack/scripts/validate-spec.ts}}` against the file. TD-06 (wontfix requires both rationale fields non-null) must pass. On validation pass, `git add` the file and commit with message `tech-debt(<td-id>): wontfix`. The four frontmatter writes plus the log append land in this single auto-commit, preserving atomicity. On validation failure, halt; unstaged changes can be reverted via `git checkout -- <td-file>`.
48
+ Run `node hstack/scripts/validate-spec.mjs <path>` against the file. TD-06 (wontfix requires both rationale fields non-null) must pass. On validation pass, `git add` the file and commit with message `tech-debt(<td-id>): wontfix`. The four frontmatter writes plus the log append land in this single auto-commit, preserving atomicity. On validation failure, halt; unstaged changes can be reverted via `git checkout -- <td-file>`.
68
49
 
69
50
  7. **Confirm completion.** Print: "TD-NNNN is now `wontfix`. Per TD-03, no further field rewrites are permitted on this artifact. If the team's decision later reverses, author a new tech-debt via `/hstack:tech-debt-new` rather than re-opening this one."
70
51
 
@@ -88,17 +69,9 @@ Beyond the kernel's general stop conditions:
88
69
 
89
70
  - The TD does not exist or is at a non-`open` status. Halt with status named.
90
71
  - The wontfix-reason answer reads as a deferral (per step 3). The Skill refuses to write and surfaces the recommendation.
91
- - Either answer exceeds 200 characters. Ask for a tighter version — wontfix rationales are short and load-bearing.
92
72
  - The engineer declines confirmation at step 5.
93
73
 
94
74
  ## Failure modes
95
75
 
96
76
  - **Direct write fails (filesystem, validator, or git).** Halt; the TD's status flip and the two frontmatter writes must land in a single auto-commit. Partial writes are not possible if the Skill aborts on validator failure before staging.
97
- - **Deferral disguised as wontfix.** The prose-level check in step 3 is the v1 defense. v2 substrate could add LLM-graded rationale assessment, but v1 trusts the engineer's willingness to be honest with themselves.
98
-
99
- ## Anti-patterns
100
-
101
- - Never accept a wontfix-reason that reads as a deferral. The check is mandatory and is the only friction protecting against backlog amnesia.
102
- - Never write `status: wontfix` without both rationale fields non-null. TD-06 enforces this at validation.
103
- - Never re-open a wontfix TD. Per TD-03, wontfix is terminal — author a new TD instead.
104
- - Never invoke `spec-author` for the wontfix transition. Per the kernel's Mechanical operations section (ADR-0001), this Skill performs the writes directly. The three writes (status, wontfix-reason, wontfix-accepted-alternative) plus the Resolution Log append land atomically in a single Skill-driven commit.
77
+ - **Deferral disguised as wontfix.** The step-3 judgment is the v1 defense, and it is a judgment rather than a word list because the list it replaced fired on legitimate rationales and missed the paraphrase. The Skill's job is to make the distinction visible, not to pattern-match it.
@@ -1,26 +1,6 @@
1
1
  ---
2
2
  name: hstack-telemetry
3
- description: |
4
- Use this skill when the engineer wants a retrospective observability report — token economics, workflow shape, quality outcomes, overengineering detection, and contract drift — generated from on-disk artifacts, git history, and Claude Code transcripts. Read-only across every source; no subagents invoked, no LLM turns, safe to run any time.
5
-
6
- <example>
7
- Context: The engineer wants a weekly health check on the hstack workflow.
8
- user: "/hstack:telemetry"
9
- assistant: "I'll run the telemetry report against this repo with a 30-day window. Output lands at `hstack/telemetry/reports/<today>.md`. No subagents, no LLM turns — pure derivation from frontmatter + git + transcripts."
10
- <commentary>
11
- Default mode. The Skill shells out to `python hstack/scripts/telemetry/report.py` and reports the output path. The kernel's "no parallel tracker" rule is preserved because the report is derivative — re-runnable from source, never authoritative.
12
- </commentary>
13
- </example>
14
-
15
- <example>
16
- Context: The engineer wants a deeper history window than the default 30 days.
17
- user: "/hstack:telemetry --window 90"
18
- assistant: "I'll run the report with a 90-day window. Larger windows surface more contract-drift signal (TD half-life, module-spec staleness) at the cost of slower transcript walks."
19
- <commentary>
20
- The Skill passes `--window <N>` through to the underlying script. A window of 0 means all-history; use sparingly on repos with months of transcript data.
21
- </commentary>
22
- </example>
23
-
3
+ description: Use for a retrospective observability report on token economics, workflow shape, quality outcomes, overengineering, and contract drift, derived from artifacts, git history, and transcripts. Read-only; no subagents, no LLM turns.
24
4
  tools:
25
5
  - Read
26
6
  - Bash
@@ -33,14 +13,14 @@ tools:
33
13
 
34
14
  The report covers six buckets:
35
15
 
36
- 1. **Token economics** — TE-1 cost-score per Skill, TE-2 cache-hit ratio per Skill, TE-3 subagent entry-tax amortization.
16
+ 1. **Token economics** — TE-1 cost-score per Skill, TE-2 cache-hit ratio per Skill, TE-3 subagent entry-tax amortization (all three session-scoped), plus TE-4 cost per phase and TE-5 cost per change, summed from the sidecar phase windows (ADR-0009). TE-4/TE-5 supersede TE-1 wherever a sidecar exists, and print a coverage fraction: only five Skills emit sidecars, so their totals are a subset by construction. A phase whose window or transcript cannot be read is reported as *unmeasured*, never as zero.
37
17
  2. **Workflow shape** — WS-1 phase duration, WS-2 gate findings density, WS-4 scope-amendment rate, WS-6 halt reasons.
38
18
  3. **Quality outcomes** — QO-2 severity × resolution-type mix, QO-3 test-immutability audit, QO-4 verifier observed-vs-promised.
39
19
  4. **Overengineering** — OE-1 artifact tokens per diff line, OE-3 subagent invocations × host cost, OE-5 trivial-eligible changes that ran the full gauntlet.
40
20
  5. **Contract drift** — module-spec staleness × recent commit activity, ADR supersession lag, tech-debt half-life by exit path.
41
21
  6. **Kernel-fit candidates** — KF-P1 Category-A claim spans production paths (post-PR-#5 misclassification), KF-P2 halt-reason cluster, KF-P3 missed-gate recovery. Detection-only rollup; the canonical findings live at `hstack/kernel-fit/findings/` and are produced by `/hstack:kernel-fit-scan`. See ADR-0004.
42
22
 
43
- A watch-list at the report bottom surfaces anomalies (low cache-hit Skills, high-severity findings resolved as `justified-in-prose`, candidate test-immutability violations, scope-amendment rate above 30%, module drift, fired kernel-fit patterns).
23
+ A watch-list at the report bottom surfaces anomalies (low cache-hit Skills, unmeasured phase sidecars, high-severity findings resolved as `justified-in-prose`, candidate test-immutability violations, scope-amendment rate above 30%, module drift, fired kernel-fit patterns).
44
24
 
45
25
  ## When to invoke
46
26
 
@@ -52,6 +32,8 @@ Run any time. Common cadence:
52
32
 
53
33
  The Skill is read-only and idempotent — re-running produces a fresh report at the same path (overwrites the same-day file).
54
34
 
35
+ The report is a retrospective lens, never an in-flight signal: no Skill that writes artifacts takes it as input. Old reports stay in git so trend lines can be checked against them; deleting reports to reshape a trend defeats the point. Any v2 "agent-ledger" rebrand of this tool waits on at least three months of real runs showing the data layer is worth promoting.
36
+
55
37
  ## Inputs
56
38
 
57
39
  - `--window <N>` (optional): limit git/transcript history to the last N days. Default 30. `--window 0` means all-history.
@@ -89,10 +71,3 @@ Re-running on the same day overwrites the same-day report file. Different window
89
71
  - `hstack/scripts/telemetry/report.py` is missing.
90
72
  - Python 3 is not available.
91
73
  - The git repository is corrupt or `.git/` is missing.
92
-
93
- ## Anti-patterns
94
-
95
- - Never claim the telemetry report is authoritative. It is derivative of frontmatter, git, and transcripts — re-runnable from source. The kernel's "no parallel tracker" rule applies.
96
- - Never use the report as an input to a Skill that writes artifacts. It is a retrospective lens, not an in-flight signal.
97
- - Never delete reports to manipulate trend lines. Old reports are git-tracked and can be referenced for retrospective comparison.
98
- - Never propose a v2 "agent-ledger" rebrand of this tool without first running it for at least 3 months and finding the data layer worth promoting.
@@ -1,34 +1,6 @@
1
1
  ---
2
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>
3
+ description: "Use when a change-spec is at `ready-to-plan` and needs `test-plan.md` before `/hstack:change-plan` can run — the planner refuses to sequence phases without it. Skipped for changes marked `trivial: true`."
32
4
  tools:
33
5
  - Read
34
6
  - Write
@@ -37,7 +9,7 @@ tools:
37
9
  - Glob
38
10
  - Bash
39
11
  - Task
40
- - "{{TODO-SCRIPT: hstack/scripts/validate-spec.ts — validates test-plan frontmatter and TS-01..TS-06}}"
12
+ - "node hstack/scripts/validate-spec.mjs — validates test-plan frontmatter and TS-01..TS-06"
41
13
  ---
42
14
 
43
15
  ## Purpose
@@ -71,6 +43,8 @@ Before any work:
71
43
 
72
44
  ## Orchestration steps
73
45
 
46
+ 0. **Open the phase window (mechanical, no LLM turn, no commit).** The moment the preconditions above pass and *before* any subagent invocation, run `python3 hstack/scripts/telemetry/session_id.py` and keep its `session_id` and `now` values — they become `session_id` and `phase_opened_at` in the sidecar below (ADR-0009). On failure or a null session id, hold `null` for both and continue.
47
+
74
48
  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
49
 
76
50
  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.
@@ -83,11 +57,11 @@ Before any work:
83
57
 
84
58
  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
59
 
86
- 7. **Three challenge prompts (mandatory).** Per TS-02 and the subagent's contract, the subagent answers all three challenge prompts verbatim:
60
+ 7. **Three challenge prompts (mandatory).** Per TS-02 and the subagent's contract, the subagent answers all three challenge prompts. The canonical wording:
87
61
  - "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
62
  - "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
63
  - "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.
64
+ The prompts must be answered; they need not be transcribed. Where a probe fits the change poorly as written, the subagent adapts it so it bites harder and records the adapted question in the heading — the `(a)` / `(b)` / `(c)` prefixes stay, because that is what TS-02 locates the answers by. Each answer is at least one paragraph. The Skill verifies `challenge-prompts-answered: 3` in frontmatter.
91
65
 
92
66
  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
67
 
@@ -97,7 +71,7 @@ Before any work:
97
71
 
98
72
  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
73
 
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`).
74
+ 12. **Validate.** Run `node hstack/scripts/validate-spec.mjs <path>` — 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
75
 
102
76
  ## Outputs
103
77
 
@@ -118,9 +92,12 @@ At the terminal-status auto-commit above (`test-plan(<change-id>): passed` or `c
118
92
 
119
93
  ```json
120
94
  {
121
- "schema_version": 1,
95
+ "schema_version": 2,
122
96
  "skill": "hstack-test-plan",
123
97
  "change_id": "<change-id>",
98
+ "session_id": "<session id from step 0, or null>",
99
+ "phase_opened_at": "<ISO-8601 from step 0, or null>",
100
+ "phase_closed_at": "<ISO-8601, now — same write as this sidecar, or null>",
124
101
  "completed_at": "<ISO-8601, when terminal status reached>",
125
102
  "status": "passed | concerns-acknowledged",
126
103
  "coverage_layers": {<mirror of frontmatter coverage-layers map>},
@@ -140,6 +117,18 @@ At the terminal-status auto-commit above (`test-plan(<change-id>): passed` or `c
140
117
 
141
118
  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
119
 
120
+ The three phase-window fields (`session_id`, `phase_opened_at`, `phase_closed_at`) come from step 0 and from this write. Their rules — best-effort, unmeasured rather than zero, never a halt — are stated once in `hstack/templates/telemetry-sidecar.md` § The phase window, which is the canonical schema and wins over any Skill.
121
+
122
+ ## Session boundary
123
+
124
+ `test-plan` is a natural session cut: the auto-commit above left `test-plan.md` on disk, so the conversation holds nothing the next phase needs. The cut-notice format, the kickoff-prompt template and the context-block rules are in `KERNEL.md` § Session boundaries; this Skill's two variables are:
125
+
126
+ ```
127
+ HSTACK-CUT: test-plan complete — cut recommended before change-plan.
128
+ ```
129
+
130
+ and the next command, `/hstack:change-plan <change-id>`.
131
+
143
132
  ## Idempotency contract
144
133
 
145
134
  - 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.
@@ -168,15 +157,3 @@ Beyond the kernel's general stop conditions:
168
157
  - **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
158
  - **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
159
  - **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`.
@@ -1,25 +1,6 @@
1
1
  ---
2
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>
3
+ description: Use when a change-spec with `ui` in `surfaces` is at `ready-to-plan` or later and needs `ui-brief.md` drafted before Figma work and before `/hstack:change-plan` runs.
23
4
  tools:
24
5
  - Read
25
6
  - Write
@@ -29,7 +10,7 @@ tools:
29
10
  - Bash
30
11
  - Task
31
12
  - "{{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}}"
13
+ - "node hstack/scripts/validate-spec.mjs — validates ui-brief frontmatter and UI-01/UI-02"
33
14
  ---
34
15
 
35
16
  ## Purpose
@@ -62,7 +43,7 @@ Before any work:
62
43
 
63
44
  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
45
 
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).
46
+ 4. **Validate.** Run `node hstack/scripts/validate-spec.mjs <path>` 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
47
 
67
48
  5. **Transition.** When every section is confirmed and the validator passes, `ui-ux-briefer` advances status from `draft` to `drafted`. Auto-commit fires.
68
49
 
@@ -98,11 +79,3 @@ Beyond the kernel's general stop conditions:
98
79
  - **Linked story unreachable.** Halt; reconcile via `hstack-story-draft` or fix the change-spec's `user-stories` array.
99
80
  - **Figma MCP absent.** Degraded mode — `ui-ux-briefer` produces the brief without frame-content hints, flags in the conversation, continues.
100
81
  - **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.
@@ -1,34 +1,6 @@
1
1
  ---
2
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
-
24
- <example>
25
- Context: The integration suite is gated by `RUN_INTEGRATION=1` and the engineer ran `npm test` without setting it; the runner reported `Tests: 0 passed, 0 failed`.
26
- user: "/hstack:verify 2026-06-knowledge-citations"
27
- assistant: "I'll invoke verifier. Per V-05, an integration suite that executed zero tests is recorded as `not-run`, not `pass` — zero failures is not evidence of correctness when there were zero assertions to fail. The Skill halts at `status: ran` with a high-severity Discrepancy naming the suspected reason (env-gated, all-skipped, empty-collection, or filter-collapse)."
28
- <commentary>
29
- V-05 closes the verifier false-positive where a suite gated by an unset env var would silently pass on the absence of failures. The remediation is either supplying the missing env / fixture and re-running, or amending the plan's Verifier Expectations via scope amendment so the zero-test state is intentional and recorded.
30
- </commentary>
31
- </example>
3
+ description: Use after `plan.steps-completed` covers every phase in the plan body and the change needs `verification.md` from the canonical test, lint, and typecheck runs. A partial verification run is meaningless.
32
4
  tools:
33
5
  - Read
34
6
  - Write
@@ -37,8 +9,8 @@ tools:
37
9
  - Glob
38
10
  - Bash
39
11
  - Task
40
- - "{{TODO-SCRIPT: hstack/scripts/run-gates.sh — runs the consuming repo's test/lint/typecheck suite and captures output, including an observed-test-count per suite for V-05}}"
41
- - "{{TODO-SCRIPT: hstack/scripts/validate-spec.ts — validates verification.md frontmatter and V-01/V-02/V-05}}"
12
+ - "hstack/scripts/run-gates.sh — runs the consuming repo's test/lint/typecheck suite and captures output, including an observed-test-count per suite for V-05"
13
+ - "node hstack/scripts/validate-spec.mjs — validates verification.md frontmatter and V-01/V-02/V-05"
42
14
  ---
43
15
 
44
16
  ## Purpose
@@ -65,13 +37,15 @@ Before any work:
65
37
 
66
38
  ## Orchestration steps
67
39
 
68
- 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}}`).
40
+ 0. **Open the phase window (mechanical, no LLM turn, no commit).** The moment the preconditions above pass and *before* any subagent invocation, run `python3 hstack/scripts/telemetry/session_id.py` and keep its `session_id` and `now` values they become `session_id` and `phase_opened_at` in the sidecar below (ADR-0009). On failure or a null session id, hold `null` for both and continue.
69
41
 
70
- 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`.
42
+ 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 `hstack/scripts/run-gates.sh --change <change-id> --json`, which executes the canonical commands declared in `ci-cd.md` § Canonical Commands — every one of them, and nothing else. Extending the canonical command set is `hstack-configure --interview ci-cd`, not an ad-hoc addition here.
43
+
44
+ 2. **Capture output.** `run-gates.sh` writes the captured stdout/stderr to `hstack/specs/changes/<change-id>/test-output.txt`; the subagent references that path from `verification.artifacts.test-output`.
71
45
 
72
46
  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`.
73
47
 
74
- 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`. Per V-05, before mapping `unit`, `integration`, or `e2e` to `pass`, the subagent confirms the runner's observed-test-count for that suite is greater than zero — a suite gated by an unset env var, all-skipped, empty-collection, or filter-collapsed to zero tests is recorded as `not-run` with a high-severity Discrepancy, not as `pass` on the absence of failures.
48
+ 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`. Per V-05, before mapping `unit`, `integration`, or `e2e` to `pass`, the subagent confirms the runner's observed-test-count for that suite is greater than zero — a suite gated by an unset env var, all-skipped, empty-collection, or filter-collapsed to zero tests is recorded as `not-run` with a high-severity Discrepancy, not as `pass` on the absence of failures. The Skill propagates the zero-tests-ran signal from the runner output into the subagent's context so the rule is enforceable rather than inferred.
75
49
 
76
50
  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`.
77
51
 
@@ -79,9 +53,9 @@ Before any work:
79
53
 
80
54
  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.
81
55
 
82
- 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.
56
+ 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 `node hstack/scripts/validate-spec.mjs <path>` 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`.
83
57
 
84
- 9. **Validate.** Run `{{TODO-SCRIPT: hstack/scripts/validate-spec.ts}}` — V-01, V-02, V-03, V-04, V-05.
58
+ 9. **Validate.** Run `node hstack/scripts/validate-spec.mjs <path>` — V-01, V-02, V-03, V-04, V-05.
85
59
 
86
60
  ## Outputs
87
61
 
@@ -101,9 +75,12 @@ At the change-spec advance commit (only when verification status is `passed`), w
101
75
 
102
76
  ```json
103
77
  {
104
- "schema_version": 1,
78
+ "schema_version": 2,
105
79
  "skill": "hstack-verify",
106
80
  "change_id": "<change-id>",
81
+ "session_id": "<session id from step 0, or null>",
82
+ "phase_opened_at": "<ISO-8601 from step 0, or null>",
83
+ "phase_closed_at": "<ISO-8601, now — same write as this sidecar, or null>",
107
84
  "ran_at": "<ISO-8601, when canonical commands started>",
108
85
  "test_suite_runtime_s": <float seconds, wall clock across canonical commands>,
109
86
  "phase_coverage": {<mirror of verification.md frontmatter>},
@@ -115,6 +92,18 @@ At the change-spec advance commit (only when verification status is `passed`), w
115
92
 
116
93
  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.
117
94
 
95
+ The three phase-window fields (`session_id`, `phase_opened_at`, `phase_closed_at`) come from step 0 and from this write. Their rules — best-effort, unmeasured rather than zero, never a halt — are stated once in `hstack/templates/telemetry-sidecar.md` § The phase window, which is the canonical schema and wins over any Skill.
96
+
97
+ ## Session boundary
98
+
99
+ `verify` is a natural session cut: the auto-commit above left `verification.md` on disk, so the conversation holds nothing the next phase needs. The cut-notice format, the kickoff-prompt template and the context-block rules are in `KERNEL.md` § Session boundaries; this Skill's two variables are:
100
+
101
+ ```
102
+ HSTACK-CUT: verify complete — cut recommended before adversarial-review.
103
+ ```
104
+
105
+ and the next command, `/hstack:adversarial-review <change-id>`.
106
+
118
107
  ## Idempotency contract
119
108
 
120
109
  - 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.
@@ -137,14 +126,3 @@ Beyond the kernel's general stop conditions:
137
126
  - **Environment misconfiguration prevents a canonical command from running.** Halt before invoking the subagent; surface the issue and the resolution.
138
127
  - **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`.
139
128
  - **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.
140
-
141
- ## Anti-patterns
142
-
143
- - Never invent a PASS. If tests are not green, status is `ran` or `failed`, not `passed`.
144
- - Never record a suite as `pass` on the absence of failures alone (V-05). A suite that ran zero tests — gated by an unset env var, all `.skip` / `.todo`, empty collection, or filter-collapsed — is `not-run`, not `pass`. The Skill propagates the zero-tests-ran signal from the runner output into the subagent context so the rule is enforceable rather than inferred.
145
- - Never skip a canonical command. The consuming repo's commands in `ci-cd.md` are mandatory.
146
- - Never silently drop a discrepancy. Even benign discrepancies get a one-line note.
147
- - Never score security or data. Stay in the mechanical-verification lane.
148
- - Never modify code or tests to make verification pass. That requires a new `hstack-implement` invocation.
149
- - Never claim phase coverage for phases not in `plan.steps-completed`.
150
- - Never run any command not declared in `ci-cd.md`. Extending the canonical command set requires `hstack-configure --interview ci-cd`.