hstack 0.7.1 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/CHANGELOG.md +308 -0
  2. package/README.md +90 -154
  3. package/VERSION +1 -1
  4. package/dist/commands/doctor.js +69 -9
  5. package/dist/commands/doctor.js.map +1 -1
  6. package/dist/commands/init.js +7 -3
  7. package/dist/commands/init.js.map +1 -1
  8. package/dist/commands/update.js +17 -4
  9. package/dist/commands/update.js.map +1 -1
  10. package/dist/lib/descriptions.js +160 -0
  11. package/dist/lib/descriptions.js.map +1 -0
  12. package/dist/lib/diff.js +1 -1
  13. package/dist/lib/git.js +16 -0
  14. package/dist/lib/git.js.map +1 -1
  15. package/dist/lib/wire.js +274 -142
  16. package/dist/lib/wire.js.map +1 -1
  17. package/dist/manifest.js +49 -22
  18. package/dist/manifest.js.map +1 -1
  19. package/package.json +4 -3
  20. package/template/.claude/agents/adversarial-reviewer.md +42 -98
  21. package/template/.claude/agents/app-architect.md +44 -133
  22. package/template/.claude/agents/data-architect.md +46 -127
  23. package/template/.claude/agents/test-strategist.md +39 -109
  24. package/template/.claude/skills/hstack-adr-new/SKILL.md +23 -100
  25. package/template/.claude/skills/hstack-adversarial-review/SKILL.md +47 -174
  26. package/template/.claude/skills/hstack-adversarial-review/references/finding-categories.md +134 -0
  27. package/template/.claude/skills/hstack-app-architecture/SKILL.md +43 -95
  28. package/template/.claude/skills/hstack-commit/SKILL.md +28 -97
  29. package/template/.claude/skills/hstack-data-architecture/SKILL.md +34 -82
  30. package/template/.claude/skills/hstack-promote/SKILL.md +55 -0
  31. package/template/.claude/skills/hstack-story/SKILL.md +58 -0
  32. package/template/.claude/skills/hstack-test-audit/SKILL.md +64 -0
  33. package/template/.claude/skills/hstack-wrap/SKILL.md +48 -0
  34. package/template/.claude/skills/hstack-wrap/references/pr-description.md +45 -0
  35. package/template/KERNEL.md +167 -0
  36. package/template/templates/adr.md +9 -18
  37. package/template/templates/app-architecture.md +38 -50
  38. package/template/templates/data-architecture.md +39 -93
  39. package/template/templates/infrastructure.md +54 -148
  40. package/template/templates/roadmap.md +35 -0
  41. package/template/templates/story.md +7 -13
  42. package/template/templates/tech-debt.md +2 -37
  43. package/template/templates/tech-stack.md +2 -12
  44. package/template/.claude/agents/data-specialist.md +0 -126
  45. package/template/.claude/agents/implementer.md +0 -154
  46. package/template/.claude/agents/kernel-fit-analyst.md +0 -190
  47. package/template/.claude/agents/planner.md +0 -110
  48. package/template/.claude/agents/product-discovery.md +0 -165
  49. package/template/.claude/agents/product-manager.md +0 -111
  50. package/template/.claude/agents/researcher.md +0 -123
  51. package/template/.claude/agents/security-reviewer.md +0 -123
  52. package/template/.claude/agents/spec-author.md +0 -123
  53. package/template/.claude/agents/stack-architect.md +0 -137
  54. package/template/.claude/agents/ui-ux-briefer.md +0 -105
  55. package/template/.claude/agents/verifier.md +0 -113
  56. package/template/.claude/skills/hstack-branch/SKILL.md +0 -103
  57. package/template/.claude/skills/hstack-brownfield-init/SKILL.md +0 -158
  58. package/template/.claude/skills/hstack-change-new/SKILL.md +0 -111
  59. package/template/.claude/skills/hstack-change-plan/SKILL.md +0 -119
  60. package/template/.claude/skills/hstack-configure/SKILL.md +0 -126
  61. package/template/.claude/skills/hstack-coord/SKILL.md +0 -131
  62. package/template/.claude/skills/hstack-data-review/SKILL.md +0 -132
  63. package/template/.claude/skills/hstack-finalize/SKILL.md +0 -159
  64. package/template/.claude/skills/hstack-flag/SKILL.md +0 -138
  65. package/template/.claude/skills/hstack-greenfield-init/SKILL.md +0 -175
  66. package/template/.claude/skills/hstack-help/SKILL.md +0 -179
  67. package/template/.claude/skills/hstack-implement/SKILL.md +0 -185
  68. package/template/.claude/skills/hstack-kernel-fit-promote/SKILL.md +0 -164
  69. package/template/.claude/skills/hstack-kernel-fit-scan/SKILL.md +0 -197
  70. package/template/.claude/skills/hstack-kernel-fit-triage/SKILL.md +0 -159
  71. package/template/.claude/skills/hstack-module-spec/SKILL.md +0 -105
  72. package/template/.claude/skills/hstack-product-discovery/SKILL.md +0 -101
  73. package/template/.claude/skills/hstack-research/SKILL.md +0 -145
  74. package/template/.claude/skills/hstack-scaffold/SKILL.md +0 -140
  75. package/template/.claude/skills/hstack-security-review/SKILL.md +0 -133
  76. package/template/.claude/skills/hstack-ship/SKILL.md +0 -129
  77. package/template/.claude/skills/hstack-stack-decide/SKILL.md +0 -108
  78. package/template/.claude/skills/hstack-story-draft/SKILL.md +0 -119
  79. package/template/.claude/skills/hstack-tech-debt-new/SKILL.md +0 -122
  80. package/template/.claude/skills/hstack-tech-debt-resolve/SKILL.md +0 -158
  81. package/template/.claude/skills/hstack-tech-debt-stale/SKILL.md +0 -113
  82. package/template/.claude/skills/hstack-tech-debt-wontfix/SKILL.md +0 -104
  83. package/template/.claude/skills/hstack-telemetry/SKILL.md +0 -98
  84. package/template/.claude/skills/hstack-test-plan/SKILL.md +0 -182
  85. package/template/.claude/skills/hstack-ui-brief/SKILL.md +0 -108
  86. package/template/.claude/skills/hstack-verify/SKILL.md +0 -150
  87. package/template/CLAUDE.md +0 -443
  88. package/template/scripts/coord/coord_scan.py +0 -681
  89. package/template/scripts/telemetry/__init__.py +0 -6
  90. package/template/scripts/telemetry/insights/__init__.py +0 -0
  91. package/template/scripts/telemetry/insights/contract_drift.py +0 -137
  92. package/template/scripts/telemetry/insights/kernel_fit.py +0 -438
  93. package/template/scripts/telemetry/insights/overengineering.py +0 -115
  94. package/template/scripts/telemetry/insights/quality_outcomes.py +0 -131
  95. package/template/scripts/telemetry/insights/token_economics.py +0 -129
  96. package/template/scripts/telemetry/insights/workflow_shape.py +0 -198
  97. package/template/scripts/telemetry/parsers/__init__.py +0 -0
  98. package/template/scripts/telemetry/parsers/bodies.py +0 -87
  99. package/template/scripts/telemetry/parsers/commits.py +0 -219
  100. package/template/scripts/telemetry/parsers/frontmatter.py +0 -322
  101. package/template/scripts/telemetry/parsers/transcripts.py +0 -181
  102. package/template/scripts/telemetry/render.py +0 -395
  103. package/template/scripts/telemetry/report.py +0 -138
  104. package/template/scripts/telemetry/run_kernel_fit.py +0 -91
  105. package/template/templates/adversarial-review.md +0 -54
  106. package/template/templates/bootstrap.md +0 -105
  107. package/template/templates/change-spec.md +0 -82
  108. package/template/templates/ci-cd.md +0 -27
  109. package/template/templates/coord-message.md +0 -55
  110. package/template/templates/data-review.md +0 -54
  111. package/template/templates/discovery/brainstorm.md +0 -69
  112. package/template/templates/discovery/forcing-questions.md +0 -76
  113. package/template/templates/discovery/project-brief.md +0 -53
  114. package/template/templates/figma-handoff.md +0 -38
  115. package/template/templates/glossary.md +0 -20
  116. package/template/templates/hardening-checklist.md +0 -73
  117. package/template/templates/incident-runbook.md +0 -57
  118. package/template/templates/kernel-fit-finding.md +0 -63
  119. package/template/templates/kernel-fit-flag.md +0 -52
  120. package/template/templates/module-spec.md +0 -49
  121. package/template/templates/mvp-scope.md +0 -34
  122. package/template/templates/persona.md +0 -38
  123. package/template/templates/plan.md +0 -49
  124. package/template/templates/product-brief.md +0 -56
  125. package/template/templates/security-review.md +0 -63
  126. package/template/templates/telemetry-sidecar.md +0 -184
  127. package/template/templates/test-plan.md +0 -119
  128. package/template/templates/threat-model.md +0 -54
  129. package/template/templates/ui-brief.md +0 -49
  130. package/template/templates/verification.md +0 -63
  131. package/template/templates/vision.md +0 -34
