5.2 KiB
5.2 KiB
Tasks — storage-mux
Every checkbox MUST reflect work actually done in this change.
1. Spec authoring
- 1.1 Read
openspec/specs/storage/spec.mdand confirmAbstractStoragesurface - 1.2 Read
openspec/AGENTS.md§0c, §13, §14 - 1.3 Read archived
openspec/archive/2026-05-16-add-storage-cdn/for the deferral and family conventions - 1.4 Read
packages/flow/retry/src/retry/retry.tsto confirmrunWithRetry+RetryStrategysurface - 1.5 Draft
proposal.md,design.md,specs/storage-mux/spec.md,tasks.md - 1.6 Numbered Requirement/Scenario checklist per §0c step 6
2. Scaffolding
- 2.1 Create
packages/storage/storage-mux/mirroringpackages/storage/storage-cdn/conventions - 2.2
package.jsonv0.0.0,"sideEffects": false, subpath exports per feature - 2.3 Deps:
@suaveplan/error,@suaveplan/events,@suaveplan/retry,@suaveplan/storage,@suaveplan/types,@opentelemetry/api,zod,tslib - 2.4 DevDeps:
@suaveplan/testing,@vitest/coverage-istanbul,fast-check,mitata,typescript,vite,vite-plugin-dts,vitest - 2.5
tsconfig,vite.config.ts,vitest.config.tsviacreateTestConfig - 2.6
README.mdroot with Modules section linking every.md
3. Error registry
- 3.1
src/error-codes.ts—defineCodes("STORAGE_MUX", [...])with 8 codes (ALL_BACKENDS_DOWN,NO_BACKENDS_CONFIGURED,HEALTHCHECK_FAILED,BACKEND_TIMEOUT,INVALID_POLICY,INVALID_WEIGHT,WRITE_FANOUT_PARTIAL,BACKEND_ABORTED) - 3.2
src/error-codes.ts—StorageMuxError extends SuaveplanError<StorageMuxErrorCode>withbackendName,attemptIndex,attemptCountdiscriminants
4. Types & schemas
- 4.1
src/types/backend-entry.types.ts—BackendEntryinterface (name,storage,weight?,healthcheck?) - 4.2
src/types/mux-options.types.ts—MuxPolicydiscriminated string union,StorageMuxOptions - 4.3
src/types/mux-options.schemas.ts— Zod schemas validating non-empty backends, policy whitelist, weight ≥ 0
5. Selectors / policies
- 5.1
src/policies/selector.types.ts—BackendSelectorinterface (select(op, key?, healthy): BackendEntry) - 5.2
src/policies/classify.ts+.md+.test.ts— pure error classification per design §4 table - 5.3
src/policies/failover/failover.ts+.md+.test.ts— fall-through + retry composition - 5.4
src/policies/round-robin/round-robin.ts+.md+.test.ts— atomic counter, skip down - 5.5
src/policies/sticky-by-key/sticky-by-key.ts+.md+.test.ts— FNV-1a hash, deterministic - 5.6
src/policies/shield/shield.ts+.md+.test.ts— read cascade, write fan-out, partial signal
6. Health
- 6.1
src/health/health.ts+.md+.test.ts—BackendHealthtracker, exponential cooldown, recovery probe, active healthcheck via injectedClock
7. Mux core
- 7.1
src/mux/mux.ts+.md—StorageMux extends AbstractStorage, per-op routing throughBackendSelector+runWithRetry, per-backend timeout race, AbortSignal linking - 7.2
src/mux/mux.test.ts— construction validation, policy dispatch, abort surfacing - 7.3
src/mux/mux.spec-conformance.test.ts—runStorageConformance× 4 policies × 3MemoryStoragebackends
8. Observability
- 8.1
src/observability/events.ts+.md+.test.ts— event topic constants (storage-mux.backend.down,.recovered,.failover,.fanout-partial),emit*helpers consumingEventBusLike - 8.2
src/observability/otel.ts+.md+.test.ts— span attribute helpers (mux.backend.name,mux.attempt.index,mux.policy)
9. Barrel + exports
- 9.1
src/index.ts— explicit named re-exports per §6a (NOexport *) - 9.2
package.jsonsubpath exports match every feature directory
10. Tests
- 10.1
src/error-codes/error-codes.test.ts— everySTORAGE_MUX_*code reachable from a real call site - 10.2 All test imports via
@suaveplan/testing/runner(§7) - 10.3 Every
it(...)carries{ timeout: 5000 }(or 30000 for async health) - 10.4 Backend isolation test: hung-promise primary does NOT block fallback within
backendTimeoutMs
11. Documentation
- 11.1 Sibling
.mdfor every implementation.ts(≥ 200 words, all required sections) - 11.2
README.mddocuments each policy with a usage example
12. Gates
- 12.1
bun run check - 12.2
bunx turbo lint typecheck test --filter=@suaveplan/storage-mux - 12.3
bunx turbo test:coverage --filter=@suaveplan/storage-mux(100/100/100/100) - 12.4
bun scripts/lint/check-test-runner-imports.ts - 12.5 Tier-purity grep
grep -rnE "from ['\"](node:|bun:)" packages/storage/storage-mux/src/returns empty - 12.6 Banned-pattern scan returns empty
- 12.7
bun scripts/openspec-conformance.ts @suaveplan/storage-mux
13. Manifest & archival
- 13.1
bun scripts/folder-reorg/generate-manifest.ts - 13.2
bun scripts/generate-missing.ts - 13.3 Update
STATUS.mdandSUMMARY.md - 13.4
bunx markdownlint-cli2 --fix - 13.5 Fold
specs/storage-mux/spec.md→openspec/specs/storage-mux/spec.md - 13.6 Move change folder →
openspec/archive/<yyyy-mm-dd>-add-storage-mux/