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,122 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hstack-tech-debt-new
|
|
3
|
+
description: |
|
|
4
|
+
Use this skill when the engineer needs to capture a tech-debt item — a known compromise the team agreed to live with for now. The Skill orchestrates the `spec-author` subagent through a six-section interview for the TD body (genuine open-ended authoring); the reciprocal `creates-tech-debt` write on the originating change-spec is performed by the Skill directly per ADR-0001 (no second spec-author invocation). Both halves of the reciprocal pair (TD-01) land in a single atomic commit; spec-author defers its terminal-state auto-commit when invoked under this Skill so the Skill can include both files in one commit. Examples:
|
|
5
|
+
|
|
6
|
+
<example>
|
|
7
|
+
Context: The billing-overage change shipped with a one-off Tailwind class for warning-yellow because the design token isn't yet exposed; the engineer wants to log it.
|
|
8
|
+
user: "/hstack:tech-debt-new --origin 2026-05-billing-overage-warning overage-banner-tailwind-class"
|
|
9
|
+
assistant: "I'll invoke spec-author for the tech-debt interview. The six sections cover Title, Why we took the shortcut, What it costs us, Fix sketch, Pre-conditions for fixing, Acceptance. Reciprocally, I'll add this tech-debt id to the change-spec's creates-tech-debt array."
|
|
10
|
+
<commentary>
|
|
11
|
+
Reciprocity per TD-01 is load-bearing. Without the back-reference, audit queries cannot answer "who put this here?" without grepping every change-spec. Per ADR-0001, the TD body is authored by spec-author (interview) and the reciprocal `creates-tech-debt` write on the change-spec is performed by the Skill directly; both files land in one atomic commit.
|
|
12
|
+
</commentary>
|
|
13
|
+
</example>
|
|
14
|
+
|
|
15
|
+
<example>
|
|
16
|
+
Context: The adversarial-reviewer surfaced a deliberate trade-off that should be tracked as tech-debt rather than fixed in the change.
|
|
17
|
+
user: "F-03 routes to tech-debt. /hstack:tech-debt-new --origin 2026-06-knowledge-citations cookie-samesite-attributes"
|
|
18
|
+
assistant: "I'll invoke spec-author. The reciprocal write lands on the change-spec; the adversarial-review's finding gets resolution: tech-debt:<this-td-id> once the artifact is created."
|
|
19
|
+
<commentary>
|
|
20
|
+
This is the routing the adversarial-review's resolution discipline assumes. The tech-debt is created here, then referenced from the adversarial-review's `findings[].resolution`. The Skill is the only path because spec-author owns reciprocal writes.
|
|
21
|
+
</commentary>
|
|
22
|
+
</example>
|
|
23
|
+
tools:
|
|
24
|
+
- Read
|
|
25
|
+
- Write
|
|
26
|
+
- Edit
|
|
27
|
+
- Grep
|
|
28
|
+
- Glob
|
|
29
|
+
- Bash
|
|
30
|
+
- Task
|
|
31
|
+
- "{{TODO-SCRIPT: hstack/scripts/validate-spec.ts — validates tech-debt frontmatter and TD-01..TD-03}}"
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Purpose
|
|
35
|
+
|
|
36
|
+
`hstack-tech-debt-new` captures a tech-debt item via the `spec-author` subagent. Tech-debt artifacts live at `hstack/tech-debt/TD-NNNN-<slug>.md`, are append-only, and maintain a reciprocal back-reference to the originating change-spec via the `introduced-by` ↔ `creates-tech-debt` pair (TD-01).
|
|
37
|
+
|
|
38
|
+
## When to invoke
|
|
39
|
+
|
|
40
|
+
Invoke when:
|
|
41
|
+
- The engineer ships a deliberate compromise (a hack-now-fix-later) and wants it logged.
|
|
42
|
+
- The `adversarial-reviewer` surfaces a finding routed to `tech-debt:<id>` and the artifact does not yet exist.
|
|
43
|
+
- A retrospective surfaces accumulated debt that was not captured at the time it landed (origin: `found-later`).
|
|
44
|
+
|
|
45
|
+
## Inputs
|
|
46
|
+
|
|
47
|
+
- `<slug>` (required, positional): kebab-case slug. Examples: `overage-banner-tailwind-class`, `stripe-webhook-idempotency-buffer`.
|
|
48
|
+
- `--origin <change-spec-id>` (optional): the change-spec that introduced this debt. When set, reciprocal writes apply. When omitted, origin defaults to `found-later`.
|
|
49
|
+
|
|
50
|
+
## Preconditions
|
|
51
|
+
|
|
52
|
+
Before any work:
|
|
53
|
+
|
|
54
|
+
- Verify `hstack/config.yaml` exists at `init-status: complete`.
|
|
55
|
+
- Read every existing tech-debt item under `hstack/tech-debt/` to determine the next sequential id.
|
|
56
|
+
- Verify the `<slug>` matches `^[a-z][a-z0-9-]*$` and is not already used.
|
|
57
|
+
- When `--origin <change-spec-id>` is provided: verify the change-spec exists.
|
|
58
|
+
- Scan existing tech-debt for a near-duplicate (same module, similar slug). Surface any candidates to the engineer; if the new debt is genuinely a duplicate, the Skill halts and directs the engineer to update the existing item instead.
|
|
59
|
+
|
|
60
|
+
## Orchestration steps
|
|
61
|
+
|
|
62
|
+
1. **Compute the next id.** `TD-NNNN-<slug>`.
|
|
63
|
+
|
|
64
|
+
2. **Invoke `spec-author` with explicit deferred-commit instruction.** Use the Task tool with `subagent_type: spec-author` and context = [kernel, `hstack/templates/tech-debt.md`, glossary, the originating change-spec when `--origin`]. The subagent walks the six sections — Title, Why we took the shortcut, What it costs us, Fix sketch, Pre-conditions for fixing, Acceptance — with confirmation gates. **Critical instruction to spec-author**: do NOT auto-commit at terminal author-state (`status: open`) when invoked under `/hstack:tech-debt-new`. The Skill will perform the atomic commit after the reciprocal change-spec write in step 7. Spec-author should leave the new TD file staged-but-uncommitted (or unstaged) so the Skill can include both halves of the reciprocal pair in a single commit. This deviation from spec-author's normal auto-commit-at-status-transition behavior is mandated by the kernel's atomicity rule for reciprocal pairs.
|
|
65
|
+
|
|
66
|
+
3. **Severity.** The subagent elicits severity (critical | high | medium | low). For `severity: critical`, a `target-resolve-by` date is required per TD-02 (this is a future field — surface in the conversation that v1 does not yet enforce it via the validator).
|
|
67
|
+
|
|
68
|
+
4. **Cost and fix-sketch-effort.** Both are controlled enums (`small | medium | large`).
|
|
69
|
+
|
|
70
|
+
5. **Reciprocity.** When `--origin <change-spec-id>` is set:
|
|
71
|
+
- **Authoring half (spec-author).** `spec-author` writes `introduced-by: <change-spec-id>` on the new tech-debt frontmatter during its interview (this field is part of the artifact being authored, so it lands inside the spec-author session). Per the deferred-commit instruction in step 2, spec-author does NOT auto-commit on terminal author-state under this Skill — it leaves the TD file written but uncommitted.
|
|
72
|
+
- **Reciprocal half (direct write by this Skill).** After `spec-author` finishes the interview and returns, this Skill performs the reciprocal write itself via the `Edit` tool — no second `spec-author` invocation. Edit `hstack/specs/changes/<change-spec-id>/spec.md`:
|
|
73
|
+
- Append the new tech-debt id to the frontmatter `creates-tech-debt` array (idempotent — if already present, no-op).
|
|
74
|
+
- Update frontmatter `updated: <today>`.
|
|
75
|
+
- Per the kernel's Mechanical operations section, this reciprocal write is mechanical: the value to append is fully determined by the just-authored TD's id. No interview is required.
|
|
76
|
+
- TD-01 enforces this at validation. Both files land in a single auto-commit (step 7 below) so the reciprocal pair is atomic.
|
|
77
|
+
|
|
78
|
+
6. **Proposed-diff preview (confirmation gate).** Per the kernel's AI-writes-humans-confirm contract for mechanical operations, print the proposed reciprocal-write diff (the `creates-tech-debt` array append on the change-spec, the `updated` bump) and ask "Proceed with these writes? (Y/n)". Default Yes. On `n`, halt without staging the change-spec edit; the TD file remains unstaged so the engineer can `git checkout -- <td-file>` to discard.
|
|
79
|
+
|
|
80
|
+
7. **Validate and atomic-commit both files.** Run `{{TODO-SCRIPT: hstack/scripts/validate-spec.ts}}` against the new TD and (when `--origin` is set) the modified change-spec. TD-01 (reciprocity), TD-02 (severity:critical requires target-resolve-by — v1 surfaces only), TD-03 (no field rewrites once resolved; v1 informational) all checked. On validation pass, `git add` both files and commit with message `tech-debt(TD-NNNN): open` (with `(introduced-by: <change-spec-id>)` appended when applicable). The reciprocal pair (TD `introduced-by` ↔ change-spec `creates-tech-debt`) lands in this single atomic commit. On validation failure, halt; both files remain unstaged for the engineer to inspect or discard.
|
|
81
|
+
|
|
82
|
+
8. **Status note.** The new artifact lands at `status: open`. Advancing to `in-progress` or `resolved` is a separate later operation, not this Skill's domain.
|
|
83
|
+
|
|
84
|
+
## Outputs
|
|
85
|
+
|
|
86
|
+
- `hstack/tech-debt/TD-NNNN-<slug>.md` at `status: open`.
|
|
87
|
+
- When `--origin` is set: an edit to the originating change-spec's `creates-tech-debt` array.
|
|
88
|
+
|
|
89
|
+
The tech-debt item lands at `status: open`. To begin resolution work, invoke `/hstack:tech-debt-resolve TD-NNNN`. To close without a fix, invoke `/hstack:tech-debt-wontfix TD-NNNN`. The new fields `resolved-by`, `resolution-attempted-at`, `wontfix-reason`, `wontfix-accepted-alternative` are left as their template defaults (`null`) at creation time — they are written by the corresponding resolution Skill.
|
|
90
|
+
|
|
91
|
+
## Auto-commit triggers
|
|
92
|
+
|
|
93
|
+
- One commit at terminal author-state (`status: open`). When reciprocity writes are involved, both files are included in the commit. Commit message: `tech-debt(TD-NNNN): open` (with the origin change-spec in parentheses when applicable).
|
|
94
|
+
|
|
95
|
+
## Idempotency contract
|
|
96
|
+
|
|
97
|
+
- Re-running with the same `<slug>` halts because the slug would not be unique.
|
|
98
|
+
- Re-running mid-interview after a halt: `spec-author` reads the partial tech-debt file and resumes.
|
|
99
|
+
- Reciprocal writes are idempotent: if the change-spec's `creates-tech-debt` already contains the tech-debt id, the Skill does not duplicate.
|
|
100
|
+
|
|
101
|
+
## Stop conditions
|
|
102
|
+
|
|
103
|
+
Beyond the kernel's general stop conditions:
|
|
104
|
+
|
|
105
|
+
- The `<slug>` collides with an existing tech-debt item.
|
|
106
|
+
- `--origin` references a change-spec that does not exist.
|
|
107
|
+
- A near-duplicate tech-debt item already exists and the engineer should update it instead.
|
|
108
|
+
- The Why-we-took-the-shortcut field is empty — every tech-debt item must explain its origin, not just enumerate the cost.
|
|
109
|
+
|
|
110
|
+
## Failure modes
|
|
111
|
+
|
|
112
|
+
- **Reciprocal write to the change-spec fails (e.g., the change-spec's frontmatter is broken).** Halt before commit; the TD authoring half also rolls back unstaged. The engineer fixes the change-spec frontmatter manually (broken YAML is hand-fixed and validated; if the change-spec body needs prose authoring corrections, `spec-author` can resume the change-spec since change-spec body editing is interview-driven, but `spec-author` cannot touch the `creates-tech-debt` reciprocal field per kernel — the Skill performs that append on the re-run). Then re-run `/hstack:tech-debt-new` — the Skill is idempotent on the TD half (spec-author resumes the existing partial file) and idempotent on the reciprocal append (a no-op if the TD id is already in the array).
|
|
113
|
+
- **The change-spec is at `shipped` or `archived` status.** TD-03 forbids rewrites on resolved items, but the change-spec at `shipped` may still accept `creates-tech-debt` array appends — surface and confirm with the engineer before writing.
|
|
114
|
+
- **Validator fails TD-01.** Halt before commit; the partial state on disk is unstaged. The engineer reconciles by running the Skill again — the reciprocal half is idempotent and the TD half resumes from the existing file.
|
|
115
|
+
|
|
116
|
+
## Anti-patterns
|
|
117
|
+
|
|
118
|
+
- Never invent a tech-debt id. Sequential per the implicit rule.
|
|
119
|
+
- Never write a tech-debt item without the Why-we-took-the-shortcut section. Debt without context is paperwork.
|
|
120
|
+
- Never write `origin: <change-spec-id>` without the reciprocal `creates-tech-debt` write on that change-spec.
|
|
121
|
+
- Never advance status past `open` from this Skill. Status transitions happen on the fix side, not the capture side.
|
|
122
|
+
- Never overwrite an existing tech-debt item from this Skill. Updates happen via direct `spec-author` invocation when the item is being actively worked on.
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hstack-tech-debt-resolve
|
|
3
|
+
description: |
|
|
4
|
+
Use this skill when the engineer wants to start work on resolving a known tech-debt item. The Skill is the canonical entry point into the resolution flow: it prints the tech-debt's full body, walks each Pre-condition for engineer confirmation (a structured-elicitation loop per the kernel's Mechanical operations section), halts on any unmet pre-condition, and on confirmation performs direct mechanical writes (per ADR-0001, no spec-author invocation): flips the tech-debt to `in-progress`, scaffolds a resolution change folder with `resolves-tech-debt` pre-populated and the Acceptance section quoted into Target Behavior. Both halves of the reciprocal pair (TD ↔ change-spec) land in a single atomic commit. Examples:
|
|
5
|
+
|
|
6
|
+
<example>
|
|
7
|
+
Context: The team agreed to live with a hardcoded Tailwind class until the design token system exposed `--warning-yellow-300`. The token landed yesterday; now the team wants to fix TD-0042.
|
|
8
|
+
user: "/hstack:tech-debt-resolve TD-0042-overage-banner-tailwind-class"
|
|
9
|
+
assistant: "I'll print TD-0042 in full, walk each Pre-condition for your confirmation (the design token bullet should now be met), then flip the TD to in-progress and scaffold the resolution change-spec with the Acceptance section quoted into Target Behavior. After the scaffold, continue with /hstack:test-plan."
|
|
10
|
+
<commentary>
|
|
11
|
+
The Skill is the only authoring path that flips a tech-debt out of `open`. The kernel forbids manual frontmatter edits to tech-debt status. Pre-conditions are prose in v1 and require engineer confirmation; the Skill logs that confirmation into the scaffolded change-spec's Open Questions section so the adversarial-reviewer can later verify the team didn't rationalize away an unmet pre-condition.
|
|
12
|
+
</commentary>
|
|
13
|
+
</example>
|
|
14
|
+
|
|
15
|
+
<example>
|
|
16
|
+
Context: An engineer attempts to start resolving a tech-debt whose Pre-conditions reference an ADR that has not been accepted.
|
|
17
|
+
user: "/hstack:tech-debt-resolve TD-0019-event-ordering-fallback"
|
|
18
|
+
assistant: "I'll halt — TD-0019's Pre-conditions name 'ADR-0034 must be accepted before we pick a strategy', and ADR-0034 is at `proposed`. Resolve that first via /hstack:adr-new or by advancing ADR-0034 to `accepted`."
|
|
19
|
+
<commentary>
|
|
20
|
+
Some pre-conditions are mechanically checkable (ADR exists at `accepted`, file exists, related TD at `resolved`). The Skill checks those mechanically and halts on failure. Prose pre-conditions still require engineer confirmation. Mechanical halts cannot be overridden by engineer confirmation — the upstream artifact must actually change state first.
|
|
21
|
+
</commentary>
|
|
22
|
+
</example>
|
|
23
|
+
|
|
24
|
+
<example>
|
|
25
|
+
Context: An engineer wants to resolve a tech-debt but only partially — the change addresses 2 of 3 Acceptance bullets.
|
|
26
|
+
user: "/hstack:tech-debt-resolve TD-0027-rls-cleanup --partial"
|
|
27
|
+
assistant: "I'll halt — partial resolution is not supported in v1. Either author a new tech-debt via /hstack:tech-debt-new for the portion this change will fix and leave TD-0027 at `open`, or expand the change's scope to satisfy all Acceptance bullets."
|
|
28
|
+
<commentary>
|
|
29
|
+
Per the kernel's tech-debt resolution rules, a change-spec either fully resolves a TD or it doesn't. Partial work creates audit ambiguity ("did this fix it?") and breaks the AR-07 Acceptance-satisfied finding lens. The Skill refuses --partial flags and forces the engineer to make the split explicit.
|
|
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 the TD frontmatter flip and the scaffolded change-spec frontmatter}}"
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Purpose
|
|
44
|
+
|
|
45
|
+
`hstack-tech-debt-resolve` is the canonical entry point for resolving a known tech-debt item. The Skill performs direct mechanical writes in the main session (per ADR-0001, no `spec-author` invocation): flips the TD status `open → in-progress`, sets `resolution-attempted-at`, appends a Resolution Log entry, and scaffolds a resolution change-spec under `hstack/specs/changes/<id>/` with `resolves-tech-debt` pre-populated and the TD's Acceptance section quoted into the change-spec's "Resolves Tech-Debt" section. After this Skill, the engineer continues with the normal workflow (`/hstack:test-plan`, etc.).
|
|
46
|
+
|
|
47
|
+
This Skill exists because manual frontmatter edits to tech-debt status are forbidden by the kernel. The reciprocal `change-spec.resolves-tech-debt: [<td-id>]` write at scaffold time is enforced by TD-04 and lands atomically with the TD status flip in a single auto-commit.
|
|
48
|
+
|
|
49
|
+
## When to invoke
|
|
50
|
+
|
|
51
|
+
Invoke when a tech-debt item is at `status: open`, its Pre-conditions are met, and the engineer wants to begin work on the fix. Re-invoking on a TD already at `in-progress` is a no-op (idempotency): the Skill detects the existing scaffolded change folder via `resolved-by` (set provisionally) and reports its current state.
|
|
52
|
+
|
|
53
|
+
## Inputs
|
|
54
|
+
|
|
55
|
+
- `<td-id>` (required, positional): the tech-debt id (e.g., `TD-0042-overage-banner-tailwind-class` or the short `TD-0042`).
|
|
56
|
+
|
|
57
|
+
Optional:
|
|
58
|
+
|
|
59
|
+
- `--area <module>`: override the area for the scaffolded change-spec. Default: the TD's `related-modules[0]` if non-empty; otherwise the Skill asks.
|
|
60
|
+
- `--slug <slug>`: override the slug for the resolution change-spec. Default: `resolve-<td-slug-suffix>` (e.g., `resolve-overage-banner-tailwind-class`).
|
|
61
|
+
|
|
62
|
+
The `--partial` flag is explicitly rejected — v1 does not support partial resolution.
|
|
63
|
+
|
|
64
|
+
## Preconditions
|
|
65
|
+
|
|
66
|
+
Before any work:
|
|
67
|
+
|
|
68
|
+
- Verify `hstack/tech-debt/<td-id>.md` exists and is at `status: open`. If at `in-progress`, the Skill enters idempotent-resume mode (see below). If at `resolved`, `wontfix`, or `archived`, halt with the terminal status named.
|
|
69
|
+
- Verify the engineer is not on `main` (or the configured default branch) if hstack's branch-hygiene rule applies — the resolve flow will create a new branch as part of the scaffold step.
|
|
70
|
+
- Read the TD's Pre-conditions section. For each bullet, classify mechanically when possible:
|
|
71
|
+
- References to ADR-NNNN: check that the ADR exists at `status: accepted`. If at `proposed` or `deprecated`, halt mechanically.
|
|
72
|
+
- References to another TD: check that the referenced TD is at `resolved`. If not, halt mechanically.
|
|
73
|
+
- References to a file or symbol existing: grep-verify. If absent, halt mechanically.
|
|
74
|
+
- Prose pre-conditions that name no checkable artifact: defer to engineer confirmation in step 2 of orchestration.
|
|
75
|
+
|
|
76
|
+
Mechanical halts cannot be overridden by engineer confirmation; the upstream artifact must change state first.
|
|
77
|
+
|
|
78
|
+
## Orchestration steps
|
|
79
|
+
|
|
80
|
+
1. **Print the TD in full.** Read `hstack/tech-debt/<td-id>.md` and print its Title, Why we took the shortcut, What it costs us, Fix sketch, Pre-conditions, and Acceptance sections to the conversation. The engineer should re-read this before starting; tech-debt context decays.
|
|
81
|
+
|
|
82
|
+
2. **Walk Pre-conditions for confirmation.** For each Pre-condition bullet, ask "Is this met? (y/n + one-sentence justification)". Mechanical halts have already filtered the un-confirmable cases; remaining bullets require engineer judgment. Record each `(bullet, met, justification)` triple in a transient state file at `hstack/.session-state/td-resolve-<td-id>.yaml` for resumability and for inclusion in the scaffolded change-spec's Open Questions section. Any "no" halts the Skill with the recommended remediation surfaced from the bullet text.
|
|
83
|
+
|
|
84
|
+
3. **Confirm proceed.** Print: "TD-NNNN is ready to resolve. Pre-conditions confirmed by `<owner>` on `<date>`. Proceed to scaffold the resolution change folder? (Y/n)". Default Yes.
|
|
85
|
+
|
|
86
|
+
4. **Determine area, slug, and change-id.** If `--area` not provided, use TD's `related-modules[0]`. If `related-modules` is empty, ask the engineer. If `--slug` not provided, default to `resolve-<td-slug-suffix>`. Confirm with engineer. Compute the change-spec id as `<YYYY-MM>-<area>-<slug>`. Verify the area has a current module-spec; verify the derived change folder does not already exist. The id is now known and will be referenced by both writes below.
|
|
87
|
+
|
|
88
|
+
5. **Preview proposed writes (confirmation gate).** Per the kernel's AI writes / humans confirm contract for mechanical operations, print the proposed diff to the engineer:
|
|
89
|
+
- TD frontmatter changes: `status: open → in-progress`, `resolution-attempted-at: <today>`, `updated: <today>`.
|
|
90
|
+
- TD Resolution Log entry to append: `status: open → in-progress on <today> by <owner>. Resolution change-spec: <change-id>.`
|
|
91
|
+
- New change-spec frontmatter (will be seeded in step 7).
|
|
92
|
+
|
|
93
|
+
Ask "Proceed with these writes? (Y/n)". Default Yes. On `n`, halt.
|
|
94
|
+
|
|
95
|
+
6. **Write the TD (direct write + immediate validation).** Edit `hstack/tech-debt/<td-id>.md`:
|
|
96
|
+
- **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.
|
|
97
|
+
- Edit frontmatter: `status: open → in-progress`, `resolution-attempted-at: <today>`, `updated: <today>`.
|
|
98
|
+
- Append the Resolution Log entry: `status: open → in-progress on <today> by <owner>. Resolution change-spec: <change-id>.`
|
|
99
|
+
- Run `{{TODO-SCRIPT: hstack/scripts/validate-spec.ts}}` against the file. On validation failure, halt — do NOT proceed to step 7. Unstaged changes can be reverted via `git checkout -- <td-file>`.
|
|
100
|
+
|
|
101
|
+
7. **Scaffold the resolution change folder.** (Do not call `/hstack:change-new` to avoid duplicate interview prompts.)
|
|
102
|
+
- Create `hstack/specs/changes/<change-id>/`.
|
|
103
|
+
- Seed `spec.md` from `hstack/templates/change-spec.md` with frontmatter populated: `id`, `type: change-spec`, `status: draft`, `owner` (from `git config user.name`), `area`, `related-spec: <area>`, `resolves-tech-debt: [<td-id>]`, `created` and `updated` to today, `schema-version: 1`.
|
|
104
|
+
- Pre-populate the "Resolves Tech-Debt" prose section: a pointer to `../../tech-debt/<td-id>.md` followed by the TD's Acceptance section quoted verbatim under the heading "Acceptance from TD-NNNN".
|
|
105
|
+
- Pre-populate the Open Questions section with the Pre-conditions confirmation log from step 2 (the `(bullet, met, justification)` triples), so the adversarial-reviewer can later verify the team did not rationalize away an unmet pre-condition.
|
|
106
|
+
- Pre-populate Problem section opener: "Resolves [<td-id>](../../tech-debt/<td-id>.md): <TD Title>. The TD was introduced by <introduced-by> and has been at `open` since <created>."
|
|
107
|
+
- Run `{{TODO-SCRIPT: hstack/scripts/validate-spec.ts}}` against the seeded change-spec. On validation failure, halt — the TD write from step 6 must be reverted manually via `git checkout -- <td-file>` before re-running the Skill.
|
|
108
|
+
|
|
109
|
+
8. **Offer branch creation.** Mirror `/hstack:change-new`'s branch hygiene step: offer to create `change/<change-id>` from the current branch. Default Yes.
|
|
110
|
+
|
|
111
|
+
9. **Auto-commit (single atomic commit).** `git add` both the TD and the new change-spec, commit with message `chore(tech-debt-resolve): scaffold <change-id> resolving <td-id>`. The reciprocal pair (TD `in-progress` ↔ change-spec `resolves-tech-debt: [<td-id>]`) lands in this single commit, preserving the kernel's atomicity rule.
|
|
112
|
+
|
|
113
|
+
10. **Direct engineer to next step.** Print: "Resolution change scaffolded at `hstack/specs/changes/<change-id>/`. Continue with `/hstack:test-plan <change-id>` when ready. The TD is now at `in-progress` and will be flipped to `resolved` by `/hstack:finalize` after the resolving change is merged."
|
|
114
|
+
|
|
115
|
+
## Outputs
|
|
116
|
+
|
|
117
|
+
- `hstack/tech-debt/<td-id>.md` advanced to `status: in-progress` with `resolution-attempted-at` and an appended Resolution Log entry.
|
|
118
|
+
- `hstack/specs/changes/<change-id>/spec.md` at `status: draft`, with `resolves-tech-debt: [<td-id>]` and the Resolves Tech-Debt section pre-populated.
|
|
119
|
+
- Optional new branch `change/<change-id>`.
|
|
120
|
+
- One commit at scaffold completion (with the TD flip and the change-spec scaffold both included in the same commit so the reciprocal write lands atomically).
|
|
121
|
+
|
|
122
|
+
## Auto-commit triggers
|
|
123
|
+
|
|
124
|
+
- One commit at scaffold completion, both files included. Commit message: `chore(tech-debt-resolve): scaffold <change-id> resolving <td-id>`.
|
|
125
|
+
|
|
126
|
+
## Idempotency contract
|
|
127
|
+
|
|
128
|
+
- Re-running on a TD already at `in-progress`: the Skill reads the TD's Resolution Log to find the existing resolving change-spec id, verifies the change folder exists, and reports its current state ("Resolution in progress at `<change-id>`; current change-spec status: `<status>`. Continue with `<next-skill>`."). No new scaffold is created.
|
|
129
|
+
- Re-running mid-interview after a halt: the Skill reads `hstack/.session-state/td-resolve-<td-id>.yaml` and resumes at the next un-confirmed Pre-condition.
|
|
130
|
+
- Re-running after the TD's `resolved-by` is set but status is still `in-progress` (an inconsistent state): the Skill halts and surfaces the inconsistency. Reconciliation is manual: either (a) `git checkout HEAD -- hstack/tech-debt/<td-id>.md` to revert to the prior committed state if the inconsistency came from an interrupted finalize, or (b) directly edit the TD frontmatter to set `resolved-by: null` and re-run `validate-spec.ts`. Do not invoke `spec-author` for this reconciliation — the kernel forbids it for reciprocal-back-reference writes.
|
|
131
|
+
|
|
132
|
+
## Stop conditions
|
|
133
|
+
|
|
134
|
+
Beyond the kernel's general stop conditions:
|
|
135
|
+
|
|
136
|
+
- The TD does not exist or is at a terminal status (`resolved`, `wontfix`, `archived`). Halt with the status named.
|
|
137
|
+
- A mechanical Pre-condition halts the Skill (ADR not accepted, dependent TD not resolved, named file absent). Cannot be overridden by engineer confirmation.
|
|
138
|
+
- The engineer answers "no" on any prose Pre-condition. The Skill logs the unmet bullet and surfaces the recommended remediation from the bullet text.
|
|
139
|
+
- The TD's `related-modules[0]` is empty and the engineer does not provide `--area`.
|
|
140
|
+
- The area has no current module-spec.
|
|
141
|
+
- The change-spec id (`<YYYY-MM>-<area>-<slug>`) collides with an existing change folder. Ask the engineer for a different slug.
|
|
142
|
+
- The TD's Acceptance section is empty (TD authored without Acceptance, which TD-01 should have caught — flag as a validation gap).
|
|
143
|
+
- `--partial` flag is passed. Halt with the message above.
|
|
144
|
+
|
|
145
|
+
## Failure modes
|
|
146
|
+
|
|
147
|
+
- **TD's Acceptance is too vague to satisfy mechanically.** The Skill scaffolds anyway but flags in the change-spec's Open Questions that the adversarial-reviewer will need to interpret. The engineer is reminded that AR-07 makes Acceptance-satisfied a mandatory finding lens.
|
|
148
|
+
- **Pre-condition confirmation session interrupted.** Resumable via the session-state file; engineer continues from the next un-confirmed bullet.
|
|
149
|
+
- **A direct write fails mid-scaffold.** Halt before any commit. Per the new ordering (step 6 writes TD, step 7 writes change-spec, step 9 commits both atomically), no partial commit is possible — the failure leaves both files unstaged for the engineer to inspect or discard via `git checkout -- <file>`.
|
|
150
|
+
|
|
151
|
+
## Anti-patterns
|
|
152
|
+
|
|
153
|
+
- Never invoke `spec-author` for the TD status flip. Per the kernel's Mechanical operations section (ADR-0001), this Skill performs the flip directly via the `Edit` tool. The kernel's "spec-author is the only subagent permitted to write" rule applies to subagents; this Skill runs in the main session.
|
|
154
|
+
- Never accept blanket "all pre-conditions are met" confirmations. Each bullet must be individually confirmed with a one-sentence justification.
|
|
155
|
+
- Never silently downgrade a mechanical halt to a soft warning. Mechanical halts represent upstream state that must actually change.
|
|
156
|
+
- Never scaffold without quoting the TD's Acceptance into the change-spec's Resolves Tech-Debt section. The quote is what AR-07 checks against.
|
|
157
|
+
- Never accept `--partial`. Direct the engineer to split the TD via `/hstack:tech-debt-new` instead.
|
|
158
|
+
- Never proceed when the TD is at a terminal status. Resolved is resolved; wontfix is final.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hstack-tech-debt-stale
|
|
3
|
+
description: |
|
|
4
|
+
Use this skill when a tech-debt item's original claim no longer reproduces because the surrounding code was rewritten, a dependency was upgraded, the bug was fixed incidentally as part of unrelated work, or the system the TD described no longer exists. This is distinct from `/hstack:tech-debt-wontfix`: wontfix says "the problem is still real but we choose to live with it"; stale-no-longer-reproducible says "the problem no longer exists, verifiably." The Skill runs a one-question structured-elicitation loop (a per-kernel Mechanical operations pattern), captures the verification evidence into the TD's frontmatter, and performs direct mechanical writes (per ADR-0001, no spec-author invocation): writes `stale-verified-at` and `stale-verification-method`, flips status `open → stale-no-longer-reproducible`, appends a Resolution Log entry, all in a single atomic commit. The new status is terminal — per TD-03, no field rewrites are permitted afterwards. Examples:
|
|
5
|
+
|
|
6
|
+
<example>
|
|
7
|
+
Context: TD-0042 captured a workaround needed because a Tiptap plugin had a known bug. The team upgraded Tiptap last week and the bug is fixed upstream; the workaround is still in the codebase but the underlying claim no longer holds.
|
|
8
|
+
user: "/hstack:tech-debt-stale TD-0042-tiptap-paste-workaround"
|
|
9
|
+
assistant: "I'll ask one question: what evidence shows the original claim no longer reproduces? On confirmation, the Skill writes stale-verified-at and stale-verification-method directly (per ADR-0001, no spec-author invocation), flips status to stale-no-longer-reproducible, and commits atomically. The new status is terminal."
|
|
10
|
+
<commentary>
|
|
11
|
+
Stale-no-longer-reproducible is the controlled exit for organic-decay closures. The kernel requires the verification evidence because "we don't reproduce it anymore" without an artefact is the kind of silent backlog-clearing that lets real debt slip through unaudited. Future engineers reading the TD see the explicit verification rather than just an unexplained closure.
|
|
12
|
+
</commentary>
|
|
13
|
+
</example>
|
|
14
|
+
|
|
15
|
+
<example>
|
|
16
|
+
Context: An engineer wants to use this Skill on a TD whose original problem IS still real but they no longer want to fix it.
|
|
17
|
+
user: "/hstack:tech-debt-stale TD-0017-prompt-template-string-concat"
|
|
18
|
+
assistant: "Wait — this is wontfix territory, not stale. Stale-no-longer-reproducible means the problem has verifiably gone away. If the prompt-template string-concat is still in the codebase and still has the original issue, the team is choosing to live with it (wontfix), not observing that it no longer exists (stale). I'll halt and direct you to /hstack:tech-debt-wontfix instead, OR you can show me evidence the string-concat code was actually removed and I'll proceed with stale."
|
|
19
|
+
<commentary>
|
|
20
|
+
The Skill applies a deliberate semantic check at the verification step. Misusing stale for a deferral-flavored closure corrupts the audit signal that distinguishes deliberate-deferral (wontfix) from organic-decay (stale). The engineer's verification evidence must describe an absence, not a preference.
|
|
21
|
+
</commentary>
|
|
22
|
+
</example>
|
|
23
|
+
tools:
|
|
24
|
+
- Read
|
|
25
|
+
- Write
|
|
26
|
+
- Edit
|
|
27
|
+
- Grep
|
|
28
|
+
- Glob
|
|
29
|
+
- Bash
|
|
30
|
+
- "{{TODO-SCRIPT: hstack/scripts/validate-spec.ts — validates the TD status flip and TD-07 (stale requires both verification fields non-null)}}"
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Purpose
|
|
34
|
+
|
|
35
|
+
`hstack-tech-debt-stale` is the controlled closure path for tech-debt items whose original claim no longer reproduces. The Skill captures the verification evidence in two required fields (`stale-verified-at` and `stale-verification-method`) and flips status `open → stale-no-longer-reproducible` directly in the main session (per ADR-0001, no `spec-author` invocation). Per TD-03, the new status is terminal — no field rewrites are permitted afterwards.
|
|
36
|
+
|
|
37
|
+
The Skill exists because closing aged-out TDs via `/hstack:tech-debt-wontfix` would corrupt the audit signal `wontfix` carries (deliberate cost-benefit decision to live with the compromise). Stale-no-longer-reproducible is the structurally honest closure for organic decay.
|
|
38
|
+
|
|
39
|
+
## When to invoke
|
|
40
|
+
|
|
41
|
+
Invoke when a tech-debt item at `status: open` has a claim that no longer reproduces — typically because:
|
|
42
|
+
|
|
43
|
+
- The surrounding code was rewritten or removed.
|
|
44
|
+
- A third-party dependency was upgraded and shipped a fix.
|
|
45
|
+
- The bug was fixed incidentally as part of an unrelated change.
|
|
46
|
+
- The system, module, or call path the TD described no longer exists.
|
|
47
|
+
|
|
48
|
+
Do NOT invoke for deferrals ("we won't get to this") — those go to `/hstack:tech-debt-wontfix`. Do NOT invoke for TDs that are still observably true but the team is choosing not to fix — also `/hstack:tech-debt-wontfix`. The semantic distinction is load-bearing: stale describes an absence, wontfix describes a choice.
|
|
49
|
+
|
|
50
|
+
## Inputs
|
|
51
|
+
|
|
52
|
+
- `<td-id>` (required, positional): the tech-debt id.
|
|
53
|
+
|
|
54
|
+
## Preconditions
|
|
55
|
+
|
|
56
|
+
- Verify `hstack/tech-debt/<td-id>.md` exists and is at `status: open`. If at `in-progress`, halt — work is already underway; complete or cancel the resolution change-spec first. If at any terminal status (`resolved`, `wontfix`, `stale-no-longer-reproducible`, `archived`), halt with the status named.
|
|
57
|
+
|
|
58
|
+
## Orchestration steps
|
|
59
|
+
|
|
60
|
+
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 a stale-no-longer-reproducible closure; the verification step depends on understanding what the original claim actually was.
|
|
61
|
+
|
|
62
|
+
2. **Ask the verification question.** "What evidence shows this TD's claim no longer reproduces? Be specific — a grep result that returns nothing, a git log showing the dependent code was removed, a dependency upgrade that fixes the issue upstream, etc. (one sentence, ≤ 300 characters)". Capture the answer.
|
|
63
|
+
|
|
64
|
+
3. **Semantic check.** If the answer reads like a deferral or a preference rather than an absence ("we don't care anymore", "not worth it", "moved on", "low priority", "not blocking us"), halt with: "That reads like a wontfix rationale, not stale-no-longer-reproducible. Stale means the original problem has verifiably gone away — code removed, dependency upgraded, system retired. If the problem is still observably present and the team is choosing not to fix it, use /hstack:tech-debt-wontfix instead." The Skill does not write anything in this case.
|
|
65
|
+
|
|
66
|
+
4. **Confirm.** Print the captured verification method and ask "Mark TD-NNNN as stale-no-longer-reproducible with this evidence? (Y/n)". Default Yes. Include a one-line summary of what will be written to disk so the engineer sees the proposed-diff before committing (per the kernel's AI writes / humans confirm contract for mechanical operations).
|
|
67
|
+
|
|
68
|
+
5. **Verify the answer length.** If the answer exceeds 300 characters, ask for a tighter version — stale verification methods are short, specific, and load-bearing. If the engineer cannot tighten below 300 chars without losing evidence, the verification probably isn't structural enough to qualify as stale; consider whether wontfix is the right path.
|
|
69
|
+
|
|
70
|
+
6. **Write the stale 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`:
|
|
71
|
+
- **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.
|
|
72
|
+
- Edit frontmatter: `stale-verified-at: <today>`, `stale-verification-method: <answer>`, `status: open → stale-no-longer-reproducible`, `updated: <today>`.
|
|
73
|
+
- Append to the Resolution Log section: `status: open → stale-no-longer-reproducible on <today> by <owner>. Verification method: <answer>.`
|
|
74
|
+
|
|
75
|
+
Run `{{TODO-SCRIPT: hstack/scripts/validate-spec.ts}}` against the file. TD-07 (stale-no-longer-reproducible requires both `stale-verified-at` and `stale-verification-method` non-null) must pass once the validator ships; until then, the proposed-diff preview in step 4 is the v1 substitute per the kernel's AI writes / humans confirm clause. On validation pass (or v1 proposed-diff acknowledgement), `git add` the file and commit with message `tech-debt(<td-id>): stale-no-longer-reproducible`. The three 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>`.
|
|
76
|
+
|
|
77
|
+
7. **Confirm completion.** Print: "TD-NNNN is now `stale-no-longer-reproducible`. Per TD-03, no further field rewrites are permitted on this artifact. If the original claim ever reappears, author a new tech-debt via `/hstack:tech-debt-new` rather than re-opening this one."
|
|
78
|
+
|
|
79
|
+
## Outputs
|
|
80
|
+
|
|
81
|
+
- `hstack/tech-debt/<td-id>.md` advanced to `status: stale-no-longer-reproducible` with `stale-verified-at` and `stale-verification-method` set, and a Resolution Log entry appended.
|
|
82
|
+
- One commit. Message: `tech-debt(<td-id>): stale-no-longer-reproducible`.
|
|
83
|
+
|
|
84
|
+
## Auto-commit triggers
|
|
85
|
+
|
|
86
|
+
- One commit at the status flip. The kernel's auto-commit-at-status-transition rule applies.
|
|
87
|
+
|
|
88
|
+
## Idempotency contract
|
|
89
|
+
|
|
90
|
+
- Re-running on a TD already at `stale-no-longer-reproducible`: the Skill reads the existing artifact and produces a no-op aside from informing the engineer the TD is already stale.
|
|
91
|
+
- Re-running mid-interview after a halt: the Skill does not persist session state (the interview is one question; re-asking is cheaper than state-file management).
|
|
92
|
+
|
|
93
|
+
## Stop conditions
|
|
94
|
+
|
|
95
|
+
Beyond the kernel's general stop conditions:
|
|
96
|
+
|
|
97
|
+
- The TD does not exist or is at a non-`open` status. Halt with the status named.
|
|
98
|
+
- The verification answer reads as a deferral or preference (per step 3). The Skill refuses to write and surfaces the wontfix recommendation.
|
|
99
|
+
- The answer exceeds 300 characters and the engineer cannot tighten it without losing evidence. Halt and surface the wontfix recommendation — overly long stale verifications usually indicate the claim isn't actually absent.
|
|
100
|
+
- The engineer declines confirmation at step 4.
|
|
101
|
+
|
|
102
|
+
## Failure modes
|
|
103
|
+
|
|
104
|
+
- **Direct write fails (filesystem, validator, or git).** Halt; the four frontmatter writes plus the Resolution Log append must land in a single auto-commit. Partial writes are not possible if the Skill aborts on validator failure before staging. Concrete recovery: `git checkout -- hstack/tech-debt/<td-id>.md` to revert to the prior committed state.
|
|
105
|
+
- **Stale claim turns out to be reproducible after closure.** Per TD-03 the closed TD is immutable; the engineer authors a new tech-debt via `/hstack:tech-debt-new` describing the reappeared claim. The new TD references the closed one in its Title or Why-we-took-the-shortcut for audit-trail continuity.
|
|
106
|
+
|
|
107
|
+
## Anti-patterns
|
|
108
|
+
|
|
109
|
+
- Never accept a stale verification that reads as a deferral. The check is mandatory and is the v1 defense against misusing stale to clear backlog without an actual claim-absence verification.
|
|
110
|
+
- Never write `status: stale-no-longer-reproducible` without both `stale-verified-at` and `stale-verification-method` non-null. TD-07 enforces this at validation (once the validator ships); the Skill's structured-elicitation loop enforces it at write time.
|
|
111
|
+
- Never invoke `spec-author` for this transition. Per the kernel's Mechanical operations section (ADR-0001), this Skill performs the writes directly. The status flip, two field writes, and Resolution Log append land atomically in a single Skill-driven commit.
|
|
112
|
+
- Never re-open a stale-no-longer-reproducible TD. Per TD-03, the status is terminal — author a new TD instead if the claim reappears.
|
|
113
|
+
- Never use this Skill as a faster path to `wontfix`. The semantic distinction (absence vs choice) is load-bearing for audit signal honesty. If the engineer is tempted to bypass `wontfix`'s two-question discipline by routing through stale, the Skill's semantic check (step 3) is the v1 defense.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
---
|
|
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>
|
|
23
|
+
tools:
|
|
24
|
+
- Read
|
|
25
|
+
- Write
|
|
26
|
+
- Edit
|
|
27
|
+
- Grep
|
|
28
|
+
- Glob
|
|
29
|
+
- Bash
|
|
30
|
+
- Task
|
|
31
|
+
- "{{TODO-SCRIPT: hstack/scripts/validate-spec.ts — validates the TD frontmatter flip and TD-06 (wontfix-reason and wontfix-accepted-alternative both non-null)}}"
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Purpose
|
|
35
|
+
|
|
36
|
+
`hstack-tech-debt-wontfix` is the controlled closure path for tech-debt items the team has decided not to fix. The Skill captures the rationale in two required fields (`wontfix-reason` and `wontfix-accepted-alternative`) and flips status `open → wontfix` directly in the main session (per ADR-0001, no `spec-author` invocation). Per TD-03, wontfix is terminal — no field rewrites are permitted afterwards.
|
|
37
|
+
|
|
38
|
+
## When to invoke
|
|
39
|
+
|
|
40
|
+
Invoke when a tech-debt item at `status: open` will not be fixed and the team has decided to live with the compromise permanently. Do NOT invoke for deferrals ("we'll get to it later") — those items stay at `open`. The Skill applies a deliberate prose-level friction to refuse deferral-flavored rationales.
|
|
41
|
+
|
|
42
|
+
## Inputs
|
|
43
|
+
|
|
44
|
+
- `<td-id>` (required, positional): the tech-debt id.
|
|
45
|
+
|
|
46
|
+
## Preconditions
|
|
47
|
+
|
|
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.
|
|
49
|
+
|
|
50
|
+
## Orchestration steps
|
|
51
|
+
|
|
52
|
+
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
|
+
|
|
54
|
+
2. **Ask the first question.** "Why won't this tech-debt be fixed? (one sentence, ≤ 200 characters)". Capture the answer.
|
|
55
|
+
|
|
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.
|
|
57
|
+
|
|
58
|
+
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
|
+
|
|
60
|
+
5. **Confirm.** Print both answers and ask "Mark TD-NNNN as wontfix with this rationale? (Y/n)". Default Yes.
|
|
61
|
+
|
|
62
|
+
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.
|
|
64
|
+
- Edit frontmatter: `wontfix-reason: <answer-a>`, `wontfix-accepted-alternative: <answer-b>`, `status: open → wontfix`, `updated: <today>`.
|
|
65
|
+
- Append to the Resolution Log section: `status: open → wontfix on <today> by <owner>. Reason: <answer-a>. Accepted alternative: <answer-b>.`
|
|
66
|
+
|
|
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>`.
|
|
68
|
+
|
|
69
|
+
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
|
+
|
|
71
|
+
## Outputs
|
|
72
|
+
|
|
73
|
+
- `hstack/tech-debt/<td-id>.md` advanced to `status: wontfix` with `wontfix-reason` and `wontfix-accepted-alternative` set, and a Resolution Log entry appended.
|
|
74
|
+
- One commit. Message: `tech-debt(<td-id>): wontfix`.
|
|
75
|
+
|
|
76
|
+
## Auto-commit triggers
|
|
77
|
+
|
|
78
|
+
- One commit at the status flip. The kernel's auto-commit-at-status-transition rule applies.
|
|
79
|
+
|
|
80
|
+
## Idempotency contract
|
|
81
|
+
|
|
82
|
+
- Re-running on a TD already at `wontfix`: the Skill reads the existing artifact and produces a no-op aside from informing the engineer the TD is already wontfix.
|
|
83
|
+
- Re-running mid-interview after a halt: the Skill does not persist session state (the interview is short enough that re-asking both questions is cheaper than state-file management).
|
|
84
|
+
|
|
85
|
+
## Stop conditions
|
|
86
|
+
|
|
87
|
+
Beyond the kernel's general stop conditions:
|
|
88
|
+
|
|
89
|
+
- The TD does not exist or is at a non-`open` status. Halt with status named.
|
|
90
|
+
- 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
|
+
- The engineer declines confirmation at step 5.
|
|
93
|
+
|
|
94
|
+
## Failure modes
|
|
95
|
+
|
|
96
|
+
- **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.
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
---
|
|
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
|
+
|
|
24
|
+
tools:
|
|
25
|
+
- Read
|
|
26
|
+
- Bash
|
|
27
|
+
- Glob
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Purpose
|
|
31
|
+
|
|
32
|
+
`hstack-telemetry` produces a retrospective observability report — a markdown file under `hstack/telemetry/reports/` — by parsing on-disk artifacts, git history, and Claude Code transcripts. The Skill is mechanical: it shells out to a Python script, reports the output path, and returns. No subagent is invoked. The kernel's "no parallel tracker" rule is preserved because the report is derivative — re-runnable from source, never authoritative.
|
|
33
|
+
|
|
34
|
+
The report covers five buckets:
|
|
35
|
+
|
|
36
|
+
1. **Token economics** — TE-1 cost-score per Skill, TE-2 cache-hit ratio per Skill, TE-3 subagent entry-tax amortization.
|
|
37
|
+
2. **Workflow shape** — WS-1 phase duration, WS-2 gate findings density, WS-4 scope-amendment rate, WS-6 halt reasons.
|
|
38
|
+
3. **Quality outcomes** — QO-2 severity × resolution-type mix, QO-3 test-immutability audit, QO-4 verifier observed-vs-promised.
|
|
39
|
+
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
|
+
5. **Contract drift** — module-spec staleness × recent commit activity, ADR supersession lag, tech-debt half-life by exit path.
|
|
41
|
+
|
|
42
|
+
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).
|
|
43
|
+
|
|
44
|
+
## When to invoke
|
|
45
|
+
|
|
46
|
+
Run any time. Common cadence:
|
|
47
|
+
|
|
48
|
+
- Weekly for active engineering — catches drift early.
|
|
49
|
+
- After every ~5 shipped changes — surfaces trend lines that single-change inspection misses.
|
|
50
|
+
- Whenever a Skill or subagent has been tuned — confirm the change moved the relevant metric.
|
|
51
|
+
|
|
52
|
+
The Skill is read-only and idempotent — re-running produces a fresh report at the same path (overwrites the same-day file).
|
|
53
|
+
|
|
54
|
+
## Inputs
|
|
55
|
+
|
|
56
|
+
- `--window <N>` (optional): limit git/transcript history to the last N days. Default 30. `--window 0` means all-history.
|
|
57
|
+
- `--out <path>` (optional): override the report output path. Default `hstack/telemetry/reports/<YYYY-MM-DD>.md`.
|
|
58
|
+
|
|
59
|
+
## Preconditions
|
|
60
|
+
|
|
61
|
+
- The consuming repo has been initialized via `/hstack:init` (at minimum: `hstack/` directory exists).
|
|
62
|
+
- Python 3.10+ is available on PATH (the script uses `from __future__ import annotations` and modern typing).
|
|
63
|
+
- The git repository is intact (`.git/` present); the Skill walks `git log --all`.
|
|
64
|
+
|
|
65
|
+
## Orchestration steps
|
|
66
|
+
|
|
67
|
+
1. **Locate the script.** The Skill resolves `hstack/scripts/telemetry/report.py` relative to the consuming repo's hstack root. If the script is missing, halt with: "telemetry script not found — re-vendor hstack or run `/hstack:configure`".
|
|
68
|
+
2. **Shell out.** Invoke `python3 hstack/scripts/telemetry/report.py --repo <repo-root> --window <N>`. Capture stdout/stderr.
|
|
69
|
+
3. **Surface the output path.** On success, print the report path and a one-line summary (number of changes, TDs, commits, sessions analyzed — already printed to stderr by the script).
|
|
70
|
+
4. **On failure.** Surface the Python traceback. The script is dependency-light (no PyYAML required); failures typically indicate a corrupted artifact or a git repo issue.
|
|
71
|
+
|
|
72
|
+
## Outputs
|
|
73
|
+
|
|
74
|
+
- `hstack/telemetry/reports/<YYYY-MM-DD>.md` — the markdown report.
|
|
75
|
+
- No frontmatter changes. No commits. The Skill is read-only.
|
|
76
|
+
|
|
77
|
+
## Auto-commit triggers
|
|
78
|
+
|
|
79
|
+
None. The Skill is read-only.
|
|
80
|
+
|
|
81
|
+
## Idempotency contract
|
|
82
|
+
|
|
83
|
+
Re-running on the same day overwrites the same-day report file. Different windows produce different reports under the same date — last run wins. To preserve a snapshot, copy or rename the file manually.
|
|
84
|
+
|
|
85
|
+
## Stop conditions
|
|
86
|
+
|
|
87
|
+
- `hstack/scripts/telemetry/report.py` is missing.
|
|
88
|
+
- Python 3 is not available.
|
|
89
|
+
- The git repository is corrupt or `.git/` is missing.
|
|
90
|
+
|
|
91
|
+
## Anti-patterns
|
|
92
|
+
|
|
93
|
+
- 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.
|
|
94
|
+
- Never use the report as an input to a Skill that writes artifacts. It is a retrospective lens, not an in-flight signal.
|
|
95
|
+
- Never delete reports to manipulate trend lines. Old reports are git-tracked and can be referenced for retrospective comparison.
|
|
96
|
+
- 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.
|