# Tasks — Extract shared crypto interfaces > Every checkbox MUST reflect work actually done in this change. No > retroactive ticking. Implementation is gated on user sign-off of the > API shape (§1.5). ## 1. Spec authoring & sign-off - [x] 1.1 Author `proposal.md` with audit-revised consumer list and parity checklist - [x] 1.2 Author this `tasks.md` - [x] 1.3 Author `specs/types/spec.md` with one Requirement per added type - [x] 1.4 Author `specs/bitpacker-crypto/spec.md` with the MODIFIED requirements (DI options) - [ ] 1.5 **GATE — user sign-off on the API shape** before any further implementation work - [ ] 1.6 `openspec change validate extract-shared-crypto-interfaces --strict` exits clean ## 2. `@suaveplan/types` — add Authority/DomainTag/AeadOps interfaces - [ ] 2.1 Author `packages/core/types/src/domain-tag.ts` — branded `DomainTag` type + sibling `domain-tag.md` (≥200 words, basic + advanced examples) - [ ] 2.2 Author `packages/core/types/src/authority.ts` — `Authority`, `KeySlotPublic`, `KeySlotPrivate`, `SlotId`, `AuthorityVerifier` + sibling `authority.md` - [ ] 2.3 Author `packages/core/types/src/aead-ops.ts` — `AeadAlgorithm`, `AeadOpsOptions`, `AeadOps` + sibling `aead-ops.md` - [ ] 2.4 Wire all three into `packages/core/types/src/index.ts` (alphabetical insertion) - [ ] 2.5 Run `bunx turbo lint typecheck test --filter=@suaveplan/types` — verify green and zero-runtime byte-budget guard still passes (no `.js` file > 200 bytes) ## 3. `@suaveplan/crypto` — re-export types from `@suaveplan/types` - [ ] 3.1 Edit `packages/crypto/crypto/src/domain-tags/domain-tags.ts`: drop the local `DomainTag` declaration; re-export from `@suaveplan/types`. Keep all `DOMAIN_*` runtime constants and the `encodeDomainTag` / `buildSigningInput` / `isDomainTag` helpers. - [ ] 3.2 Edit `packages/crypto/crypto/src/authority/authority.ts`: drop the local `Authority`, `KeySlotPublic`, `SlotId` declarations; re-export from `@suaveplan/types`. Keep `InMemoryAuthority`, `inMemoryAuthority`, and `verifyAuthoritySignature` runtime helpers. Cast `slotId` to `PurposeTag` at the indexing site (one-line cast — type contract unchanged at the public surface). - [ ] 3.3 `packages/crypto/crypto/src/authority/index.ts` re-exports the canonical types from `@suaveplan/types` so `@suaveplan/crypto/authority` subpath continues to expose `Authority` / `KeySlotPublic` / `SlotId`. - [ ] 3.4 Run `bunx turbo lint typecheck test --filter=@suaveplan/crypto` — 265/265 tests stay green - [ ] 3.5 Verify no API regression: `grep -rE "import.*Authority.*from.*@suaveplan/crypto" /home/ubuntu/web/genesis/packages/` finds the same call-sites compiling unchanged ## 4. `@suaveplan/bitpacker-crypto` — drop crypto runtime dep, accept verifier+aead via DI - [ ] 4.1 Edit `packages/bitpacker/bitpacker-crypto/package.json`: move `@suaveplan/crypto` from `dependencies` to `devDependencies`. Update package description. - [ ] 4.2 Edit `vite.config.ts` externals: drop `"@suaveplan/crypto"` and `/^@suaveplan\/crypto\//` entries - [ ] 4.3 Refactor `src/signed/signed-bitschema.ts`: - Import `Authority`, `AuthorityVerifier`, `DomainTag`, `KeySlotPublic`, `SlotId` from `@suaveplan/types` - Add required `verifier: AuthorityVerifier` to `SignedBitSchemaOptions` - Add `verifier` to Zod options schema - Replace `verifyAuthoritySignature(...)` calls with `verifier(...)` - [ ] 4.4 Refactor `src/multisigned/multisigned-bitschema.ts` — same shape - [ ] 4.5 Refactor `src/hashchain/hashchain-schema.ts` — same shape - [ ] 4.6 Refactor `src/encrypted/encrypted-bitschema.ts`: - Import `AeadAlgorithm`, `AeadOps`, `Rng` from `@suaveplan/types` - Move `AEAD_KEY_LENGTH`, `AEAD_NONCE_LENGTH`, `AEAD_XCHACHA_NONCE_LENGTH` constant declarations into this file (drop the `@suaveplan/crypto` import) - Add required `aead: AeadOps` to `EncryptedBitSchemaOptions` - Add `aead` to Zod options schema - Replace `aeadEncrypt(...)` / `aeadDecrypt(...)` with `aead.encrypt(...)` / `aead.decrypt(...)` - [ ] 4.7 Author `tests/helpers/crypto-deps.ts`: exports `cryptoVerifier: AuthorityVerifier` (= `verifyAuthoritySignature`) and `cryptoAead: AeadOps` (= `{ encrypt: aeadEncrypt, decrypt: aeadDecrypt }`). Single test-side import point for `@suaveplan/crypto` runtime functions. - [ ] 4.8 Update `tests/helpers/fake-authority.ts`: types from `@suaveplan/types`; runtime helpers (`buildSigningInput`, `ed25519`) continue from `@suaveplan/crypto` - [ ] 4.9 Update every `*.test.ts` and `*.spec-conformance.test.ts` that constructs a primitive: import `cryptoVerifier` / `cryptoAead` from `tests/helpers/crypto-deps.ts` and pass into the options bundle - `src/signed/signed-bitschema.test.ts` (16 sites) - `src/signed/signed-bitschema.spec-conformance.test.ts` (4 sites) - `src/multisigned/multisigned-bitschema.test.ts` (11 sites) - `src/hashchain/hashchain-schema.test.ts` (13 sites) - `src/encrypted/encrypted-bitschema.test.ts` (17 sites) - `src/encrypted/encrypted-bitschema.spec-conformance.test.ts` (5 sites) - `src/composition.test.ts` (6 sites) - `src/coverage.test.ts` (17 sites) - [ ] 4.10 Update sibling `.md` docs to reflect new DI options: - `src/signed/signed-bitschema.md` — `verifier` shown in basic + advanced examples - `src/multisigned/multisigned-bitschema.md` — `verifier` shown - `src/hashchain/hashchain-schema.md` — `verifier` shown - `src/encrypted/encrypted-bitschema.md` — `aead` shown; AEAD constants documented as locally-declared - Root `README.md` quick-start examples updated ## 5. Verification — 5-gate - [ ] 5.1 `bun run check` — Biome 0/0/0 across the monorepo - [ ] 5.2 `bunx turbo lint typecheck test --filter=@suaveplan/types` — green; zero-runtime byte-budget guard satisfied - [ ] 5.3 `bunx turbo lint typecheck test --filter=@suaveplan/crypto` — 265/265 stays green - [ ] 5.4 `bunx turbo lint typecheck test --filter=@suaveplan/bitpacker-crypto` — green - [ ] 5.5 `bunx turbo test:coverage --filter=@suaveplan/bitpacker-crypto` — 100/100/100/100 - [ ] 5.6 `bunx turbo build --filter=...@suaveplan/bitpacker-crypto` — every dependent compiles green - [ ] 5.7 `bun scripts/folder-reorg/generate-manifest.ts` — dep graph stays acyclic; manifest regenerates clean - [ ] 5.8 Grep guard: `! grep -rE 'from "@suaveplan/crypto"|from "@suaveplan/crypto/' packages/bitpacker/bitpacker-crypto/src/ --include="*.ts" | grep -v "\.test\.ts"` — zero matches in production source ## 6. Pre-archive 7-row checklist (AGENTS.md §13) - [ ] 6.1 Generics threaded — `Authority`, `KeySlotPublic`, `AuthorityVerifier`, `AeadOps` all stay generic-friendly through the refactor - [ ] 6.2 Zod schemas wired at every declared boundary — 4 primitive options bundles updated to validate the new `verifier`/`aead` field - [ ] 6.3 Every error code touched in this change is still thrown by ≥1 production code path - [ ] 6.4 Strict-mode behaviors tested both on and off where applicable (DI rejection on missing `verifier` covered by Zod boundary) - [ ] 6.5 OTel spans emitted from production paths; asserted with the existing in-process recording tracer - [ ] 6.6 Lifecycle dedup tested where claimed - [ ] 6.7 No retroactive tick — every box reflects work done in this change ## 7. Archive - [ ] 7.1 Fold `specs/types/spec.md` into `openspec/specs/types/spec.md` - [ ] 7.2 Fold `specs/bitpacker-crypto/spec.md` into `openspec/specs/bitpacker-crypto/spec.md` - [ ] 7.3 Move `openspec/changes/extract-shared-crypto-interfaces/` → `openspec/archive/-extract-shared-crypto-interfaces/` - [ ] 7.4 STATUS.md update: refactor landed; cycle eliminated; `chain-bundle-adopt-envelope-schema` and `public-bundle-adopt-envelope-schema` follow-ups unblocked - [ ] 7.5 Update `CLAUDE.md` package listing for `@suaveplan/types` (note new shared crypto interfaces) and `@suaveplan/bitpacker-crypto` (note required DI options) ## 8. Follow-up changes (queue, not done in this change) - [ ] 8.1 `chain-bundle-adopt-envelope-schema` — migrate `crypto::ChainBundle` to use `EnvelopeSchema` (now unblocked); wire format byte-identical pinned by snapshot test - [ ] 8.2 `public-bundle-adopt-envelope-schema` — migrate `crypto::PublicBundle` to use `EnvelopeSchema` + `SignedBitSchema` (now unblocked)