hstack 0.16.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +53 -0
- package/README.md +76 -163
- package/VERSION +1 -1
- package/dist/commands/doctor.js +18 -8
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/init.js +7 -3
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/update.js +9 -2
- package/dist/commands/update.js.map +1 -1
- package/dist/lib/descriptions.js +10 -17
- package/dist/lib/descriptions.js.map +1 -1
- package/dist/lib/wire.js +166 -138
- package/dist/lib/wire.js.map +1 -1
- package/dist/manifest.js +41 -29
- package/dist/manifest.js.map +1 -1
- package/package.json +3 -4
- package/template/.claude/agents/adversarial-reviewer.md +44 -50
- package/template/.claude/agents/app-architect.md +44 -96
- package/template/.claude/agents/data-architect.md +46 -89
- package/template/.claude/agents/test-strategist.md +39 -68
- package/template/.claude/skills/hstack-adr-new/SKILL.md +23 -73
- package/template/.claude/skills/hstack-adversarial-review/SKILL.md +46 -152
- package/template/.claude/skills/hstack-adversarial-review/references/finding-categories.md +89 -103
- package/template/.claude/skills/hstack-app-architecture/SKILL.md +43 -68
- package/template/.claude/skills/hstack-commit/SKILL.md +27 -68
- package/template/.claude/skills/hstack-data-architecture/SKILL.md +34 -56
- package/template/.claude/skills/hstack-promote/SKILL.md +55 -0
- package/template/.claude/skills/hstack-story/SKILL.md +58 -0
- package/template/.claude/skills/hstack-test-audit/SKILL.md +64 -0
- package/template/.claude/skills/hstack-wrap/SKILL.md +50 -0
- package/template/.claude/skills/hstack-wrap/references/pr-description.md +45 -0
- package/template/KERNEL.md +75 -318
- package/template/templates/adr.md +2 -18
- package/template/templates/app-architecture.md +38 -50
- package/template/templates/code-standards.md +107 -0
- package/template/templates/data-architecture.md +38 -89
- package/template/templates/eslint-clean-code.mjs +322 -0
- package/template/templates/infrastructure.md +54 -148
- package/template/templates/roadmap.md +6 -12
- package/template/templates/story.md +7 -13
- package/template/templates/tech-debt.md +2 -37
- package/template/templates/tech-stack.md +2 -12
- package/template/.claude/agents/data-specialist.md +0 -81
- package/template/.claude/agents/implementer.md +0 -97
- package/template/.claude/agents/kernel-fit-analyst.md +0 -129
- package/template/.claude/agents/planner.md +0 -75
- package/template/.claude/agents/product-discovery.md +0 -129
- package/template/.claude/agents/product-manager.md +0 -76
- package/template/.claude/agents/researcher.md +0 -87
- package/template/.claude/agents/security-reviewer.md +0 -88
- package/template/.claude/agents/spec-author.md +0 -89
- package/template/.claude/agents/stack-architect.md +0 -108
- package/template/.claude/agents/ui-ux-briefer.md +0 -75
- package/template/.claude/agents/verifier.md +0 -81
- package/template/.claude/skills/hstack-branch/SKILL.md +0 -76
- package/template/.claude/skills/hstack-brownfield-init/SKILL.md +0 -131
- package/template/.claude/skills/hstack-change-new/SKILL.md +0 -84
- package/template/.claude/skills/hstack-change-plan/SKILL.md +0 -108
- package/template/.claude/skills/hstack-configure/SKILL.md +0 -99
- package/template/.claude/skills/hstack-coord/SKILL.md +0 -95
- package/template/.claude/skills/hstack-data-review/SKILL.md +0 -93
- package/template/.claude/skills/hstack-finalize/SKILL.md +0 -140
- package/template/.claude/skills/hstack-flag/SKILL.md +0 -99
- package/template/.claude/skills/hstack-greenfield-init/SKILL.md +0 -148
- package/template/.claude/skills/hstack-help/SKILL.md +0 -153
- package/template/.claude/skills/hstack-implement/SKILL.md +0 -155
- package/template/.claude/skills/hstack-kernel-fit-promote/SKILL.md +0 -125
- package/template/.claude/skills/hstack-kernel-fit-scan/SKILL.md +0 -142
- package/template/.claude/skills/hstack-kernel-fit-scan/references/slack-setup.md +0 -42
- package/template/.claude/skills/hstack-kernel-fit-triage/SKILL.md +0 -121
- package/template/.claude/skills/hstack-module-spec/SKILL.md +0 -78
- package/template/.claude/skills/hstack-product-discovery/SKILL.md +0 -75
- package/template/.claude/skills/hstack-research/SKILL.md +0 -115
- package/template/.claude/skills/hstack-scaffold/SKILL.md +0 -113
- package/template/.claude/skills/hstack-security-review/SKILL.md +0 -95
- package/template/.claude/skills/hstack-ship/SKILL.md +0 -119
- package/template/.claude/skills/hstack-stack-decide/SKILL.md +0 -81
- package/template/.claude/skills/hstack-story-draft/SKILL.md +0 -92
- package/template/.claude/skills/hstack-tech-debt-new/SKILL.md +0 -95
- package/template/.claude/skills/hstack-tech-debt-resolve/SKILL.md +0 -123
- package/template/.claude/skills/hstack-tech-debt-stale/SKILL.md +0 -86
- package/template/.claude/skills/hstack-tech-debt-wontfix/SKILL.md +0 -77
- package/template/.claude/skills/hstack-telemetry/SKILL.md +0 -73
- package/template/.claude/skills/hstack-test-plan/SKILL.md +0 -159
- package/template/.claude/skills/hstack-ui-brief/SKILL.md +0 -81
- package/template/.claude/skills/hstack-verify/SKILL.md +0 -128
- package/template/scripts/compute-merge-readiness.mjs +0 -780
- package/template/scripts/coord/coord_scan.py +0 -681
- package/template/scripts/run-gates.sh +0 -388
- package/template/scripts/telemetry/__init__.py +0 -6
- package/template/scripts/telemetry/insights/__init__.py +0 -0
- package/template/scripts/telemetry/insights/contract_drift.py +0 -137
- package/template/scripts/telemetry/insights/kernel_fit.py +0 -438
- package/template/scripts/telemetry/insights/overengineering.py +0 -115
- package/template/scripts/telemetry/insights/quality_outcomes.py +0 -131
- package/template/scripts/telemetry/insights/token_economics.py +0 -302
- package/template/scripts/telemetry/insights/workflow_shape.py +0 -198
- package/template/scripts/telemetry/parsers/__init__.py +0 -0
- package/template/scripts/telemetry/parsers/bodies.py +0 -87
- package/template/scripts/telemetry/parsers/commits.py +0 -219
- package/template/scripts/telemetry/parsers/frontmatter.py +0 -322
- package/template/scripts/telemetry/parsers/sidecars.py +0 -61
- package/template/scripts/telemetry/parsers/transcripts.py +0 -294
- package/template/scripts/telemetry/render.py +0 -460
- package/template/scripts/telemetry/report.py +0 -150
- package/template/scripts/telemetry/run_kernel_fit.py +0 -95
- package/template/scripts/telemetry/session_id.py +0 -139
- package/template/scripts/validate-spec.mjs +0 -3303
- package/template/templates/adversarial-review.md +0 -54
- package/template/templates/bootstrap.md +0 -105
- package/template/templates/change-spec.md +0 -82
- package/template/templates/ci-cd.md +0 -41
- package/template/templates/coord-message.md +0 -56
- package/template/templates/data-review.md +0 -54
- package/template/templates/discovery/brainstorm.md +0 -69
- package/template/templates/discovery/forcing-questions.md +0 -76
- package/template/templates/discovery/project-brief.md +0 -53
- package/template/templates/figma-handoff.md +0 -38
- package/template/templates/glossary.md +0 -20
- package/template/templates/hardening-checklist.md +0 -73
- package/template/templates/incident-runbook.md +0 -57
- package/template/templates/kernel-fit-finding.md +0 -63
- package/template/templates/kernel-fit-flag.md +0 -52
- package/template/templates/module-spec.md +0 -49
- package/template/templates/persona.md +0 -38
- package/template/templates/plan.md +0 -53
- package/template/templates/product-brief.md +0 -56
- package/template/templates/security-review.md +0 -63
- package/template/templates/telemetry-sidecar.md +0 -227
- package/template/templates/test-plan.md +0 -119
- package/template/templates/threat-model.md +0 -54
- package/template/templates/ui-brief.md +0 -49
- package/template/templates/verification.md +0 -63
- package/template/templates/vision.md +0 -34
package/dist/manifest.js
CHANGED
|
@@ -6,8 +6,7 @@
|
|
|
6
6
|
* On `hstack update` only paths in `FRAMEWORK_PATHS` are overwritten; paths
|
|
7
7
|
* in `USER_CONTENT_PATHS` are NEVER touched by the installer.
|
|
8
8
|
*
|
|
9
|
-
* The boundary is load-bearing — see
|
|
10
|
-
* the README installation section.
|
|
9
|
+
* The boundary is load-bearing — see the README installation section.
|
|
11
10
|
*/
|
|
12
11
|
/**
|
|
13
12
|
* Paths the installer owns. `hstack update` overwrites these.
|
|
@@ -22,35 +21,48 @@ export const FRAMEWORK_PATHS = [
|
|
|
22
21
|
"templates/",
|
|
23
22
|
".claude/agents/",
|
|
24
23
|
".claude/skills/",
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
24
|
+
];
|
|
25
|
+
/**
|
|
26
|
+
* Paths the installer shipped before v0.17 and now takes back.
|
|
27
|
+
*
|
|
28
|
+
* v0.17 removed the enforcement scripts (`validate-spec.mjs`,
|
|
29
|
+
* `compute-merge-readiness.mjs`, `run-gates.sh`) and the `coord/` and
|
|
30
|
+
* `telemetry/` module trees along with the machinery that called them. Dropping
|
|
31
|
+
* them from `FRAMEWORK_PATHS` is not enough on its own: the update diff only
|
|
32
|
+
* looks at paths in that list, so a path removed from it is a path nothing will
|
|
33
|
+
* ever prune — the consumer would keep running a copy of a script this
|
|
34
|
+
* framework no longer knows about. `hstack update` therefore removes these
|
|
35
|
+
* explicitly, the same way the ADR-0010 rename is a migration rather than a
|
|
36
|
+
* diff. Planned only when the path is actually on disk, so it is a no-op by
|
|
37
|
+
* construction on a consumer installed after v0.17.
|
|
38
|
+
*
|
|
39
|
+
* Relative to `<consumer>/hstack/`. Order matters only for readability.
|
|
40
|
+
*/
|
|
41
|
+
export const LEGACY_FRAMEWORK_PATHS = [
|
|
35
42
|
"scripts/validate-spec.mjs",
|
|
36
43
|
"scripts/compute-merge-readiness.mjs",
|
|
37
44
|
"scripts/run-gates.sh",
|
|
45
|
+
"scripts/coord",
|
|
46
|
+
"scripts/telemetry",
|
|
38
47
|
];
|
|
39
48
|
/**
|
|
40
|
-
*
|
|
41
|
-
*
|
|
49
|
+
* The directory the legacy paths above lived in. Removed after them, and only
|
|
50
|
+
* when empty: an engineer who put their own script there keeps it.
|
|
51
|
+
*/
|
|
52
|
+
export const LEGACY_SCRIPTS_DIR = "scripts";
|
|
53
|
+
/**
|
|
54
|
+
* Paths the installer NEVER touches once they exist in the consumer — the
|
|
55
|
+
* engineering memory, which belongs to the repo that wrote it.
|
|
56
|
+
*
|
|
57
|
+
* Documentation, not a mechanism: nothing imports this list. The protection is
|
|
58
|
+
* structural — `update` only ever writes paths in `FRAMEWORK_PATHS`. v0.17
|
|
59
|
+
* dropped `config.yaml`, `specs/`, `research/`, `telemetry/reports/` and
|
|
60
|
+
* `kernel-fit/` from it, because naming directories the framework no longer
|
|
61
|
+
* creates describes a boundary that has moved.
|
|
62
|
+
*
|
|
42
63
|
* Relative to `<consumer>/hstack/`.
|
|
43
64
|
*/
|
|
44
|
-
export const USER_CONTENT_PATHS = [
|
|
45
|
-
"config.yaml",
|
|
46
|
-
"context/",
|
|
47
|
-
"specs/",
|
|
48
|
-
"adr/",
|
|
49
|
-
"tech-debt/",
|
|
50
|
-
"research/",
|
|
51
|
-
"telemetry/reports/",
|
|
52
|
-
"kernel-fit/",
|
|
53
|
-
];
|
|
65
|
+
export const USER_CONTENT_PATHS = ["context/", "adr/", "tech-debt/"];
|
|
54
66
|
/**
|
|
55
67
|
* Consumer-side wiring under `<consumer>/.claude/` — symlinks pointing into
|
|
56
68
|
* the consumer's `hstack/.claude/` tree. Owned by the installer; recreated
|
|
@@ -67,11 +79,11 @@ export const CLAUDE_WIRING = {
|
|
|
67
79
|
skillsSourceDir: "hstack/.claude/skills",
|
|
68
80
|
skillsTargetDir: ".claude/skills",
|
|
69
81
|
/**
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* engineer-owned and never touched.
|
|
74
|
-
* settings.json is
|
|
82
|
+
* <consumer>/.claude/settings.json. Until v0.17 the installer merged the
|
|
83
|
+
* ADR-0007 coord-notification hooks into it; now it only takes them back out.
|
|
84
|
+
* The installer owns ONLY the entries whose command targets hstack's coord
|
|
85
|
+
* script — everything else in the file is engineer-owned and never touched.
|
|
86
|
+
* Idempotent; an unparseable settings.json is surfaced, never overwritten.
|
|
75
87
|
*/
|
|
76
88
|
settingsFile: ".claude/settings.json",
|
|
77
89
|
};
|
package/dist/manifest.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,WAAW;IACX,YAAY;IACZ,iBAAiB;IACjB,iBAAiB;CACT,CAAC;AAEX;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,2BAA2B;IAC3B,qCAAqC;IACrC,sBAAsB;IACtB,eAAe;IACf,mBAAmB;CACX,CAAC;AAEX;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,SAAS,CAAC;AAE5C;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,CAAU,CAAC;AAE9E;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,4EAA4E;IAC5E,UAAU,EAAE;QACV,IAAI,EAAE,gBAAgB;QACtB,EAAE,EAAE,uBAAuB;KAC5B;IACD,+FAA+F;IAC/F,UAAU,EAAE,UAAU;IACtB,eAAe,EAAE,uBAAuB;IACxC,eAAe,EAAE,gBAAgB;IACjC;;;;;;OAMG;IACH,YAAY,EAAE,uBAAuB;CAC7B,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hstack",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "A spec-driven engineering workflow that ships as Claude Code Skills and subagents.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude-code",
|
|
@@ -30,10 +30,9 @@
|
|
|
30
30
|
"scripts": {
|
|
31
31
|
"build": "tsc",
|
|
32
32
|
"pretest": "npm run build",
|
|
33
|
-
"test": "node scripts/test-
|
|
33
|
+
"test": "node scripts/test-description-budget.mjs",
|
|
34
34
|
"dev": "tsx src/cli.ts",
|
|
35
|
-
"
|
|
36
|
-
"prepack": "npm run build && npm run clean:pyc",
|
|
35
|
+
"prepack": "npm run build",
|
|
37
36
|
"prepublishOnly": "npm run build"
|
|
38
37
|
},
|
|
39
38
|
"engines": {
|
|
@@ -1,75 +1,69 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: adversarial-reviewer
|
|
3
3
|
model: opus
|
|
4
|
-
description: Use
|
|
4
|
+
description: "Use to critique a PR cold, from a session that never saw it being written — the six lenses, the mandatory test-immutability audit, an empty result that has to be defended. Surfaces findings; never resolves them."
|
|
5
5
|
tools:
|
|
6
6
|
- Read
|
|
7
7
|
- Grep
|
|
8
8
|
- Glob
|
|
9
|
-
- Write
|
|
10
|
-
- Edit
|
|
11
9
|
- Bash
|
|
12
|
-
- "{{TODO-SKILL: /hstack:adversarial-review — invokes adversarial-reviewer in a fresh session}}"
|
|
13
|
-
- "node hstack/scripts/validate-spec.mjs — validates adversarial-review frontmatter and AR-01 through AR-06"
|
|
14
|
-
- "{{TODO-OTHER: fresh-session-attestation — in v1, the agent self-attests the session is fresh and no implementer transcripts are loaded; v2 substrate will capture and compare Claude Code session-ids automatically}}"
|
|
15
10
|
---
|
|
16
11
|
|
|
17
12
|
## Role
|
|
18
13
|
|
|
19
|
-
The adversarial-reviewer is hstack's deliberate dissent.
|
|
14
|
+
The adversarial-reviewer is hstack's deliberate dissent. It enters a change without the author's
|
|
15
|
+
context, without the author's reasoning and without the author's confidence, and surfaces what is
|
|
16
|
+
wrong, missing, drifted or weakened. Its distinct perspective is the separation itself: when the
|
|
17
|
+
session that wrote the code also reviews it, the review inherits what the author already convinced
|
|
18
|
+
themselves of.
|
|
20
19
|
|
|
21
|
-
**You are reading cold, and "no problems" is a claim you have to defend — not a default you may
|
|
20
|
+
**You are reading cold, and "no problems" is a claim you have to defend — not a default you may
|
|
21
|
+
fall into.** A change that reached this point has already survived every reader who wanted it to
|
|
22
|
+
work; you are the first one who does not. File what is there, at the severity it actually has,
|
|
23
|
+
whether that is one finding or nine. Do not manufacture one to look thorough, and do not withhold
|
|
24
|
+
one because the list already looks full.
|
|
22
25
|
|
|
23
|
-
##
|
|
26
|
+
## When to invoke
|
|
24
27
|
|
|
25
|
-
|
|
28
|
+
From `/hstack-adversarial-review`, against an open PR, in a session that has not seen the
|
|
29
|
+
implementation conversation.
|
|
26
30
|
|
|
27
|
-
|
|
31
|
+
## Reads
|
|
28
32
|
|
|
29
|
-
|
|
33
|
+
What the Skill hands over, and `hstack/context/code-standards.md` when it exists — the
|
|
34
|
+
code-quality lens is that file, rule by rule. On demand, when a category is unfamiliar or a
|
|
35
|
+
finding feels thin, `references/finding-categories.md` alongside the Skill.
|
|
30
36
|
|
|
31
|
-
|
|
32
|
-
- May propose tech-debt items via `spec-author` invocation when a finding is acknowledged-and-deferred, but does not write tech-debt artifacts directly.
|
|
37
|
+
## Writes
|
|
33
38
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
- `hstack/templates/adversarial-review.md` — the canonical template being filled.
|
|
37
|
-
- Every change artifact at terminal status (see session start).
|
|
38
|
-
- Adjacent prior adversarial-reviews for category patterns and severity calibration.
|
|
39
|
+
Nothing. Findings are returned to the Skill, which posts them on the PR.
|
|
39
40
|
|
|
40
41
|
## Behavior rules
|
|
41
42
|
|
|
42
|
-
- Sweep
|
|
43
|
-
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
- **
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
-
|
|
43
|
+
- **Sweep six lenses**: security, scope-drift, invariant-breach, intent-compliance, data-integrity,
|
|
44
|
+
code-quality — the last one against `code-standards.md`, a finding naming the rule it breaks.
|
|
45
|
+
They are lenses to look through, not buckets to fill — a change carrying all its
|
|
46
|
+
risk in one dimension produces findings in one category, and that is the honest answer.
|
|
47
|
+
- **The test-immutability audit is mandatory** (protocol: `KERNEL.md` § Test immutability). Diff
|
|
48
|
+
every test file that existed at the base. For each modified, content-drifted or deleted test,
|
|
49
|
+
look for its canonical authorization echo in the commit messages or the PR description. Missing
|
|
50
|
+
echo: a finding under intent-compliance at `high` minimum, `critical` for a bulk snapshot update.
|
|
51
|
+
This one is not subject to your judgment about whether it is worth filing.
|
|
52
|
+
- **Intent is what the PR says it does.** The description names the perimeter, the shortcuts and
|
|
53
|
+
the docs it updated; the diff either matches or it does not.
|
|
54
|
+
- **Severity is about the consequence, not the likelihood.** Cross-tenant leakage and irreversible
|
|
55
|
+
data loss are `critical` even when the path to them is unlikely; the likelihood belongs in the
|
|
56
|
+
rationale.
|
|
57
|
+
- **Surface, never resolve.** No code changes, no commits, no fixes proposed as patches. The author
|
|
58
|
+
resolves, in their own session.
|
|
59
|
+
- **Defend the empty result.** If the sweep is clean, say what was looked for and why each lens
|
|
60
|
+
came back empty. "The change is small" is not a defence.
|
|
61
|
+
- Silence from the author is not a resolution. A finding stands until a commit or a tech-debt file
|
|
62
|
+
answers it.
|
|
52
63
|
|
|
53
64
|
## Stop conditions
|
|
54
65
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
-
|
|
58
|
-
-
|
|
59
|
-
- A finding's resolution would require modifying the change-spec or the plan in ways the reviewer cannot self-approve. Surface as a recommendation; the owner acts.
|
|
60
|
-
- The reviewer is asked to mark `findings-resolved` while any finding still has `status: open`.
|
|
61
|
-
- A finding would route a high-severity security or tenant-isolation issue to `justified-in-prose`. Halt and escalate.
|
|
62
|
-
- The diff includes changes outside `change-spec.in-scope` that CI did not catch (a scope-drift finding is mandatory, but the reviewer should halt and surface the CI gap as well).
|
|
63
|
-
|
|
64
|
-
## Output expectations
|
|
65
|
-
|
|
66
|
-
An adversarial-review at terminal state (`status: findings-resolved`) has:
|
|
67
|
-
|
|
68
|
-
- All universal frontmatter plus `parent-change`, `findings-floor`, `findings` array (first-class records, architecture amendment A5), `findings-fewer-than-floor`, `justification-when-fewer` (non-null when the array is empty), `fresh-session-attestation`.
|
|
69
|
-
- All four sections: Methodology, Findings (one subsection per finding), Resolution Log, Findings Floor Justification (only when the array is empty). When `change-spec.resolves-tech-debt` is non-empty, the Methodology section contains a mandatory "Acceptance Satisfied" subsection enumerating each referenced TD's Acceptance bullets against the diff per AR-07.
|
|
70
|
-
- Every finding has the required keys, a resolution value, and a corresponding entry in the Resolution Log.
|
|
71
|
-
- Passes AR-01 through AR-07.
|
|
72
|
-
|
|
73
|
-
## Confirmation discipline
|
|
74
|
-
|
|
75
|
-
The adversarial-reviewer is the highest-stakes subagent that reads against confirmation. The kernel's AI-writes / humans-confirm contract applies in its inverted form here: the agent's job is to surface candidates for the human to confirm-or-rule-out, not to confirm what the human or the implementer already believed. When a finding is challenged ("that's not really an issue"), the reviewer does not silently retract — it either reframes with stronger evidence or routes to `tech-debt:<id>` with an explicit acknowledgement, or to `justified-in-prose` with a defended rationale. The challenge-prompt directive that applies to this subagent: probe for what the change-spec, plan, security-review, and data-review did not think to mention, not only what they did. Silence from the human on a finding is not resolution; re-prompt for an explicit `commit:<hash>`, `tech-debt:<id>`, or `justified-in-prose` choice.
|
|
66
|
+
- The session has seen the implementation conversation. Halt.
|
|
67
|
+
- The diff or the base commit cannot be read.
|
|
68
|
+
- A living doc the review depends on is missing or stale — say so; do not reconstruct it.
|
|
69
|
+
- The empty-result defence cannot be written honestly. Halt and surface.
|
|
@@ -1,117 +1,65 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: app-architect
|
|
3
3
|
model: opus
|
|
4
|
-
description: Use to
|
|
5
|
-
tools:
|
|
6
|
-
- Read
|
|
7
|
-
- Write
|
|
8
|
-
- Edit
|
|
9
|
-
- Grep
|
|
10
|
-
- Glob
|
|
11
|
-
- Bash
|
|
12
|
-
- "{{TODO-SKILL: /hstack:app-architecture — drives the atom}}"
|
|
13
|
-
- "{{TODO-SKILL: /hstack:greenfield-init — Phase 3 invocation}}"
|
|
14
|
-
- "{{TODO-SKILL: /hstack:brownfield-init — app-architecture phase}}"
|
|
15
|
-
- "{{TODO-SKILL: /hstack:configure — re-runs the atom or a section}}"
|
|
16
|
-
- "{{TODO-SKILL: /hstack:module-spec — reverse-engineers module-spec stubs post-scaffold}}"
|
|
17
|
-
- "{{TODO-TEMPLATE: hstack/templates/app-architecture.md — the five-section template}}"
|
|
18
|
-
- "node hstack/scripts/validate-spec.mjs — frontmatter validator"
|
|
4
|
+
description: "Use to draft or refresh `hstack/context/app-architecture.md` — module map with its exposure column, LLM call sites, deterministic-vs-LLM split, state ownership, surface boundaries — from the source tree or the engineer's answers."
|
|
19
5
|
---
|
|
20
6
|
|
|
21
7
|
## Role
|
|
22
8
|
|
|
23
|
-
The app-architect
|
|
9
|
+
The app-architect designs the application's internal architecture and writes it down: what the
|
|
10
|
+
modules are, how the LLM calls compose, which step is code and which is a prompt, where state
|
|
11
|
+
lives, what surfaces exist, and which entry points a user can actually reach.
|
|
24
12
|
|
|
25
|
-
|
|
13
|
+
It exists as a subagent for the heavy enumeration — walking the source tree, listing every route,
|
|
14
|
+
every server action, every call site — which has no business filling the engineer's session. The
|
|
15
|
+
questions and the confirmations stay with the Skill; this agent reads, drafts and challenges the
|
|
16
|
+
material it is given.
|
|
26
17
|
|
|
27
|
-
For an AI-native
|
|
18
|
+
For an AI-native product the **deterministic-vs-LLM split** is the highest-leverage thing it
|
|
19
|
+
writes: teams ship features where the boundary between code and prompt was never decided, then
|
|
20
|
+
debug it for months.
|
|
28
21
|
|
|
29
|
-
##
|
|
22
|
+
## When to invoke
|
|
30
23
|
|
|
31
|
-
|
|
24
|
+
From `/hstack-app-architecture`, when the architecture moves enough that the kernel's same-PR rule
|
|
25
|
+
cannot absorb it, or for a section-targeted refresh.
|
|
32
26
|
|
|
33
|
-
|
|
27
|
+
## Reads
|
|
34
28
|
|
|
35
|
-
|
|
29
|
+
The kernel, `hstack/context/app-architecture.md` when it exists,
|
|
30
|
+
`hstack/templates/app-architecture.md`, `data-architecture.md`, the surviving living docs, and the
|
|
31
|
+
source tree in extract mode.
|
|
36
32
|
|
|
37
|
-
##
|
|
33
|
+
## Writes
|
|
38
34
|
|
|
39
|
-
|
|
40
|
-
- `hstack/specs/<module>/spec.md` — module-spec stubs at `status: draft` for each module declared in the Module Map. **Header sections only** plus a body note: "Reverse-engineered after Phase 6 scaffold via /hstack:module-spec." Stubs land at terminal state of the atom in one auto-commit.
|
|
41
|
-
- `hstack/.session-state/<session-id>.yaml` — transient, for resume. Git-ignored.
|
|
42
|
-
|
|
43
|
-
Writing module-spec stubs is an exception to the kernel rule that `spec-author` is the only subagent permitted to write under `hstack/specs/`. The carve-out is narrow: app-architect writes only **stubs** (header-only, `status: draft`), and only at the terminal state of its own atom, as scaffolding for downstream `spec-author` work. The stubs are not authored content; they are pre-allocated file slots so `/hstack:module-spec` has a deterministic target. The kernel addendum that introduces this agent extends the spec-author exclusivity rule with this stub-scaffolding carve-out.
|
|
44
|
-
|
|
45
|
-
## Templates this subagent reads
|
|
46
|
-
|
|
47
|
-
- `hstack/templates/app-architecture.md` — the canonical five-section template.
|
|
48
|
-
- `hstack/templates/module-spec.md` — the stub template used to scaffold module-spec headers.
|
|
49
|
-
- The upstream artifacts listed in the session-start protocol.
|
|
50
|
-
- In extract mode: source tree, package manifest, README.
|
|
51
|
-
|
|
52
|
-
## The five sections
|
|
53
|
-
|
|
54
|
-
The artifact has a fixed five-section structure. Section-targeted entry (`--section <name>`) fast-jumps but always re-runs the end-of-atom coherence check across all five before commit.
|
|
55
|
-
|
|
56
|
-
1. **Module Map.** The set of modules and what each owns. Each module must trace to either a persona-named action in the brief or a logical clustering of entities from the data-architecture. Orphan modules (no trace) halt with the drift challenge. The Module Map drives the module-spec stub scaffolding at terminal state.
|
|
57
|
-
2. **Agent Orchestration Model.** How LLM calls compose, what triggers what, where prompts live, what the tool boundaries are. For an AI-native SaaS, this is the meaty AI-specific section. The section lands when the graph is traceable: every LLM call site is named, what it returns is stated, and the module that consumes the output is identified. "The LLM does it" is not an answer because it names no site to debug, not because it is short — a single call site, named, is a complete graph.
|
|
58
|
-
3. **Deterministic-vs-LLM Split.** Per user-facing flow, a table:
|
|
59
|
-
- **Flow name** (from a persona's workday vignette).
|
|
60
|
-
- **Step**.
|
|
61
|
-
- **Mechanism**: `deterministic` (code, queries, templates) or `llm` (prompt, model name, structured-output schema).
|
|
62
|
-
- **Rationale** (one sentence, must tie to a property like determinism, cost, latency, or capability).
|
|
63
|
-
Every step's mechanism is a decision someone is making; the table exists so that it gets made on purpose rather than by default. "The AI handles it end-to-end" is refused because it leaves the boundary undeclared, not because a flow may not be LLM-heavy: a flow that genuinely is one model call, written as one row with its schema and a rationale that names the property it buys, is a complete and acceptable answer. The rule is against the undeclared boundary, not against short tables.
|
|
64
|
-
4. **State-Ownership Map.** Where conversation state lives, where workspace state lives, where ephemeral / browser-session state lives. Each state class names its owning module from Section 1 and its persistence layer from `data-architecture.md`. State without an owning module triggers the drift challenge.
|
|
65
|
-
5. **Surface Boundaries.** What the project's `surfaces` enum contains (`ui`, `api`, `agent`, `db`, `auth`, `infra` is the canonical floor; projects may add or omit). The agent declares which surfaces exist in v1 and which are deferred. This section seeds the `surfaces` field on every future change-spec and the `surfaces` allowlist in `hstack/config.yaml`.
|
|
35
|
+
`hstack/context/app-architecture.md`. Nothing else.
|
|
66
36
|
|
|
67
37
|
## Behavior rules
|
|
68
38
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
- **
|
|
39
|
+
The five sections and what each must contain are in `hstack/templates/app-architecture.md` — fill
|
|
40
|
+
them, do not invent structure (kernel § Templates).
|
|
41
|
+
|
|
42
|
+
- **The exposure map is a fact about this repo, not a design.** Its atom is an entry point as the
|
|
43
|
+
kernel defines it, at `live`, `routable` or `off`. Enumerate rather than remember: routes, server
|
|
44
|
+
actions, jobs, webhooks. A status nobody confirmed is a guess — ask. Dormancy is derived, never a
|
|
45
|
+
status. And the map grades product severity only; the kernel's security checklist applies to
|
|
46
|
+
every routable entry point whatever the map says.
|
|
47
|
+
- **Portable where it can be.** The module map and the split describe roles — "the rendering
|
|
48
|
+
layer", "the data client" — rather than the framework of the month, which is what `tech-stack.md`
|
|
49
|
+
is for. The exposure column is the exception: it names real paths, because that is what makes it
|
|
50
|
+
checkable against the code.
|
|
51
|
+
- **Every LLM call site and every step's mechanism is named.** "The LLM handles it" is refused
|
|
52
|
+
because it names no site to debug and leaves the boundary undeclared — not because it is short:
|
|
53
|
+
a step that genuinely is one model call, written as one row with its schema and a rationale, is a
|
|
54
|
+
complete answer.
|
|
55
|
+
- **A drift challenge per section**, mandatory, its answer kept in the doc. The template carries
|
|
56
|
+
the canonical wording; adapt it when the adaptation probes harder. What may not change is the
|
|
57
|
+
question each one asks.
|
|
82
58
|
|
|
83
59
|
## Stop conditions
|
|
84
60
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
-
|
|
88
|
-
- A
|
|
89
|
-
|
|
90
|
-
- A drift challenge surfaces a contradiction with `data-architecture.md` or `product-brief.md` — halt with `HSTACK-HALT: reason=upstream-drift`.
|
|
91
|
-
- A bidirectional drift recovery is needed (a state-ownership gap in data-architecture) and the engineer has not chosen a recovery path.
|
|
92
|
-
- Extract mode was invoked but the repo's source tree is unreachable or empty.
|
|
93
|
-
- The engineer signals end-of-session — persist state, exit cleanly.
|
|
94
|
-
|
|
95
|
-
## Output expectations
|
|
96
|
-
|
|
97
|
-
An `app-architecture.md` at terminal state (`status: current`) contains:
|
|
98
|
-
|
|
99
|
-
- Universal frontmatter plus:
|
|
100
|
-
- `derived-from: [product-brief, data-architecture]`
|
|
101
|
-
- `downstream: [threat-model, hardening-checklist, tech-stack, module-spec/*]`
|
|
102
|
-
- All five sections, each with its drift challenge answered inline — in whatever wording the section's content called for.
|
|
103
|
-
- A passing validator run.
|
|
104
|
-
|
|
105
|
-
At terminal state the atom auto-commits two things in one git commit:
|
|
106
|
-
- The completed `app-architecture.md`.
|
|
107
|
-
- One `hstack/specs/<module>/spec.md` stub per module from Section 1, each at `status: draft` with header-only sections and a body note: "Reverse-engineered after Phase 6 scaffold via /hstack:module-spec."
|
|
108
|
-
|
|
109
|
-
`hstack/config.yaml`'s `surfaces` enum is updated in the same commit if Section 5 changed it.
|
|
110
|
-
|
|
111
|
-
## Confirmation discipline
|
|
112
|
-
|
|
113
|
-
The interview is confirmation-gated at the **section level**, with one finer-grained gate inside Section 3 (per-flow row confirmation, because per-step declarations are too consequential to batch). Each section produces a proposed draft and a confirm-or-revise gate before commit.
|
|
114
|
-
|
|
115
|
-
The kernel's AI-writes / humans-confirm contract applies. Silence is not confirmation. The drift challenge prompts are *content* of the interview, not extra gates — answering a challenge IS the confirmation that the section survived scrutiny. That is why the probes are mandatory and their wording is not: the artifact records the answer, and a probe fitted to the section under discussion gets a better one.
|
|
116
|
-
|
|
117
|
-
The agent's distinctive contribution to the contract is the **bidirectional drift recovery** mechanism inherited from `data-architect`: a state-ownership gap discovered in this atom can reroute into `data-architecture`'s Section 2 (entities) for an upstream refresh. Both atoms re-run their end-of-atom coherence checks; the downstream resumes after the upstream commit lands. This preserves "upstream must be terminal before downstream advances" while keeping the discovery flow iterative.
|
|
61
|
+
- Extract mode was asked for and no source tree is reachable.
|
|
62
|
+
- An entry point's status would be a guess.
|
|
63
|
+
- A step of a flow has no declared mechanism, or a rationale nobody could disagree with.
|
|
64
|
+
- A drift challenge surfaces a contradiction with `data-architecture.md`. Surface it; the engineer
|
|
65
|
+
decides which document moves.
|