Files
suaveplan/openspec/archive/2026-05-03-restore-crypto-cli-and-allowlist/tasks.md
2026-05-27 23:29:53 +01:00

85 lines
5.3 KiB
Markdown

# Tasks — restore-crypto-cli-and-allowlist
## 1. `@suaveplan/crypto-cli` scaffold
- [ ] 1.1 Create `packages/crypto/crypto-cli/` from package template (`package.json`, `tsconfig.lib.json`, `vite.config.ts`, `vitest.config.ts`, `README.md`, `src/index.ts`)
- [ ] 1.2 `package.json` `bin` entry → `dist/keychain.js`
- [ ] 1.3 Deps: `@suaveplan/cli`, `@suaveplan/readline`, `@suaveplan/crypto`, `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/i18n`, `@suaveplan/opentelemetry`
## 2. Subcommands
- [ ] 2.1 `keychain root init` — generate root identity, write encrypted vault, emit public bundle
- [ ] 2.2 `keychain server init` — generate server identity under a root, emit signed public bundle, append audit log
- [ ] 2.3 `keychain server roll` — version-bump rotation; appends CRL + audit; `--idempotency-key`
- [ ] 2.4 `keychain server revoke` — appends CRL + audit; no re-issue; `--idempotency-key`
- [ ] 2.5 `keychain inspect` — view a packed public keychain (verifies self-signature)
- [ ] 2.6 `keychain verify` — verify any signed envelope against a trust anchor + CRL
- [ ] 2.7 `keychain export-public` — strip secrets, output portable public bundle
- [ ] 2.8 `keychain restore` — re-derive a vault from BIP39 mnemonic + version
## 3. Cross-cutting CLI behaviour
- [ ] 3.1 TTY-only password input via `cli`'s `password` prompt; `--password` flag rejected
- [ ] 3.2 Stdin/stdout streamable; `--output json|binary|text`
- [ ] 3.3 Distinct exit codes: 0/2/10/11/12/13/14/15
- [ ] 3.4 `--idempotency-key` on `server roll` and `server revoke`; local-file ledger
- [ ] 3.5 OTel spans + structured logger output for every command
- [ ] 3.6 Co-located `.md` per command (≥ 200 words)
## 4. CLI tests
- [ ] 4.1 Per-command happy-path test
- [ ] 4.2 Per-command failure-mode tests (bad password, tampered vault, expired key, revoked key, missing trust anchor)
- [ ] 4.3 `tests/exit-codes.test.ts` — every documented exit code reachable
- [ ] 4.4 `tests/no-password-flag.test.ts` — `--password` rejected with security pointer
- [ ] 4.5 `tests/tty-mock.test.ts` — TTY prompt UX without a real TTY (driven via `cli`'s `InputReader`)
- [ ] 4.6 `tests/round-trip-end-to-end.test.ts` — `root init` → `inspect` → `verify` → `export-public` byte-equal
## 5. `@suaveplan/slsa` migration
- [ ] 5.1 Snapshot pre-migration DSSE fixtures (round-trip equality target)
- [ ] 5.2 Replace direct `crypto.ed25519.sign(secretKey, …)` with `Authority.sign(DOMAIN_SLSA_BUILDER_V1, …)`
- [ ] 5.3 Builder identity constructed from a `ServerIdentity` issued under a SLSA-builder root
- [ ] 5.4 `package.json`: add `@suaveplan/crypto`; remove `@suaveplan/crypto` (now `crypto-core`) for signing; retain `crypto-hash` + `crypto-utils`
- [ ] 5.5 New test `tests/no-direct-crypto-core.test.ts` — pins import discipline (no signing-related imports of `@suaveplan/crypto-core` etc.)
- [ ] 5.6 Round-trip equality test against pre-migration DSSE fixtures
## 6. Import-allowlist conformance gate
- [ ] 6.1 Create `scripts/conformance/crypto-core-allowlist.yml` with two entries: `@suaveplan/crypto`, `@suaveplan/crypto-cli`
- [ ] 6.2 Extend `scripts/openspec-conformance.ts` to scan every workspace package's `src/` for forbidden primitive imports; fail with `error` severity for non-allowlisted packages
- [ ] 6.3 Test `scripts/conformance/crypto-core-allowlist.test.ts` — positive (allowed) + negative (forbidden) fixture packages
- [ ] 6.4 Audit the 5 current consumers (`crypto-sodium`, `crypto-browser`, `slsa`, `bitpacker-crypto`, `drive-plugin-chunks`, `packer`): for each, decide migrate or allowlist with rationale; document the decision in `scripts/conformance/crypto-core-allowlist.yml` comments
## 7. Verification gates (per package touched)
For each of `@suaveplan/crypto-cli`, `@suaveplan/slsa`:
- [ ] 7.1 `bun run check` — Biome 0/0/0
- [ ] 7.2 `bunx turbo lint typecheck test --filter=@suaveplan/<pkg>` green
- [ ] 7.3 `bunx turbo test:coverage --filter=@suaveplan/<pkg>` 100/100/100/100
- [ ] 7.4 `bun scripts/openspec-conformance.ts @suaveplan/<pkg>` exit 0, no `error` findings
- [ ] 7.5 `bunx turbo build --filter=@suaveplan/<pkg>` green
## 8. Pre-archive 7-row checklist (AGENTS.md Section 13)
- [ ] 8.1 Generics threaded; `expectTypeOf` assertions on every literal-type claim
- [ ] 8.2 Zod schemas wired at every CLI command boundary
- [ ] 8.3 Every error code thrown by ≥ 1 production path
- [ ] 8.4 Strict-mode behaviours tested both on and off (allowlist gate strict mode)
- [ ] 8.5 OTel instruments emitted from production paths and asserted with a real `MeterProvider`
- [ ] 8.6 Lifecycle dedup tested (`--idempotency-key` ledger)
- [ ] 8.7 No retroactive tick
## 9. Manifest + docs
- [ ] 9.1 `CLAUDE.md`: add `crypto-cli` package entry
- [ ] 9.2 `bun scripts/folder-reorg/generate-manifest.ts` to refresh `MANIFEST.md`
- [ ] 9.3 Root `README.md`: brief mention of the `keychain` CLI
## 10. Archive
- [ ] 10.1 Fold spec deltas into `openspec/specs/crypto-cli/spec.md`, `openspec/specs/slsa/spec.md`, `openspec/specs/crypto-core/spec.md` (allowlist requirement)
- [ ] 10.2 Move the umbrella `openspec/changes/restore-crypto-keychain-packer/` → `openspec/archive/<yyyy-mm-dd>-restore-crypto-keychain-packer/` (umbrella is now fully resolved by the four child slices)
- [ ] 10.3 Move `openspec/changes/restore-crypto-cli-and-allowlist/` → `openspec/archive/<yyyy-mm-dd>-restore-crypto-cli-and-allowlist/`