# Tasks — Bitpacker crypto rewrite (slim) > Slimmed 2026-05-02 after `restore-crypto-keychain-packer` discovery. > Two primitives only: `schemaFingerprint` + `HashAlgorithmRegistry`. > Every checkbox MUST reflect work actually done in this change. ## 1. Spec sign-off & validation - [x] 1.1 Slim proposal authored (this version) - [x] 1.2 Slim spec delta authored (`specs/bitpacker-crypto/spec.md`) - [x] 1.3 Slim tasks authored (this file) - [x] 1.4 `openspec change validate bitpacker-crypto-rewrite --strict` exits clean - [x] 1.5 User sign-off on the slim API shape ## 2. Decision-history maintenance - [x] 2.1 Update `packages/bitpacker/bitpacker-crypto/SUPERSEDED.md` "What we built instead" table to show only `SchemaFingerprint` + `HashAlgorithmRegistry`. Drop the five primitives that moved to `restore-crypto-keychain-packer`. Add a "What lives in `@suaveplan/crypto` instead" cross-reference. - [x] 2.2 Update `bitpacker-modular-restructure/proposal.md` parity-table notes (5 crypto rows) — point at `restore-crypto-keychain-packer` for `Packer` / `Authority` / `AuditLog` / `RevocationList`; mention the slim auxiliary primitives in `bitpacker-crypto-rewrite`. - [x] 2.3 Update `bitpacker-modular-restructure/tasks.md` §14.6 — point at both changes (`restore-crypto-keychain-packer` for the main consolidation, `bitpacker-crypto-rewrite` for the auxiliary primitives). ## 3. Package metadata - [x] 3.1 Update `packages/bitpacker/bitpacker-crypto/package.json` `dependencies`: add `@suaveplan/types`, `@suaveplan/error`, `@opentelemetry/api`, `zod`. (No `@suaveplan/crypto` dep — slim rewrite is independent of crypto layer.) - [x] 3.2 Run `bun install`; verify lockfile updates clean. - [x] 3.3 Run `bun scripts/folder-reorg/generate-manifest.ts`; verify manifest is acyclic. ## 4. Error codes - [x] 4.1 Add to `packages/bitpacker/bitpacker/src/error-codes.ts`: `CRYPTO_HASH_ALGORITHM_UNKNOWN`, `CRYPTO_SCHEMA_FINGERPRINT_MISMATCH`. - [x] 4.2 Each new code must be thrown by ≥ 1 production code path in this change. ## 5. `HashAlgorithmRegistry` — pluggable extension point - [x] 5.1 Author `packages/bitpacker/bitpacker-crypto/src/hash-registry/hash-registry.ts`. - [x] 5.2 Public types: `HashAlgorithm` (`name`, `outputBytes`, `hash(data)`), `HashAlgorithmRegistry` (`register`, `resolve`, `has`, `list`). - [x] 5.3 Default impls for `xxhash32`, `crc32`, `sha256` (re-using existing `bitpacker-crypto` checksums; `sha256` via the existing `@noble/hashes` impl OR via Web Crypto API — pick the env-portable path). - [x] 5.4 `defaultHashRegistry()` returns a process-wide singleton; `createHashRegistry()` returns a fresh registry seeded with the same defaults. - [x] 5.5 Re-register replaces with last-write-wins; emit OTel span `bitpacker-crypto.hash-registry.replaced` with the prior algorithm's `outputBytes` as an attribute. - [x] 5.6 Sibling `hash-registry.md` ≥ 200 words. ## 6. `schemaFingerprint` + `assertSchemaFingerprint` - [x] 6.1 Author `packages/bitpacker/bitpacker-crypto/src/fingerprint/schema-fingerprint.ts`. - [x] 6.2 Canonicalize: sort object keys, no whitespace, deterministic encoding for `BitPackerSchema` shapes (`object`, `array`, primitives, `_optional`, `_oneOf`, `_conditional`, `_version`, `_ref`, etc.). - [x] 6.3 Default algorithm `"sha256"`; resolve via `HashAlgorithmRegistry`. - [x] 6.4 `assertSchemaFingerprint` throws `BitpackerError` code `CRYPTO_SCHEMA_FINGERPRINT_MISMATCH` on disagreement; unknown algorithm throws `CRYPTO_HASH_ALGORITHM_UNKNOWN`. - [x] 6.5 OTel span `bitpacker-crypto.fingerprint`. - [x] 6.6 Sibling `schema-fingerprint.md` ≥ 200 words. ## 7. Tests - [x] 7.1 `hash-registry/hash-registry.test.ts` — defaults present, register replaces with last-write-wins, list returns registered names. - [x] 7.2 `hash-registry/hash-registry.spec-conformance.test.ts` — `createHashRegistry` isolates from singleton, replacement emits OTel `bitpacker-crypto.hash-registry.replaced` span (asserted via real in-memory `MeterProvider`). - [x] 7.3 `fingerprint/schema-fingerprint.test.ts` — equal schemas in different declaration orders fingerprint identically; different schemas fingerprint differently; `assertSchemaFingerprint` throws on mismatch. - [x] 7.4 `fingerprint/schema-fingerprint.spec-conformance.test.ts` — unknown algorithm throws coded error; BLAKE3 plug-in works after registration; no `Math.random`/`Date.now` in implementation files. - [x] 7.5 Existing `superseded.test.ts` re-runs green (the upstream provider symbols are still absent under the rewrite). - [x] 7.6 Every `it(...)` carries `{ timeout: 5000 }`. ## 8. Pre-archive verification (5-gate) - [x] 8.1 `bun run check` — Biome 0/0/0 across the monorepo. - [x] 8.2 `bunx turbo lint typecheck test --filter=@suaveplan/bitpacker-crypto` — green. - [x] 8.3 `bunx turbo test:coverage --filter=@suaveplan/bitpacker-crypto` — 100/100/100/100. - [x] 8.4 `bun scripts/openspec-conformance.ts @suaveplan/bitpacker-crypto` — exit 0. - [x] 8.5 `bunx turbo build --filter=...@suaveplan/bitpacker-crypto` — every dependent compiles green (no consumer breakage). - [x] 8.6 Grep guard: `! grep -rE "Math\\.random\\(\\)|Date\\.now\\(\\)" packages/bitpacker/bitpacker-crypto/src/ --include="*.ts" | grep -v "\\.test\\.ts"` — zero matches. ## 9. Pre-archive 7-row checklist (AGENTS.md §13) - [x] 9.1 No new generic types beyond `HashAlgorithm`/`HashAlgorithmRegistry` interfaces. - [x] 9.2 Zod schemas for `HashAlgorithm` shape (boundary validation when `register` is called). - [x] 9.3 Both new error codes (`CRYPTO_HASH_ALGORITHM_UNKNOWN`, `CRYPTO_SCHEMA_FINGERPRINT_MISMATCH`) thrown by ≥ 1 production code path. - [x] 9.4 Strict-mode behaviors: register-replace, registry-isolation tested. - [x] 9.5 OTel span `bitpacker-crypto.hash-registry.replaced` and `bitpacker-crypto.fingerprint` emitted from production paths; asserted with real in-memory `MeterProvider`. - [x] 9.6 Singleton lifecycle: `defaultHashRegistry()` returns the same reference on every call; `createHashRegistry()` returns a fresh one. - [x] 9.7 No retroactive tick. ## 10. Archive - [x] 10.1 Fold `specs/bitpacker-crypto/spec.md` into `openspec/specs/bitpacker-crypto/spec.md` (creating the file). - [x] 10.2 Move `openspec/changes/bitpacker-crypto-rewrite/` → `openspec/archive/-bitpacker-crypto-rewrite/`. - [x] 10.3 Move `openspec/changes/bitpacker-crypto-port/` → `openspec/archive/-bitpacker-crypto-port/` (the original superseded predecessor). - [x] 10.4 STATUS.md update: bitpacker-crypto auxiliary primitives landed; full crypto/bitpacker consolidation lives in `restore-crypto-keychain-packer`. - [x] 10.5 Update `CLAUDE.md` package listing for `bitpacker-crypto` to describe `SchemaFingerprint`, `HashAlgorithmRegistry`, plus the existing checksum surface. ## 11. Notes for `restore-crypto-keychain-packer` These items are NOT this change's scope but are recorded for the parallel work: - The audit findings from this change's first draft (eight inline consumers manually re-implementing crypto+bitpacker patterns) feed into `restore-crypto-keychain-packer`'s consumer list. Those consumers will migrate to its `Packer` / `Authority` / `AuditLog` primitives in follow-up changes. - `MultiSignedBitSchema` (co-signed payloads — needed by `MeshTrustToken` NET-110 with `bothServerSignatures: [Uint8Array, Uint8Array]`) is NOT in `restore-crypto-keychain-packer`'s current spec. If/when needed, the spec delta lands there next to `Packer` and `RevocationList`, not in `bitpacker-crypto`. - The `bytes` field type and `byteAlign()` core-bitpacker additions in `restore-crypto-keychain-packer/specs/bitpacker/spec.md` are unaffected by this slim rewrite.