# Tasks — Enterprise hardening (integrity cluster) for `@suaveplan/packer` ## 1. Spec authoring - [ ] 1.1 Read `../suaveplan/enterprise/packer.md` end-to-end - [ ] 1.2 Read `openspec/specs/packer/spec.md` - [ ] 1.3 Read `openspec/AGENTS.md` Sections 13 and 14 - [ ] 1.4 Draft `proposal.md` from `openspec/templates/proposal.md` - [ ] 1.5 Fill in `## Source mapping` table — every requirement cites a line range - [ ] 1.6 Draft `specs/packer/spec.md` from `openspec/templates/spec-delta.md` - [ ] 1.7 Every requirement in the spec delta carries a `**Verified by:**` line naming concrete `it(...)` titles ## 2. Implementation — Integrity (I-1) - [ ] 2.1 Add `@noble/hashes` to `packer/package.json` deps (catalog:crypto) - [ ] 2.2 New `src/integrity/integrity.ts` with `entryDigestBlake3(data)` and `merkleRootBlake3(digests)` + `.types.ts` + `.md` + barrel - [ ] 2.3 Extend `PackedDataMetadata` with optional `integrity?: { entryDigest, merkleRoot }` - [ ] 2.4 `Packer.pack` always populates `metadata.integrity` - [ ] 2.5 `Unpacker.unpack` always verifies; throws `PackerError(PACKER.INTEGRITY_FAILED)` on mismatch / absence (unless `verifyIntegrity: false` is passed) - [ ] 2.6 Extend `ManifestChunkEntry` with `entryDigest` (BLAKE3 of wire bytes), extend `Manifest` with `merkleRoot` - [ ] 2.7 `buildManifest` populates both; `verifyManifest` covers them via canonical signature - [ ] 2.8 Add `unpackChunksWithManifest(chunks, manifest, opts)` — verifies per-chunk BLAKE3 and manifest Merkle root before yielding plaintext - [ ] 2.9 Register `PACKER_INTEGRITY_FAILED` in `defineCodes(...)` plus metadata row ## 3. Implementation — OTel (I-2) - [ ] 3.1 Add `@opentelemetry/sdk-trace-base` + `@opentelemetry/sdk-metrics` as devDependencies (catalog:observability) - [ ] 3.2 Add `@suaveplan/opentelemetry` to deps - [ ] 3.3 New `src/observability/observability.ts` exporting `createPackerObservability(meter?, tracer?)` returning a `PackerObservability` with named instruments - [ ] 3.4 Wire counters: `packer_bundle_size_bytes`, `packer_entry_count`, `packer_pack_total`, `packer_unpack_total`, `packer_integrity_failure_total` - [ ] 3.5 Wire histograms: `packer_pack_duration_ms`, `packer_unpack_duration_ms`, `packer_entry_decode_ms` - [ ] 3.6 Wrap public entrypoints `Packer.pack`, `Unpacker.unpack`, `packChunks`, `unpackChunks`, `unpackChunksWithManifest` in spans via `withSpan` ## 4. Implementation — i18n (I-3) - [ ] 4.1 New `src/i18n/messages.ts` — English-defaults catalog keyed `packer.error..` - [ ] 4.2 Add `messageResolver?: MessageResolver` to `PackerOptions` and to chunked option bundles - [ ] 4.3 Default resolver = `defaultPackerResolver` that walks the local catalog - [ ] 4.4 Replace every hard-coded English string in `throw new PackerError(...)` across `src/` with a resolver call ## 5. Tests - [ ] 5.1 `src/integrity/integrity.test.ts` — BLAKE3 + Merkle KAT vectors, edge cases (empty, single entry, 1 / 2 / 3 / N entries) - [ ] 5.2 `src/integrity/integrity.spec-conformance.test.ts` — surface invariants - [ ] 5.3 `src/packer/packer.spec-conformance.test.ts` extended — pack always writes integrity; unpack rejects on missing / mismatched / mutated integrity - [ ] 5.4 `src/chunked/unpacker/unpacker-with-manifest.spec-conformance.test.ts` — verifies per-chunk BLAKE3, Merkle root, rejects mutation - [ ] 5.5 `src/observability/observability.spec-conformance.test.ts` — REAL in-memory `MeterProvider` + `InMemoryMetricExporter`, REAL `BasicTracerProvider` + `InMemorySpanExporter`; assert every named counter / histogram / span fires - [ ] 5.6 `src/i18n/messages.spec-conformance.test.ts` — custom `MessageResolver` is consulted at every throw site; catalog covers every code+scenario keyed in src - [ ] 5.7 Every `it(...)` carries `{ timeout: 5000 }` ## 6. Documentation - [ ] 6.1 Sibling `.md` for every new implementation `.ts` (≥200 words, basic + advanced examples, full API reference) - [ ] 6.2 Update `README.md` Modules list with the three new feature folders - [ ] 6.3 Update existing `.md`s touched by signature changes ## 7. Pre-archive verification (the 5-gate triple) - [ ] 7.1 `bun run check` — Biome 0/0/0 - [ ] 7.2 `bunx turbo lint typecheck test --filter=@suaveplan/packer` — green - [ ] 7.3 `bunx turbo test:coverage --filter=@suaveplan/packer` — 100/100/100/100 - [ ] 7.4 `bun scripts/openspec-conformance.ts @suaveplan/packer` — exit 0, no `error` findings - [ ] 7.5 `bunx turbo build --filter=@suaveplan/packer` — green ## 8. Consumer sweep - [ ] 8.1 `bunx turbo lint typecheck test --filter=@suaveplan/drive-plugin-chunks --filter=@suaveplan/drive-webrtc` — green ## 9. Pre-archive 9-row checklist - [ ] 9.1 Generics threaded; `expectTypeOf` assertions on every literal-type claim - [ ] 9.2 Zod schemas wired at every declared boundary - [ ] 9.3 Every error code in `error-codes.ts` thrown by at least one production path - [ ] 9.4 OTel instruments emitted from production paths and asserted with a real in-memory `MeterProvider` (NO `vi.mock`) - [ ] 9.5 No `export *` in feature barrels - [ ] 9.6 No direct `vitest` / `bun:test` imports - [ ] 9.7 No retroactive tick — every box above reflects work done in this change - [ ] 9.8 Sibling `.md` for every new `.ts` - [ ] 9.9 Items I-1, I-2, I-3 each have ≥1 production code path and ≥1 test pinning every named scenario ## 10. Archive - [ ] 10.1 Fold `specs/packer/spec.md` into `openspec/specs/packer/spec.md` - [ ] 10.2 Move `openspec/changes/enterprise-packer-integrity/` → `openspec/archive/-enterprise-packer-integrity/` - [ ] 10.3 Refresh `MANIFEST.md`