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
|
@@ -1,82 +1,57 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: hstack-app-architecture
|
|
3
|
-
description: Use
|
|
4
|
-
tools:
|
|
5
|
-
- Read
|
|
6
|
-
- Write
|
|
7
|
-
- Edit
|
|
8
|
-
- Grep
|
|
9
|
-
- Glob
|
|
10
|
-
- Bash
|
|
11
|
-
- Task
|
|
12
|
-
- "node hstack/scripts/validate-spec.mjs — 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."
|
|
13
4
|
---
|
|
14
5
|
|
|
15
6
|
## Purpose
|
|
16
7
|
|
|
17
|
-
|
|
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.
|
|
18
12
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
- Standalone via `/hstack:app-architecture [--mode extract|elicit] [--section <name>]` for refresh or single-section edits.
|
|
24
|
-
- 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.
|
|
25
17
|
|
|
26
18
|
## Inputs
|
|
27
19
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
##
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
- `hstack/config.yaml` with updated `surfaces` enum.
|
|
56
|
-
- `hstack/.session-state/<session-id>.yaml` (transient).
|
|
57
|
-
|
|
58
|
-
## Auto-commit triggers
|
|
59
|
-
|
|
60
|
-
- Each confirmed section writes immediately and auto-commits.
|
|
61
|
-
- Per-flow row in Section 3 commits individually (not full-section batch).
|
|
62
|
-
- Terminal-state side effects (artifact + stubs + config) land in one atomic commit.
|
|
63
|
-
|
|
64
|
-
## Idempotency contract
|
|
65
|
-
|
|
66
|
-
- Artifact at `current` + no `--section` + no `--force`: print summary, exit no-op.
|
|
67
|
-
- Artifact at `draft` or partial: resume at next non-confirmed section.
|
|
68
|
-
- Artifact at `needs-refresh`: walk all sections in confirm-or-revise mode.
|
|
69
|
-
- 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.
|
|
70
47
|
|
|
71
48
|
## Stop conditions
|
|
72
49
|
|
|
73
|
-
|
|
74
|
-
- A module in Section 1 has no trace to brief or data-architecture entities.
|
|
75
|
-
- A Section 3 flow step has no declared mechanism or no measurable-property rationale.
|
|
76
|
-
- A drift challenge surfaces an unresolved contradiction.
|
|
77
|
-
- Extract mode invoked but no source tree reachable.
|
|
78
|
-
|
|
79
|
-
## Failure modes
|
|
50
|
+
Beyond the kernel's:
|
|
80
51
|
|
|
81
|
-
-
|
|
82
|
-
-
|
|
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.
|
|
@@ -1,94 +1,53 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: hstack-commit
|
|
3
|
-
description: Use to commit
|
|
4
|
-
tools:
|
|
5
|
-
- Bash
|
|
6
|
-
- Read
|
|
7
|
-
- Grep
|
|
3
|
+
description: "Use to commit: the one Commitizen format Hugo, Luke and the agents all write, so the git log reads the same whoever wrote the commit. Stages by named path, honours every hook, pushes only on confirmation."
|
|
8
4
|
---
|
|
9
5
|
|
|
10
6
|
## Purpose
|
|
11
7
|
|
|
12
|
-
|
|
8
|
+
One format for every commit in the repo — Hugo's, Luke's, an agent's. A reader scanning `git log` cannot tell which is which, because all three write `<type>(<scope>): <summary>`. It costs nothing per change, which is why it survived the pivot.
|
|
13
9
|
|
|
14
10
|
## When to invoke
|
|
15
11
|
|
|
16
|
-
|
|
17
|
-
- You've made an edit by hand (outside a hstack subagent flow) and want to commit it.
|
|
18
|
-
- You want to commit work-in-progress before stepping away.
|
|
19
|
-
- A subagent auto-commit didn't fire (rare, but possible if a Skill halted mid-phase) and you need to capture state manually.
|
|
20
|
-
|
|
21
|
-
Do NOT invoke inside an hstack subagent flow — the subagents auto-commit on status transitions per the kernel.
|
|
12
|
+
Whenever there is something to commit: the end of a change (`/hstack-wrap` commits in this format), a typo fix, work in progress before stepping away.
|
|
22
13
|
|
|
23
14
|
## Inputs
|
|
24
15
|
|
|
25
|
-
|
|
26
|
-
- Optional `--push` flag: if set, push after committing (still subject to explicit per-invocation confirmation; the system never force-pushes).
|
|
27
|
-
|
|
28
|
-
## Preconditions
|
|
29
|
-
|
|
30
|
-
Before any work:
|
|
31
|
-
|
|
32
|
-
- Verify the working directory is a git repository.
|
|
33
|
-
- Read `hstack/config.yaml` if present, to namespace the commit scope when committing inside an hstack-governed repo. Absent config is fine — the Skill works on any repo, hstack-installed or not.
|
|
34
|
-
- Verify there are changes to commit. If working tree is clean, halt with "nothing to commit."
|
|
35
|
-
|
|
36
|
-
## Orchestration steps
|
|
37
|
-
|
|
38
|
-
1. **Read git status.** Run `git status --short` and show the file list with their status markers. Categorize: modified, untracked, deleted, renamed.
|
|
16
|
+
Optional `--push`: push after committing — still subject to per-invocation confirmation.
|
|
39
17
|
|
|
40
|
-
|
|
41
|
-
- Exception: if every file is clearly part of one logical change AND none of the file names match common sensitive patterns (`.env`, `secret`, `credential`, `*.key`, `*.pem`), the Skill may propose `git add -A` with the engineer's explicit confirmation.
|
|
42
|
-
- Sensitive-file guardrail: if any staged file's name matches the sensitive-pattern list, halt and ask before committing.
|
|
18
|
+
## Steps
|
|
43
19
|
|
|
44
|
-
|
|
20
|
+
1. **Read `git status --short`** and show the file list with its status markers.
|
|
45
21
|
|
|
46
|
-
|
|
47
|
-
- Format: `<type>(<scope>): <summary>`
|
|
48
|
-
- `<type>` is one of: `feat`, `fix`, `chore`, `docs`, `refactor`, `test`, `style`, `perf`, `ci`
|
|
49
|
-
- `<scope>` names the area actually touched — never an invented or aspirational one. For commits inside hstack-governed code, prefer the change-id, the area, the Skill name, or the artifact type (e.g., `change-plan`, `billing`, `implement`, `data-review`). For non-hstack commits in the same repo, use the natural area (e.g., `auth`, `orchestrator`, `webhooks`). When the change spans several unrelated areas, no single honest scope exists — propose splitting into multiple commits.
|
|
50
|
-
- `<summary>` ≤ 72 characters, imperative present tense ("add" not "added"), no trailing period.
|
|
51
|
-
- Body (optional): the "why" rather than the "what". For commits inside hstack workflow, name the related change-id or artifact. For status transitions, name the transition explicitly.
|
|
52
|
-
- **Never add "Generated with Claude Code" or similar attribution.** The user's global rule.
|
|
53
|
-
- Footer: only conventional-commits footers (`BREAKING CHANGE:`, `Refs: <issue>`) when applicable.
|
|
22
|
+
2. **Stage by named path.** Not `git add -A`, which sweeps in `.env`, credentials and large binaries. Propose the specific paths that belong to the change being committed; the engineer confirms. `git add -A` is available when every file is clearly part of one logical change and no filename matches a sensitive pattern (`.env`, `secret`, `credential`, `*.key`, `*.pem`) — with explicit confirmation. If a staged filename matches one of those patterns, halt and ask.
|
|
54
23
|
|
|
55
|
-
|
|
24
|
+
3. **Show the diff.** `git diff --cached --stat`, then the full `git diff --cached` when it is small enough to read. For a large one, the stat plus the most-changed files.
|
|
56
25
|
|
|
57
|
-
|
|
26
|
+
4. **Draft the message.**
|
|
27
|
+
- `<type>(<scope>): <summary>`, where `<type>` is one of `feat`, `fix`, `chore`, `docs`, `refactor`, `test`, `style`, `perf`, `ci`.
|
|
28
|
+
- `<scope>` names the area actually touched — never an invented or aspirational one. When the change spans unrelated areas, no single honest scope exists: propose splitting it into several commits.
|
|
29
|
+
- `<summary>` ≤ 72 characters, imperative present ("add", not "added"), no trailing period.
|
|
30
|
+
- Body, when it earns its place: the why, not the what.
|
|
31
|
+
- **Never "Generated with Claude Code" or any similar attribution.**
|
|
32
|
+
- Footer: conventional-commits footers only (`BREAKING CHANGE:`, `Refs: <issue>`).
|
|
58
33
|
|
|
59
|
-
|
|
34
|
+
5. **Confirm, then commit.** Show the message; commit on confirmation. Every hook runs — `--no-verify`, `--no-gpg-sign` and every other bypass are forbidden, whatever the deadline.
|
|
60
35
|
|
|
61
|
-
|
|
36
|
+
6. **Verify it landed.** `git log -1 --format='%h %s'`, surfaced.
|
|
62
37
|
|
|
63
|
-
|
|
38
|
+
7. **Push only on explicit confirmation.** A push is visible to others and hard to reverse, so it is never automatic. Push to the current branch's tracked upstream, never with `--force`.
|
|
64
39
|
|
|
65
|
-
|
|
66
|
-
- Optionally, a `git push` to the current branch's upstream — but only with explicit per-invocation confirmation.
|
|
67
|
-
- No artifact writes. No subagent invocations.
|
|
40
|
+
## Output
|
|
68
41
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
None. This Skill IS the commit — there is nothing else for it to auto-commit. Subagents have their own auto-commit logic governed by the kernel.
|
|
72
|
-
|
|
73
|
-
## Idempotency contract
|
|
74
|
-
|
|
75
|
-
Not idempotent in the strict sense — a commit is a one-shot operation. Re-running the Skill on a clean working tree halts with "nothing to commit," which is the natural idempotency boundary.
|
|
42
|
+
One commit on the current branch. Optionally one push, confirmed in the conversation.
|
|
76
43
|
|
|
77
44
|
## Stop conditions
|
|
78
45
|
|
|
79
|
-
Beyond the kernel's
|
|
80
|
-
|
|
81
|
-
- Working tree is clean. Nothing to commit.
|
|
82
|
-
- A staged file's name matches the sensitive-pattern list (`.env`, `*secret*`, `*credential*`, `*.key`, `*.pem`). Halt and ask.
|
|
83
|
-
- A pre-commit hook fails. Investigate and fix the underlying issue — do NOT bypass with `--no-verify`. If the fix requires out-of-scope edits (when committing inside an hstack-governed change), halt and surface as a scope-amendment situation.
|
|
84
|
-
- The proposed commit message exceeds 72 characters on the summary line. Re-draft.
|
|
85
|
-
- A destructive push operation is requested (`--force`, force-with-lease, push to `main`) without explicit per-invocation authorization in the current conversation. Halt and confirm.
|
|
86
|
-
- `git commit --amend` would rewrite a commit that has already been pushed. Halt and confirm per-invocation; amending published history is not a default.
|
|
87
|
-
- The engineer requested `--push` but the current branch has no upstream. Halt and ask which remote / branch to push to.
|
|
88
|
-
|
|
89
|
-
## Failure modes
|
|
46
|
+
Beyond the kernel's:
|
|
90
47
|
|
|
91
|
-
-
|
|
92
|
-
-
|
|
93
|
-
-
|
|
94
|
-
-
|
|
48
|
+
- Nothing to commit — the tree is clean.
|
|
49
|
+
- A staged filename matches the sensitive-pattern list.
|
|
50
|
+
- A pre-commit hook fails. Surface its output and fix the cause; never bypass. A gpg signing failure is the same case — fix the gpg configuration.
|
|
51
|
+
- The push would be forced, or `--amend` would rewrite a commit that is already pushed.
|
|
52
|
+
- `--push` was asked for and the branch has no upstream. Ask which remote and branch.
|
|
53
|
+
- The push is rejected as non-fast-forward. Rebase and retry; never propose `--force`.
|
|
@@ -1,74 +1,52 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: hstack-data-architecture
|
|
3
|
-
description: Use
|
|
4
|
-
tools:
|
|
5
|
-
- Read
|
|
6
|
-
- Write
|
|
7
|
-
- Edit
|
|
8
|
-
- Grep
|
|
9
|
-
- Glob
|
|
10
|
-
- Bash
|
|
11
|
-
- Task
|
|
12
|
-
- "{{TODO-MCP: Supabase MCP — live schema introspection in extract mode}}"
|
|
13
|
-
- "node hstack/scripts/validate-spec.mjs — frontmatter validator"
|
|
3
|
+
description: "Use when the data layer really moves — tenancy, entities, RLS posture, RAG layout — to write or refresh `hstack/context/data-architecture.md`. Ordinary schema changes are covered by the kernel's same-PR rule."
|
|
14
4
|
---
|
|
15
5
|
|
|
16
6
|
## Purpose
|
|
17
7
|
|
|
18
|
-
|
|
8
|
+
`/hstack-data-architecture` writes or refreshes `hstack/context/data-architecture.md`, the living
|
|
9
|
+
doc that holds the data layer's posture in five sections: tenancy, entities, RLS, RAG, migrations.
|
|
10
|
+
It is what the next session reads before touching the database.
|
|
19
11
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
- Standalone via `/hstack:data-architecture [--mode extract|elicit] [--section <name>]` for refresh or single-section edits.
|
|
25
|
-
- Routed-into-from-downstream when `/hstack:app-architecture` finds a state-ownership gap that requires an entity addition (the bidirectional drift recovery path).
|
|
12
|
+
It is not how the doc stays current day to day. A change that adds a column updates the doc in its
|
|
13
|
+
own PR — that rule is the kernel's and costs nothing. This Skill is for the moves that rule cannot
|
|
14
|
+
absorb: the first write, a change of tenant, an entity graph that no longer matches the schema, an
|
|
15
|
+
RLS posture that has drifted.
|
|
26
16
|
|
|
27
17
|
## Inputs
|
|
28
18
|
|
|
29
|
-
|
|
30
|
-
- `--section <name>` — one of `tenancy | entities | rls | rag | migrations`. Fast-jumps but re-runs end-of-atom coherence.
|
|
31
|
-
|
|
32
|
-
## Preconditions
|
|
33
|
-
|
|
34
|
-
- `hstack/config.yaml` at `init-status: minimal-complete` or later.
|
|
35
|
-
- `hstack/context/product/product-brief.md` at `status: current`. The brief is upstream; entities trace to it. If brief is at `draft` or `needs-refresh`, halt with `HSTACK-HALT: reason=upstream-non-terminal`.
|
|
36
|
-
- `hstack/templates/data-architecture.md` present.
|
|
37
|
-
- In extract mode, the Supabase MCP is reachable OR `supabase/migrations/` exists OR equivalent schema source is reachable; otherwise halt.
|
|
38
|
-
|
|
39
|
-
## Orchestration steps
|
|
19
|
+
`--section tenancy | entities | rls | rag | migrations`, optional — refreshes one section.
|
|
40
20
|
|
|
41
|
-
|
|
42
|
-
2. **Invoke `data-architect` subagent.** Via the Task tool with `subagent_type: data-architect`. Pass mode, optional section, the canonical session-start context, and (in extract mode) the live-schema introspection results.
|
|
43
|
-
3. **Walk sections.** The subagent walks Section 1 first (Tenancy is gate). For section-targeted entry, jumps directly. Each confirmed section writes to disk + auto-commits.
|
|
44
|
-
4. **Run drift challenge prompts.** Each section ends with a drift challenge before confirmation. A real drift halts with `HSTACK-HALT: reason=upstream-drift` and offers (a) revise this section, (b) re-enter the upstream atom (`/hstack:product-discovery` or `/hstack:configure vision`), (c) log as ADR via `/hstack:adr-new`.
|
|
45
|
-
5. **End-of-atom coherence check.** Even on section-targeted entry, the subagent re-runs all five drift challenges before terminal commit. Any unanswered challenge blocks the commit.
|
|
21
|
+
## Steps
|
|
46
22
|
|
|
47
|
-
|
|
23
|
+
1. **Extract or elicit.** Extract when a schema exists: the Supabase MCP if it is configured,
|
|
24
|
+
otherwise `supabase/migrations/`. Elicit when nothing exists yet. **If the MCP is unreachable
|
|
25
|
+
and the migrations are used instead, say so to the engineer** — the fallback is announced, never
|
|
26
|
+
silent (kernel § Stop conditions). If neither is reachable, stop.
|
|
27
|
+
2. **Invoke `data-architect`** with the material gathered. It reads the schema, drafts each section
|
|
28
|
+
and challenges it. The questions and the confirmations happen here, in this session — a subagent
|
|
29
|
+
cannot interview.
|
|
30
|
+
3. **Walk the sections in order.** Tenancy first: nothing downstream stabilizes until the tenant is
|
|
31
|
+
one concrete noun with a rule for who is inside one. Then entities, RLS, RAG, migrations.
|
|
32
|
+
4. **Each section ends with its drift challenge** and the answer stays in the doc as evidence the
|
|
33
|
+
probe ran. A challenge that surfaces a real contradiction stops the section: the engineer
|
|
34
|
+
revises it, files an ADR, or writes a tech-debt file — none of which this Skill decides.
|
|
35
|
+
5. **A section-targeted refresh re-reads the other four challenges** before the PR. Changing an
|
|
36
|
+
entity and leaving the RLS section describing the old one is the failure this catches.
|
|
48
37
|
|
|
49
|
-
|
|
50
|
-
- `hstack/.session-state/<session-id>.yaml` (transient).
|
|
38
|
+
## Output
|
|
51
39
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
- Each confirmed section writes immediately and auto-commits.
|
|
55
|
-
- Artifact reaches `status: current` → final commit with the coherence-check evidence in the body.
|
|
56
|
-
|
|
57
|
-
## Idempotency contract
|
|
58
|
-
|
|
59
|
-
- Artifact at `current` + no `--section` + no `--force`: print summary, exit no-op.
|
|
60
|
-
- Artifact at `draft` or partial: read disk + session-state, resume at next non-confirmed section.
|
|
61
|
-
- Artifact at `needs-refresh`: walk all sections in confirm-or-revise mode.
|
|
40
|
+
`hstack/context/data-architecture.md`, updated in the PR that changes it. Section 5 holds migration
|
|
41
|
+
*sketches* — no `.sql` file is written here.
|
|
62
42
|
|
|
63
43
|
## Stop conditions
|
|
64
44
|
|
|
65
|
-
|
|
66
|
-
- Section 1's tenant is not yet one concrete noun with a rule for who is inside it, after one re-ask.
|
|
67
|
-
- A drift challenge surfaces an unresolved contradiction.
|
|
68
|
-
- Extract mode invoked but no schema source reachable.
|
|
69
|
-
- The `assumes-database: postgres` value contradicts an in-flight stack decision.
|
|
70
|
-
|
|
71
|
-
## Failure modes
|
|
45
|
+
Beyond the kernel's:
|
|
72
46
|
|
|
73
|
-
-
|
|
74
|
-
|
|
47
|
+
- No schema source is reachable in extract mode: the Supabase MCP is down *and* there are no
|
|
48
|
+
migrations. Halt rather than describe a schema from memory.
|
|
49
|
+
- The tenant is still not one concrete noun after one re-ask.
|
|
50
|
+
- A drift challenge surfaces a contradiction the engineer has not resolved.
|
|
51
|
+
- The database in the doc's `assumes-database` is not the one the repo is using. Surface it; a
|
|
52
|
+
silent switch invalidates every RLS predicate in the doc.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hstack-promote
|
|
3
|
+
description: Use after a PR merges, to release it — pending production migrations, a smoke test on the unpromoted production build, then promotion. The concrete commands live in infrastructure.md § Deploy Pipeline.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Purpose
|
|
7
|
+
|
|
8
|
+
`/hstack-promote` is the only deploy step hstack carries. The **sequence** lives here; the **commands** live in `hstack/context/infrastructure.md` § Deploy Pipeline. That split is deliberate: the sequence is the same whoever hosts the product, and a provider hardcoded here would be wrong for the next one.
|
|
9
|
+
|
|
10
|
+
## When to invoke
|
|
11
|
+
|
|
12
|
+
After a PR merges. Short trains — promote every two or three days rather than letting merges pile up, and let a change on a sensitive surface travel alone.
|
|
13
|
+
|
|
14
|
+
One promoter at a time. Say you are promoting before you start, because two overlapping promotions cannot be untangled afterwards.
|
|
15
|
+
|
|
16
|
+
A hotfix takes the same PR and the same fast lane. It skips the preview and the train, never the checks.
|
|
17
|
+
|
|
18
|
+
## Preconditions
|
|
19
|
+
|
|
20
|
+
- The PR is merged and the fast lane is green on what is about to ship.
|
|
21
|
+
- `hstack/context/infrastructure.md` has a § Deploy Pipeline naming the six commands this sequence needs: apply a pending migration to production, list deployments and their state, smoke-test a specific deployment URL, read production logs, promote a deployment, roll back to the previous one.
|
|
22
|
+
|
|
23
|
+
**If that section is missing, or does not name them, halt.** Guessing a production command from a provider's documentation is how the wrong project gets migrated.
|
|
24
|
+
|
|
25
|
+
## Steps
|
|
26
|
+
|
|
27
|
+
1. **Confirm the preconditions.** Merged; fast lane green.
|
|
28
|
+
|
|
29
|
+
2. **List the pending production migrations** and show them to the human. Ask: *migrations OK?* Apply them only on an explicit yes, then verify they applied.
|
|
30
|
+
|
|
31
|
+
3. **Wait for the production build** of the merge commit to reach a ready state.
|
|
32
|
+
|
|
33
|
+
4. **Smoke-test the unpromoted build** at its own URL — the deployment that carries the new code against the new schema, before any user can reach it. Check its health and its error logs, then hand the URL to the human, who tests the behaviour. This step is the entire reason the pipeline is staged.
|
|
34
|
+
|
|
35
|
+
5. **Check the exposure map.** If this release changes what a user can reach, the Module Map column in `app-architecture.md` is updated before the promotion, not after.
|
|
36
|
+
|
|
37
|
+
6. **Ask: staging OK, do we promote?** Promote on an explicit yes. Nothing else is an authorization.
|
|
38
|
+
|
|
39
|
+
7. **Watch production for five minutes** — error logs, then the error tracker. A release nobody looked at is not a release that worked.
|
|
40
|
+
|
|
41
|
+
8. **If it screams, roll back** by re-promoting the previous deployment. The migrations stay: they are additive by default, so the previous code runs against the new schema. Contraction ships in a later PR (kernel § Security checklist).
|
|
42
|
+
|
|
43
|
+
## Output
|
|
44
|
+
|
|
45
|
+
One production deployment promoted, or one rolled back — and, when the exposure map moved, the commit that moved it.
|
|
46
|
+
|
|
47
|
+
## Stop conditions
|
|
48
|
+
|
|
49
|
+
Beyond the kernel's:
|
|
50
|
+
|
|
51
|
+
- The fast lane is not green on what is about to be promoted.
|
|
52
|
+
- `infrastructure.md` has no § Deploy Pipeline, or it does not name the six commands.
|
|
53
|
+
- Someone else is already mid-promotion.
|
|
54
|
+
|
|
55
|
+
The kernel forbids a write-capable MCP against production outside this skill. This sequence is where that exception is spent — on the migration in step 2, with the human's yes. Enable it for that step; disable it afterwards.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hstack-story
|
|
3
|
+
description: "Use to draft or refine the user story of a Notion feature — five sections, the user's point of view, written into the feature via the Notion MCP. A product tool, never a gate on a change."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Purpose
|
|
7
|
+
|
|
8
|
+
`/hstack-story` writes one user story: who it is for, what shipping looks like to them, how we
|
|
9
|
+
know it worked. It exists so the people building the product stay on the user's side of the
|
|
10
|
+
screen — it is not part of any change's path to merge. **No rule requires a change to reference a
|
|
11
|
+
story.** The PR description names the Notion feature it serves, and that is the whole link.
|
|
12
|
+
|
|
13
|
+
Features live in Notion, in the Epics and Features databases. The story is written into its
|
|
14
|
+
feature page through the Notion MCP; the repo keeps nothing.
|
|
15
|
+
|
|
16
|
+
## When to invoke
|
|
17
|
+
|
|
18
|
+
When a feature needs its story written, or when the story it has no longer describes what is being
|
|
19
|
+
built. Nothing invokes this Skill and nothing waits on it.
|
|
20
|
+
|
|
21
|
+
## Inputs
|
|
22
|
+
|
|
23
|
+
`--feature <notion-id | url>` and `--persona <slug>`, both optional — the interview asks when they
|
|
24
|
+
are missing.
|
|
25
|
+
|
|
26
|
+
## Steps
|
|
27
|
+
|
|
28
|
+
Read `hstack/templates/story.md` first: the five sections are the shape, and filling them is the
|
|
29
|
+
job. Personas at `hstack/context/personas/` are frozen documents — read them for the user's voice,
|
|
30
|
+
and if none fits, say so and anchor the story on the user the interview describes. A missing
|
|
31
|
+
persona never blocks a story.
|
|
32
|
+
|
|
33
|
+
1. **Who and Why.** The persona and the job to be done, in one or two sentences.
|
|
34
|
+
2. **What Shipping Looks Like.** What the user sees, does and feels. A paragraph, not a spec.
|
|
35
|
+
3. **Success Metric.** One measurable thing. If the answer is not measurable, ask once more with a
|
|
36
|
+
candidate; record what the engineer settles on rather than inventing a number.
|
|
37
|
+
4. **Edge Cases the User Cares About.** The challenge that earns this section: *what does the user
|
|
38
|
+
notice if this ships but is slightly broken?* Two bullets minimum, from the user's side.
|
|
39
|
+
5. **Out of Scope for This Story.** The adjacent thing this story is not.
|
|
40
|
+
|
|
41
|
+
Then write the story into the Notion feature page via the MCP, with `id: NOTION:<id>` naming it.
|
|
42
|
+
Refining an existing story reads it first and proposes the current values as the starting point.
|
|
43
|
+
|
|
44
|
+
## Output
|
|
45
|
+
|
|
46
|
+
The story, in its Notion feature. No file in the repo, no status, no link written back onto
|
|
47
|
+
anything.
|
|
48
|
+
|
|
49
|
+
## Stop conditions
|
|
50
|
+
|
|
51
|
+
Beyond the kernel's:
|
|
52
|
+
|
|
53
|
+
- The Notion MCP is unreachable. Say so and stop — no local file stands in for it
|
|
54
|
+
(kernel § Stop conditions).
|
|
55
|
+
- The named feature page does not exist. Ask which one, or whether to create it; never write the
|
|
56
|
+
story onto a different page.
|
|
57
|
+
- The story is being asked for as a precondition to writing code. It is not one — say so, and
|
|
58
|
+
offer to write it afterwards if it is still wanted.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hstack-test-audit
|
|
3
|
+
description: "Use on demand for one module whose tests look thin: map its business rules against the existing tests, name the gaps, write the missing tests, record the invariants found. Never a per-change phase."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Purpose
|
|
7
|
+
|
|
8
|
+
`/hstack-test-audit <module>` audits one module's coverage of its **business rules** — the places
|
|
9
|
+
where the code decides something that would be wrong in silence — and closes the gaps the engineer
|
|
10
|
+
chooses to close. It produces tests and an `invariants.md` update. No artifact, no status, no
|
|
11
|
+
report file.
|
|
12
|
+
|
|
13
|
+
## When to invoke
|
|
14
|
+
|
|
15
|
+
When a module's tests look thin (kernel § Workflow trigger table), or before a module starts
|
|
16
|
+
carrying real users' money, data or identity. On demand only: the kernel's per-change rule is one
|
|
17
|
+
question at plan time, and this Skill is never a phase of a change.
|
|
18
|
+
|
|
19
|
+
## Inputs
|
|
20
|
+
|
|
21
|
+
`<module>` — a module from the Module Map in `app-architecture.md`, or a path.
|
|
22
|
+
|
|
23
|
+
## Steps
|
|
24
|
+
|
|
25
|
+
1. **Map the rules.** Read the module's code, `hstack/context/invariants.md`, the Module Map, and
|
|
26
|
+
`data-architecture.md` when the module touches the database. Write each rule as *decides X;
|
|
27
|
+
wrong in silence if Y*. A module whose code decides nothing has no gap to close — say so and
|
|
28
|
+
stop rather than write tests for the sake of coverage.
|
|
29
|
+
2. **Map the existing tests onto the rules.** Existing test files are read-only here
|
|
30
|
+
(kernel § Test immutability); this step reads them, it never edits them.
|
|
31
|
+
3. **Name the gaps** — rules with no test, and tests asserting something no rule needs.
|
|
32
|
+
4. **Interview the edges.** A handful of questions, not a script: *what does the user notice if
|
|
33
|
+
this breaks in silence?* — plus concurrency, retries, and the cross-tenant case when the module
|
|
34
|
+
touches tenant-scoped data. The answers sharpen the gap list.
|
|
35
|
+
5. **Propose extractions.** A rule buried in a component is a rule nobody can test. Propose
|
|
36
|
+
pulling it into a pure function; the engineer decides, and an accepted extraction ships in the
|
|
37
|
+
same PR as the test that justifies it.
|
|
38
|
+
6. **The engineer picks the gaps to close now.** A module with twenty uncovered rules would make
|
|
39
|
+
an unreviewable PR. Close the chosen ones; name the rest in the PR description so the next
|
|
40
|
+
audit starts there.
|
|
41
|
+
7. **Write the tests.** New test files need no authorization — "new" means the path did not exist
|
|
42
|
+
at session start. If closing a gap requires editing or deleting an existing test, halt and ask;
|
|
43
|
+
nothing in this Skill authorizes that.
|
|
44
|
+
8. **Record the invariants.** Every rule the audit surfaced goes into `hstack/context/invariants.md`
|
|
45
|
+
in this PR — **including the gaps left open**. The memory is the cheap half; write it whether or
|
|
46
|
+
not the test was written.
|
|
47
|
+
|
|
48
|
+
The heavy reading in steps 1–3 goes to the `test-strategist` subagent, which returns the rule map
|
|
49
|
+
and the gap list. Steps 4 and 6 are questions for the engineer and happen here, in this session.
|
|
50
|
+
|
|
51
|
+
## Output
|
|
52
|
+
|
|
53
|
+
New test files, an `invariants.md` diff, and a summary for the PR description naming the gaps left
|
|
54
|
+
open. Nothing else.
|
|
55
|
+
|
|
56
|
+
## Stop conditions
|
|
57
|
+
|
|
58
|
+
Beyond the kernel's:
|
|
59
|
+
|
|
60
|
+
- Closing a gap would require touching an existing test. Halt (§ Test immutability).
|
|
61
|
+
- The module cannot be located, or spans so much of the repo that "one module" is not what is
|
|
62
|
+
being audited. Ask which one.
|
|
63
|
+
- An invariant the audit surfaces contradicts one already in `invariants.md`. Surface both; the
|
|
64
|
+
engineer decides which is true.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hstack-wrap
|
|
3
|
+
description: Use at the end of a change, before the PR — reads the diff against code-standards, runs /review and /security-review, audits test immutability, updates the living docs the diff invalidated, writes the PR description.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Purpose
|
|
7
|
+
|
|
8
|
+
`/hstack-wrap` closes a change. It is loaded fresh at the moment it runs, which is the point: the end-of-change rules do not have to survive two hundred turns of conversation in order to be applied. It is a checklist fired by an event, not a phase — nothing here is produced unless a change is actually ending.
|
|
9
|
+
|
|
10
|
+
## When to invoke
|
|
11
|
+
|
|
12
|
+
When the code and its tests are done and the next step is a pull request. Once per change; re-running it after a fix is normal and cheap.
|
|
13
|
+
|
|
14
|
+
Not on a change that is still moving, and never to merge — `/hstack-wrap` opens the PR and stops there.
|
|
15
|
+
|
|
16
|
+
## Inputs
|
|
17
|
+
|
|
18
|
+
None. The diff under review is everything that will land in the PR — committed, staged and unstaged — against the merge-base with the default branch.
|
|
19
|
+
|
|
20
|
+
## Steps
|
|
21
|
+
|
|
22
|
+
1. **Read `hstack/context/review-miss.md`** when it exists. A category a review has already missed once gets re-checked explicitly in the pass below; that is the whole reason the file exists.
|
|
23
|
+
|
|
24
|
+
2. **Read the diff against `hstack/context/code-standards.md`**, rule by rule, when the file exists. This is the pass the linter cannot make: a second implementation of something that already existed, a component talking to the network, an orchestrating function that also does the steps, a legacy path left wired, a returned error nobody reads. Fix what is found — the fix is usually the extraction or the deletion the rule names — and when a rule's `Seen here` line is empty and this diff is the first example, fill it in this PR. What survives on purpose is a tech-debt file, not silence.
|
|
25
|
+
|
|
26
|
+
3. **Run `/review`, then `/security-review`** on that diff. Fix what is fixable inside the announced perimeter. Everything else is declared in the PR description — the finding, and why it was not fixed. A finding is never dropped silently, and an empty result is reported as what it is: the reviewer found nothing.
|
|
27
|
+
|
|
28
|
+
4. **Audit test immutability.** Diff the test files that already existed at the merge-base. An edit or a deletion without the canonical authorization echoed in this conversation is a blocking finding — halt, and do not open the PR (kernel § Test immutability).
|
|
29
|
+
|
|
30
|
+
5. **Ask each living doc whether this diff invalidated it**, and update it in this PR when it did (kernel § Context docs). When an entry point changed status — live, routable, off — the exposure column of the Module Map in `app-architecture.md` moves with it.
|
|
31
|
+
|
|
32
|
+
6. **Name the conscious shortcuts.** A shortcut that survives the merge becomes a file under `hstack/tech-debt/`, from the template, written in this PR and named in its description.
|
|
33
|
+
|
|
34
|
+
7. **Sensitive surface?** If the diff touches one (kernel § Review), the PR says so in its first line and asks for the deep pass in a fresh session — `/hstack-adversarial-review`.
|
|
35
|
+
|
|
36
|
+
8. **Write the PR description** from `references/pr-description.md`: intention, perimeter, decisions, shortcuts and tech-debt, the review findings split into what was fixed and what was declared, and the Notion feature it serves when there is one. When the consumer has a `.github/pull_request_template.md`, that rendered file is the one you fill — the reference file is the seed it was copied from, not a second authority.
|
|
37
|
+
|
|
38
|
+
9. **Run the fast lane locally, then commit, push and open the PR.** Typecheck, lint and the critical tests run here, on this machine, and are green before the commit — a red PR costs a paid CI round trip for something a local run would have caught in a minute. Lint is at `error`: fix the finding, never add a suppression or a disable comment to get past it (kernel § Stop conditions). If the repo names no fast-lane command, say so in the PR rather than inventing one. Commit in the `hstack-commit` format. Push and `gh pr create` only after explicit confirmation in the conversation.
|
|
39
|
+
|
|
40
|
+
## Output
|
|
41
|
+
|
|
42
|
+
One open PR against the default branch, carrying the code, the living-doc updates, any tech-debt file, and a description that says what the reviews found.
|
|
43
|
+
|
|
44
|
+
## Stop conditions
|
|
45
|
+
|
|
46
|
+
Beyond the kernel's:
|
|
47
|
+
|
|
48
|
+
- A pre-existing test was modified or deleted without authorization.
|
|
49
|
+
- A hook or a check was bypassed to get here.
|
|
50
|
+
- A living doc is invalidated and you cannot update it. Say "stale" in the PR description; never invent the content.
|