Files
2026-05-27 23:29:53 +01:00

5.7 KiB

Tasks — Enterprise hardening (resilience 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 — Runtime defaults (R-4 foundation)

  • 2.1 New src/runtime/runtime.ts — defaultClock, defaultMonotonicClock, defaultRng, resolveRuntime(opts) returning { clock, monotonicClock, rng }.
  • 2.2 Sibling .md, .types.ts, index.ts barrel.
  • 2.3 Extend PackerOptions, PackChunkedOptions, UnpackChunkedOptions with clock?: Clock, monotonicClock?: MonotonicClock, rng?: Rng.

3. Implementation — Retry (R-1)

  • 3.1 Add @suaveplan/retry to packer/package.json deps (workspace:^).
  • 3.2 New src/retry/retryable-read.ts — retryRead(reader, opts) wrapping reader.read() in withRetry.
  • 3.3 Extend normalizeSource to accept retryConfig? and route ReadableStream reads through retryRead.
  • 3.4 Extend AbstractPacker.packStream's collect helper to accept and propagate retryConfig? to normalizeSource.
  • 3.5 Thread retryConfig? and signal? through PackerOptions, PackChunkedOptions, UnpackChunkedOptions.

4. Implementation — Idempotency (R-2)

  • 4.1 Add @suaveplan/idempotency to packer/package.json deps (workspace:^).
  • 4.2 New src/idempotency/idempotency.ts — PackIdempotencyGuard consuming IdempotencyStoreAdapter, computing content-derived dedup key.
  • 4.3 Sibling .md, .types.ts, index.ts barrel.
  • 4.4 Add idempotency?: { store, ttlMs?, enabled? } to PackerOptions.
  • 4.5 Packer.pack short-circuits on cache hit before any pipeline work; populates store on miss.

5. Implementation — Whole-file AbortSignal (R-3)

  • 5.1 Add signal?: AbortSignal to UnpackOptions.
  • 5.2 Add PackOptions interface ({ filename?, signal? }) on types/packer.types.ts.
  • 5.3 Overload Packer.pack(data, filenameOrOpts?, opts?) accepting either filename string or PackOptions.
  • 5.4 Unpacker.unpack checks signal.aborted at every yield point (5 places).
  • 5.5 Packer.pack checks signal.aborted at every yield point (5 places).
  • 5.6 packChunks checks signal.aborted between emitted chunks.
  • 5.7 New i18n catalog keys packer.error.ABORTED.pack, packer.error.ABORTED.pack-chunks.

6. Implementation — Clock / Rng audit-and-replace (R-4)

  • 6.1 AbstractPacker.buildMetadata reads timestamp from this.options.clock.
  • 6.2 packer/packer.ts randomBytes replaced with this.options.rng.nextBytes(n).
  • 6.3 All nowMs() helpers across the package route through this.options.monotonicClock (or resolved per-call for chunked async fns).
  • 6.4 Grep verify: zero Date.now\|Math.random\|crypto.getRandomValues\|performance.now outside src/runtime/runtime.ts.

7. Tests

  • 7.1 src/runtime/runtime.test.ts + .spec-conformance.test.ts — pins defaults; grep audit.
  • 7.2 src/retry/retryable-read.test.ts + .spec-conformance.test.ts — pins retry attempts, abort mid-backoff, default single-attempt.
  • 7.3 src/idempotency/idempotency.test.ts + .spec-conformance.test.ts — pins hit / miss / disabled / custom store.
  • 7.4 src/packer/packer.spec-conformance.test.ts extended — abort, idempotency, clock, rng, determinism, legacy overload.
  • 7.5 src/unpacker/unpacker.spec-conformance.test.ts extended — pre-flight abort, mid-pipeline abort.
  • 7.6 src/chunked/packer/packer.spec-conformance.test.ts extended — mid-stream abort.
  • 7.7 Every it(...) carries { timeout: 5000 } (or 30000 for async I/O).

8. Documentation

  • 8.1 Sibling .md for every new implementation .ts (≥200 words, basic + advanced examples).
  • 8.2 Update README.md Modules list with retry/, idempotency/, runtime/.

9. Pre-archive verification (the 5-gate triple)

  • 9.1 bun run check — Biome 0/0/0.
  • 9.2 bunx turbo lint typecheck test --filter=@suaveplan/packer — green.
  • 9.3 bunx turbo test:coverage --filter=@suaveplan/packer — 100/100/100/100.
  • 9.4 bun scripts/openspec-conformance.ts @suaveplan/packer — exit 0.
  • 9.5 bunx turbo build --filter=@suaveplan/packer — green.

10. Consumer sweep

  • 10.1 bunx turbo lint typecheck test --filter=@suaveplan/drive-plugin-chunks --filter=@suaveplan/drive-webrtc — green.

11. Pre-archive 9-row checklist

  • 11.1 Generics threaded; expectTypeOf assertions on every literal-type claim.
  • 11.2 Zod schemas wired at every declared boundary.
  • 11.3 Every error code in error-codes.ts thrown by at least one production path.
  • 11.4 OTel instruments emitted from production paths and asserted with a real in-memory MeterProvider (NO vi.mock).
  • 11.5 No export * in feature barrels.
  • 11.6 No direct vitest / bun:test imports.
  • 11.7 No retroactive tick — every box above reflects work done in this change.
  • 11.8 Sibling .md for every new .ts.
  • 11.9 Items R-1, R-2, R-3, R-4 each have ≥1 production code path and ≥1 test pinning every named scenario.

12. Archive

  • 12.1 Fold specs/packer/spec.md into openspec/specs/packer/spec.md.
  • 12.2 Move openspec/changes/enterprise-packer-resilience/ → openspec/archive/<yyyy-mm-dd>-enterprise-packer-resilience/.
  • 12.3 Refresh MANIFEST.md.