@@ -1,187 +1,60 @@
1
1
  ---
2
2
  name: hstack-adversarial-review
3
- description: |
4
- Use this skill only in a fresh Claude Code session — separate from the session that ran the implementer — after verification has landed at `status: passed` and the change is at `ready-for-review`. The Skill orchestrates the `adversarial-reviewer` subagent to produce a quota-driven critique. v1 fresh-session enforcement is honor-system; the Skill emits a clear instruction reminding the engineer that the v2 substrate will verify via session-id comparison. Examples:
5
-
6
- <example>
7
- Context: The implementer finished the last phase of a billing change; verification passed; the engineer has opened a fresh session for adversarial review.
8
- user: "I've opened a new session. /hstack:adversarial-review 2026-05-billing-overage-warning"
9
- assistant: "I'll invoke adversarial-reviewer. Findings floor is 5 because area=billing. I'll load every change artifact and the full diff; no implementer transcripts. Minimum 5 findings or a defended sub-floor justification — 'no issues found' is not a terminal state."
10
- <commentary>
11
- AR-06 raises the findings floor to 5 for changes in {agent, auth, billing}. The reviewer must spread findings across categories — clustering all findings in one category is a smell unless flagged in Methodology.
12
- </commentary>
13
- </example>
14
-
15
- <example>
16
- Context: A small copy-fix change has been verified and the reviewer can only honestly produce two findings.
17
- user: "/hstack:adversarial-review 2026-05-billing-copy-tweak"
18
- assistant: "I'll invoke adversarial-reviewer. If I can only honestly produce two findings, I'll set findings-fewer-than-floor: true and write a defended justification in section 4 — enumerate every category considered and explain why each produced no honest finding."
19
- <commentary>
20
- The sub-floor path is explicit and rare. AR-01 demands `findings` length ≥ `findings-floor` OR `findings-fewer-than-floor: true` plus non-empty `justification-when-fewer`. "The change is small" alone is insufficient.
21
- </commentary>
22
- </example>
23
-
24
- <example>
25
- Context: The adversarial reviewer finds a high-severity tenant-isolation issue the security review missed.
26
- user: "/hstack:adversarial-review 2026-06-retrieval-rpc-rewrite"
27
- assistant: "I'll invoke adversarial-reviewer with the new pgvector RPC under scrutiny. If a severity:high tenant-isolation finding lands, the resolution must be commit:<hash> or tech-debt:<id> — not justified-in-prose. High-severity security routed to justified-in-prose is a smell and I'll halt."
28
- <commentary>
29
- Resolution discipline matters: `commit:<hash>` for code fixes, `tech-debt:<id>` for deliberate deferral, `justified-in-prose` only for low-severity findings where in-prose reasoning is genuinely right. High-severity security via justified-in-prose is a halt condition.
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 adversarial-review frontmatter and AR-01..AR-06}}"
41
- - "{{TODO-OTHER: fresh-session-attestation — in v1, the subagent self-attests the session is fresh; v2 substrate captures and compares Claude Code session ids automatically}}"
3
+ description: "Use in a fresh session — never the one that wrote the change — to review a PR that touches a sensitive surface. Findings land as a PR comment; the author is the one who fixes them."
42
4
  ---
