@thebassclef/lite 1.1.1 → 1.2.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/dist/cli.cjs +23 -6
- package/dist/cli.js +23 -6
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/lite/.claude/bassclef-configs.jsonc +56 -0
- package/dist/lite/.claude/bassclef-orientation.md +120 -0
- package/dist/lite/.claude/hooks/adr-discipline-check.sh +132 -0
- package/dist/lite/.claude/hooks/atomic-pr-check.sh +169 -0
- package/dist/lite/.claude/hooks/auto-save-idle.sh +51 -0
- package/dist/lite/.claude/hooks/bassclef-sync.sh +51 -13
- package/dist/lite/.claude/hooks/bet-doc-gate.sh +283 -0
- package/dist/lite/.claude/hooks/bug-diagnosis.sh +64 -0
- package/dist/lite/.claude/hooks/destructive-command-guard.sh +136 -0
- package/dist/lite/.claude/hooks/file-rename-discipline-check.sh +147 -0
- package/dist/lite/.claude/hooks/hook-classifier-canary.sh +158 -0
- package/dist/lite/.claude/hooks/kiss-default-check.sh +129 -0
- package/dist/lite/.claude/hooks/multi-tenancy-check.sh +83 -0
- package/dist/lite/.claude/hooks/oo-ad-entry-point-check.sh +216 -0
- package/dist/lite/.claude/hooks/operator-private-path-check.sh +203 -0
- package/dist/lite/.claude/hooks/pattern-annotation-validate.sh +142 -0
- package/dist/lite/.claude/hooks/plain-english-steering.sh +15 -1
- package/dist/lite/.claude/hooks/post-write-trace.sh +66 -0
- package/dist/lite/.claude/hooks/pr-body-scrub-check.sh +446 -0
- package/dist/lite/.claude/hooks/pre-commit-identifier-leak-scrub.sh +137 -0
- package/dist/lite/.claude/hooks/pre-gh-pr-body-scrub.sh +192 -0
- package/dist/lite/.claude/hooks/pre-gh-pr-title-scrub.sh +172 -0
- package/dist/lite/.claude/hooks/role-entry-gate.sh +115 -0
- package/dist/lite/.claude/hooks/save-state.sh +268 -0
- package/dist/lite/.claude/hooks/session-reflection.d/08-settings-drift.sh +8 -1
- package/dist/lite/.claude/hooks/session-reflection.d/10-abrupt-stop-recovery.sh +52 -0
- package/dist/lite/.claude/hooks/session-reflection.d/55-orientation-gate.sh +40 -4
- package/dist/lite/.claude/hooks/session-reflection.d/80-hook-heartbeat-check.sh +12 -5
- package/dist/lite/.claude/hooks/session-reflection.d/81-hook-manifest-staleness.sh +18 -2
- package/dist/lite/.claude/hooks/session-reflection.d/91-npm-version-drift.sh +54 -0
- package/dist/lite/.claude/hooks/session-reflection.d/tests/10-abrupt-stop-recovery.test.sh +95 -0
- package/dist/lite/.claude/hooks/session-reflection.sh +62 -15
- package/dist/lite/.claude/hooks/tool-failure-diagnosis.sh +50 -0
- package/dist/lite/.claude/luminaries/andrej-karpathy.md +165 -0
- package/dist/lite/.claude/luminaries/dave-gray.md +155 -0
- package/dist/lite/.claude/luminaries/gary-klein.md +166 -0
- package/dist/lite/.claude/luminaries/kaoru-ishikawa.md +162 -0
- package/dist/lite/.claude/luminaries/lean-product-canvas.md +33 -0
- package/dist/lite/.claude/luminaries/luke-wroblewski.md +224 -0
- package/dist/lite/.claude/luminaries/ryan-singer.md +113 -0
- package/dist/lite/.claude/luminaries/steve-krug.md +168 -0
- package/dist/lite/.claude/luminaries/tony-ulwick.md +134 -0
- package/dist/lite/.claude/rules/arc-level-orientation-before-leaf.md +60 -0
- package/dist/lite/.claude/rules/architect-review-discipline.md +71 -0
- package/dist/lite/.claude/rules/auto-fix-criteria.md +126 -0
- package/dist/lite/.claude/rules/bassclef-hook-drift-blocker.md +144 -0
- package/dist/lite/.claude/rules/bassclef-models-discovery.md +107 -0
- package/dist/lite/.claude/rules/bassclef-workflow-parity.md +104 -0
- package/dist/lite/.claude/rules/cost-governance.md +154 -0
- package/dist/lite/.claude/rules/file-rename-discipline.md +95 -0
- package/dist/lite/.claude/rules/mechanism-fidelity.md +88 -0
- package/dist/lite/.claude/rules/prototype-production-coupling.md +125 -0
- package/dist/lite/.claude/rules/quick-fix-criteria.md +90 -0
- package/dist/lite/.claude/rules/session-artifacts.md +30 -0
- package/dist/lite/.claude/rules/sibling-smoke-after-substrate-change.md +107 -0
- package/dist/lite/.claude/rules/substrate-as-system.md +67 -0
- package/dist/lite/.claude/rules/usability.md +22 -0
- package/dist/lite/.claude/settings.json +20 -0
- package/dist/lite/.claude/skills/agent-research-spawn/SKILL.md +100 -0
- package/dist/lite/.claude/skills/architect-review/SKILL.md +201 -0
- package/dist/lite/.claude/skills/auto-fix/SKILL.md +297 -0
- package/dist/lite/.claude/skills/autonomous/SKILL.md +300 -0
- package/dist/lite/.claude/skills/bind-subdomain/SKILL.md +232 -0
- package/dist/lite/.claude/skills/canvas/SKILL.md +41 -0
- package/dist/lite/.claude/skills/deploy-prod/SKILL.md +106 -0
- package/dist/lite/.claude/skills/docs-sync/SKILL.md +188 -0
- package/dist/lite/.claude/skills/eisenhower/SKILL.md +273 -0
- package/dist/lite/.claude/skills/empathy-map/SKILL.md +168 -0
- package/dist/lite/.claude/skills/frontend-design/SKILL.md +53 -0
- package/dist/lite/.claude/skills/interview-me/SKILL.md +171 -0
- package/dist/lite/.claude/skills/journal-export/SKILL.md +293 -0
- package/dist/lite/.claude/skills/jtbd-tasks/SKILL.md +203 -0
- package/dist/lite/.claude/skills/objectory-decompose/SKILL.md +256 -0
- package/dist/lite/.claude/skills/pick-luminaries/SKILL.md +100 -0
- package/dist/lite/.claude/skills/pre-mortem/SKILL.md +180 -0
- package/dist/lite/.claude/skills/prototype-gallery/SKILL.md +264 -0
- package/dist/lite/.claude/skills/provision-deploy-host/SKILL.md +257 -0
- package/dist/lite/.claude/skills/quick-fix/SKILL.md +273 -0
- package/dist/lite/.claude/skills/release/SKILL.md +311 -0
- package/dist/lite/.claude/skills/release-notes/SKILL.md +202 -0
- package/dist/lite/.claude/skills/rfc/SKILL.md +222 -0
- package/dist/lite/.claude/skills/riff-prototypes/SKILL.md +637 -0
- package/dist/lite/.claude/skills/secrets-bootstrap/SKILL.md +209 -0
- package/dist/lite/.claude/skills/skill/SKILL.md +304 -0
- package/dist/lite/.claude/skills/smoke-test/SKILL.md +100 -0
- package/dist/lite/.claude/skills/state/SKILL.md +204 -0
- package/dist/lite/.claude/skills/substrate-check/SKILL.md +218 -0
- package/dist/lite/.claude/skills/synthetic-user/SKILL.md +381 -0
- package/dist/lite/.claude/skills/task-scenarios/SKILL.md +105 -0
- package/dist/lite/.claude/skills/tier-dependency-audit/SKILL.md +139 -0
- package/dist/lite/.claude/skills/ux-migration/SKILL.md +424 -0
- package/dist/lite/.claude/skills/value-prop-canvas/SKILL.md +297 -0
- package/dist/lite/README.md +5 -1
- package/dist/lite/gitignore +6 -0
- package/dist/lite/lib/bassclef-dir-resolver.sh +85 -0
- package/dist/lite/lib/clone-failure-classifier.sh +59 -0
- package/dist/lite/lib/fixture-builder.sh +190 -0
- package/dist/lite/lib/fresh-install-check.sh +49 -0
- package/dist/lite/lib/hook-heartbeat.sh +0 -1
- package/dist/lite/lib/mechanism-fidelity.sh +569 -0
- package/dist/lite/lib/npm-version-check.sh +112 -0
- package/dist/lite/lib/preview-state.sh +229 -0
- package/dist/lite/lib/session-rescue.sh +0 -1
- package/dist/lite/scripts/generate-lite-manifest.sh +145 -4
- package/dist/lite/scripts/lite-manifest-drift-check.sh +5 -1
- package/dist/lite/standards/architect-review-discipline.md +222 -0
- package/dist/lite/standards/bassclef-platform.md +249 -0
- package/dist/lite/standards/bassclef-test-repos.md +97 -0
- package/dist/lite/standards/bassclef-wiring-manifest.json +25 -1
- package/dist/lite/standards/cold-adopter-harness.md +205 -0
- package/dist/lite/standards/data-management.md +135 -0
- package/dist/lite/standards/frontend-stack/nextjs-prisma.md +124 -0
- package/dist/lite/standards/lite-manifest-schema-changes.md +27 -0
- package/dist/lite/standards/lite-manifest.json +1456 -14
- package/dist/lite/standards/mechanism-fidelity.md +205 -0
- package/dist/lite/standards/operator-private-discipline.md +200 -0
- package/dist/lite/standards/operator-to-public-flow.md +195 -0
- package/dist/lite/standards/prototype-gallery.md +251 -0
- package/dist/lite/standards/pseudonym-key-schema.md +109 -0
- package/dist/lite/standards/sibling-validation-checklist.md +181 -0
- package/dist/lite/standards/slack-notifications.md +161 -0
- package/dist/lite/standards/synthetic-user-testing.md +173 -0
- package/dist/lite/standards/vendor-bindings.md +165 -0
- package/dist/lite/standards/vendor-plugins/frontend-design.md +66 -0
- package/dist/lite/standards/vpc-fit-validation.md +167 -0
- package/dist/lite/templates/gallery-yml.md +113 -0
- package/dist/lite/templates/product-canvas.md +169 -0
- package/dist/lite/templates/value-prop-canvas.md +180 -0
- package/package.json +3 -3
- /package/dist/lite/{whereami.md → docs/whereami.md} +0 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
---
|
|
2
|
+
tier: lite
|
|
3
|
+
name: secrets-bootstrap
|
|
4
|
+
description: "Verify the operator's shell env against the secrets manifest. Calls the per-storage-type adapter; env and github_actions_secret implemented, others stub for V2. --write bootstraps ~/.config/bassclef/secrets.env. Read-only by default."
|
|
5
|
+
problem: "Operator shell env drifts from the secrets manifest. Missing secrets surface mid-session."
|
|
6
|
+
value: "Verifies the operator's shell env against the secrets manifest. Calls adapters per storage type."
|
|
7
|
+
inputs: [Optional --verbose flag]
|
|
8
|
+
outputs: [Secret check status per key, Missing secrets list, Adapter output]
|
|
9
|
+
user_invocable: true
|
|
10
|
+
disable_model_invocation: false
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# /secrets-bootstrap — Verify + Bootstrap Shell Secrets
|
|
14
|
+
|
|
15
|
+
Reads substrate.secrets.md, dispatches each entry to the adapter for
|
|
16
|
+
its `storage.type`, and reports green/red per secret. With `--write`,
|
|
17
|
+
writes placeholder shell-env entries for missing `storage.type: env`
|
|
18
|
+
secrets so the operator can fill in values once.
|
|
19
|
+
|
|
20
|
+
## When to invoke
|
|
21
|
+
|
|
22
|
+
- **First-time setup** of a fresh bassclef clone — run with `--write`
|
|
23
|
+
to bootstrap `~/.config/bassclef/secrets.env`
|
|
24
|
+
- **Pre-flight before `/provision-deploy-host`** (called automatically
|
|
25
|
+
as Phase 0 by that skill) — verifies all required env vars exist
|
|
26
|
+
before any external API call
|
|
27
|
+
- **Periodic health-check** — run with `--health-check` to invoke
|
|
28
|
+
each entry's `health_check_command` and surface stale or revoked
|
|
29
|
+
secrets
|
|
30
|
+
|
|
31
|
+
## When NOT to invoke
|
|
32
|
+
|
|
33
|
+
- Routine session-start orientation — the `90-secrets-expiry.sh`
|
|
34
|
+
reflection hook already surfaces expired/expiring secrets
|
|
35
|
+
- Setting GitHub Actions secrets — those live in GitHub; bootstrap
|
|
36
|
+
reads them via API but does NOT write them. Use `gh secret set`
|
|
37
|
+
for GHA-side writes.
|
|
38
|
+
|
|
39
|
+
## Sources read
|
|
40
|
+
|
|
41
|
+
- `substrate.secrets.md` — declarative secrets manifest (Shape B,
|
|
42
|
+
YAML frontmatter)
|
|
43
|
+
- `bassclef-platform.yml` — `secrets.storage_default` (used as
|
|
44
|
+
fallback when an entry's `storage.type` is unset)
|
|
45
|
+
- `scripts/adapters/secrets/<type>.sh` — per-type adapter implementations
|
|
46
|
+
- `standards/secrets-lifecycle.md` — semantics for storage_default
|
|
47
|
+
+ per-secret override
|
|
48
|
+
- `standards/bassclef-platform.md` — XDG `~/.config/bassclef/secrets.env`
|
|
49
|
+
convention
|
|
50
|
+
|
|
51
|
+
## Storage.type adapters
|
|
52
|
+
|
|
53
|
+
| `storage.type` | Adapter | V1 status | What it does |
|
|
54
|
+
|----------------|---------|-----------|--------------|
|
|
55
|
+
| `env` | `scripts/adapters/secrets/env.sh` | **implemented** | Checks `${reference}` shell env var; `--write` appends placeholder to `~/.config/bassclef/secrets.env` |
|
|
56
|
+
| `github_actions_secret` | `scripts/adapters/secrets/github_actions_secret.sh` | **implemented** | Checks via `gh secret list` (read-only); never writes |
|
|
57
|
+
| `1password` | `scripts/adapters/secrets/1password.sh` | stub | Stubs `op read op://<vault>/<item>/<field>`; reports "V2 adapter deferred" |
|
|
58
|
+
| `aws_secrets_manager` | `scripts/adapters/secrets/aws_secrets_manager.sh` | stub | Stubs `aws secretsmanager get-secret-value`; "V2 adapter deferred" |
|
|
59
|
+
| `file` | `scripts/adapters/secrets/file.sh` | stub | Stubs file-existence check at `reference` path; "V2 adapter deferred" |
|
|
60
|
+
| `custom` | `scripts/adapters/secrets/custom.sh` | stub | Stubs custom-reference resolution; "V2 adapter deferred" |
|
|
61
|
+
|
|
62
|
+
V2 adapters land when a real consumer needs them. The pattern is
|
|
63
|
+
schema-stable — adapters drop in without schema changes.
|
|
64
|
+
|
|
65
|
+
## Usage
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# Read-only check — surfaces green per secret with all-good or red with gap
|
|
69
|
+
bash scripts/secrets-bootstrap.sh
|
|
70
|
+
|
|
71
|
+
# Bootstrap missing env-typed secrets to ~/.config/bassclef/secrets.env
|
|
72
|
+
bash scripts/secrets-bootstrap.sh --write
|
|
73
|
+
|
|
74
|
+
# Run health_check_command per entry
|
|
75
|
+
bash scripts/secrets-bootstrap.sh --health-check
|
|
76
|
+
|
|
77
|
+
# Repair legacy secrets.env that lacks `export ` prefixes (bassclef#976).
|
|
78
|
+
# Without `export`, bash subprocesses don't inherit the variable — adapter
|
|
79
|
+
# checks pass in zsh but fail in `bash lib/luminary-pick.sh` etc.
|
|
80
|
+
# Creates dated backup before rewriting.
|
|
81
|
+
bash scripts/secrets-bootstrap.sh --repair
|
|
82
|
+
|
|
83
|
+
# Combinations
|
|
84
|
+
bash scripts/secrets-bootstrap.sh --write --health-check
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## --repair (bassclef#976)
|
|
88
|
+
|
|
89
|
+
`/secrets-bootstrap --repair` walks `~/.config/bassclef/secrets.env`
|
|
90
|
+
line by line and adds the `export ` prefix to every assignment line
|
|
91
|
+
that lacks it. Comments, blank lines, and already-exported lines pass
|
|
92
|
+
through untouched. A dated backup (`secrets.env.bak.YYYYMMDDTHHMMSSZ`)
|
|
93
|
+
is created before the rewrite.
|
|
94
|
+
|
|
95
|
+
Why this matters: sourcing a file with bare `VAR=value` lines sets
|
|
96
|
+
the shell variable in zsh — `echo $VAR` works — but the variable does
|
|
97
|
+
NOT enter the environment. Every bash subprocess the shell launches
|
|
98
|
+
(every bassclef hook, every helper script) reads only the environment.
|
|
99
|
+
Result: `[OK] ANTHROPIC_API_KEY (env) — set via secrets.env` in the
|
|
100
|
+
bootstrap output, then `bash lib/luminary-pick.sh` reports "not set"
|
|
101
|
+
seconds later. `--repair` closes that surface.
|
|
102
|
+
|
|
103
|
+
The env adapter's own writes already use the `export ` prefix
|
|
104
|
+
(`scripts/adapters/secrets/env.sh`). `--repair` is for the case where
|
|
105
|
+
an operator hand-edited the file and dropped the prefix, or where the
|
|
106
|
+
file pre-dates the bassclef#976 fix.
|
|
107
|
+
|
|
108
|
+
## Output format
|
|
109
|
+
|
|
110
|
+
One line per secret:
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
[OK] SLACK_WEBHOOK_ACTIVITY (github_actions_secret) — verified via gh
|
|
114
|
+
[OK] CLOUDFLARE_API_TOKEN (env) — set in shell env
|
|
115
|
+
[GAP] ANTHROPIC_API_KEY (env) — env var unset
|
|
116
|
+
→ fix: export ANTHROPIC_API_KEY=<value> ; or rerun with --write
|
|
117
|
+
[STUB] OP_VAULT_DEMO (1password) — adapter deferred to V2
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Summary line at end:
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
Result: 12/14 OK / 1 gap / 1 stub (14 secrets tracked)
|
|
124
|
+
Exit code: 0 (no gaps in implemented adapters) / 1 (gaps surface)
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
`--write` mode:
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
[GAP] ANTHROPIC_API_KEY (env) — env var unset
|
|
131
|
+
→ wrote placeholder to ~/.config/bassclef/secrets.env
|
|
132
|
+
→ edit the file + add real value, then run `source ~/.zshrc`
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Procedure
|
|
136
|
+
|
|
137
|
+
1. **Read substrate.secrets.md** YAML frontmatter
|
|
138
|
+
2. **For each secret entry**:
|
|
139
|
+
1. Resolve `storage.type` (use `secrets.storage_default` from
|
|
140
|
+
bassclef-platform.yml as fallback)
|
|
141
|
+
2. Source `scripts/adapters/secrets/${storage.type}.sh`
|
|
142
|
+
3. Call adapter's `secret_check <name> <reference>` → returns OK/GAP/STUB
|
|
143
|
+
4. If `--write` AND result is GAP AND adapter supports `secret_write`,
|
|
144
|
+
call `secret_write <name> <reference>` (env adapter only V1)
|
|
145
|
+
5. If `--health-check` AND `health_check_command` present, run it;
|
|
146
|
+
surface result
|
|
147
|
+
3. **Aggregate** results, print summary line, exit 0 (all OK or only
|
|
148
|
+
stubs) / 1 (one or more GAPs in implemented adapters)
|
|
149
|
+
|
|
150
|
+
## Idempotency
|
|
151
|
+
|
|
152
|
+
- Read-only by default; running twice in a row produces identical output
|
|
153
|
+
- `--write` is idempotent: if `~/.config/bassclef/secrets.env` already
|
|
154
|
+
has a line for the secret, the existing line is left in place
|
|
155
|
+
(writes never overwrite). If the file doesn't exist, it's created
|
|
156
|
+
with `chmod 600`.
|
|
157
|
+
- `--write` prompts the operator once at first invocation to add a
|
|
158
|
+
source-line to `~/.zshrc` if not already present:
|
|
159
|
+
```
|
|
160
|
+
Add `source ~/.config/bassclef/secrets.env` to ~/.zshrc? [y/N]
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Test plan
|
|
164
|
+
|
|
165
|
+
- [x] All-present: every secret has its env var set / its GHA secret
|
|
166
|
+
exists → exit 0, 0 gaps
|
|
167
|
+
- [x] One missing: a single env var unset → exit 1, 1 GAP, remediation
|
|
168
|
+
hint shown
|
|
169
|
+
- [x] Stub-only adapter: secret with `storage.type: 1password` →
|
|
170
|
+
STUB report, doesn't count toward exit-code-1
|
|
171
|
+
- [x] `--write` mode: missing env-typed secret → placeholder written
|
|
172
|
+
to ~/.config/bassclef/secrets.env (created if missing, chmod 600)
|
|
173
|
+
- [x] `--write` idempotent: re-run leaves file unchanged
|
|
174
|
+
- [x] `--health-check` mode: runs `health_check_command` per entry,
|
|
175
|
+
surfaces output
|
|
176
|
+
|
|
177
|
+
## Composes with
|
|
178
|
+
|
|
179
|
+
| Skill | How it composes |
|
|
180
|
+
|---|---|
|
|
181
|
+
| `/provision-deploy-host` | Calls `/secrets-bootstrap` as Phase 0 (fail-fast on missing creds) |
|
|
182
|
+
| `/launch-preview` | Optional pre-flight verification |
|
|
183
|
+
| `90-secrets-expiry.sh` (hook) | Sibling concern — expiry vs. presence |
|
|
184
|
+
|
|
185
|
+
## Distinct from
|
|
186
|
+
|
|
187
|
+
- `90-secrets-expiry.sh` — checks `expires_at` field; complementary
|
|
188
|
+
- `gh secret set` — actual write-side for GHA secrets; bootstrap is read-only for that storage type
|
|
189
|
+
- `op signin` / `op item create` — actual write-side for 1Password; V2 adapter would call these
|
|
190
|
+
|
|
191
|
+
## Override paths
|
|
192
|
+
|
|
193
|
+
- `SKIP_SECRETS_BOOTSTRAP=1` env var (logged) — bypass the skill
|
|
194
|
+
entirely; rare, not for normal work
|
|
195
|
+
- `--storage-types env,github_actions_secret` — limit dispatch to a
|
|
196
|
+
subset of types (useful for testing)
|
|
197
|
+
- `--secret SLACK_WEBHOOK_ACTIVITY` — check just one secret by name
|
|
198
|
+
|
|
199
|
+
## Refs
|
|
200
|
+
|
|
201
|
+
- bassclef#461 — issue this skill closes (WU-2 of 2026-05-04 bet)
|
|
202
|
+
- bassclef#462 — sibling: bassclef-platform.yml provides storage_default
|
|
203
|
+
- standards/secrets-lifecycle.md — secret lifecycle semantics
|
|
204
|
+
- standards/bassclef-platform.md — XDG path convention
|
|
205
|
+
- substrate.secrets.md — manifest read
|
|
206
|
+
|
|
207
|
+
## Output discipline
|
|
208
|
+
|
|
209
|
+
Dispatch `/kiss words --rewrite` on your skill output before you return it. See `standards/skill-output-discipline.md` for the contract.
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
---
|
|
2
|
+
tier: lite
|
|
3
|
+
name: skill
|
|
4
|
+
description: "Compose a new bassclef skill from idea to conforming SKILL.md. Runs the taxonomy gate (skill / rule / hook / luminary?). Generates a verb-first plain-language description. Scaffolds the frame. Pre-validates against the live clarity gate."
|
|
5
|
+
problem: "Adding a new bassclef skill takes manual scaffolding. Frontmatter and body shape drift."
|
|
6
|
+
value: "Composes a new bassclef skill from idea to conforming SKILL.md. Runs the taxonomy gate."
|
|
7
|
+
inputs: [Skill idea and rough description]
|
|
8
|
+
outputs: [SKILL.md file conforming to shape, Frontmatter with all required fields, Body sections]
|
|
9
|
+
user_invocable: true
|
|
10
|
+
disable_model_invocation: false
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# /skill — Meta-Workflow for Skill Creation
|
|
14
|
+
|
|
15
|
+
Closes the methodology+mechanism+workflow triad with `bassclef#371`
|
|
16
|
+
(context-engineering rule), `bassclef#377` (skill-description-clarity
|
|
17
|
+
rule), and `bassclef#382` (substrate-clarity-gate hook). Rules
|
|
18
|
+
prescribe; the hook BLOCKs violations; this workflow PRODUCES
|
|
19
|
+
conforming output from the start.
|
|
20
|
+
|
|
21
|
+
Pre-emptive shaping beats post-hoc blocking.
|
|
22
|
+
|
|
23
|
+
## When to use
|
|
24
|
+
|
|
25
|
+
- Operator dispatches `/skill <name-or-purpose>` to compose a new substrate skill
|
|
26
|
+
- Agent considers proposing a new skill but is unsure if a rule, hook, or luminary would be the right primitive (taxonomy-only mode answers this)
|
|
27
|
+
- Existing skill description fails substrate-clarity-gate; description-only mode regenerates
|
|
28
|
+
|
|
29
|
+
## When NOT to use
|
|
30
|
+
|
|
31
|
+
- Modifying existing skills — that's audit territory (bassclef#373/#374/#375)
|
|
32
|
+
- Creating a new rule, hook, or luminary — different surfaces, different scaffolds (taxonomy gate refuses and routes the operator)
|
|
33
|
+
- Auto-generating skill body content — workflow scaffolds the frame; operator writes substance
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
/skill <name-or-purpose> → interactive: taxonomy gate → full SKILL.md draft
|
|
39
|
+
/skill <name> --taxonomy-only → just answers "skill / rule / hook / luminary?"
|
|
40
|
+
/skill <name> --description-only → just generates the description per bassclef#377
|
|
41
|
+
/skill <name> --full → full SKILL.md scaffold (default for new skills)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## The taxonomy gate (the hardest check)
|
|
45
|
+
|
|
46
|
+
Before generating, workflow asks itself the four-quadrant question
|
|
47
|
+
and surfaces the answer to the operator:
|
|
48
|
+
|
|
49
|
+
| If the thing... | Use |
|
|
50
|
+
|----------------|-----|
|
|
51
|
+
| Loads into every conversation as persistent context (do/don't) | **rule** in `.claude/rules/` |
|
|
52
|
+
| Mechanically enforces at write/edit time (BLOCK on violation) | **hook** in `.claude/hooks/` |
|
|
53
|
+
| Provides bounded perspective for design/architecture decisions | **luminary** in `.claude/luminaries/` |
|
|
54
|
+
| Is a composable procedure with clear input + output, dispatchable by operator | **skill** in `.claude/skills/` |
|
|
55
|
+
|
|
56
|
+
If multiple match: surface the choice to operator. Default to **skill**
|
|
57
|
+
only when ALL of:
|
|
58
|
+
|
|
59
|
+
- Input/output is clearly procedural (verb-noun shape: "compose X", "audit Y", "dispatch Z")
|
|
60
|
+
- Operator would dispatch it more than once
|
|
61
|
+
- The work has a clear endpoint, not "always-on" enforcement
|
|
62
|
+
|
|
63
|
+
If the thing is "always-on enforcement" → it's a **rule** (loaded as
|
|
64
|
+
context) or **hook** (mechanical). If the thing is "perspective for
|
|
65
|
+
decisions" → it's a **luminary**. INSTEAD of writing a skill, route
|
|
66
|
+
to the right primitive.
|
|
67
|
+
|
|
68
|
+
## Procedure
|
|
69
|
+
|
|
70
|
+
### Step 1 — Taxonomy gate
|
|
71
|
+
|
|
72
|
+
Ask the four-quadrant question. Default to skill ONLY when the test
|
|
73
|
+
above passes. If routing to rule/hook/luminary, output:
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
TAXONOMY ROUTING:
|
|
77
|
+
Input: <name-or-purpose>
|
|
78
|
+
Decision: <rule | hook | luminary>
|
|
79
|
+
Why: <one-sentence reason>
|
|
80
|
+
Next: <where to go — pointer to rule/hook/luminary creation pattern>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Operator decides whether to proceed with the routed primitive or
|
|
84
|
+
override taxonomy and force a skill.
|
|
85
|
+
|
|
86
|
+
### Step 2 — Generate description
|
|
87
|
+
|
|
88
|
+
If taxonomy = skill, run:
|
|
89
|
+
|
|
90
|
+
1. **Compose with `/value-prop` tweet mode** for the verb-first claim + sharpener (≤280 chars target)
|
|
91
|
+
2. **Compose with `/kiss words` mode** to substitute jargon for plain-language alternatives
|
|
92
|
+
3. **Verify against bassclef#377 rule format**: `<verb> <outcome>. <one-line how>. <one-line why-distinct>.`
|
|
93
|
+
|
|
94
|
+
INSTEAD of reimplementing description generation, this skill DISPATCHES
|
|
95
|
+
to the existing skills. Output is "/value-prop tweet" + "/kiss words"
|
|
96
|
+
applied in sequence.
|
|
97
|
+
|
|
98
|
+
### Step 3 — Scaffold the frame (per ADR-044 unified template)
|
|
99
|
+
|
|
100
|
+
Default frame per ADR-044. This supersedes ADR-040 D4 and the prior /skill scaffold.
|
|
101
|
+
|
|
102
|
+
<!-- FKGL-EXEMPT: ADR-044 spec content — required substrate contract -->
|
|
103
|
+
|
|
104
|
+
**Frontmatter fields:**
|
|
105
|
+
- `name` — use lowercase, numbers, and dashes. Gerund form preferred per Anthropic.
|
|
106
|
+
- `description` — from Step 2. Up to 280 chars. Third person. Both what and when. Pushy trigger.
|
|
107
|
+
- `tier` — one of upstream, lite, standard, or ultra per ADR-043.
|
|
108
|
+
- `maturity` — one of alpha, beta, stable, or hardened per ADR-043. Optional. Defaults to stable.
|
|
109
|
+
- `user_invocable`, `disable_model_invocation` — Anthropic Claude Code convention.
|
|
110
|
+
- `modes` / `tiers` / `sizes` — YAML list when applicable. Mirror inline in description per bassclef#535.
|
|
111
|
+
- `composes_with` — YAML list. Resolves to real skills per substrate-clarity-gate.
|
|
112
|
+
- `depends_on` — YAML list. Advisory in V1.
|
|
113
|
+
|
|
114
|
+
**Body sections in order:**
|
|
115
|
+
|
|
116
|
+
1. `# /skill-name` — H1 with the slash command form.
|
|
117
|
+
2. `## What you get` — outcome opener written in past tense as if shipped.
|
|
118
|
+
3. `## When to use it` — discriminator that names the primary persona per Cooper.
|
|
119
|
+
4. `## When NOT to use` — anti scope. Names sibling skills per Krug.
|
|
120
|
+
5. `## FAQ` — 4 to 6 questions with 2-3 sentence answers.
|
|
121
|
+
6. `## Details below the fold` — runnable protocol. Numbered steps with feedback loops.
|
|
122
|
+
7. `## Examples` — input and output pairs. Required when the skill produces prose or code the reader will ship.
|
|
123
|
+
8. `## Anti-patterns and INSTEAD` — required table. At least 3 rows.
|
|
124
|
+
9. `## Composes with` — bullet list of skills this one runs or extends.
|
|
125
|
+
10. `## Distinct from` — bullet list of adjacent skills. Each entry names the discriminator.
|
|
126
|
+
11. `## Rules` — self check bullets.
|
|
127
|
+
12. `## Test cases` — evaluation prompts. Required when body is over 100 lines OR skill ships to bassclef-lite.
|
|
128
|
+
13. `## Sources read` — evidence trail per bassclef#559.
|
|
129
|
+
14. `## Why this skill exists` — rationale.
|
|
130
|
+
|
|
131
|
+
**Progressive disclosure per Anthropic:**
|
|
132
|
+
- When SKILL.md approaches 500 lines, split detail into `.claude/skills/<slug>/references/<domain>.md`.
|
|
133
|
+
- Reference files must be one level deep from SKILL.md.
|
|
134
|
+
- Reference files longer than 100 lines carry a table of contents at top.
|
|
135
|
+
- Executable scripts live at `.claude/skills/<slug>/scripts/`.
|
|
136
|
+
|
|
137
|
+
**Prose disciplines the scaffold owes (enforced at Step 4):**
|
|
138
|
+
- FKGL grade 8-9 for 80% of prose. Ceiling grade 10 per ADR-040 D4 kept alive by ADR-044.
|
|
139
|
+
- Avoid compound nouns not in the substrate allowlist per `standards/bassclef-internal-jargon.md`.
|
|
140
|
+
- Plain English at grade 8-9 per bassclef#790.
|
|
141
|
+
|
|
142
|
+
<!-- /FKGL-EXEMPT -->
|
|
143
|
+
|
|
144
|
+
The frame is structural. You write the content.
|
|
145
|
+
|
|
146
|
+
### Step 4 — Pre-validate the full clarity chain (ADR-044)
|
|
147
|
+
|
|
148
|
+
Before writing the file, `/skill` runs the draft through the full clarity chain. Three hooks fire in order. Any BLOCK returns the draft to Step 2 for description work or Step 3 for body work.
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
INPUT_JSON=$(jq -n --arg fp "$FILE_PATH" --arg c "$DRAFT_CONTENT" \
|
|
152
|
+
'{tool_name: "Write", tool_input: {file_path: $fp, content: $c}}')
|
|
153
|
+
|
|
154
|
+
# Layer 1 — substrate-clarity-gate (frontmatter + description + INSTEAD blocks)
|
|
155
|
+
printf '%s' "$INPUT_JSON" | bash .claude/hooks/substrate-clarity-gate.sh || exit 2
|
|
156
|
+
|
|
157
|
+
# Layer 2 — skill-body-grade-gate (FKGL grade 8-9 for 80% of prose; ceiling 10)
|
|
158
|
+
printf '%s' "$INPUT_JSON" | bash .claude/hooks/skill-body-grade-gate.sh || exit 2
|
|
159
|
+
|
|
160
|
+
# Layer 3 — compound-noun-scrub (allowlist per standards/bassclef-internal-jargon.md)
|
|
161
|
+
printf '%s' "$INPUT_JSON" | bash .claude/hooks/compound-noun-scrub.sh || exit 2
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Prior /skill Step 4 ran only Layer 1. Layers 2 and 3 fired post-facto at Write time, so drafts often produced a BLOCK the operator saw after the file was ready. ADR-044 wires all three into the workflow so the draft is clean before the Write call.
|
|
165
|
+
|
|
166
|
+
What the chain checks on a SKILL.md.
|
|
167
|
+
|
|
168
|
+
Layer 1 runs `substrate-clarity-gate`:
|
|
169
|
+
|
|
170
|
+
| Check | Tier | Source |
|
|
171
|
+
|---|---|---|
|
|
172
|
+
| Frontmatter required fields (name + description) | BLOCK | bassclef#862 Gap 1 |
|
|
173
|
+
| Frontmatter recognized fields | WARN | bassclef#862 Gap 1 |
|
|
174
|
+
| `composes_with:` names resolve to real skills | BLOCK | bassclef#862 Gap 3 |
|
|
175
|
+
| `depends_on:` names resolve | ADVISORY | bassclef#862 Gap 3 |
|
|
176
|
+
| Description ≤280 chars | BLOCK | bassclef#377 |
|
|
177
|
+
| Description verb-first opener | BLOCK | bassclef#377 |
|
|
178
|
+
| Description in plain English (no bassclef jargon) | BLOCK | bassclef#496 |
|
|
179
|
+
| Body INSTEAD block discipline — every DON'T or NEVER or AVOID paired with INSTEAD within 5 lines | BLOCK | bassclef#371 / bassclef#1249 |
|
|
180
|
+
| ADR-044 required sections present (V1 advisory) | ADVISORY | ADR-044 |
|
|
181
|
+
|
|
182
|
+
Layer 2 runs `skill-body-grade-gate`:
|
|
183
|
+
|
|
184
|
+
| Check | Tier | Source |
|
|
185
|
+
|---|---|---|
|
|
186
|
+
| FKGL grade 8-9 for 80% of prose; ceiling 10 per sentence | BLOCK | ADR-040 D4 kept alive by ADR-044 + bassclef#790 |
|
|
187
|
+
| FKGL-EXEMPT blocks honored for structured spec content | pass-through | ADR-040 D4 |
|
|
188
|
+
|
|
189
|
+
Layer 3 runs `compound-noun-scrub`:
|
|
190
|
+
|
|
191
|
+
| Check | Tier | Source |
|
|
192
|
+
|---|---|---|
|
|
193
|
+
| Hyphenated compounds outside allowlist BLOCK | BLOCK | standards/bassclef-internal-jargon.md + bassclef#382 |
|
|
194
|
+
| Standard tech vocab in allowlist passes | pass-through | allowlist |
|
|
195
|
+
|
|
196
|
+
Three outcomes:
|
|
197
|
+
|
|
198
|
+
- **Hook PASSES (exit 0, no ADVISORY)**: write file (or surface for operator review + commit)
|
|
199
|
+
- **Hook ADVISORY (exit 0, ADVISORY message)**: surface message + ship anyway (operator decides)
|
|
200
|
+
- **Hook BLOCKs (exit 2)**: surface the BLOCK message + iterate (return to Step 2 for description; return to Step 3 + revise body content for INSTEAD-pairing)
|
|
201
|
+
|
|
202
|
+
INSTEAD of operator discovering the violation post-write, the workflow
|
|
203
|
+
catches it before write. The hook is bassclef-internal; bypassing it
|
|
204
|
+
defeats the whole point of the workflow.
|
|
205
|
+
|
|
206
|
+
The body INSTEAD-block check uses the same shape as the rule + luminary
|
|
207
|
+
surfaces (substrate-clarity-gate.sh lines 491-540): every negation
|
|
208
|
+
trigger word requires a literal `INSTEAD:` substitute within 5 lines.
|
|
209
|
+
Allowlist grandfathers 42 existing skills with 60-day grace through
|
|
210
|
+
2026-08-18 per bassclef#1249.
|
|
211
|
+
|
|
212
|
+
### Step 5 — Output for operator review
|
|
213
|
+
|
|
214
|
+
```
|
|
215
|
+
DRAFT skill: <path>
|
|
216
|
+
|
|
217
|
+
<full SKILL.md content>
|
|
218
|
+
|
|
219
|
+
Pre-validation: PASS / ADVISORY / BLOCK
|
|
220
|
+
Action: operator commits OR rejects
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
Workflow does NOT auto-commit. Operator reviews, edits if needed,
|
|
224
|
+
then `git add` + `git commit`.
|
|
225
|
+
|
|
226
|
+
## Args reference
|
|
227
|
+
|
|
228
|
+
| Arg | Mode | Use |
|
|
229
|
+
|-----|------|-----|
|
|
230
|
+
| `<name-or-purpose>` | full (default) | Interactive: taxonomy gate → description → frame → pre-validate |
|
|
231
|
+
| `--taxonomy-only` | taxonomy | Just answers "skill / rule / hook / luminary?" without scaffolding |
|
|
232
|
+
| `--description-only` | description | Just generates the description per bassclef#377; useful for fixing existing skills (operator-owned) |
|
|
233
|
+
| `--full` | full | Same as default; explicit for scripting |
|
|
234
|
+
|
|
235
|
+
Unknown args rejected with a helpful message; the workflow does NOT
|
|
236
|
+
silently proceed with defaults.
|
|
237
|
+
|
|
238
|
+
## Composes with
|
|
239
|
+
|
|
240
|
+
- `/value-prop` (tweet mode) — verb-first ≤280-char claim + sharpener
|
|
241
|
+
- `/kiss` (words mode) — plain-language substitution
|
|
242
|
+
- `.claude/hooks/substrate-clarity-gate.sh` — live pre-validation gate
|
|
243
|
+
- `.claude/rules/skill-description-clarity.md` — per-surface clarity rule
|
|
244
|
+
- `.claude/rules/context-engineering.md` — meta-rule
|
|
245
|
+
|
|
246
|
+
## Distinct from
|
|
247
|
+
|
|
248
|
+
- `/promote` — proposes promoting an APP-level pattern to bassclef (substrate); this workflow creates a NEW substrate skill from scratch
|
|
249
|
+
- `/new-feature` — scaffolds a feature chain (canvas → spec → issue → branch); not a new substrate primitive
|
|
250
|
+
- `/value-prop` — generates a value proposition for a ticket/goal/feature; this workflow USES /value-prop as one input but produces a full SKILL.md
|
|
251
|
+
|
|
252
|
+
## Rules
|
|
253
|
+
|
|
254
|
+
- Workflow NEVER auto-commits. Output is a draft for operator review.
|
|
255
|
+
- Workflow NEVER modifies existing skills. New files only.
|
|
256
|
+
- Workflow NEVER scaffolds rules, hooks, or luminaries — taxonomy gate routes to those primitives but doesn't generate them (separate concerns; deferred to v1).
|
|
257
|
+
- Workflow NEVER auto-generates skill body content (Procedure, examples, etc.). Frame-only output; operator writes substance.
|
|
258
|
+
- Workflow ALWAYS pre-validates against the live `substrate-clarity-gate.sh` hook before writing.
|
|
259
|
+
- Workflow ALWAYS includes `## Sources read` placeholder; operator fills in.
|
|
260
|
+
- Workflow ALWAYS surfaces the taxonomy decision to the operator, even when routing isn't ambiguous.
|
|
261
|
+
|
|
262
|
+
## Sources read
|
|
263
|
+
|
|
264
|
+
- bassclef#390 — the bassclef-evolution issue this skill closes
|
|
265
|
+
- bassclef#382 — substrate-clarity-gate hook (live; pre-validation surface)
|
|
266
|
+
- bassclef#377 — skill-description-clarity rule (per-surface enforcement target)
|
|
267
|
+
- bassclef#371 — context-engineering rule (meta-rule)
|
|
268
|
+
- `.claude/skills/value-prop/SKILL.md` — compose-with for description
|
|
269
|
+
- `.claude/skills/kiss/SKILL.md` — compose-with for plain-language substitution
|
|
270
|
+
- `.claude/hooks/substrate-clarity-gate.sh` — live pre-validation
|
|
271
|
+
- `chronicle/2026-05-01c-substrate-clarity-gate.md` — predecessor (gate ships; this skill closes the loop)
|
|
272
|
+
|
|
273
|
+
## Why this skill exists
|
|
274
|
+
|
|
275
|
+
Three primitives existed before this skill:
|
|
276
|
+
|
|
277
|
+
1. bassclef#371 (context-engineering rule) — meta-discipline
|
|
278
|
+
2. bassclef#377 (skill-description-clarity rule) — per-surface rule
|
|
279
|
+
3. bassclef#382 (substrate-clarity-gate hook) — mechanical enforcement
|
|
280
|
+
|
|
281
|
+
All three react to violations. None of them produces conforming output
|
|
282
|
+
from the start. Operators (and agents) wrote new skills by copying
|
|
283
|
+
existing skills, which copied whatever shape the source had —
|
|
284
|
+
verbose, jargon-laden, unclear scope, missing INSTEAD discipline.
|
|
285
|
+
|
|
286
|
+
Even with rules loaded into every conversation, agents rationalized
|
|
287
|
+
"this is what existing skills look like" and shipped non-conforming
|
|
288
|
+
output. The audit at bassclef#382 closeout revealed 36 of 61 existing
|
|
289
|
+
skills (59%) violate length or verb-first checks.
|
|
290
|
+
|
|
291
|
+
Methodology + mechanism + workflow is the SENTINEL_bassclef_pattern made
|
|
292
|
+
complete. The workflow is the positive-direction primitive — the
|
|
293
|
+
shaper of new skills, with the rules loaded into its own context and
|
|
294
|
+
the hook as its pre-validation surface. Engineers + operators now
|
|
295
|
+
have a single dispatch (`/skill <name>`) to produce conforming
|
|
296
|
+
output, not a manual copy-and-edit loop.
|
|
297
|
+
|
|
298
|
+
INSTEAD of "copy an existing SKILL.md and hope," dispatch `/skill`
|
|
299
|
+
and let the workflow do the shaping work. Output is conforming by
|
|
300
|
+
construction.
|
|
301
|
+
|
|
302
|
+
## Output discipline
|
|
303
|
+
|
|
304
|
+
Dispatch `/kiss words --rewrite` on your skill output before you return it. See `standards/skill-output-discipline.md` for the contract.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
---
|
|
2
|
+
tier: lite
|
|
3
|
+
name: smoke-test
|
|
4
|
+
description: "Smoke test for deployed apps \u2014 health, auth redirect, critical API paths. Pass/fail gate, not a persona journey. Renamed from /test-e2e on 2026-04-15 to disambiguate from /synthetic-user."
|
|
5
|
+
problem: "Deploys ship without a post-release check. Broken auth or a 500 on a critical path lands in prod."
|
|
6
|
+
value: "Smoke test for deployed apps \u2014 health then auth redirect then critical API paths."
|
|
7
|
+
inputs: [App URL or subdomain]
|
|
8
|
+
outputs: [Pass/fail per check, Gate signal, Log per failing check]
|
|
9
|
+
user_invocable: true
|
|
10
|
+
disable_model_invocation: false
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# End-to-End Smoke Test
|
|
14
|
+
|
|
15
|
+
Two-layer verification: automated tests first, then manual checks for what
|
|
16
|
+
automation can't cover (visual rendering, interactive flows, auth completion).
|
|
17
|
+
|
|
18
|
+
## Procedure
|
|
19
|
+
|
|
20
|
+
### Step 0: Automated Smoke Tests (ALWAYS run first)
|
|
21
|
+
|
|
22
|
+
Run the project's E2E test suite against local or production:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# Against local dev server (must be running)
|
|
26
|
+
npx vitest run src/__tests__/e2e-smoke.test.ts
|
|
27
|
+
|
|
28
|
+
# Against production (set base URL)
|
|
29
|
+
E2E_BASE_URL=<production-url> npx vitest run src/__tests__/e2e-smoke.test.ts
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
If any fail → run `/diagnose` before proceeding to manual checks.
|
|
33
|
+
|
|
34
|
+
### Step 1: Health Check
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
curl -s <app-url>/api/health | python3 -m json.tool
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Expected: healthy status with all dependency checks passing.
|
|
41
|
+
|
|
42
|
+
### Step 2: Auth Flow (requires browser)
|
|
43
|
+
|
|
44
|
+
- Unauthenticated request → redirects to sign-in
|
|
45
|
+
- Sign-in page renders correctly
|
|
46
|
+
- After sign-in → redirects to main page (not stuck on spinner)
|
|
47
|
+
- User identity visible (name, role)
|
|
48
|
+
- Sign out → returns to sign-in
|
|
49
|
+
- Re-sign-in works without errors
|
|
50
|
+
|
|
51
|
+
### Step 3: Core Pages (requires auth)
|
|
52
|
+
|
|
53
|
+
For each user-facing page:
|
|
54
|
+
- Page loads without console errors
|
|
55
|
+
- Data renders (not empty state when data exists)
|
|
56
|
+
- Interactive elements respond (filters, pagination, navigation)
|
|
57
|
+
- Click-through paths work (list → detail → back)
|
|
58
|
+
|
|
59
|
+
### Step 4: API Routes
|
|
60
|
+
|
|
61
|
+
For each API endpoint:
|
|
62
|
+
- Protected routes require auth (401/403 without session)
|
|
63
|
+
- Response shape matches expected contract
|
|
64
|
+
- Pagination works if applicable
|
|
65
|
+
|
|
66
|
+
### Step 5: Data Pipeline Verification
|
|
67
|
+
|
|
68
|
+
Verify the backend pipeline is producing current data:
|
|
69
|
+
- Check record counts by source/type
|
|
70
|
+
- Check recent job runs and their status
|
|
71
|
+
- Verify no stuck or failed jobs
|
|
72
|
+
|
|
73
|
+
## Pass Criteria
|
|
74
|
+
|
|
75
|
+
- Step 0 (automated): all tests pass
|
|
76
|
+
- Steps 1-5 (manual): all checks pass
|
|
77
|
+
|
|
78
|
+
Any failure → run `/diagnose` before fixing.
|
|
79
|
+
|
|
80
|
+
## Maintenance
|
|
81
|
+
|
|
82
|
+
When adding a new page or API route, update the E2E smoke test file:
|
|
83
|
+
- New page → add auth redirect test
|
|
84
|
+
- New API route → add auth gate test + response shape test
|
|
85
|
+
- New public route → add 200 status test
|
|
86
|
+
|
|
87
|
+
The pre-build hook reminds you; the pre-commit hook warns if you forget.
|
|
88
|
+
|
|
89
|
+
## App-Specific Override
|
|
90
|
+
|
|
91
|
+
If your project has a `.claude/skills/smoke-test.md` (or `test-e2e/SKILL.md`),
|
|
92
|
+
it should extend this template with:
|
|
93
|
+
- Specific URLs (production, staging, local)
|
|
94
|
+
- Specific pages and their expected content
|
|
95
|
+
- Specific API endpoints and response shapes
|
|
96
|
+
- Specific pipeline verification commands (SSH, DB queries)
|
|
97
|
+
|
|
98
|
+
## Output discipline
|
|
99
|
+
|
|
100
|
+
Dispatch `/kiss words --rewrite` on your skill output before you return it. See `standards/skill-output-discipline.md` for the contract.
|