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-commit
|
|
3
|
+
description: |
|
|
4
|
+
Use this skill when the engineer wants to commit work by hand using the same Commitizen format hstack subagents use for auto-commits — so the git log reads uniformly whether a phase landed through `/hstack:implement` or you fixed a typo manually. Pushed only on explicit confirmation. Examples:
|
|
5
|
+
|
|
6
|
+
<example>
|
|
7
|
+
Context: The engineer made a small cleanup edit between hstack workflow phases and wants to commit it without polluting the git history with a divergent message format.
|
|
8
|
+
user: "/hstack:commit"
|
|
9
|
+
assistant: "I'll read git status, walk you through which files to stage (specific paths over `-A`), show the diff, propose a Commitizen-format commit message, and commit on your confirmation. Push is a separate confirmation."
|
|
10
|
+
<commentary>
|
|
11
|
+
The Skill is for human-driven commits outside the hstack subagent flow. It's not used by subagents — they have their own auto-commit logic embedded in their session-start protocols. The format match is the value: same git log shape whether the commit came from an agent or a human.
|
|
12
|
+
</commentary>
|
|
13
|
+
</example>
|
|
14
|
+
|
|
15
|
+
<example>
|
|
16
|
+
Context: A pre-commit hook fails on the first attempt and the engineer is tempted to bypass.
|
|
17
|
+
user: "The hook is failing because of an unrelated lint error. Can we just --no-verify?"
|
|
18
|
+
assistant: "No — the kernel forbids hook bypass. I'll investigate the failing hook with you, fix the underlying issue, then re-attempt the commit cleanly."
|
|
19
|
+
<commentary>
|
|
20
|
+
Defense in depth on the kernel's forbidden-tools list: the Skill refuses --no-verify and other hook-bypass flags. Same rule the implementer subagent enforces. Hooks fail for a reason; investigating beats bypassing.
|
|
21
|
+
</commentary>
|
|
22
|
+
</example>
|
|
23
|
+
tools:
|
|
24
|
+
- Bash
|
|
25
|
+
- Read
|
|
26
|
+
- Grep
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Purpose
|
|
30
|
+
|
|
31
|
+
`hstack-commit` is the human-driven commit Skill that matches the Commitizen format hstack subagents use for their auto-commits. The point is uniform git history: a reader scanning the log cannot tell whether a given commit was a subagent auto-commit or a human-typed one, because both follow `<type>(<scope>): <summary>`. It does not replace the kernel's auto-commit-at-status-transition rule — subagents still auto-commit on their own. The Skill is for everything else: typo fixes, ad-hoc cleanups, edits between hstack invocations, the occasional manual touch.
|
|
32
|
+
|
|
33
|
+
## When to invoke
|
|
34
|
+
|
|
35
|
+
Invoke when:
|
|
36
|
+
- You've made an edit by hand (outside a hstack subagent flow) and want to commit it.
|
|
37
|
+
- You want to commit work-in-progress before stepping away.
|
|
38
|
+
- A subagent auto-commit didn't fire (rare, but possible if a Skill halted mid-phase) and you need to capture state manually.
|
|
39
|
+
|
|
40
|
+
Do NOT invoke inside an hstack subagent flow — the subagents auto-commit on status transitions per the kernel.
|
|
41
|
+
|
|
42
|
+
## Inputs
|
|
43
|
+
|
|
44
|
+
- No positional arguments. The Skill drives entirely from `git status` and conversation.
|
|
45
|
+
- Optional `--push` flag: if set, push after committing (still subject to explicit per-invocation confirmation; the system never force-pushes).
|
|
46
|
+
|
|
47
|
+
## Preconditions
|
|
48
|
+
|
|
49
|
+
Before any work:
|
|
50
|
+
|
|
51
|
+
- Verify the working directory is a git repository.
|
|
52
|
+
- Read `hstack/config.yaml` if present, to namespace the commit scope when committing inside an hstack-governed repo. Absent config is fine — the Skill works on any repo, hstack-installed or not.
|
|
53
|
+
- Verify there are changes to commit. If working tree is clean, halt with "nothing to commit."
|
|
54
|
+
|
|
55
|
+
## Orchestration steps
|
|
56
|
+
|
|
57
|
+
1. **Read git status.** Run `git status --short` and show the file list with their status markers. Categorize: modified, untracked, deleted, renamed.
|
|
58
|
+
|
|
59
|
+
2. **Stage with intent.** Default to staging by named path, NOT `git add -A`. The latter sweeps in `.env`, credentials, large binaries, and other unintended files. The Skill proposes the specific files to stage based on the change being committed, the engineer confirms.
|
|
60
|
+
- Exception: if every file is clearly part of one logical change AND none of the file names match common sensitive patterns (`.env`, `secret`, `credential`, `*.key`, `*.pem`), the Skill may propose `git add -A` with the engineer's explicit confirmation.
|
|
61
|
+
- Sensitive-file guardrail: if any staged file's name matches the sensitive-pattern list, halt and ask before committing.
|
|
62
|
+
|
|
63
|
+
3. **Show the diff.** Run `git diff --cached --stat` for a summary, then `git diff --cached` for the full diff if the diff is reasonably small. For large diffs, show stat plus a sample of the most-changed files.
|
|
64
|
+
|
|
65
|
+
4. **Draft a Commitizen-format commit message.** Following the format codified for hstack:
|
|
66
|
+
- Format: `<type>(<scope>): <summary>`
|
|
67
|
+
- `<type>` is one of: `feat`, `fix`, `chore`, `docs`, `refactor`, `test`, `style`, `perf`, `ci`
|
|
68
|
+
- `<scope>` names the area being touched. For commits inside hstack-governed code, prefer the change-id, the area, the Skill name, or the artifact type (e.g., `change-plan`, `billing`, `implement`, `data-review`). For non-hstack commits in the same repo, use the natural area (e.g., `auth`, `orchestrator`, `webhooks`).
|
|
69
|
+
- `<summary>` ≤ 72 characters, imperative present tense ("add" not "added"), no trailing period.
|
|
70
|
+
- Body (optional): the "why" rather than the "what". For commits inside hstack workflow, name the related change-id or artifact. For status transitions, name the transition explicitly.
|
|
71
|
+
- **Never add "Generated with Claude Code" or similar attribution.** The user's global rule.
|
|
72
|
+
- Footer: only conventional-commits footers (`BREAKING CHANGE:`, `Refs: <issue>`) when applicable.
|
|
73
|
+
|
|
74
|
+
5. **Confirm and commit.** Show the proposed commit message to the engineer. On confirmation, run `git commit -m "<subject>" -m "<body>"` (HEREDOC for multi-line bodies). Honor every git hook — `--no-verify`, `--no-gpg-sign`, and other bypass flags are forbidden.
|
|
75
|
+
|
|
76
|
+
6. **Verify the commit landed.** Run `git log -1 --format='%h %s'` and surface the result.
|
|
77
|
+
|
|
78
|
+
7. **Push (only with explicit confirmation).** Push is hard-to-reverse and visible to others — never auto-push. If `--push` was provided, ask for confirmation in the conversation; if not provided, end without pushing. When pushing, use the current branch's tracked upstream (no `--force`, no force-with-lease without per-invocation authorization, no push to `main` if the current branch is `main` without explicit confirmation).
|
|
79
|
+
|
|
80
|
+
## Outputs
|
|
81
|
+
|
|
82
|
+
- One git commit on the current branch.
|
|
83
|
+
- Optionally, a `git push` to the current branch's upstream — but only with explicit per-invocation confirmation.
|
|
84
|
+
- No artifact writes. No subagent invocations.
|
|
85
|
+
|
|
86
|
+
## Auto-commit triggers
|
|
87
|
+
|
|
88
|
+
None. This Skill IS the commit — there is nothing else for it to auto-commit. Subagents have their own auto-commit logic governed by the kernel.
|
|
89
|
+
|
|
90
|
+
## Idempotency contract
|
|
91
|
+
|
|
92
|
+
Not idempotent in the strict sense — a commit is a one-shot operation. Re-running the Skill on a clean working tree halts with "nothing to commit," which is the natural idempotency boundary.
|
|
93
|
+
|
|
94
|
+
## Stop conditions
|
|
95
|
+
|
|
96
|
+
Beyond the kernel's general stop conditions:
|
|
97
|
+
|
|
98
|
+
- Working tree is clean. Nothing to commit.
|
|
99
|
+
- A staged file's name matches the sensitive-pattern list (`.env`, `*secret*`, `*credential*`, `*.key`, `*.pem`). Halt and ask.
|
|
100
|
+
- A pre-commit hook fails. Investigate and fix the underlying issue — do NOT bypass with `--no-verify`. If the fix requires out-of-scope edits (when committing inside an hstack-governed change), halt and surface as a scope-amendment situation.
|
|
101
|
+
- The proposed commit message exceeds 72 characters on the summary line. Re-draft.
|
|
102
|
+
- A destructive push operation is requested (`--force`, force-with-lease, push to `main`) without explicit per-invocation authorization in the current conversation. Halt and confirm.
|
|
103
|
+
- The engineer requested `--push` but the current branch has no upstream. Halt and ask which remote / branch to push to.
|
|
104
|
+
|
|
105
|
+
## Failure modes
|
|
106
|
+
|
|
107
|
+
- **Pre-commit hook fails.** Investigate; surface the hook's output; propose a fix. Re-run the commit attempt with the fix in place. Never bypass.
|
|
108
|
+
- **`gpg-sign` configured but signing key unavailable.** Surface the gpg error; do NOT bypass with `--no-gpg-sign`. Engineer fixes their gpg config and re-runs.
|
|
109
|
+
- **`git push` rejected (non-fast-forward).** Surface the rejection; recommend `git pull --rebase` then re-attempt; never propose `--force` without explicit authorization.
|
|
110
|
+
- **Empty commit attempted.** If `git add` left the index empty (e.g., every staged change was already committed), halt with the empty-commit message; do not use `--allow-empty` without engineer confirmation.
|
|
111
|
+
|
|
112
|
+
## Anti-patterns
|
|
113
|
+
|
|
114
|
+
- Never use `git add -A` silently. Default to staging by named path; sweep only with explicit engineer confirmation.
|
|
115
|
+
- Never use `--no-verify`, `--no-gpg-sign`, or any hook-bypass flag.
|
|
116
|
+
- Never use `git commit --amend` to modify a published (pushed) commit without explicit per-invocation authorization. The system prompt's safety rule applies.
|
|
117
|
+
- Never auto-push. Push is a separate, explicit, per-invocation decision.
|
|
118
|
+
- Never use `git push --force` or `--force-with-lease` without explicit per-invocation authorization in the current conversation.
|
|
119
|
+
- Never add "Generated with Claude Code" or any AI-attribution footer to the commit message. The user's global rule forbids it.
|
|
120
|
+
- Never invent a `<scope>` that doesn't reflect what was actually touched. If the change spans multiple unrelated areas, propose splitting into multiple commits.
|
|
121
|
+
- Never commit a file whose name matches the sensitive-pattern list without explicit engineer confirmation.
|
|
122
|
+
- Never bypass the kernel's database-workflow or forbidden-tools rules even when committing manually — `service_role` keys, `supabase db push` against remote, etc., are forbidden regardless of the commit path.
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hstack-configure
|
|
3
|
+
description: |
|
|
4
|
+
Use this skill when an engineer needs to update `hstack/config.yaml` after init has already completed, re-run the interview for a single product-context document, or migrate the schema-version when hstack itself ships a structural change. This is the editor counterpart to `hstack-init`; it never bootstraps from nothing and never advances the global `init-status` field. Examples:
|
|
5
|
+
|
|
6
|
+
<example>
|
|
7
|
+
Context: The team has decided to move their personas store from `hstack/context/personas/` to a Notion database now that the Notion MCP is wired up.
|
|
8
|
+
user: "Re-configure hstack to use the Notion personas store."
|
|
9
|
+
assistant: "I'll run /hstack:configure and walk the personas-store config field. Existing personas in hstack/context/personas/ stay on disk as sync stubs pointing at the new Notion records."
|
|
10
|
+
<commentary>
|
|
11
|
+
Configure is the right entry point because init has already produced a complete config; the change is scoped to one field and its downstream side effects. Re-running init would re-interview every product-context document, which is wasted work.
|
|
12
|
+
</commentary>
|
|
13
|
+
</example>
|
|
14
|
+
|
|
15
|
+
<example>
|
|
16
|
+
Context: An hstack point release introduces a new required frontmatter field on `change-spec.md` and bumps `schemaVersion` from 1 to 2.
|
|
17
|
+
user: "Run /hstack:configure --migrate."
|
|
18
|
+
assistant: "I'll detect the schema-version delta, walk through the field-level migration plan, and re-stamp every existing artifact's frontmatter under the new schema."
|
|
19
|
+
<commentary>
|
|
20
|
+
Migration is the one mode of configure that can touch many files at once. The Skill plans the migration first, presents the planned edits to the engineer, and executes only on confirmation — never silently rewrites artifact frontmatter.
|
|
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 frontmatter after every migration write}}"
|
|
32
|
+
- "{{TODO-SCRIPT: hstack/scripts/migrate-schema.ts — applies declarative migration steps between schema-version values}}"
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Purpose
|
|
36
|
+
|
|
37
|
+
`hstack-configure` is the post-init editor of `hstack/config.yaml` and the product-context layer. It runs in three modes: edit a single config field, re-run the interview for a single product-context document via `--interview <doc-name>`, or migrate every artifact's `schema-version` via `--migrate` when an hstack upgrade introduces a structural change. It does not bootstrap from nothing (that is `hstack-init`'s role) and does not write per-change artifacts.
|
|
38
|
+
|
|
39
|
+
## When to invoke
|
|
40
|
+
|
|
41
|
+
Invoke when the engineer wants to change a config field after init has completed, refresh a single context document (e.g., quarterly threat-model review), wire up a previously-absent MCP, or migrate after an hstack release bumps `schemaVersion`. If init has not completed, halt and direct the engineer to `hstack-init`.
|
|
42
|
+
|
|
43
|
+
## Inputs
|
|
44
|
+
|
|
45
|
+
- `--interview <doc-name>` (optional): re-run the conversational interview for one of `vision`, `glossary`, `mvp-scope`, `personas`, `data-architecture`, `tech-stack`, `ci-cd`, `infrastructure`, `threat-model`, `hardening-checklist`, `incident-runbook`.
|
|
46
|
+
- `--migrate` (optional): detect the gap between `hstack/config.yaml`'s `schemaVersion` and the version declared by the current hstack release, and apply the declarative migration steps.
|
|
47
|
+
- No flag: open an interactive config editor that walks the engineer through `hstack/config.yaml` field by field, confirming or correcting each.
|
|
48
|
+
|
|
49
|
+
`--interview` and `--migrate` are mutually exclusive.
|
|
50
|
+
|
|
51
|
+
## Preconditions
|
|
52
|
+
|
|
53
|
+
Before any work:
|
|
54
|
+
|
|
55
|
+
- Verify `hstack/config.yaml` exists and contains a valid `init-status: complete` value. If init has not completed, halt and surface the message to run `hstack-init` first.
|
|
56
|
+
- Read `hstack/CLAUDE.md` (kernel) and `hstack/templates/`.
|
|
57
|
+
- For `--interview <doc-name>`: verify the named document template exists under `hstack/templates/` and the corresponding instance exists under `hstack/context/`. Read the existing instance's current state to seed the interview.
|
|
58
|
+
- For `--migrate`: read the current `hstack/config.yaml schemaVersion` and the target version declared by the installed hstack release. If they match, halt with a "no migration needed" message.
|
|
59
|
+
|
|
60
|
+
## Orchestration steps
|
|
61
|
+
|
|
62
|
+
### Edit-config mode (no flag)
|
|
63
|
+
|
|
64
|
+
1. Read `hstack/config.yaml` and walk every field with the engineer using the `product-manager` subagent via Task. For each field, the subagent proposes the current value, the engineer accepts or corrects, the subagent writes the field to disk immediately.
|
|
65
|
+
2. For fields with downstream effects (e.g., changing the configured story store), emit an explicit warning naming the affected workflow Skills before writing.
|
|
66
|
+
3. On completion, commit. Update `hstack/config.yaml`'s `updated` field.
|
|
67
|
+
|
|
68
|
+
### `--interview <doc-name>` mode
|
|
69
|
+
|
|
70
|
+
1. Read the existing `hstack/context/<doc-name>.md`.
|
|
71
|
+
2. Invoke the doc's canonical author via Task with `subagent_type` set per the routing table below. Context = [kernel, template, existing instance]. The subagent walks the document's fields, treating the existing values as the proposal layer and the engineer's responses as accept-or-correct. The routing must match the authoring agent used by `hstack-init` for the same document — same author at init time and at refresh time, different cadence:
|
|
72
|
+
- `vision`, `glossary`, `mvp-scope`, `personas`, `data-architecture`, `tech-stack`, `ci-cd` → `product-manager`.
|
|
73
|
+
- `infrastructure`, `incident-runbook` → `spec-author`.
|
|
74
|
+
- `threat-model`, `hardening-checklist` → `security-reviewer`.
|
|
75
|
+
3. Updated document is written incrementally per the kernel's per-field write rule. Status moves to `drafted` if it had been `current`, then back to `current` at the end. Prompt source-cleanup per the subagent's contract.
|
|
76
|
+
4. Commit.
|
|
77
|
+
|
|
78
|
+
### `--migrate` mode
|
|
79
|
+
|
|
80
|
+
1. Read `hstack/scripts/migrate-schema.ts` (or its current location) for the declarative migration steps between the current and target `schemaVersion`. Each step names: which artifact types it touches, which frontmatter fields it adds/renames/removes, and any prose-section structural changes.
|
|
81
|
+
2. Run a dry-run scan over `hstack/` and produce a written migration plan that lists every artifact file the migration would touch and the specific edits per file. Present the plan to the engineer for confirmation.
|
|
82
|
+
3. On confirmation, execute the migration step by step. After each artifact file is edited, run `{{TODO-SCRIPT: hstack/scripts/validate-spec.ts}}` against it; if validation fails, halt and surface the failure rather than continuing.
|
|
83
|
+
4. Update `hstack/config.yaml`'s `schemaVersion` to the target value on a successful migration. Commit.
|
|
84
|
+
|
|
85
|
+
For destructive or ambiguous migrations (renames of frontmatter fields, status enum changes), the Skill presents each ambiguity to the engineer rather than guessing.
|
|
86
|
+
|
|
87
|
+
## Outputs
|
|
88
|
+
|
|
89
|
+
- Edits to `hstack/config.yaml` (any mode).
|
|
90
|
+
- Edits to one `hstack/context/<doc-name>.md` (`--interview` mode).
|
|
91
|
+
- Edits to many artifact files under `hstack/specs/`, `hstack/context/`, `hstack/adr/`, `hstack/tech-debt/` (`--migrate` mode).
|
|
92
|
+
- An optional migration log file at `hstack/.migrations/<from>-to-<to>.md` capturing the dry-run plan and per-file outcomes.
|
|
93
|
+
|
|
94
|
+
## Auto-commit triggers
|
|
95
|
+
|
|
96
|
+
- End of edit-config interview: one commit summarizing the edited fields.
|
|
97
|
+
- End of `--interview <doc-name>` session: status transition back to `current` triggers a commit.
|
|
98
|
+
- End of successful `--migrate`: one commit per migrated artifact (so a partial migration is partly reversible), plus a final commit advancing `schemaVersion`.
|
|
99
|
+
|
|
100
|
+
## Idempotency contract
|
|
101
|
+
|
|
102
|
+
- Re-running edit-config mode is safe; the Skill reads current values, walks every field, and produces a no-op commit when the engineer accepts all current values unchanged.
|
|
103
|
+
- Re-running `--interview <doc-name>` is safe; the existing instance is the proposal layer, identical re-confirmation is a no-op.
|
|
104
|
+
- Re-running `--migrate` after a successful migration is a no-op; the version check at the start short-circuits. Re-running `--migrate` mid-migration (after a halt) resumes by reading the migration log file and processing the next un-migrated artifact.
|
|
105
|
+
|
|
106
|
+
## Stop conditions
|
|
107
|
+
|
|
108
|
+
Beyond the kernel's general stop conditions:
|
|
109
|
+
|
|
110
|
+
- A `--migrate` step would touch an artifact whose current frontmatter does not match the source `schemaVersion`. Halt and ask; do not migrate inconsistent state.
|
|
111
|
+
- A `--interview` document is referenced by an in-flight change-spec at a non-terminal status. The Skill warns about cascade effects but proceeds on engineer confirmation; the cascade is the engineer's call.
|
|
112
|
+
- A config field change would invalidate existing artifacts (e.g., removing a module from the module-to-area mapping when change-specs still reference it). Halt and surface the affected files.
|
|
113
|
+
|
|
114
|
+
## Failure modes
|
|
115
|
+
|
|
116
|
+
- **`migrate-schema.ts` absent or malformed.** Halt and surface as a hstack installation issue.
|
|
117
|
+
- **Validator failure on a migrated artifact.** Halt the migration; previous artifacts are already committed and represent a stable partial state.
|
|
118
|
+
- **Subagent halts mid-interview.** Persist current state; partial fields are already written per the kernel's incremental-write rule.
|
|
119
|
+
|
|
120
|
+
## Anti-patterns
|
|
121
|
+
|
|
122
|
+
- Never silently advance `schemaVersion` without a corresponding migration run.
|
|
123
|
+
- Never write context document content without invoking `product-manager`. This Skill orchestrates; it does not author.
|
|
124
|
+
- Never edit per-change artifacts (specs, plans, reviews) from this Skill. Those belong to their authoring subagents.
|
|
125
|
+
- Never apply a `--migrate` plan without the engineer's explicit confirmation of the dry-run output.
|
|
126
|
+
- Never re-run `hstack-init` semantics from this Skill. If the engineer wants to start over, they delete and re-init explicitly.
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hstack-data-review
|
|
3
|
+
description: |
|
|
4
|
+
Use this skill when a change-spec includes `db` in its surfaces and is at `status: ready-to-plan` or later, and needs `data-review.md` produced before the implementer can start. The Skill orchestrates the `data-specialist` subagent. In v1 the output is a structured judgment grounded in live-schema introspection via the Supabase MCP when available; v2 substrate hard-fails when the MCP is unreachable. Examples:
|
|
5
|
+
|
|
6
|
+
<example>
|
|
7
|
+
Context: A change-spec introduces a new public-schema table with RLS and is at ready-to-plan.
|
|
8
|
+
user: "/hstack:data-review 2026-06-knowledge-citations"
|
|
9
|
+
assistant: "I'll invoke data-specialist with the Supabase MCP reading the live schema. RLS-coverage is gated by DR-02 (every new-table value must be `covered`); pgvector-tenant-id presence is gated by DR-03."
|
|
10
|
+
<commentary>
|
|
11
|
+
data-review is gated upstream of the implementer when surfaces touches db. The Skill enforces SR-style discipline on tenant-isolation in pgvector RPCs and refuses to mark `passed` if RLS coverage is `partial` or `missing`.
|
|
12
|
+
</commentary>
|
|
13
|
+
</example>
|
|
14
|
+
|
|
15
|
+
<example>
|
|
16
|
+
Context: A migration is additive (new table, new index) but touches a hot table during business hours.
|
|
17
|
+
user: "/hstack:data-review 2026-05-billing-overage-warning"
|
|
18
|
+
assistant: "I'll invoke data-specialist. Migration safety review will examine locking behavior on non-empty production tables; risky migrations require an explicit mitigation strategy."
|
|
19
|
+
<commentary>
|
|
20
|
+
Even when the migration is "additive", the data-specialist evaluates locking on the target table. A plain `CREATE INDEX` on a large hot table can take production offline; the subagent's challenge prompt surfaces this exactly.
|
|
21
|
+
</commentary>
|
|
22
|
+
</example>
|
|
23
|
+
|
|
24
|
+
<example>
|
|
25
|
+
Context: A change touches a pgvector RPC that joins against a tenant-scoped table; the Supabase MCP is wired up.
|
|
26
|
+
user: "/hstack:data-review 2026-06-retrieval-rpc-rewrite"
|
|
27
|
+
assistant: "I'll invoke data-specialist. tenant_id-arg-present must be true on the modified RPC; if it isn't, I'll halt — pgvector RPCs that drop tenant context are a kernel-level stop condition."
|
|
28
|
+
<commentary>
|
|
29
|
+
DR-03 plus the tenant-isolation lint together close the multi-tenant retrieval gap. The Skill refuses to write `passed` if the RPC drops tenant_id, and the v2 substrate will hard-fail when the live-schema MCP is unreachable for this kind of change.
|
|
30
|
+
</commentary>
|
|
31
|
+
</example>
|
|
32
|
+
tools:
|
|
33
|
+
- Read
|
|
34
|
+
- Write
|
|
35
|
+
- Edit
|
|
36
|
+
- Grep
|
|
37
|
+
- Glob
|
|
38
|
+
- Bash
|
|
39
|
+
- Task
|
|
40
|
+
- "{{TODO-MCP: Supabase MCP — required for live schema, RLS policies, and pgvector index introspection; v1 permits a degraded-with-flag fallback, v2 hard-fails when unreachable}}"
|
|
41
|
+
- "{{TODO-SCRIPT: hstack/scripts/validate-spec.ts — validates data-review frontmatter and DR-01..DR-06}}"
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Purpose
|
|
45
|
+
|
|
46
|
+
`hstack-data-review` produces `data-review.md` for a change-spec with `db` in its surfaces by orchestrating the `data-specialist` subagent. The artifact covers schema changes, RLS coverage, migration safety, index and performance impact, pgvector and RAG implications, and data lifecycle. It is the upstream gate the implementer refuses to bypass when surfaces touches db. In v1 the artifact is a structured judgment grounded in live-schema introspection via the Supabase MCP when available; the v1/v2 split governs MCP fallback behavior.
|
|
47
|
+
|
|
48
|
+
## When to invoke
|
|
49
|
+
|
|
50
|
+
Invoke when a change-spec with `db` in surfaces reaches `status: ready-to-plan` or later. The data-review can run before, after, or concurrently with `hstack-change-plan` and `hstack-security-review`.
|
|
51
|
+
|
|
52
|
+
## Inputs
|
|
53
|
+
|
|
54
|
+
- `<change-id>` (required, positional): the change-spec id.
|
|
55
|
+
|
|
56
|
+
## Preconditions
|
|
57
|
+
|
|
58
|
+
Before any work:
|
|
59
|
+
|
|
60
|
+
- Verify the change-spec exists and is at `status: ready-to-plan` or later.
|
|
61
|
+
- Verify `surfaces` includes `db`. If not, halt with a surface-conditional message.
|
|
62
|
+
- Verify `hstack/context/data-architecture.md` is at `status: current`. Halt otherwise.
|
|
63
|
+
- Read `hstack/context/tech-stack.md` and `hstack/context/ci-cd.md`.
|
|
64
|
+
- **Supabase MCP availability.** Probe the MCP. In v1, an unreachable MCP is a degraded read (flagged in rationale), not a hard fail, except for high-stakes cases: new public-schema tables, new RLS policies, new pgvector RPCs. For high-stakes cases the Skill halts in v1 as well; the v2 substrate will hard-fail uniformly. The Skill is explicit about which mode it is in.
|
|
65
|
+
- Read `supabase/migrations/` to identify migration files the diff would introduce.
|
|
66
|
+
|
|
67
|
+
## Orchestration steps
|
|
68
|
+
|
|
69
|
+
1. **Invoke `data-specialist`.** Use the Task tool with `subagent_type: data-specialist` and context = [kernel, `hstack/templates/data-review.md`, change-spec, module-spec for the change's area, data-architecture, tech-stack, ci-cd, live schema and RLS / pgvector index introspection via MCP when available]. The subagent walks the six sections — Schema Changes, RLS Coverage, Migration Safety, Index and Performance Impact, pgvector and RAG, Data Lifecycle.
|
|
70
|
+
|
|
71
|
+
2. **RLS coverage gate.** Per the subagent's contract and DR-02, every new table must have a `covered` value in `rls-coverage.new-tables` for status `passed`. Per DR-01 and DR-05, every new table named in section 1 must appear in the frontmatter and have a section 2 entry. Per the RLS coverage challenge prompt, the subagent cites the exact RLS rule and the test that would catch its absence.
|
|
72
|
+
|
|
73
|
+
3. **pgvector tenant-id gate.** Per DR-03, when the diff touches any pgvector RPC, `pgvector-changes.tenant-id-arg-present` must be `true`. If false, the Skill halts — this is a kernel-level stop condition (tenant-isolation breach).
|
|
74
|
+
|
|
75
|
+
4. **Migration safety.** When `migration-safety: risky`, section 3 must enumerate the locking behavior and the mitigation (e.g., `CREATE INDEX CONCURRENTLY`, batched backfill, feature-gated consumer). DR-04 enforces this.
|
|
76
|
+
|
|
77
|
+
5. **Index discipline and RAG implications.** Per the subagent's contract, every added index has a stated query pattern; pgvector index changes get extra scrutiny for HNSW rebuild pressure. RAG-broadening changes receive cross-tenant leak attention.
|
|
78
|
+
|
|
79
|
+
6. **Data lifecycle.** Every new table declares retention (`retained-indefinitely`, `retained-N-days`, `ephemeral`). DR-06 enforces the controlled enum.
|
|
80
|
+
|
|
81
|
+
7. **Migration proposals.** The subagent may propose migration files in section 3 (named, with intent) but does not execute them. Execution belongs to the implementer per the kernel's database workflow.
|
|
82
|
+
|
|
83
|
+
8. **v1 framing.** When live-schema MCP is degraded, every rationale paragraph names the degraded source explicitly: "Reviewed against data-architecture.md dated YYYY-MM-DD because Supabase MCP unreachable." The Skill rejects rationale paragraphs that imply live verification when the MCP was not available.
|
|
84
|
+
|
|
85
|
+
9. **Status transitions.** When every score is acceptable and validation passes, the subagent transitions to `status: passed`. When any RLS coverage is `partial` or `missing`, status moves only to `concerns-acknowledged` and only with explicit human acknowledgement plus a tech-debt item via `hstack-tech-debt-new`.
|
|
86
|
+
|
|
87
|
+
10. **Validate.** Run `{{TODO-SCRIPT: hstack/scripts/validate-spec.ts}}` — DR-01 through DR-06.
|
|
88
|
+
|
|
89
|
+
## Outputs
|
|
90
|
+
|
|
91
|
+
- `hstack/specs/changes/<change-id>/data-review.md` at `status: passed` or `concerns-acknowledged`.
|
|
92
|
+
- Optional surfaced recommendation to file tech-debt for deferred RLS or migration concerns.
|
|
93
|
+
- Optional migration-file proposals named in section 3 (for the implementer to act on).
|
|
94
|
+
|
|
95
|
+
## Auto-commit triggers
|
|
96
|
+
|
|
97
|
+
- Status transition to `in-progress` after the first frontmatter fields land.
|
|
98
|
+
- Status transition to terminal. Commit message: `data-review(<change-id>): passed` or `concerns-acknowledged`.
|
|
99
|
+
- Edits to `rls-coverage`, `pgvector-changes` (because gating depends on them).
|
|
100
|
+
|
|
101
|
+
## Idempotency contract
|
|
102
|
+
|
|
103
|
+
- Re-running on a terminal data-review without diff changes: a no-op aside from `updated` timestamps.
|
|
104
|
+
- Re-running after `in-scope` has expanded: the subagent re-reads the diff and may surface new tables or RPCs; the engineer confirms.
|
|
105
|
+
- Re-running mid-authoring after a halt: the subagent reads the partial artifact and resumes.
|
|
106
|
+
|
|
107
|
+
## Stop conditions
|
|
108
|
+
|
|
109
|
+
Beyond the kernel's general stop conditions:
|
|
110
|
+
|
|
111
|
+
- `data-architecture.md` at `needs-refresh` or absent. **Hard-fail of the Supabase MCP** when the change is high-stakes (new public-schema table, new RLS policy, new pgvector RPC). The v1/v2 split applies; the v2 substrate hard-fails uniformly.
|
|
112
|
+
- pgvector RPC drops tenant context (`tenant-id-arg-present: false`). Halt — kernel-level.
|
|
113
|
+
- A new public-schema table is introduced without an RLS policy in the same migration. Halt.
|
|
114
|
+
- A migration is proposed that requires `service_role` keys, raw shell against production, or `supabase db push` against a remote project. Halt — kernel-forbidden tools.
|
|
115
|
+
- A backfill strategy is required and the engineer has not provided one.
|
|
116
|
+
|
|
117
|
+
## Failure modes
|
|
118
|
+
|
|
119
|
+
- **Supabase MCP unreachable on a high-stakes change.** Halt in v1; v2 hard-fails. Do not silently fall back to data-architecture.md as ground truth.
|
|
120
|
+
- **Validator fails DR-02 because RLS coverage is `partial`.** Halt; the engineer either fixes the policy or acknowledges via tech-debt and the subagent moves to `concerns-acknowledged`.
|
|
121
|
+
- **A pgvector RPC modification is detected but tenant_id is absent from the RPC signature.** Halt — kernel-level stop condition.
|
|
122
|
+
|
|
123
|
+
## Anti-patterns
|
|
124
|
+
|
|
125
|
+
- Never write `passed` when any RLS coverage entry is `partial` or `missing`.
|
|
126
|
+
- Never approve a pgvector RPC change that drops `tenant_id`.
|
|
127
|
+
- Never silently treat `data-architecture.md` as ground truth when the live-schema MCP is unreachable. Flag the degradation in every affected rationale.
|
|
128
|
+
- Never execute migrations from this Skill. Propose only; the implementer executes.
|
|
129
|
+
- Never use `service_role` Supabase keys, raw shell against production, or `supabase db push` against a remote project. Kernel-forbidden.
|
|
130
|
+
- Never recommend disabling RLS to "simplify" a query.
|
|
131
|
+
- Never approve a `risky` migration without a named locking-mitigation strategy.
|
|
132
|
+
- Never claim live verification you did not perform.
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hstack-finalize
|
|
3
|
+
description: |
|
|
4
|
+
Use this skill once a change-spec's branch has been merged into the configured default branch. The Skill is the post-merge cleanup step: it verifies the merge actually landed, then performs direct mechanical writes (per ADR-0001, no spec-author invocation) — first resolving each tech-debt referenced in `change-spec.resolves-tech-debt` (write `resolved-by`, append Resolution Log entry, flip status `in-progress → resolved`), then advancing the change-spec `ready-to-ship → shipped`. The TDs-first ordering ensures that a mid-finalize failure leaves the change-spec at `ready-to-ship` (recoverable by re-running finalize), never at `shipped` referencing an unresolved TD. Per TD-03, no further field rewrites are permitted on the tech-debt afterwards. Examples:
|
|
5
|
+
|
|
6
|
+
<example>
|
|
7
|
+
Context: The billing-overage-warning change just merged. Its change-spec has `resolves-tech-debt: [TD-0042-overage-banner-tailwind-class]`.
|
|
8
|
+
user: "/hstack:finalize 2026-05-billing-overage-warning"
|
|
9
|
+
assistant: "I'll verify the change branch merged to main, then first resolve TD-0042 (write resolved-by, append Resolution Log, flip status to resolved — one commit), then advance the change-spec to shipped (one commit). Per TD-03, TD-0042 becomes immutable after this point."
|
|
10
|
+
<commentary>
|
|
11
|
+
Finalize is the only Skill that flips a tech-debt to `resolved` (mirroring how `/hstack:tech-debt-resolve` is the only Skill that flips one to `in-progress`). Per ADR-0001, the writes are direct (no spec-author invocation); reciprocity for `tech-debt.resolved-by ↔ change-spec.resolves-tech-debt` (TD-04) is preserved because the change-spec's `resolves-tech-debt` array was set at scaffold time by `/hstack:tech-debt-resolve`, and finalize completes the pair by filling in `resolved-by` on the TD side.
|
|
12
|
+
</commentary>
|
|
13
|
+
</example>
|
|
14
|
+
|
|
15
|
+
<example>
|
|
16
|
+
Context: An engineer runs finalize on a change whose branch has not actually merged yet.
|
|
17
|
+
user: "/hstack:finalize 2026-06-knowledge-citations"
|
|
18
|
+
assistant: "I'll halt — `change/2026-06-knowledge-citations` has not been merged into main per git log. Finalize is post-merge cleanup; running it pre-merge would mark a tech-debt resolved that's not yet deployed. Open or complete the PR first."
|
|
19
|
+
<commentary>
|
|
20
|
+
The merge-verification check is load-bearing. Marking a tech-debt `resolved` based on intent rather than landed code is exactly the audit-trail corruption the workflow is built to prevent.
|
|
21
|
+
</commentary>
|
|
22
|
+
</example>
|
|
23
|
+
|
|
24
|
+
<example>
|
|
25
|
+
Context: A change-spec with empty `resolves-tech-debt` is finalized after merge.
|
|
26
|
+
user: "/hstack:finalize 2026-05-typo-fix"
|
|
27
|
+
assistant: "I'll advance the change-spec to shipped. No tech-debt to resolve. Single auto-commit."
|
|
28
|
+
<commentary>
|
|
29
|
+
Finalize works on every merged change, not just those that resolve tech-debt. The change-spec → shipped transition is always written here; the tech-debt flips are conditional on `resolves-tech-debt`.
|
|
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 change-spec and tech-debt status flips and TD-04/TD-05 reciprocity}}"
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Purpose
|
|
44
|
+
|
|
45
|
+
`hstack-finalize` is the post-merge cleanup Skill. It performs exactly two kinds of state changes, **directly via Skill-level Edit calls in the main session** (per the kernel's Mechanical operations section, ADR-0001):
|
|
46
|
+
|
|
47
|
+
1. **Advance the change-spec.** `ready-to-ship → shipped`. Always runs on invocation.
|
|
48
|
+
2. **Resolve referenced tech-debt.** For each entry in `change-spec.resolves-tech-debt`: write `resolved-by: <change-spec-id>`, append a Resolution Log entry, flip status `in-progress → resolved`. Only runs when `resolves-tech-debt` is non-empty.
|
|
49
|
+
|
|
50
|
+
The Skill is the only path that flips a tech-debt to `resolved`, mirroring how `/hstack:tech-debt-resolve` is the only path that flips one to `in-progress`. The reciprocal `tech-debt.resolved-by ↔ change-spec.resolves-tech-debt` (TD-04) is enforced by writing both halves atomically within a single auto-commit per tech-debt.
|
|
51
|
+
|
|
52
|
+
## When to invoke
|
|
53
|
+
|
|
54
|
+
Invoke once the change's branch (`change/<change-id>`) has been merged into the configured default branch and the engineer is closing out the change. **Run finalize on the default branch itself, not on the (now-merged) change branch.** The Skill writes auto-commits as part of its work; those commits must land on the default branch so the audit trail (change-spec at `shipped`, TDs at `resolved`) is visible to everyone reading `main`. Running on the merged change branch strands the finalize commits — they're committed cleanly but never reach the default branch.
|
|
55
|
+
|
|
56
|
+
Workflow: merge the PR → `git checkout <default-branch>` → `git pull` → `/hstack:finalize <change-id>` → `git push`. Idempotent: re-running on a change-spec already at `shipped` is a no-op aside from informing the engineer.
|
|
57
|
+
|
|
58
|
+
## Inputs
|
|
59
|
+
|
|
60
|
+
- `<change-id>` (required, positional): the change-spec id.
|
|
61
|
+
|
|
62
|
+
## Preconditions
|
|
63
|
+
|
|
64
|
+
Before any work:
|
|
65
|
+
|
|
66
|
+
- **Verify the current branch is the configured default branch and is up-to-date with its remote.** Read the default branch from `hstack/config.yaml` (fallback `main`). Run `git rev-parse --abbrev-ref HEAD` and confirm it equals the default branch. Run `git fetch <remote>` (default `origin`) then `git rev-list --left-right --count <default-branch>...<remote>/<default-branch>` and confirm both sides are `0` (local is neither ahead nor behind remote). If the current branch is not the default branch, halt with: "finalize must run on `<default-branch>`. You're on `<current-branch>`. Run `git checkout <default-branch> && git pull`, then re-invoke." If the local default is behind or ahead of remote, halt with the specific divergence and recommended `git pull` / push action. This precondition is load-bearing: the Skill's auto-commits land on whatever branch is checked out, and stranding them on a merged change branch defeats the audit-trail purpose of finalize.
|
|
67
|
+
- Verify `hstack/specs/changes/<change-id>/spec.md` exists. Read `status` and `resolves-tech-debt`.
|
|
68
|
+
- Verify `status: ready-to-ship`. If at `ready-for-review` (ship hasn't run yet), halt and direct the engineer to `/hstack:ship` first. If at `shipped` or `archived`, halt as a no-op with the terminal status named.
|
|
69
|
+
- **Verify the merge landed.** Run `git log <default-branch> --grep="<change-id>"` and `git log <default-branch> --merges --oneline` and check that the change's branch merge commit exists on the default branch. Multiple verification heuristics are acceptable: (a) a merge commit whose message references the change-id; (b) the change-spec's auto-commit history appearing in the default branch's log via `git log <default-branch> -- hstack/specs/changes/<change-id>/`; (c) the change branch's tip being an ancestor of the default branch's tip (`git merge-base --is-ancestor`). If none of these is true, halt — finalize is post-merge cleanup, never pre-merge.
|
|
70
|
+
- For each entry in `resolves-tech-debt`: verify the tech-debt artifact exists, is at `status: in-progress`, and its `resolved-by` field is currently `null`. Any deviation halts. Reconciliation is manual: `git log -- hstack/tech-debt/<td-id>.md` to see the recent state changes; `git checkout HEAD -- hstack/tech-debt/<td-id>.md` to revert if the deviation came from a partial prior finalize; or direct frontmatter edit + `validate-spec.ts` rerun if the deviation reflects intentional out-of-band state. Do not invoke `spec-author` — the kernel forbids it for status flips and reciprocal back-reference writes.
|
|
71
|
+
- **Adversarial-review id preflight read.** When `resolves-tech-debt` is non-empty, read `hstack/specs/changes/<change-id>/adversarial-review.md` and capture its frontmatter `id` field. This id is interpolated into each TD's Resolution Log entry (see step 2). If the adversarial-review file is missing, halt — the AR-07 Acceptance-satisfied confirmation that GT-11 already verified would not be locatable from the resulting Resolution Log entry. The captured id is surfaced in the proposed-diff preview alongside the other writes.
|
|
72
|
+
|
|
73
|
+
## Orchestration steps
|
|
74
|
+
|
|
75
|
+
1. **Print the plan.** Summarize what will be written: "Finalize change `<change-id>`: status `ready-to-ship → shipped`. Resolve tech-debt: `[TD-NNNN, TD-MMMM]` (or `none`). Proceed? (Y/n)". Default Yes.
|
|
76
|
+
|
|
77
|
+
2. **Resolve each referenced tech-debt FIRST (direct write per TD, in order).** Per the kernel's ordering rule for finalize: every TD must be resolved before the change-spec advances to `shipped`. This ensures a mid-finalize failure leaves the change-spec at `ready-to-ship` (recoverable by re-running finalize), never at `shipped` referencing an unresolved TD. For each entry in `resolves-tech-debt`, perform the following:
|
|
78
|
+
- `Edit` `hstack/tech-debt/<td-id>.md`:
|
|
79
|
+
- **Defensive Resolution Log check.** If `## Resolution Log` is not present in the file (legacy TDs), append `\n## Resolution Log\n` to the end of the file first.
|
|
80
|
+
- Edit frontmatter: `resolved-by: <change-id>`, `status: in-progress → resolved`, `updated: <today>`.
|
|
81
|
+
- Append to the Resolution Log section: `status: in-progress → resolved on <today> by <owner>. Resolving change-spec: <change-id>. Adversarial-review Acceptance-satisfied confirmation: <adversarial-review-id>.`
|
|
82
|
+
- Run `{{TODO-SCRIPT: hstack/scripts/validate-spec.ts}}` against the file. TD-04 (resolves-tech-debt ↔ resolved-by) and TD-05 (status:resolved requires resolved-by non-null) must pass. On validation failure, halt — the change-spec remains at `ready-to-ship`, prior TDs in this run have already committed (idempotent on re-run), and the engineer reconciles the failing TD before re-invoking finalize.
|
|
83
|
+
- On validation pass, `git add` and commit with message `tech-debt(<td-id>): resolved (resolved-by: <change-id>)`.
|
|
84
|
+
- Per TD-03, no further field rewrites are permitted after this commit.
|
|
85
|
+
|
|
86
|
+
3. **Advance the change-spec to `shipped` (direct write, last step).** Only after every entry in `resolves-tech-debt` has been successfully resolved and committed above. Use the `Edit` tool against `hstack/specs/changes/<change-id>/spec.md`:
|
|
87
|
+
- Frontmatter `status: ready-to-ship → shipped`.
|
|
88
|
+
- Frontmatter `updated: <today>`.
|
|
89
|
+
|
|
90
|
+
Run `{{TODO-SCRIPT: hstack/scripts/validate-spec.ts}}` against the file. On validation pass, `git add` the file and commit with message `change-spec(<change-id>): shipped`. Do not invoke `spec-author` — this is a mechanical write per the kernel.
|
|
91
|
+
|
|
92
|
+
4. **Validate reciprocity.** Run `{{TODO-SCRIPT: hstack/scripts/validate-spec.ts}}` against the change-spec and each affected tech-debt. TD-04 (resolves-tech-debt ↔ resolved-by reciprocity) and TD-05 (status:resolved requires resolved-by non-null) must pass. If either fails, halt and surface — the audit trail is broken. Concrete reconciliation: `git log` the affected files to find the last known-good commit; `git revert <commit>` the bad commit if it landed; or direct frontmatter edit + `validate-spec.ts` rerun if the corruption is isolated to one field. Do not invoke `spec-author` — the kernel forbids it for reciprocal back-reference writes.
|
|
93
|
+
|
|
94
|
+
5. **Confirm completion.** Print: "Finalized: change-spec at `shipped`, [TD-NNNN, TD-MMMM] at `resolved`. Per TD-03, these tech-debt items are now immutable. The change-spec may later move to `archived` via direct edit when historical pruning is desired."
|
|
95
|
+
|
|
96
|
+
## Outputs
|
|
97
|
+
|
|
98
|
+
- `hstack/specs/changes/<change-id>/spec.md` advanced to `status: shipped`.
|
|
99
|
+
- For each resolved tech-debt: `hstack/tech-debt/<td-id>.md` at `status: resolved` with `resolved-by` set and a Resolution Log entry appended.
|
|
100
|
+
- One commit per artifact transition. Commit messages: `change-spec(<change-id>): shipped` and `tech-debt(<td-id>): resolved (resolved-by: <change-id>)`.
|
|
101
|
+
|
|
102
|
+
## Auto-commit triggers
|
|
103
|
+
|
|
104
|
+
- One commit when the change-spec advances to `shipped`.
|
|
105
|
+
- One commit per tech-debt resolution. Each commit's body cites the resolving change-spec id for cross-reference.
|
|
106
|
+
|
|
107
|
+
## Telemetry sidecar
|
|
108
|
+
|
|
109
|
+
At the change-spec `shipped` commit (the final write in the finalize sequence), write `hstack/specs/changes/<change-id>/.telemetry/finalize.json` in the same `git add && git commit` as the change-spec advance. The sidecar is derivative of git + frontmatter (see `hstack/templates/telemetry-sidecar.md`). Schema:
|
|
110
|
+
|
|
111
|
+
```json
|
|
112
|
+
{
|
|
113
|
+
"schema_version": 1,
|
|
114
|
+
"skill": "hstack-finalize",
|
|
115
|
+
"change_id": "<change-id>",
|
|
116
|
+
"shipped_at": "<ISO-8601, now>",
|
|
117
|
+
"merge_commit_sha": "<full SHA of the merge commit verified in preconditions>",
|
|
118
|
+
"change_duration_days": <int, change-spec.created -> merge author date>,
|
|
119
|
+
"tds_resolved": [<TD ids that were resolved this finalize run>]
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
The finalize sidecar is the most valuable of the three — it closes the per-change observability loop and lets `/hstack:telemetry` compute end-to-end change cycle time without walking transcripts. `.telemetry/` is git-ignored. If the sidecar write fails, log and continue; the canonical commit must still land.
|
|
124
|
+
|
|
125
|
+
## Idempotency contract
|
|
126
|
+
|
|
127
|
+
Under the TDs-first-then-change-spec ordering, the legitimate resume cases are:
|
|
128
|
+
|
|
129
|
+
- **Change-spec at `ready-to-ship` with all `resolves-tech-debt` items at `resolved`**: the Skill skips the (already-completed) TD resolutions and advances the change-spec to `shipped`.
|
|
130
|
+
- **Change-spec at `ready-to-ship` with some TDs at `resolved` and others at `in-progress`**: the Skill detects per-TD status, skips the resolved ones (no-op on those), and resumes from the first un-resolved TD. Once all TDs are resolved, it advances the change-spec.
|
|
131
|
+
- **Change-spec at `shipped`**: clean no-op halt with the terminal status reported. By construction this state cannot coexist with any TD at `in-progress` (the ordering rule guarantees TDs finish first), so no resume work is needed.
|
|
132
|
+
|
|
133
|
+
The state "change-spec at `shipped` with a TD still at `in-progress`" is not reachable from a normal partial run under the new ordering. If observed (e.g., manual frontmatter edit, prior-run before this ADR landed), the Skill halts at the change-spec `shipped` precondition and the engineer reconciles via manual investigation.
|
|
134
|
+
|
|
135
|
+
## Stop conditions
|
|
136
|
+
|
|
137
|
+
Beyond the kernel's general stop conditions:
|
|
138
|
+
|
|
139
|
+
- The current branch is not the configured default branch, or the local default branch is not in sync with its remote. Direct the engineer to `git checkout <default-branch> && git pull` (and `git push` if local is ahead) before re-invoking.
|
|
140
|
+
- The change-spec is not at `ready-to-ship`. Direct the engineer to either `/hstack:ship` (if at `ready-for-review`) or surface the existing terminal status.
|
|
141
|
+
- The merge cannot be verified via any of the heuristics. Hard halt — finalize is strictly post-merge.
|
|
142
|
+
- Any referenced tech-debt is not at `in-progress` or already has a non-null `resolved-by`. Halt; the audit trail is inconsistent.
|
|
143
|
+
- The validator fails TD-04 or TD-05 after the writes. Halt and surface — manual reconciliation is required (see step 4's concrete recovery guidance: git revert the bad commit, or direct frontmatter edit + validator rerun). `spec-author` is not a valid recovery path for these reciprocal-write fields per the kernel.
|
|
144
|
+
|
|
145
|
+
## Failure modes
|
|
146
|
+
|
|
147
|
+
- **A direct write fails mid-resolution.** Because TDs are resolved BEFORE the change-spec advances to `shipped`, a mid-finalize failure leaves the change-spec at `ready-to-ship` — never at `shipped` referencing an unresolved TD. Prior TDs in the current run may have already committed; the Skill is idempotent on re-run (already-resolved TDs are detected and skipped). The audit trail records the partial state honestly.
|
|
148
|
+
- **Resolved tech-debt was not actually delivered by the merged change.** The adversarial-review's AR-07 Acceptance-satisfied confirmation is the upstream guard. If a tech-debt is flipped to `resolved` but the change did not actually deliver it, that is an adversarial-review failure, not a finalize failure. Surface it as a `wontfix → re-open` is not permitted; the engineer authors a new TD via `/hstack:tech-debt-new`.
|
|
149
|
+
- **Default branch detection fails.** The Skill reads `hstack/config.yaml` for the configured default branch; if absent, defaults to `main`. If neither resolves, halt and ask the engineer.
|
|
150
|
+
|
|
151
|
+
## Anti-patterns
|
|
152
|
+
|
|
153
|
+
- Never flip a tech-debt to `resolved` without an accompanying change-spec at `shipped` whose `resolves-tech-debt` references it. The reciprocal-write pair is the only legal path.
|
|
154
|
+
- Never run finalize pre-merge. The merge-verification check is mandatory.
|
|
155
|
+
- Never run finalize on the (now-merged) change branch. The Skill's auto-commits land on the current branch; running on a merged change branch strands the `shipped` and `resolved` commits where the default branch never sees them. The default-branch precondition enforces this.
|
|
156
|
+
- Never overwrite a non-null `resolved-by` field. Per TD-03, a resolved tech-debt is immutable.
|
|
157
|
+
- Never invoke `spec-author` for these writes. They are mechanical operations per the kernel's Mechanical operations section; the Skill performs them directly via the `Edit` tool. Invoking `spec-author` costs ~25k tokens per call for what is a handful of frontmatter character changes.
|
|
158
|
+
- Never skip TD-04/TD-05 post-write validation. The reciprocity check is the v1 substitute for the v2 substrate's mechanical cross-graph validator.
|
|
159
|
+
- Never accept a force-merge or rebase-merge that loses the change branch's auto-commit history. The merge-verification heuristics assume the auto-commit log lands on the default branch; squash-merges that compress the history break heuristic (b). The engineer should configure merge strategy to preserve history, or the Skill should be re-run after manual confirmation.
|