43
5
 
44
6
  ## Purpose
45
7
 
46
- `hstack-adversarial-review` produces `adversarial-review.md` by orchestrating the `adversarial-reviewer` subagent in a Claude Code session separate from the one that ran the implementer. The output is structurally biased against "looks good" — the reviewer must produce at least the findings floor across the six categories or defend a smaller count with explicit rationale. In v1, fresh-session separation is honor-system; the Skill's first job is to remind the engineer of that.
47
-
48
- ## When to invoke
49
-
50
- Invoke after `verification.md` reaches `status: passed`, in a **fresh Claude Code session**. The Skill opens with a clear instruction to the engineer naming the requirement. If the engineer reports they are in the same session as the implementer, halt and ask them to start a new session.
51
-
52
- ## Inputs
53
-
54
- - `<change-id>` (required, positional): the change-spec id.
55
-
56
- ## Preconditions
57
-
58
- Before any work:
59
-
60
- - **Fresh-session attestation.** The Skill's first action is to print: "This Skill must run in a Claude Code session separate from the one that ran `hstack-implement`. The kernel's authoring-and-review-never-share-a-session principle is honor-system in v1; v2 substrate will verify via session-id comparison. Confirm you are in a fresh session before I proceed." Halt until the engineer confirms.
61
- - Verify the change-spec exists and is at `status: ready-for-review`.
62
- - Verify every required upstream artifact is at terminal status:
63
- - test-plan at `passed` or `concerns-acknowledged`
64
- - plan at `completed`
65
- - security-review at `passed` or `concerns-acknowledged`
66
- - data-review at `passed` or `concerns-acknowledged` when applicable
67
- - ui-brief at `drafted` and figma-handoff at `ready` when applicable
68
- - verification at `passed`
69
- - Determine the findings floor: 3 default; 5 when `change-spec.area` is in {agent, auth, billing} per AR-06.
70
-
71
- ## Orchestration steps
72
-
73
- 1. **Open with the fresh-session reminder.** Print the message verbatim; wait for the engineer's confirmation.
74
-
75
- 2. **Invoke `adversarial-reviewer`.** Use the Task tool with `subagent_type: adversarial-reviewer` and context = [kernel, `hstack/templates/adversarial-review.md`, change-spec, plan, test-plan, ui-brief and figma-handoff when present, security-review, data-review when present, verification, full diff, module-spec, threat-model, hardening-checklist, data-architecture, tech-stack]. Explicitly NOT included: any implementer conversation transcript or scratchpad.
76
-
77
- 3. **Findings generation across six categories.** The subagent produces findings in security, scope-drift, invariant-breach, spec-compliance, data-integrity, and code-quality. Clustering in one category is a smell — when it happens, the subagent flags the clustering in Methodology and explains why the change genuinely lives in one risk dimension. Test-plan adherence is a first-class lens: missing edge-case tests surface as spec-compliance findings; missing tenant-isolation tests surface as data-integrity findings; unmet performance budgets surface as code-quality or data-integrity findings depending on cause; unmapped invariants in `verification.test-plan-coverage` surface as spec-compliance findings. **Test-immutability audit:** the subagent diffs every pre-existing test file against the branch base; any modification, deletion, or snapshot update without a matching `Ok to change/delete/update/refresh ...` authorization echo in a commit message is a mandatory finding under spec-compliance at minimum `severity: high`. Bulk snapshot-update flags visible in the diff or in CI logs escalate to `severity: critical`. These findings are filed even when they push the total over the findings-floor.
78
-
79
- 4. **Findings-floor compliance.** Per AR-01, `findings` length must be ≥ `findings-floor`. If the subagent honestly cannot produce the floor, it sets `findings-fewer-than-floor: true` and writes a defended `justification-when-fewer` enumerating every category considered and why each produced no honest finding. "The change is small" alone is insufficient.
80
-
81
- 5. **Resolution discipline.** Each finding's `resolution` is one of:
82
- - `commit:<hash>` — must reference an existing commit on the change's branch (AR-04).
83
- - `tech-debt:<id>` — must reference an existing tech-debt artifact at `open` or `in-progress` (AR-05). When the engineer chooses this path, they invoke `hstack-tech-debt-new` to create the tech-debt artifact before this review terminates.
84
- - `justified-in-prose` — reserved for low-severity findings only. High-severity findings routed to `justified-in-prose` halt the Skill.
8
+ `/hstack-adversarial-review <pr-number>` reads an open PR cold and reports what is wrong, missing,
9
+ drifted or weakened. It orchestrates the `adversarial-reviewer` subagent and posts the findings on
10
+ the PR. It writes no file and changes no code.
85
11
 
86
- 6. **Fresh-session attestation in frontmatter.** The subagent writes `fresh-session-attestation: "session <id>; opened <timestamp>; no prior implementer context loaded"`. v1 records this as honor-system text; v2 substrate captures the actual session id from Claude Code's session file.
12
+ Reviews are judgments, not evidence (kernel § Review). An empty findings list means the reviewer
13
+ found nothing, not that nothing is there — which is why an empty result is defended rather than
14
+ returned.
87
15
 
