hstack 0.7.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +277 -0
- package/README.md +39 -13
- package/VERSION +1 -1
- package/dist/commands/doctor.js +51 -1
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/update.js +8 -2
- package/dist/commands/update.js.map +1 -1
- package/dist/lib/descriptions.js +167 -0
- package/dist/lib/descriptions.js.map +1 -0
- package/dist/lib/diff.js +1 -1
- package/dist/lib/git.js +16 -0
- package/dist/lib/git.js.map +1 -1
- package/dist/lib/wire.js +108 -4
- package/dist/lib/wire.js.map +1 -1
- package/dist/manifest.js +17 -2
- package/dist/manifest.js.map +1 -1
- package/package.json +3 -1
- package/template/.claude/agents/adversarial-reviewer.md +16 -64
- package/template/.claude/agents/app-architect.md +12 -49
- package/template/.claude/agents/data-architect.md +13 -51
- package/template/.claude/agents/data-specialist.md +5 -50
- package/template/.claude/agents/implementer.md +8 -65
- package/template/.claude/agents/kernel-fit-analyst.md +7 -68
- package/template/.claude/agents/planner.md +7 -42
- package/template/.claude/agents/product-discovery.md +12 -48
- package/template/.claude/agents/product-manager.md +8 -43
- package/template/.claude/agents/researcher.md +5 -41
- package/template/.claude/agents/security-reviewer.md +19 -54
- package/template/.claude/agents/spec-author.md +18 -52
- package/template/.claude/agents/stack-architect.md +14 -43
- package/template/.claude/agents/test-strategist.md +16 -57
- package/template/.claude/agents/ui-ux-briefer.md +6 -36
- package/template/.claude/agents/verifier.md +13 -45
- package/template/.claude/skills/hstack-adr-new/SKILL.md +6 -33
- package/template/.claude/skills/hstack-adversarial-review/SKILL.md +31 -52
- package/template/.claude/skills/hstack-adversarial-review/references/finding-categories.md +157 -0
- package/template/.claude/skills/hstack-app-architecture/SKILL.md +2 -29
- package/template/.claude/skills/hstack-branch/SKILL.md +4 -31
- package/template/.claude/skills/hstack-brownfield-init/SKILL.md +10 -37
- package/template/.claude/skills/hstack-change-new/SKILL.md +4 -31
- package/template/.claude/skills/hstack-change-plan/SKILL.md +21 -32
- package/template/.claude/skills/hstack-commit/SKILL.md +7 -35
- package/template/.claude/skills/hstack-configure/SKILL.md +7 -34
- package/template/.claude/skills/hstack-coord/SKILL.md +3 -39
- package/template/.claude/skills/hstack-data-architecture/SKILL.md +4 -30
- package/template/.claude/skills/hstack-data-review/SKILL.md +3 -42
- package/template/.claude/skills/hstack-finalize/SKILL.md +30 -49
- package/template/.claude/skills/hstack-flag/SKILL.md +9 -48
- package/template/.claude/skills/hstack-greenfield-init/SKILL.md +9 -36
- package/template/.claude/skills/hstack-help/SKILL.md +11 -37
- package/template/.claude/skills/hstack-implement/SKILL.md +28 -58
- package/template/.claude/skills/hstack-kernel-fit-promote/SKILL.md +7 -46
- package/template/.claude/skills/hstack-kernel-fit-scan/SKILL.md +5 -60
- package/template/.claude/skills/hstack-kernel-fit-scan/references/slack-setup.md +42 -0
- package/template/.claude/skills/hstack-kernel-fit-triage/SKILL.md +12 -50
- package/template/.claude/skills/hstack-module-spec/SKILL.md +5 -32
- package/template/.claude/skills/hstack-product-discovery/SKILL.md +5 -31
- package/template/.claude/skills/hstack-research/SKILL.md +3 -33
- package/template/.claude/skills/hstack-scaffold/SKILL.md +2 -29
- package/template/.claude/skills/hstack-security-review/SKILL.md +5 -43
- package/template/.claude/skills/hstack-ship/SKILL.md +43 -53
- package/template/.claude/skills/hstack-stack-decide/SKILL.md +3 -30
- package/template/.claude/skills/hstack-story-draft/SKILL.md +6 -33
- package/template/.claude/skills/hstack-tech-debt-new/SKILL.md +4 -31
- package/template/.claude/skills/hstack-tech-debt-resolve/SKILL.md +9 -44
- package/template/.claude/skills/hstack-tech-debt-stale/SKILL.md +10 -37
- package/template/.claude/skills/hstack-tech-debt-wontfix/SKILL.md +8 -35
- package/template/.claude/skills/hstack-telemetry/SKILL.md +5 -30
- package/template/.claude/skills/hstack-test-plan/SKILL.md +23 -46
- package/template/.claude/skills/hstack-ui-brief/SKILL.md +3 -30
- package/template/.claude/skills/hstack-verify/SKILL.md +26 -48
- package/template/KERNEL.md +410 -0
- package/template/scripts/compute-merge-readiness.mjs +780 -0
- package/template/scripts/coord/coord_scan.py +121 -22
- package/template/scripts/run-gates.sh +388 -0
- package/template/scripts/telemetry/insights/kernel_fit.py +1 -1
- package/template/scripts/telemetry/insights/token_economics.py +181 -8
- package/template/scripts/telemetry/parsers/sidecars.py +61 -0
- package/template/scripts/telemetry/parsers/transcripts.py +135 -22
- package/template/scripts/telemetry/render.py +68 -3
- package/template/scripts/telemetry/report.py +16 -4
- package/template/scripts/telemetry/run_kernel_fit.py +6 -2
- package/template/scripts/telemetry/session_id.py +139 -0
- package/template/scripts/validate-spec.mjs +3303 -0
- package/template/templates/adr.md +7 -0
- package/template/templates/adversarial-review.md +5 -5
- package/template/templates/ci-cd.md +14 -0
- package/template/templates/coord-message.md +3 -2
- package/template/templates/data-architecture.md +3 -6
- package/template/templates/kernel-fit-finding.md +2 -2
- package/template/templates/kernel-fit-flag.md +2 -2
- package/template/templates/plan.md +4 -0
- package/template/templates/product-brief.md +2 -2
- package/template/templates/roadmap.md +41 -0
- package/template/templates/security-review.md +1 -1
- package/template/templates/telemetry-sidecar.md +56 -13
- package/template/templates/test-plan.md +1 -1
- package/template/CLAUDE.md +0 -443
- package/template/templates/mvp-scope.md +0 -34
|
@@ -37,3 +37,10 @@ _Positive, negative, and neutral outcomes. Particularly the trade-offs accepted.
|
|
|
37
37
|
## Alternatives Considered
|
|
38
38
|
|
|
39
39
|
_What was on the table; why each was rejected. One paragraph per alternative._
|
|
40
|
+
|
|
41
|
+
## Forecloses / Enables
|
|
42
|
+
|
|
43
|
+
_Against `hstack/context/roadmap.md`: which Next/Later item does this decision make more expensive (foreclose) or cheaper (enable)? One line each. "None" is a valid answer. When the roadmap is missing or stale, write `n/a — roadmap stale/missing` instead of guessing. Advisory — never a merge gate._
|
|
44
|
+
|
|
45
|
+
- Forecloses:
|
|
46
|
+
- Enables:
|
|
@@ -4,10 +4,10 @@ type: adversarial-review
|
|
|
4
4
|
status: draft # draft | in-progress | findings-open | findings-resolved | superseded
|
|
5
5
|
owner: <git-handle>
|
|
6
6
|
parent-change: <change-spec-id>
|
|
7
|
-
findings-floor: 3 # 3 default; 5 when change-spec.area in {agent, auth, billing}
|
|
7
|
+
findings-floor: 3 # AR-06: 3 default; 5 when change-spec.area in {agent, auth, billing}. The area's expected finding count — measured by telemetry, gated by nothing (ADR-0014)
|
|
8
8
|
findings: [] # array of finding records; see below
|
|
9
|
-
findings-fewer-than-floor: false
|
|
10
|
-
justification-when-fewer: null # required when findings-fewer-than-floor: true
|
|
9
|
+
findings-fewer-than-floor: false # true when the review came in under the expectation; must be true when `findings` is empty
|
|
10
|
+
justification-when-fewer: null # required when findings-fewer-than-floor: true, and non-negotiable when `findings` is empty (AR-01)
|
|
11
11
|
fresh-session-attestation: <session-id; opened <ISO-8601>; no implementer transcript loaded>
|
|
12
12
|
created: <YYYY-MM-DD>
|
|
13
13
|
updated: <YYYY-MM-DD>
|
|
@@ -29,7 +29,7 @@ _Fresh-session attestation; what artifacts were loaded; how findings were genera
|
|
|
29
29
|
|
|
30
30
|
## Findings
|
|
31
31
|
|
|
32
|
-
_One subsection per finding (F-01..F-N).
|
|
32
|
+
_One subsection per finding (F-01..F-N). The six categories are lenses to sweep, not buckets to fill — file what the sweep found, at the severity it has. Calibration rubric: `hstack/.claude/skills/hstack-adversarial-review/references/finding-categories.md`._
|
|
33
33
|
|
|
34
34
|
### F-01
|
|
35
35
|
|
|
@@ -51,4 +51,4 @@ _Append-only record of how each finding was resolved. Written by `owner` in resp
|
|
|
51
51
|
|
|
52
52
|
## Findings Floor Justification
|
|
53
53
|
|
|
54
|
-
_Populated
|
|
54
|
+
_Populated when `findings-fewer-than-floor: true`, and mandatory when `findings` is empty (AR-01). Reading a change cold and reporting nothing is a claim: enumerate what was looked for in each of the six categories and why each sweep came back clean. "The change is small" is not a defence._
|
|
@@ -18,6 +18,20 @@ _Every check in `.github/workflows/hstack-gates.yml` plus pre-existing CI checks
|
|
|
18
18
|
|
|
19
19
|
-
|
|
20
20
|
|
|
21
|
+
## Canonical Commands
|
|
22
|
+
|
|
23
|
+
_The exact commands `hstack/scripts/run-gates.sh` executes — the verifier runs every one of them and nothing else. The fenced `hstack-gates` block below is the machine-readable half; the prose above it is for humans. One `suite: command` pair per line. Suite keys mirror `verification.test-results`: `unit`, `integration`, `e2e`, `lint`, `typecheck`. Omit a line, or set it to `none`, for a suite this repo does not have — an omitted suite is not run and not scored. `unit` / `integration` / `e2e` are subject to V-05 (a suite that executes zero tests is recorded `not-run`, never `pass`); `lint` and `typecheck` are exempt._
|
|
24
|
+
|
|
25
|
+
_Extending this set is `/hstack:configure --interview ci-cd`, never an ad-hoc addition at verify time._
|
|
26
|
+
|
|
27
|
+
```hstack-gates
|
|
28
|
+
unit: <command>
|
|
29
|
+
integration: <command>
|
|
30
|
+
e2e: none
|
|
31
|
+
lint: <command>
|
|
32
|
+
typecheck: <command>
|
|
33
|
+
```
|
|
34
|
+
|
|
21
35
|
## Deploy targets
|
|
22
36
|
|
|
23
37
|
_Preview, staging, production. What promotes to what. Manual vs automatic._
|
|
@@ -31,8 +31,9 @@ context, a decision, a heads-up — with `refs` pointing at the committed
|
|
|
31
31
|
artifacts that carry the authoritative detail. The body summarizes; the refs
|
|
32
32
|
are the source of truth.
|
|
33
33
|
|
|
34
|
-
Validator rules (
|
|
35
|
-
is
|
|
34
|
+
Validator rules (`node hstack/scripts/validate-spec.mjs <path>`; CM-02
|
|
35
|
+
immutability is a git-history claim the validator cannot see — it stays with
|
|
36
|
+
the Skill and the reviewer):
|
|
36
37
|
|
|
37
38
|
- CM-01: at send-time, `from-repo`, `from-branch`, `to-repo`, and `subject`
|
|
38
39
|
are non-null. `status` is `sent` and never changes.
|
|
@@ -17,16 +17,13 @@ schema-version: 1
|
|
|
17
17
|
|
|
18
18
|
_The load-bearing question. The data-architect refuses to advance past this section until the tenant definition is concrete and ties to a persona in the brief._
|
|
19
19
|
|
|
20
|
-
**
|
|
20
|
+
**A tenant is a ...**
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
- **B. Tenant = a sub-team within the customer organization** — multi-workspace per customer.
|
|
24
|
-
- **C. Tenant = the individual user** — workspace-per-user.
|
|
25
|
-
- **D. Custom** — document the pattern explicitly and explain why none of A/B/C fit.
|
|
22
|
+
_One concrete noun from this product's own vocabulary, plus the rule for who is inside one and who is not. Common shapes, offered as examples rather than as a menu: the customer organization (one workspace per paying customer, users inside share visibility); a sub-team within that organization (multi-workspace per customer); the individual user (workspace-per-user). Products whose tenant is a project, a device, a contract, a site, a case or a season are ordinary and none of those three fit them — name yours._
|
|
26
23
|
|
|
27
24
|
**Rationale**
|
|
28
25
|
|
|
29
|
-
_One sentence tying the
|
|
26
|
+
_One sentence tying the tenant to a persona in `product-brief.md`. Example: "The tenant is the customer organization, because Maya (Director of CS) shares visibility with her 6 reps and no v1 persona asks for sub-team isolation."_
|
|
30
27
|
|
|
31
28
|
**Tenant identifier**
|
|
32
29
|
|
|
@@ -12,7 +12,7 @@ evidence-row-count: 0 # integer; must equal len(evidence-rows)
|
|
|
12
12
|
evidence-rows: [] # YAML array of {change|adr|td, signal} dicts; one entry per row counted above
|
|
13
13
|
related-findings: [] # KF ids — prior or adjacent findings on the same kernel surface
|
|
14
14
|
promoted-to: null # `adr:<ADR-NNNN-slug>` | `tech-debt:<TD-NNNN-slug>` | null; reciprocal with the target artifact's `promoted-from-kernel-fit`; required when status: promoted
|
|
15
|
-
dismissed-reason: null #
|
|
15
|
+
dismissed-reason: null # required when status: dismissed (KF-05); says what about the finding is wrong, specifically enough to be re-evaluated later
|
|
16
16
|
superseded-by: null # KF id when status: superseded
|
|
17
17
|
created: <YYYY-MM-DD>
|
|
18
18
|
updated: <YYYY-MM-DD>
|
|
@@ -36,7 +36,7 @@ _Per evidence row, a 2–3 sentence prose summary with at least one inline citat
|
|
|
36
36
|
|
|
37
37
|
## Kernel surface implicated
|
|
38
38
|
|
|
39
|
-
_Single-sentence pointer to the kernel section, template, validator rule, or Skill flow that the finding suggests revising. Examples: "`template/
|
|
39
|
+
_Single-sentence pointer to the kernel section, template, validator rule, or Skill flow that the finding suggests revising. Examples: "`template/KERNEL.md § Frontmatter contract` — the `internal-tooling` field"; "`template/templates/change-spec.md` frontmatter — `surfaces` enum"; "`/hstack:adversarial-review` precondition check at SKILL.md line 61"._
|
|
40
40
|
|
|
41
41
|
## Proposed direction
|
|
42
42
|
|
|
@@ -24,8 +24,8 @@ A kernel-fit-flag is a frontmatter-only pin. There is no body. Engineer
|
|
|
24
24
|
interpretation of the friction is deliberately excluded — the analyst reads
|
|
25
25
|
the transcript window and forms its own classification at processing time.
|
|
26
26
|
|
|
27
|
-
Validator rules (
|
|
28
|
-
|
|
27
|
+
Validator rules (`node hstack/scripts/validate-spec.mjs <path>`; the pin itself
|
|
28
|
+
lands regardless — see `/hstack:flag` § does NOT halt on):
|
|
29
29
|
|
|
30
30
|
- FL-01: at pin-time (status: pending) every field marked above as
|
|
31
31
|
"non-null at pin-time" must be populated. `hint` may be null; the four
|
|
@@ -12,6 +12,10 @@ updated: <YYYY-MM-DD>
|
|
|
12
12
|
schema-version: 1
|
|
13
13
|
---
|
|
14
14
|
|
|
15
|
+
## Roadmap Alignment
|
|
16
|
+
|
|
17
|
+
_One line, written by the planner against `hstack/context/roadmap.md`: does this change serve a Now/Next item, and does any phase foreclose a Next/Later item? When the roadmap is missing, not `current`, or `updated` > 90 days ago, write `n/a — roadmap stale/missing (<detail>)`. Advisory — never a gate._
|
|
18
|
+
|
|
15
19
|
## Phase Overview
|
|
16
20
|
|
|
17
21
|
_Table of phases. Three columns max._
|
|
@@ -5,7 +5,7 @@ status: draft # draft | current | needs-refresh | archi
|
|
|
5
5
|
owner: <git-handle>
|
|
6
6
|
technique-used: <brainstorm | forcing-questions | project-brief>
|
|
7
7
|
derived-from: [] # always empty — product-brief is Phase 1, no upstream
|
|
8
|
-
downstream: [vision,
|
|
8
|
+
downstream: [vision, roadmap, personas, glossary]
|
|
9
9
|
created: <YYYY-MM-DD>
|
|
10
10
|
updated: <YYYY-MM-DD>
|
|
11
11
|
schema-version: 1
|
|
@@ -44,7 +44,7 @@ _The things that could make this product fail. The forcing-prompt "What would yo
|
|
|
44
44
|
|
|
45
45
|
## Forcing-Prompt Answers
|
|
46
46
|
|
|
47
|
-
_Evidence that the three required reframes ran. Logged inline as confirmation the probes were not skipped._
|
|
47
|
+
_Evidence that the three required reframes ran. Logged inline as confirmation the probes were not skipped. The headings below are the canonical wording — record what was actually asked when a reframe was fitted to this product._
|
|
48
48
|
|
|
49
49
|
**Who specifically pays for this?**
|
|
50
50
|
_The named user / buyer plus the rationale ("Director of CS, because retention is their KPI")._
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: roadmap
|
|
3
|
+
type: roadmap
|
|
4
|
+
status: drafted # drafted | current | needs-refresh | archived
|
|
5
|
+
owner: <git-handle>
|
|
6
|
+
source: local # local | rhizome — who owns the truth; when rhizome, local edits are refused and the sync is authoritative
|
|
7
|
+
reviewed-on: <YYYY-MM-DD> # planner treats the roadmap as stale beyond 90 days
|
|
8
|
+
created: <YYYY-MM-DD>
|
|
9
|
+
updated: <YYYY-MM-DD>
|
|
10
|
+
schema-version: 1
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Now
|
|
14
|
+
|
|
15
|
+
_What we are committed to shipping. During the MVP phase, Now IS the MVP scope. Each item: one product line, one architectural-implication line. Implications are proposed by app-architect / data-architect and confirmed by the engineer — vague fortune-telling ("might need to scale") is worse than absence._
|
|
16
|
+
|
|
17
|
+
- <item> — **architectural implication:** <one line>
|
|
18
|
+
|
|
19
|
+
## Next
|
|
20
|
+
|
|
21
|
+
_Likely within ~2 quarters. A direction, not a commitment. No dates._
|
|
22
|
+
|
|
23
|
+
- <item> — **architectural implication:** <one line>
|
|
24
|
+
|
|
25
|
+
## Later
|
|
26
|
+
|
|
27
|
+
_Plausible futures. These influence one-way-door decisions ONLY — never day-to-day scoping._
|
|
28
|
+
|
|
29
|
+
- <item> — **architectural implication:** <one line>
|
|
30
|
+
|
|
31
|
+
## Not on the path
|
|
32
|
+
|
|
33
|
+
_Explicit renouncements, with the reason. Absorbs the old "Deferred" list._
|
|
34
|
+
|
|
35
|
+
- <item> — <why not>
|
|
36
|
+
|
|
37
|
+
## Success criteria for the current horizon
|
|
38
|
+
|
|
39
|
+
_Concrete observable indicators that Now is done and Next gets promoted. Bullets._
|
|
40
|
+
|
|
41
|
+
-
|
|
@@ -50,7 +50,7 @@ _Required when `threat-model-delta-required: true`. One paragraph delta against
|
|
|
50
50
|
|
|
51
51
|
## Challenge Prompts
|
|
52
52
|
|
|
53
|
-
_All three required. Each answer must be at least one paragraph._
|
|
53
|
+
_All three required. Each answer must be at least one paragraph. The questions below are the canonical wording — adapt one to the change under review when the adaptation probes harder, and record what was actually asked in the heading. Keep the `(a)` / `(b)` / `(c)` prefixes: SR-02 locates the answers by them._
|
|
54
54
|
|
|
55
55
|
### (a) What attack vector did the In-Scope diff create that is NOT covered by the hardening checklist? If none, justify.
|
|
56
56
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# Telemetry sidecar — schema and discipline
|
|
2
2
|
|
|
3
|
-
This document describes the JSON sidecar files
|
|
3
|
+
This document describes the JSON sidecar files five hstack Skills emit alongside their canonical artifact writes, to make per-change telemetry attribution cheap. Sidecars are **derivative** of git + frontmatter + transcripts — re-runnable from source, never authoritative. The kernel's "no parallel tracker" rule is preserved by this derivative property.
|
|
4
|
+
|
|
5
|
+
This file is the canonical schema and the only place the field rules are stated. The five emitting Skills reference it: each carries its own JSON schema block (its Skill-specific payload) and the executable step that opens the phase window, and points here for everything else. Per ADR-0012 they do not restate the rules below.
|
|
4
6
|
|
|
5
7
|
## Where sidecars live
|
|
6
8
|
|
|
@@ -27,12 +29,40 @@ The `.telemetry/` directory is **git-ignored** at the consuming-repo level. Side
|
|
|
27
29
|
|
|
28
30
|
The other 22 Skills do **not** emit sidecars in v1. Their data is reconstructible from git + frontmatter + transcripts; the five emissions above target the highest-signal events across the change lifecycle: test discipline up front (`test-plan`), per-phase scope-locked execution (`implement`), promised-vs-observed (`verify`), gate-firing critique (`adversarial-review`), lifecycle close (`finalize`).
|
|
29
31
|
|
|
32
|
+
## The phase window — every sidecar, every Skill (schema_version 2)
|
|
33
|
+
|
|
34
|
+
Every sidecar carries three fields on top of its Skill-specific payload. They exist so the telemetry parser can answer "what did this phase cost?" — see ADR-0009.
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"session_id": "062b8fe8-649f-4d73-b4fb-b0a28a800552",
|
|
39
|
+
"phase_opened_at": "2026-08-15T09:12:44Z",
|
|
40
|
+
"phase_closed_at": "2026-08-15T11:03:07Z"
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Field rules — one statement, applying identically to all five Skills:
|
|
45
|
+
|
|
46
|
+
- `session_id` — the active Claude Code session, resolved by `hstack/scripts/telemetry/session_id.py` (the most recently modified `*.jsonl` under `~/.claude/projects/<encoded-cwd>/`). One shared resolver, not a per-Skill heuristic. Unresolvable → `null`.
|
|
47
|
+
- `phase_opened_at` — stamped when the Skill's preconditions pass, **before any subagent invocation**. Same script call as `session_id`, so both come from one read. The script is read-only, takes milliseconds, and never halts; if it fails or reports `"session_id": null`, the Skill holds `null` for both and continues.
|
|
48
|
+
- `phase_closed_at` — stamped at the Skill's terminal state, in the same write that lands the sidecar.
|
|
49
|
+
- All three are **best-effort by contract**. Any of them `null`, unparseable, or inverted makes the phase *unmeasured*: `parsers/transcripts.py:phase_usage` returns `null`, and TE-4/TE-5 print `unmeasured`. **Never zero** — a phase whose window cannot be honoured still spent tokens, and a zero would fold it into the averages as if it were free.
|
|
50
|
+
- A sidecar write failure never blocks the canonical commit, and the window is never a halt condition. Measurement never gates the workflow.
|
|
51
|
+
- ISO-8601, UTC, second precision, `Z` suffix — the format `session_id.py` emits.
|
|
52
|
+
|
|
53
|
+
Sidecars at `schema_version: 1` (written before ADR-0009) carry no window and read as unmeasured. Nothing migrates them: the transcript timestamps they would need were never recorded.
|
|
54
|
+
|
|
55
|
+
The window measures *what the session spent while the phase was open* — not what the phase required. A detour taken between `phase_opened_at` and `phase_closed_at` is counted, and subagent spend lands in its host's window (`isSidechain: false` throughout the transcripts). Narrow, not exact.
|
|
56
|
+
|
|
30
57
|
## Schema — `test-plan.json`
|
|
31
58
|
|
|
32
59
|
```json
|
|
33
60
|
{
|
|
34
|
-
"schema_version":
|
|
61
|
+
"schema_version": 2,
|
|
35
62
|
"skill": "hstack-test-plan",
|
|
63
|
+
"session_id": "<session id, or null>",
|
|
64
|
+
"phase_opened_at": "<ISO-8601 at precondition pass, or null>",
|
|
65
|
+
"phase_closed_at": "<ISO-8601 at terminal state, or null>",
|
|
36
66
|
"change_id": "2026-05-billing-overage-warning",
|
|
37
67
|
"completed_at": "2026-05-22T11:14:00Z",
|
|
38
68
|
"status": "passed",
|
|
@@ -61,8 +91,11 @@ Field rules:
|
|
|
61
91
|
|
|
62
92
|
```json
|
|
63
93
|
{
|
|
64
|
-
"schema_version":
|
|
94
|
+
"schema_version": 2,
|
|
65
95
|
"skill": "hstack-implement",
|
|
96
|
+
"session_id": "062b8fe8-649f-4d73-b4fb-b0a28a800552",
|
|
97
|
+
"phase_opened_at": "2026-05-22T13:58:12Z",
|
|
98
|
+
"phase_closed_at": "2026-05-22T14:18:42Z",
|
|
66
99
|
"change_id": "2026-05-billing-overage-warning",
|
|
67
100
|
"phase_id": "phase-3-component",
|
|
68
101
|
"started_at": "2026-05-22T14:00:00Z",
|
|
@@ -77,19 +110,22 @@ Field rules:
|
|
|
77
110
|
|
|
78
111
|
Field rules:
|
|
79
112
|
|
|
80
|
-
- `started_at`, `completed_at` — ISO-8601. The implementer records them from session timestamps.
|
|
113
|
+
- `started_at`, `completed_at` — ISO-8601. The implementer records them from session timestamps. They describe the phase; `phase_opened_at` / `phase_closed_at` bound the *measurement window* and come from the shared resolver. They will usually be within seconds of each other; when they disagree, the window fields are the ones the parser reads.
|
|
81
114
|
- `files_touched_count` — count of distinct files modified by the phase's commit. Computed mechanically; not a judgment.
|
|
82
115
|
- `tests_written_count` — count of test files newly created in the phase (kernel test-immutability rule allows new tests without authorization).
|
|
83
116
|
- `scope_amendment_emitted` — `true` only when the implementer halted and surfaced a scope-amendment request during this phase.
|
|
84
|
-
- `halt_reasons` — array of enum values from the kernel halt sentinel (see
|
|
117
|
+
- `halt_reasons` — array of enum values from the kernel halt sentinel (see KERNEL.md § Halt sentinel).
|
|
85
118
|
- `test_immutability_authorizations` — array of canonical authorization phrases echoed during this phase (e.g., `"Ok to change test foo"`).
|
|
86
119
|
|
|
87
120
|
## Schema — `verify.json`
|
|
88
121
|
|
|
89
122
|
```json
|
|
90
123
|
{
|
|
91
|
-
"schema_version":
|
|
124
|
+
"schema_version": 2,
|
|
92
125
|
"skill": "hstack-verify",
|
|
126
|
+
"session_id": "062b8fe8-649f-4d73-b4fb-b0a28a800552",
|
|
127
|
+
"phase_opened_at": "2026-05-22T15:19:41Z",
|
|
128
|
+
"phase_closed_at": "2026-05-22T15:32:00Z",
|
|
93
129
|
"change_id": "2026-05-billing-overage-warning",
|
|
94
130
|
"ran_at": "2026-05-22T15:32:00Z",
|
|
95
131
|
"test_suite_runtime_s": 187.4,
|
|
@@ -114,8 +150,11 @@ Field rules:
|
|
|
114
150
|
|
|
115
151
|
```json
|
|
116
152
|
{
|
|
117
|
-
"schema_version":
|
|
153
|
+
"schema_version": 2,
|
|
118
154
|
"skill": "hstack-adversarial-review",
|
|
155
|
+
"session_id": "9f41c0aa-2f5e-4c31-9a77-6d0b1b0e2c14",
|
|
156
|
+
"phase_opened_at": "2026-05-22T16:40:03Z",
|
|
157
|
+
"phase_closed_at": "2026-05-22T16:42:00Z",
|
|
119
158
|
"change_id": "2026-05-billing-overage-warning",
|
|
120
159
|
"reviewed_at": "2026-05-22T16:42:00Z",
|
|
121
160
|
"findings_floor": 5,
|
|
@@ -138,17 +177,20 @@ Field rules:
|
|
|
138
177
|
|
|
139
178
|
Field rules:
|
|
140
179
|
|
|
141
|
-
- `findings_floor` is `3` by default, `5` when `change-spec.area` is in `{agent, auth, billing}` per AR-06.
|
|
142
|
-
- `findings_count`
|
|
143
|
-
- `category_counts` clustering — e.g., 5 of 5 findings in `code-quality` — is
|
|
180
|
+
- `findings_floor` is `3` by default, `5` when `change-spec.area` is in `{agent, auth, billing}` per AR-06. Since ADR-0014 it is the area's *expected* finding count and gates nothing — it is carried here so `findings_count` has a denominator to be read against.
|
|
181
|
+
- `findings_count` below `findings_floor` is an ordinary outcome, not a violation. The one count the canonical artifact must argue for is zero: AR-01 requires `findings_fewer_than_floor: true` with a defended justification when `findings` is empty. Aggregating across changes: the `findings_count / findings_floor` distribution is the primary read, and a rate of empty reviews that climbs while `severity_counts` stays flat is the signal worth acting on.
|
|
182
|
+
- `category_counts` clustering — e.g., 5 of 5 findings in `code-quality` — is a description of where a change carried its risk, not a smell in itself. It is worth reading against the change's `surfaces`: a `db`-surface change with every finding in `code-quality` is a review that did not look where the risk was. Surfaced via OE-7.
|
|
144
183
|
- `severity_counts.high + critical` paired with `resolution_mix.justified-in-prose > 0` is a high-severity-in-prose smell flagged by QO-2. The Skill's stop condition should have caught it before terminal status; sidecar presence indicates a bypass.
|
|
145
184
|
|
|
146
185
|
## Schema — `finalize.json`
|
|
147
186
|
|
|
148
187
|
```json
|
|
149
188
|
{
|
|
150
|
-
"schema_version":
|
|
189
|
+
"schema_version": 2,
|
|
151
190
|
"skill": "hstack-finalize",
|
|
191
|
+
"session_id": "c7d2e5b1-88a4-4f0d-b3ce-51a9f7d6e8b2",
|
|
192
|
+
"phase_opened_at": "2026-05-23T10:11:26Z",
|
|
193
|
+
"phase_closed_at": "2026-05-23T10:14:00Z",
|
|
152
194
|
"change_id": "2026-05-billing-overage-warning",
|
|
153
195
|
"shipped_at": "2026-05-23T10:14:00Z",
|
|
154
196
|
"merge_commit_sha": "abc1234567890",
|
|
@@ -169,8 +211,9 @@ Per the kernel § Mechanical operations § Discipline preserved:
|
|
|
169
211
|
|
|
170
212
|
- **Atomic with the canonical commit.** Each sidecar is written and `git add`-ed in the same commit as the canonical artifact write. No separate commit. The sidecar piggybacks on a commit that was happening anyway — zero new LLM turns, zero new confirmation gates.
|
|
171
213
|
- **Idempotency.** Re-running a Skill on a phase that already landed produces a no-op on the sidecar (file already present, content unchanged aside from `schema_version` bumps if any).
|
|
172
|
-
- **Derivative property.** Every value in every sidecar is reconstructible from git + frontmatter + transcripts. The sidecar is a cache, not a source. Deleting a sidecar is harmless — the next `/hstack:telemetry` run will compute the same metrics from the slower path.
|
|
173
|
-
- **Schema versioning.** `schema_version:
|
|
214
|
+
- **Derivative property.** Every value in every sidecar is reconstructible from git + frontmatter + transcripts. The sidecar is a cache, not a source. Deleting a sidecar is harmless — the next `/hstack:telemetry` run will compute the same metrics from the slower path. The phase window is the one field group with a shelf life: it points at a transcript that `cleanupPeriodDays` will eventually sweep (365 days on some machines, 30 by default), after which the phase reads as unmeasured. Deleting the sidecar loses the window for good, since nothing else records it.
|
|
215
|
+
- **Schema versioning.** `schema_version: 2` since ADR-0009 (the phase window). The bump is additive: every v1 field keeps its name and meaning, and a v1 sidecar still parses — it simply reports as unmeasured. No migration exists or is planned.
|
|
216
|
+
- **No local identifiers in git.** `session_id` is a local machine identifier. `.telemetry/` is gitignored in the consuming repo, so it never lands in history — but the discipline now depends on that gitignore line holding. A consumer that commits `.telemetry/` publishes its session ids.
|
|
174
217
|
|
|
175
218
|
## What sidecars are NOT
|
|
176
219
|
|
|
@@ -106,7 +106,7 @@ _Required when `performance-budgets-required: true`. For each hot path the chang
|
|
|
106
106
|
|
|
107
107
|
## Challenge Prompts
|
|
108
108
|
|
|
109
|
-
_All three required. Each answer must be at least one paragraph. These exist because the v1 mitigation for "humans miss what's missing" is to force the strategist to name gaps the planner and the implementer will not._
|
|
109
|
+
_All three required. Each answer must be at least one paragraph. These exist because the v1 mitigation for "humans miss what's missing" is to force the strategist to name gaps the planner and the implementer will not. The questions below are the canonical wording — adapt one to the change when the adaptation probes harder, and record what was actually asked in the heading. Keep the `(a)` / `(b)` / `(c)` prefixes: TS-02 locates the answers by them._
|
|
110
110
|
|
|
111
111
|
### (a) What behavior in this change would silently pass the test suite but break in production? Name the test that would catch it, or declare that no such test is planned and justify.
|
|
112
112
|
|