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

5.3 KiB

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/