88
- 7. **Findings-open is non-terminal.** The subagent does not advance `status: findings-resolved` until every finding has `status: resolved` and a `resolution` value.
89
-
90
- 8. **Owner response loop.** For each finding, the engineer (the change owner) responds with a resolution. The Resolution Log section records each response. The Skill walks the engineer through every finding sequentially.
91
-
92
- 9. **Validate.** Run `{{TODO-SCRIPT: hstack/scripts/validate-spec.ts}}` — AR-01 through AR-06.
93
-
94
- 10. **Change-spec advance (mechanical, only on `findings-resolved`, Skill-orchestrator write per ADR-0002).** When and only when the subagent returned with `adversarial-review.md` at `status: findings-resolved`, read `hstack/specs/changes/<change-id>/spec.md` and inspect its `status` frontmatter. If `status: ready-for-review`, print a proposed-diff preview of the change-spec edit (`status: ready-for-review → ready-to-ship`; `updated: <today>`) and prompt "Proceed with this change-spec advance? (Y/n)". Default Yes. On confirmation, perform the edit via the `Edit` tool, run `{{TODO-SCRIPT: hstack/scripts/validate-spec.ts}}` against the change-spec, then `git add` and commit with message `change-spec(<change-id>): ready-to-ship`. This is a separate commit from the adversarial-review transition commits, matching the verify and finalize precedents. If the change-spec is already at `ready-to-ship` or any downstream status (`shipped`, `archived`), this step is a no-op (idempotent on re-runs). When adversarial-review status is `findings-open` or `in-progress`, this step does not run — the change-spec remains at `ready-for-review` until every finding is resolved. Do NOT invoke `spec-author` and do NOT delegate the write to the `adversarial-reviewer` subagent; per the kernel's Mechanical operations section and ADR-0002, the value to write is fully determined by the adversarial-review postcondition and the change-spec's current status, so the Skill orchestrator writes directly. The `adversarial-reviewer` subagent retains its critique-only lane and writes only `adversarial-review.md`.
95
-
96
- ## Outputs
97
-
98
- - `hstack/specs/changes/<change-id>/adversarial-review.md` at `status: findings-resolved`.
99
- - When `adversarial-review.md` lands at `findings-resolved` and the change-spec was at `ready-for-review`: an edit to `hstack/specs/changes/<change-id>/spec.md` advancing `status: ready-for-review → ready-to-ship` and bumping `updated:` (per ADR-0002, written by the Skill orchestrator).
100
- - Optional new tech-debt artifacts produced via `hstack-tech-debt-new` invocations when findings route to `tech-debt:<id>`.
101
- - Optional new commits on the change's branch when findings route to `commit:<hash>` and the implementer is re-invoked (separately, via `hstack-implement`) to make the fix.
102
-
103
- ## Auto-commit triggers
104
-
105
- - Status transition to `in-progress` after Methodology lands.
106
- - Status transition to `findings-open` after all findings are written.
107
- - Status transition to `findings-resolved` when every finding has `status: resolved`.
108
- - Edits to the `findings` array.
109
- - Edits to any finding's `resolution`.
110
- - **Change-spec status transition `ready-for-review` → `ready-to-ship`** (per ADR-0002, Skill-orchestrator write). When `adversarial-review.md` reaches `findings-resolved`, the Skill orchestrator performs the change-spec advance directly via `Edit` (orchestration step 10), in a separate auto-commit with message `change-spec(<change-id>): ready-to-ship`. The change-spec becomes eligible for `hstack-ship` only after this commit lands. `hstack-ship` itself remains read-only across artifact statuses — it reads the already-written `ready-to-ship` and computes the merge-readiness scorecard. The `adversarial-reviewer` subagent does not write this transition; it stays in its critique-only lane.
111
-
112
- ## Telemetry sidecar
113
-
114
- At the change-spec advance commit (only when adversarial-review status is `findings-resolved`), write `hstack/specs/changes/<change-id>/.telemetry/adversarial-review.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:
115
-
116
- ```json
117
- {
118
- "schema_version": 1,
119
- "skill": "hstack-adversarial-review",
120
- "change_id": "<change-id>",
121
- "reviewed_at": "<ISO-8601, when status reached findings-resolved>",
122
- "findings_floor": <int, 3 or 5 per AR-06>,
123
- "findings_count": <int, length of frontmatter findings array>,
124
- "findings_fewer_than_floor": <bool>,
125
- "category_counts": {
126
- "security": <int>,
127
- "scope-drift": <int>,
128
- "invariant-breach": <int>,
129
- "spec-compliance": <int>,
130
- "data-integrity": <int>,
131
- "code-quality": <int>
132
- },
133
- "severity_counts": {
134
- "critical": <int>,
135
- "high": <int>,
136
- "medium": <int>,
137
- "low": <int>
138
- },
139
- "resolution_mix": {
140
- "commit": <int>,
141
- "tech-debt": <int>,
142
- "justified-in-prose": <int>
143
- },
144
- "fresh_session_attestation": "<verbatim copy of frontmatter field>",
145
- "halt_reasons": [<kernel halt-sentinel enum values, if any>]
146
- }
147
- ```
148
-
149
- When the review ends at `findings-open` or `in-progress` (no change-spec advance), the sidecar still lands with the same shape on whichever transition commit terminates the current run; `findings_fewer_than_floor` reflects the current value. `.telemetry/` is git-ignored. If the sidecar write fails, log and continue; the canonical commit must still land. This is the most directly Goodhart-resistant of the five v1 sidecars — `category_counts` + `severity_counts` + `resolution_mix` jointly surface findings-quota-gaming patterns no single field could detect.
150
-
151
- ## Idempotency contract
16
+ ## When to invoke
152
17
 
153
- - Re-running on a `findings-resolved` review: the subagent reads the existing artifact and produces a no-op aside from `updated` timestamps, unless new code or artifacts have landed since the prior run (in which case new findings may be generated and the status drops back to `findings-open`).
154
- - Re-running mid-resolution after a halt: the subagent reads the partial artifact and resumes with the first finding still at `status: open`.
155
- - The change-spec advance step (step 10) is idempotent: a re-run against a change-spec already at `ready-to-ship` (or `shipped`, `archived`) produces a no-op for that step. The Skill does not re-advance and does not regress.
18
+ On a PR touching one of the sensitive surfaces the kernel § Review names. Every PR already gets
19
+ `/review` and `/security-review` through `/wrap`; this is the deep pass on top, and its whole value
20
+ is that the session running it never saw the change being written.
21
+
22
+ **In a fresh session.** State it in one sentence before starting — "this session has not seen the
23
+ implementation conversation" — and if that is not true, stop and open a new one. This is
24
+ honor-system, as the kernel says; a sentence is the whole protocol.
25
+
26
+ ## Steps
27
+
28
+ 1. **Load the change.** `gh pr view <n>` for the description, `gh pr diff <n>` for the diff, plus
29
+ the base commit so pre-existing files can be diffed. Read the living docs the diff touches,
30
+ `hstack/context/invariants.md`, and the frozen `threat-model.md`. Do not load, ask for, or
31
+ reconstruct the conversation that produced the change.
32
+ 2. **Invoke `adversarial-reviewer`** with that material. The subagent sweeps six lenses and returns
33
+ findings; it does not resolve them and does not touch the code.
34
+ 3. **The test-immutability audit is mandatory** and is not subject to anyone's judgment about
35
+ whether it is worth filing. Every test file that existed at the base is diffed; a modification
36
+ or deletion without its canonical authorization echo — `Ok to change test <name>` /
37
+ `Ok to delete test <name>`, in a commit message or the PR description — is a finding at `high`
38
+ minimum. A bulk snapshot update is `critical`.
39
+ 4. **Post the findings** with `gh pr comment <n>`, or as a GitHub review when they are anchored to
40
+ lines. Each finding carries a severity, a category, the evidence in the diff, and what would
41
+ resolve it.
42
+ 5. **Resolution belongs to the author**: a corrective commit on the branch, or a tech-debt file
43
+ written in the same PR (kernel § Tech-debt). The reviewer never pushes the fix.
44
+
45
+ ## Output
46
+
47
+ One PR comment. No artifact, no status, no file in the repo.
156
48
 
157
49
  ## Stop conditions
158
50
 
159
- Beyond the kernel's general stop conditions:
160
-
161
- - Engineer has not confirmed they are in a fresh Claude Code session.
162
- - A required upstream artifact is non-terminal.
163
- - A high-severity security or tenant-isolation finding would route to `justified-in-prose`. Halt.
164
- - A `commit:<hash>` resolution would reference a commit not on the change's branch.
165
- - A `tech-debt:<id>` resolution would reference a non-existent tech-debt artifact (the engineer must invoke `hstack-tech-debt-new` first).
166
- - The findings floor cannot honestly be met and the sub-floor justification cannot be defended.
167
- - The diff includes changes outside `change-spec.in-scope` that CI did not catch — surface a scope-drift finding and halt the CI gap as a separate concern.
168
- - An implementer transcript or scratchpad is visible in the session.
169
-
170
- ## Failure modes
171
-
172
- - **Engineer claims fresh session but conversation shows prior implementer transcripts.** Halt; ask the engineer to truly start a new session.
173
- - **Reviewer cannot produce honest findings to meet the floor and the sub-floor justification feels thin.** Re-prompt for each category; if still under floor, the engineer must defend the sub-floor explicitly.
174
- - **A finding routes to `tech-debt:<id>` but the engineer hasn't created the tech-debt artifact.** The Skill prompts to invoke `hstack-tech-debt-new`; the review does not terminate until the artifact exists.
175
- - **A commit hash named in `resolution` does not exist on the change's branch.** Halt — the engineer either re-references the correct commit or the resolution is reconsidered.
176
-
177
- ## Anti-patterns
51
+ Beyond the kernel's:
178
52
 
179
- - Never return "no issues found" without a defended sub-floor justification.
180
- - Never run in the same Claude Code session as `hstack-implement`. Honor-system in v1; CI-verified in v2.
181
- - Never cluster all findings in one category without flagging in Methodology.
182
- - Never use `justified-in-prose` for a high-severity finding.
183
- - Never propose code changes directly the reviewer surfaces findings; the owner or implementer (via `hstack-implement`) resolves them.
184
- - Never invent a tech-debt id. The artifact must exist or be authored before the review terminates.
185
- - Never accept a `commit:<hash>` that does not exist on the change's branch.
186
- - Never advance status to `findings-resolved` while any finding has `status: open`.
187
- - Never load implementer transcripts. If visible, halt.
53
+ - The session has seen the implementation conversation. Halt and ask for a fresh one.
54
+ - The PR cannot be read, or its diff is unavailable.
55
+ - A living doc the review depends on is missing or stale. Say so in the findings; never invent its
56
+ content (kernel § Context docs).
57
+ - The sweep came back empty and the defence cannot be written honestly. Halt and surface it a
58
+ defence nobody believes is worse than an open review.
59
+ - A high-severity finding is waved away without a fix or a tech-debt file. Do not silently retract:
60
+ restate it with the evidence, and leave it in the comment.
@@ -0,0 +1,134 @@
1
+ # The six finding categories — a calibration rubric
2
+
3
+ Reference file for `hstack-adversarial-review` and the `adversarial-reviewer` subagent. Read it
4
+ when a category is unfamiliar, when a finding feels thin and you want to know whether it is real,
5
+ or when calibrating a severity. It is **not** a checklist: nothing here says how many findings a
6
+ review should produce, and a review landing entirely in one category is the correct outcome when
7
+ the change carries its risk in one dimension (ADR-0014).
8
+
9
+ ---
10
+
11
+ ## security
12
+
13
+ **What it means.** The change creates or widens a path an attacker can use, or weakens a control
14
+ that was closing one. Distinct from `data-integrity`: this is about an adversary, not about
15
+ accidental corruption.
16
+
17
+ **Real findings look like.** A new endpoint that reads a user-supplied id and queries by it without
18
+ re-deriving the caller's scope. A prompt that concatenates retrieved document text into a system
19
+ message. A secret moved from an env read to a literal. An auth check that runs after the side
20
+ effect. A dependency bump that pulls a package with a known CVE.
21
+
22
+ **Filler looks like.** "Consider adding rate limiting" on a change that touches no network surface.
23
+ Restating an item of the kernel's security checklist with no evidence from the diff that it was
24
+ missed.
25
+
26
+ **Severity.** Anything exploitable by an unauthenticated caller, or that crosses a tenant boundary,
27
+ is `critical` or `high` — never `medium` because it is unlikely. Likelihood belongs in the severity
28
+ rationale, not in the level.
29
+
30
+ ---
31
+
32
+ ## scope-drift
33
+
34
+ **What it means.** The diff touches things the PR description's announced perimeter does not name
35
+ (kernel § Scope rules), or the change quietly grew a second purpose.
36
+
37
+ **Real findings look like.** A refactor of a shared util nothing in the change asked for. A
38
+ migration altering a table outside the change's module. A "while I was in there" rename that makes
39
+ the diff unreviewable. A new dependency satisfying a convenience nobody asked for.
40
+
41
+ **Filler looks like.** Flagging a file the announced perimeter does cover. Flagging generated
42
+ files, lockfiles or formatter output the repo's conventions produce automatically.
43
+
44
+ **Severity.** Usually `medium`. It escalates when the drift lands on a path `invariants.md` covers,
45
+ because then it is also `invariant-breach`.
46
+
47
+ ---
48
+
49
+ ## invariant-breach
50
+
51
+ **What it means.** Something `hstack/context/invariants.md` or a living doc declares as always-true
52
+ is no longer always-true after this diff.
53
+
54
+ **Real findings look like.** An invariant about ordering that the new code path can violate under
55
+ concurrency. An invariant still true but now enforced by convention where it used to be enforced by
56
+ a type or a database constraint. A boundary a living doc describes — "no direct SQL outside this
57
+ module" — and a new query in an adjacent file.
58
+
59
+ **Filler looks like.** Paraphrasing an invariant back and calling it a risk. Naming an invariant the
60
+ diff does not touch.
61
+
62
+ **Severity.** `high` by default — an invariant that breaks silently is worse than a bug that throws.
63
+ Drop to `medium` only when an existing test fails loudly on the breach.
64
+
65
+ ---
66
+
67
+ ## intent-compliance
68
+
69
+ **What it means.** The diff and what the PR says it does disagree. The widest category and the one
70
+ most often under-used. The PR description is the contract here: it names the perimeter, the Notion
71
+ feature, the shortcuts taken, the living docs updated.
72
+
73
+ **Real findings look like.** Behaviour the description promises and the diff does not land.
74
+ Behaviour the diff adds that no line of the description anticipated — undeclared scope is a
75
+ compliance gap in the other direction. A living doc the change invalidated and left untouched
76
+ (kernel § Context docs). A conscious shortcut visible in the code and named nowhere. **Any
77
+ test-file modification without its canonical authorization echo** (`KERNEL.md` § Test immutability);
78
+ this one is mandatory and never subject to judgment about whether it is worth filing.
79
+
80
+ **Filler looks like.** "The description could have been clearer." Style disagreements with how the
81
+ work was sequenced.
82
+
83
+ **Severity.** Unauthorized test changes: `high` minimum, `critical` for a bulk snapshot update. A
84
+ stale living doc: `high`, because the next session will read it and believe it. Everything else:
85
+ judgment.
86
+
87
+ ---
88
+
89
+ ## data-integrity
90
+
91
+ **What it means.** Data can end up wrong, lost, or visible to the wrong tenant without anybody
92
+ attacking anything.
93
+
94
+ **Real findings look like.** A migration adding a NOT NULL column with no default and no backfill.
95
+ A destructive DDL with no stated rollback. An RLS policy whose predicate does not match the tenancy
96
+ model in `data-architecture.md`. A tenant-scoped RPC missing its tenant filter. A write path that
97
+ is not idempotent under retry. A pgvector retrieval filtering after the similarity search rather
98
+ than inside it.
99
+
100
+ **Filler looks like.** Speculating about scale on a table with a bounded row count. Recommending an
101
+ index with no query to justify it.
102
+
103
+ **Severity.** Cross-tenant leakage is `critical` — always, including when the leak needs an unlikely
104
+ sequence to trigger. Irreversible data loss is `critical`. Recoverable inconsistency is `high`.
105
+
106
+ ---
107
+
108
+ ## code-quality
109
+
110
+ **What it means.** The change works and will cost more than it should to live with. The weakest
111
+ category and the easiest to pad, which is why it is worth being strict about what belongs here.
112
+
113
+ **Real findings look like.** A third copy of logic that already exists twice, where the copies have
114
+ started to disagree. Error handling that swallows a failure the caller needs. A function whose
115
+ behaviour depends on call order with nothing that documents or enforces it.
116
+
117
+ **Filler looks like.** Naming preferences. Suggested comments. Requests to extract a function used
118
+ once. Anything a formatter or a linter would have said.
119
+
120
+ **Severity.** `low` or `medium`. A `code-quality` finding at `high` is usually mis-categorized —
121
+ look again at whether it is really `invariant-breach` or `data-integrity`.
122
+
123
+ ---
124
+
125
+ ## Resolution
126
+
127
+ Independent of category, a finding names what would resolve it:
128
+
129
+ - **A corrective commit on the branch** — the author fixes it before the merge.
130
+ - **A tech-debt file in the same PR** — the finding is real and is being lived with, on the record
131
+ and grep-able by `related-modules` (kernel § Tech-debt).
132
+ - **An argument in the comment thread** — the finding is real and the right answer is to explain
133
+ why nothing changes. Fine for a `low`; a `high` answered this way stays open, and a security or
134
+ tenant-isolation finding answered this way is escalated, not closed.
@@ -1,109 +1,57 @@
1
1
  ---
2
2
  name: hstack-app-architecture
3
- description: |
4
- Use this skill when the engineer wants to produce or refresh `hstack/context/app-architecture.md` — the five-section internal-architecture design (Module Map, Agent Orchestration, Deterministic-vs-LLM Split, State Ownership, Surface Boundaries). The Skill is Phase 3 of `/hstack:greenfield-init`, the app-architecture step of `/hstack:brownfield-init`, or a standalone atom for refreshing a single section. At terminal state the atom auto-scaffolds `hstack/specs/<module>/spec.md` stubs at `status: draft` for each declared module and updates `hstack/config.yaml`'s `surfaces` enum to match Section 5. Examples:
5
-
6
- <example>
7
- Context: Phase 3 of greenfield-init opens after data-architecture is current.
8
- user: "/hstack:app-architecture"
9
- assistant: "Loading product-brief, data-architecture, vision, mvp-scope. Stack-agnostic interview — I won't ask about frameworks here; that's Phase 4. Section 3 (Deterministic-vs-LLM Split) is the load-bearing AI-native decision: per user-facing flow, what's code and what's prompt, with rationale tied to a measurable property."
10
- <commentary>
11
- Internal architecture is stack-agnostic by design. Section 3 is where AI-native teams most often get architecture wrong by leaving the LLM/code split implicit. The atom forces per-step declaration.
12
- </commentary>
13
- </example>
14
-
15
- <example>
16
- Context: A brownfield repo's modules have evolved; the engineer wants the artifact refreshed against current code.
17
- user: "/hstack:app-architecture --mode extract"
18
- assistant: "Extract mode. Scanning src/, app/, lib/ via Glob; reading exports and dependencies. Proposing the Module Map from code-evidence. The drift challenge runs at the end of Section 1: does any module own state a persona never interacts with?"
19
- <commentary>
20
- Extract mode reads code-evidence to propose modules; the engineer confirms or revises. The orphan-module challenge catches modules that have grown beyond their persona-named purpose.
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 — frontmatter validator}}"
3
+ description: "Use when the application architecture really moves — modules, LLM call sites, state ownership, surfaces, or what a user can reach — to write or refresh `hstack/context/app-architecture.md`, exposure map included."
32
4
  ---
33
5
 
34
6
  ## Purpose
35
7
 
36
- `hstack-app-architecture` is the atom that produces or refreshes `hstack/context/app-architecture.md` via the `app-architect` subagent. The artifact captures the internal architecture in five sections; subsequent module-spec authoring and per-change-spec `surfaces` declarations depend on it.
8
+ `/hstack-app-architecture` writes or refreshes `hstack/context/app-architecture.md`: the module map
9
+ with its exposure column, the agent orchestration model, the deterministic-vs-LLM split, the
10
+ state-ownership map, the surface boundaries. It is what the next session reads to know what exists
11
+ and what a user can reach.
37
12
 
38
- ## When to invoke
39
-
40
- - Phase 3 of `/hstack:greenfield-init` (elicit mode).
41
- - Delegated by `/hstack:brownfield-init` mini-session 5b (extract mode).
42
- - Standalone via `/hstack:app-architecture [--mode extract|elicit] [--section <name>]` for refresh or single-section edits.
43
- - Routed-into-from-downstream when `/hstack:stack-decide` finds a stack constraint that contradicts the architecture (rare).
13
+ It is not how the doc stays current day to day — a change that adds a route updates the map in its
14
+ own PR, which is the kernel's rule and costs nothing. This Skill is for the moves that rule cannot
15
+ absorb: the first write, a module boundary that no longer matches the code, an exposure map that
16
+ has drifted away from the real routes.
44
17
 
45
18
  ## Inputs
46
19
 
47
- - `--mode extract | elicit` defaults: `extract` if a `src/`, `app/`, or `lib/` tree exists in the consuming repo; `elicit` if the repo is empty (greenfield).
48
- - `--section <name>` — one of `modules | orchestration | split | state | surfaces`. Fast-jumps but re-runs end-of-atom coherence.
49
-
50
- ## Preconditions
51
-
52
- - `hstack/config.yaml` at `init-status: minimal-complete` or later.
53
- - `hstack/context/product/product-brief.md` and `hstack/context/data-architecture.md` both at `status: current`. App architecture is downstream of both. If either is at non-terminal status, halt with `HSTACK-HALT: reason=upstream-non-terminal`.
54
- - `hstack/templates/app-architecture.md` and `hstack/templates/module-spec.md` present.
55
- - In extract mode, a source tree (`src/`, `app/`, or `lib/`) is reachable; otherwise halt.
56
-
57
- ## Orchestration steps
58
-
59
- 1. **Detect mode + entry.** Read disk state. If artifact at `current` and no `--section` and no `--force`: print summary, exit no-op.
60
- 2. **Invoke `app-architect` subagent.** Via the Task tool with `subagent_type: app-architect`. Pass mode, optional section, the canonical session-start context. Explicitly DO NOT pass `tech-stack.md` — the architecture is stack-agnostic.
61
- 3. **Walk sections.** The subagent walks all five sections in order in fresh-start mode. Section 3 (Deterministic-vs-LLM Split) is walked per-flow with per-step confirmation; this is the only section with finer-than-section confirmation gates because per-step declarations are too consequential to batch.
62
- 4. **Run drift challenge prompts.** Each section ends with a drift challenge. A real drift halts with `HSTACK-HALT: reason=upstream-drift` and offers (a) revise this section, (b) re-enter the upstream atom (typically `/hstack:data-architecture --section entities` for state-ownership gaps), (c) log as ADR.
63
- 5. **End-of-atom coherence check.** Even on section-targeted entry, the subagent re-runs all five drift challenges before terminal commit.
64
- 6. **Terminal-state side effects (one atomic commit).** When the artifact reaches `status: current`, the Skill performs three mechanical writes in a single commit:
65
- - The completed `app-architecture.md`.
66
- - One `hstack/specs/<module>/spec.md` stub per module from Section 1 (header sections only, `status: draft`, body note pointing to `/hstack:module-spec`).
67
- - `hstack/config.yaml` updated to set the `surfaces` enum to match Section 5.
68
- The proposed-diff preview runs before this commit lands per the kernel's mechanical-operations rule.
69
-
70
- ## Outputs
71
-
72
- - `hstack/context/app-architecture.md` at `status: current`.
73
- - One `hstack/specs/<module>/spec.md` per module at `status: draft`.
74
- - `hstack/config.yaml` with updated `surfaces` enum.
75
- - `hstack/.session-state/<session-id>.yaml` (transient).
76
-
77
- ## Auto-commit triggers
78
-
79
- - Each confirmed section writes immediately and auto-commits.
80
- - Per-flow row in Section 3 commits individually (not full-section batch).
81
- - Terminal-state side effects (artifact + stubs + config) land in one atomic commit.
82
-
83
- ## Idempotency contract
84
-
85
- - Artifact at `current` + no `--section` + no `--force`: print summary, exit no-op.
86
- - Artifact at `draft` or partial: resume at next non-confirmed section.
87
- - Artifact at `needs-refresh`: walk all sections in confirm-or-revise mode.
88
- - Module-spec stubs at `status: draft`: the atom does NOT overwrite stubs on re-run; if Section 1 added a module on refresh, the new stub lands additively; if Section 1 removed a module, the orphan stub is flagged for engineer review (the engineer either deletes it or routes the deletion through `/hstack:tech-debt-stale`).
20
+ `--section modules | orchestration | split | state | surfaces`, optional refreshes one section.
21
+
22
+ ## Steps
23
+
24
+ 1. **Extract or elicit.** Extract when a source tree exists; elicit when the repo is empty.
25
+ 2. **Invoke `app-architect`** with the material. It reads the tree, drafts each section and
26
+ challenges it. The questions and the confirmations happen here, in this session a subagent
27
+ cannot interview.
28
+ 3. **Fill the exposure column in extract mode.** Entry points are enumerable: `app/**/page.tsx` and
29
+ `app/**/route.ts` for the App Router, files carrying `'use server'` for server actions, plus the
30
+ job and webhook registrations. Enumerate them, attach each to the module it serves, and ask the
31
+ engineer for a status per entry point — `live`, `routable` or `off`, as the kernel defines them.
32
+ A module reached only through another module's entry point names that one instead; a module no
33
+ live entry point reaches is `dormant`, which is derived and never a fourth status.
34
+ 4. **One line the map carries, not this Skill's to restate:** it grades the **product** severity of
35
+ a finding, never its security severity. Every routable entry point is covered by the kernel's
36
+ security checklist whatever the map says.
37
+ 5. **Each section ends with its drift challenge**, and the answer stays in the doc as evidence the
38
+ probe ran. A challenge that surfaces a real contradiction stops the section: the engineer
39
+ revises it, files an ADR, or writes a tech-debt file.
40
+ 6. **A section-targeted refresh re-reads the other four challenges** before the PR — a module
41
+ renamed in Section 1 and left standing in Section 4 is the failure this catches.
42
+
43
+ ## Output
44
+
45
+ `hstack/context/app-architecture.md`, updated in the PR that changes it. Nothing else: no module
46
+ spec stubs, no config file, no status.
89
47
 
90
48
  ## Stop conditions
91
49
 
92
- - Product-brief or data-architecture at non-terminal status.
93
- - A module in Section 1 has no trace to brief or data-architecture entities.
94
- - A Section 3 flow step has no declared mechanism or no measurable-property rationale.
95
- - A drift challenge surfaces an unresolved contradiction.
96
- - Extract mode invoked but no source tree reachable.
97
-
98
- ## Failure modes
99
-
100
- - **Subagent unreachable.** Persist session state; retry later.
101
- - **Terminal-state side-effect commit fails partway** (e.g., one stub fails validator). The atom rolls back the in-progress write and halts with the validator error; the engineer fixes or routes through `/hstack:configure`. The artifact stays at `current` only when ALL three side effects land successfully.
102
-
103
- ## Anti-patterns
50
+ Beyond the kernel's:
104
51
 
105
- - Never name frameworks, ORMs, hosting providers, or specific runtimes in the artifact body or frontmatter. Stack-agnostic is load-bearing for portability across Phase 4 stack decisions.
106
- - Never write authored content into module-spec stubs. Headers + `status: draft` + body note only.
107
- - Never let Section 3's per-step declaration collapse to "the AI handles it end-to-end." Each step is named with mechanism + measurable-property rationale.
108
- - Never bypass the end-of-atom coherence check on section-targeted re-entry.
109
- - Never write surfaces into `hstack/config.yaml` outside the terminal-state atomic commit.
52
+ - Extract mode was asked for and no source tree is reachable.
53
+ - An entry point's status is a guess. Ask; a wrong `off` is how a live surface stops being reviewed.
54
+ - A step of a flow has no declared mechanism, or a rationale that names no property anyone could
55
+ disagree with.
56
+ - A drift challenge surfaces a contradiction with `data-architecture.md` typically a state class
57
+ with nowhere to live. Surface it; the engineer decides whether the data doc moves.