From 5029e8484e385482e5dc0fc4c5c9c9ce7b22e28f Mon Sep 17 00:00:00 2001 From: Dan Draper Date: Thu, 9 Jul 2026 16:24:22 +1000 Subject: [PATCH 1/2] docs: add CLAUDE.md and require skills to be checked on every stack change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two gaps, one fix. **Claude Code was reading no project instructions in this repo.** It loads `CLAUDE.md`, not `AGENTS.md` (https://code.claude.com/docs/en/memory#agentsmd), and this repo only had the latter. Add a `CLAUDE.md` that imports `@AGENTS.md` so both Claude Code and Codex read one source of truth, rather than duplicating the rules or relying on a symlink (which needs Developer Mode on Windows). **Skills drift silently.** `skills/*/SKILL.md` ship inside the `stash` tarball (`packages/cli/tsup.config.ts` copies them into `dist/skills/`), get copied into the user's `.claude/skills/` or `.codex/skills/` by `installSkills()`, and are inlined into their `AGENTS.md` by `readBundledSkill()`. Nothing type-checks them, so a stale sentence lands in a customer's repo. The stash-cli skill had drifted a whole command surface behind before anyone noticed. - New `## Agent Skills — these ship to customers` section in `AGENTS.md`: how skills reach users, why each `SKILL.md` must stay self-sufficient (only `SKILL.md` is inlined for the agents-md target), a package-to-skill map, and the mechanical check for CLI changes -- diff the skill against `stash manifest --json` rather than proofreading it. - New checklist item 8 in "Adding Features Safely", so the rule is hit at PR time and not only by whoever reads the section. - Note in the changeset item that a skills-only change is not internal: it ships, so it needs a `stash` patch. --- AGENTS.md | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++- CLAUDE.md | 27 +++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 CLAUDE.md diff --git a/AGENTS.md b/AGENTS.md index 5a664f562..a6de03376 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -93,6 +93,46 @@ If these variables are missing, tests that require live encryption will fail or - `docs/plans/*`: Internal design plans. User-facing documentation lives at https://cipherstash.com/docs (not in this repo). - `skills/*`: Agent skills (`stash-cli`, `stash-encryption`, `stash-drizzle`, `stash-dynamodb`, `stash-secrets`, `stash-supabase`, `stash-supply-chain-security`) +## Agent Skills — these ship to customers + +`skills/*/SKILL.md` are **published artifacts, not internal notes.** Treat a wrong +sentence in one of them the way you'd treat a wrong line of code: + +- `packages/cli/tsup.config.ts` copies `skills/` into `dist/skills/`, so they ship + inside the `stash` npm tarball (and the `@cipherstash/wizard` one). +- `installSkills()` (`packages/cli/src/commands/init/lib/install-skills.ts`) copies the + per-integration set into the user's `.claude/skills/` or `.codex/skills/` at handoff time. +- `readBundledSkill()` inlines a skill's body into the user's `AGENTS.md` for editor + agents (Cursor / Windsurf / Cline). Only `SKILL.md` is inlined — content split into + sibling files is silently dropped on that path, so keep each `SKILL.md` self-sufficient. + +**Every change to a package's public API, the CLI command surface, or a user-facing +workflow must check the affected skills in the same PR.** These skills drift silently: +nothing type-checks them, and the damage lands in a customer's repo, not ours. + +| If you change… | Check | +|---|---| +| `packages/cli` commands, flags, or prompts | `skills/stash-cli` | +| `packages/stack` encryption API, schema builders, subpath exports | `skills/stash-encryption` | +| Drizzle / Supabase / DynamoDB integrations | `skills/stash-drizzle`, `skills/stash-supabase`, `skills/stash-dynamodb` | +| The rollout/cutover lifecycle (`packages/migrate`, `stash encrypt *`) | `skills/stash-encryption` and `skills/stash-cli` | +| pnpm config, CI workflows, dependency policy | `skills/stash-supply-chain-security` | +| The durable agent rules themselves | `packages/cli/src/commands/init/doctrine/AGENTS-doctrine.md` | + +For CLI changes there is a mechanical check — the command registry is the source of +truth, so diff the skill against it rather than proofreading: + +```bash +pnpm --filter stash build +node packages/cli/dist/bin/stash.js manifest --json +``` + +Every command and flag named in `skills/stash-cli/SKILL.md` must resolve against that +manifest (the deprecated `db install` / `db upgrade` / `db status` aliases excepted — +they're intentionally absent from the registry). + +Skills must not contain Linear issue IDs; they're public. GitHub issue numbers are fine. + ## Supply Chain Security This repo applies a set of supply-chain controls (post-install script policy, install cooldown, frozen-lockfile CI, registry pinning, Dependabot cooldown, CODEOWNERS) sourced from [lirantal/npm-security-best-practices](https://github.com/lirantal/npm-security-best-practices). They're validated by `e2e/tests/supply-chain.e2e.test.ts` so silent regressions fail CI. See `skills/stash-supply-chain-security/SKILL.md` for the full guide. @@ -185,7 +225,15 @@ pnpm changeset:publish Layout in this file and the package list in `SECURITY.md` in the same PR. These files have drifted badly before; don't let them. -8. **Add a changeset before opening or finalising the PR** when the +8. **Check the skills.** If you changed a package's public API, the CLI + command surface, or a user-facing workflow, open the affected + `skills/*/SKILL.md` and fix anything your change made wrong — in the + same PR. Skills ship inside the `stash` tarball and are copied into + customer repos, so drift here becomes wrong guidance in someone + else's codebase. See "Agent Skills — these ship to customers" above + for the package→skill map and the `stash manifest --json` check. + +9. **Add a changeset before opening or finalising the PR** when the change affects a published package's public behaviour or surface (new feature, bug fix, breaking change, UX-visible tweak). Run `pnpm changeset` (interactive) or hand-write a markdown file under @@ -207,6 +255,9 @@ pnpm changeset:publish `CHANGELOG.md` entries, so a missing changeset means the change ships invisibly. + A skills-only change is **not** internal: `skills/` ships inside the + `stash` tarball, so it needs a `stash` patch changeset. + ## Useful Links - `README.md` for quickstart and feature overview diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 000000000..760055896 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,27 @@ +# CipherStash Stack — Claude Code + +The project instructions for this repo live in `AGENTS.md`, shared by every agent +that works here. It is imported below rather than duplicated, so there is exactly +one source of truth. + +@AGENTS.md + +## Before you finish + +Two rules from `AGENTS.md` are the ones most often missed. They are repeated here +because both fail silently — nothing in CI catches either: + +1. **Check the skills.** If you changed a package's public API, the CLI command + surface, or a user-facing workflow, update the affected `skills/*/SKILL.md` in + the same PR. These files ship inside the `stash` npm tarball and get copied + into customer repos, so drift becomes wrong guidance in someone else's + codebase. See "Agent Skills — these ship to customers". + +2. **Add a changeset** when the change affects a published package's surface — + including a skills-only change, since `skills/` ships in the `stash` tarball. + +## Package-specific notes + +`packages/cli` has its own `AGENTS.md` covering the two Vitest configs (unit vs. +the pty-driven e2e suite) and when each needs to run. Read it before touching +`packages/cli/src/bin/main.ts`, `src/messages.ts`, or the command registry. From a36add6fb695ecc001525a46ee9f96ebb4ee8e5f Mon Sep 17 00:00:00 2001 From: Dan Draper Date: Thu, 9 Jul 2026 17:08:26 +1000 Subject: [PATCH 2/2] docs: fully qualify the CLI paths in CLAUDE.md Addresses review on #596. `src/messages.ts` is ambiguous from the repo root -- there is no root `src/` -- so spell it `packages/cli/src/messages.ts`, matching the fully-qualified path next to it. Same for "the command registry", now named as `packages/cli/src/cli/registry.ts`. Swept every backticked path in CLAUDE.md and in the new AGENTS.md section; all resolve. --- CLAUDE.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index 760055896..8e02cb0a2 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -24,4 +24,5 @@ because both fail silently — nothing in CI catches either: `packages/cli` has its own `AGENTS.md` covering the two Vitest configs (unit vs. the pty-driven e2e suite) and when each needs to run. Read it before touching -`packages/cli/src/bin/main.ts`, `src/messages.ts`, or the command registry. +`packages/cli/src/bin/main.ts`, `packages/cli/src/messages.ts`, or the command +registry at `packages/cli/src/cli/registry.ts`.