6.9 KiB
6.9 KiB
Tasks — complete-storage-mux
Every checkbox MUST reflect work actually done in this change.
0. Pre-flight (non-negotiable)
- 0.1 Confirm clean working tree (
git statusreports nothing) and no in-flight worktrees with uncommitted work (git worktree listthengit statusin each) - 0.2 If any worktrees exist under
.claude/worktrees/, account for each one: still-active agent, work-pending-merge, or stale-and-prune. Stale worktrees MUST be removed (git worktree remove) before opening a new one — code that has been lost twice on main is the failure mode this guards against. - 0.3 Confirm the package set in
MANIFEST.mdmatchesfind packages -maxdepth 3 -name package.jsoncount. Drift here means a prior change archived without regenerating the manifest.
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/to confirmrunWithRetry+RetryStrategysurface - 1.5 Read
packages/events/events/src/to confirmEventBusLikeshape - 1.6 Draft
proposal.md,design.md,specs/storage-mux/spec.md,tasks.md - 1.7 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 directory - 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.json,vite.config.ts,vitest.config.tsviacreateTestConfigwiththresholds: 100/100/100/100 - 2.6 Root
README.mdwith Modules section linking every co-located.md
3. Error registry
- 3.1
src/error-codes/error-codes.ts—defineCodes("STORAGE_MUX", [...])with all 14 codes:ALL_BACKENDS_DOWN,NO_BACKENDS_CONFIGURED,HEALTHCHECK_FAILED,BACKEND_TIMEOUT,INVALID_MODE,INVALID_WEIGHT,WRITE_FANOUT_PARTIAL,BACKEND_ABORTED,BACKEND_NOT_FOUND,BACKEND_NAME_CONFLICT,BACKEND_DRAINING,WEIGHTED_REQUIRES_WEIGHTS,MIRROR_ORIGIN_REQUIRED,RECURSION_DEPTH_EXCEEDED - 3.2
StorageMuxError extends SuaveplanError<StorageMuxErrorCode>withbackendName,attemptIndex,attemptCount,modediscriminants - 3.3
error-codes.md+error-codes.test.ts— reachability sweep proving every code is thrown from a real call site
4. Types & schemas
- 4.1
src/types/backend-entry.types.ts—BackendEntry(name,storage,weight?,healthcheck?,tags?) - 4.2
src/types/mux-options.types.ts—MuxModeunion,StorageMuxOptions,BackendStats,MuxStats - 4.3
src/types/mux-options.schemas.ts— Zod schemas: non-empty backends, mode whitelist,weight >= 0,cooldownMs >= 0, unique names
5. Classification
- 5.1
src/classify/classify.ts+.md+.test.ts— pureclassify(err) => "transient" | "semantic" | "abort"per design §4
6. Bulkhead
- 6.1
src/bulkhead/bulkhead.ts+.md+.test.ts—Promise.racetimeout,AbortSignal.anycomposition, hung-promise non-blocking
7. Health
- 7.1
src/health/health.ts+.md+.test.ts—BackendHealthtracker, exponential cooldown capped atmaxCooldownMs, recovery probe, active healthcheck scheduling via injectedClock, draining accounting
8. Stats
- 8.1
src/stats/stats.ts+.md+.test.ts— per-backend counters, Vitter Algorithm R reservoir-sampled latencies (256 slots),mux.stats()snapshot API
9. Modes (six)
- 9.1
src/modes/selector.types.ts—BackendSelector+BackendExecutorinterfaces - 9.2
src/modes/failover/failover.ts+.md+.test.ts— fall-through + retry composition +ALL_BACKENDS_DOWN - 9.3
src/modes/round-robin/round-robin.ts+.md+.test.ts— atomic counter, skip down/draining - 9.4
src/modes/weighted/weighted.ts+.md+.test.ts— Walker alias-method, rebuild on mutation, weight validation - 9.5
src/modes/sticky-by-key/sticky-by-key.ts+.md+.test.ts— FNV-1a, deterministic, redistribution on backend removal - 9.6
src/modes/shield/shield.ts+.md+.test.ts— origin-first reads, fan-out writes,WRITE_FANOUT_PARTIALopt-in - 9.7
src/modes/mirror/mirror.ts+.md+.test.ts—Promise.anyreads,Promise.allSettledwrites, symmetric peers
10. Runtime mutation
- 10.1
src/mutate/mutate.ts+.md+.test.ts—addBackend,removeBackend,setWeight,drainwith in-flight accounting
11. Observability
- 11.1
src/observability/events.ts+.md+.test.ts— event topic constants and emit helpers consumingEventBusLike - 11.2
src/observability/otel.ts+.md+.test.ts— per-attempt child-span helper with attribute set
12. Mux core
- 12.1
src/mux/mux.ts+.md—StorageMux extends AbstractStorage, per-op routing through selector + bulkhead +runWithRetry, AbortSignal.any composition, recursion depth guard - 12.2
src/mux/mux.test.ts— construction validation, mode dispatch, abort surfacing, recursion cap - 12.3
src/mux/mux.spec-conformance.test.ts—runStorageConformance× 6 modes × 3-backend MemoryStorage fleet, plus one two-level recursive mux
13. Barrel + exports
- 13.1
src/index.ts— explicit named re-exports per §6a (NOexport *) - 13.2
package.jsonsubpath exports — one entry per feature directory; verify count matches
14. Documentation
- 14.1 Sibling
.mdfor every implementation.ts(≥ 200 words, all required sections, real-import examples) - 14.2
README.mddocuments each of the six modes with a usage example + a section on runtime mutation + stats
15. Gates
- 15.1
bun run check - 15.2
bunx turbo lint typecheck test --filter=@suaveplan/storage-mux - 15.3
bunx turbo test:coverage --filter=@suaveplan/storage-mux(100/100/100/100) - 15.4
bun scripts/lint/check-test-runner-imports.ts→ zero output - 15.5 Tier-purity grep
grep -rnE "from ['\"](node:|bun:)" packages/storage/storage-mux/src/→ empty - 15.6 Banned-pattern scan → empty
- 15.7
bun scripts/openspec-conformance.ts @suaveplan/storage-mux
16. Manifest & archival
- 16.1
bun scripts/folder-reorg/generate-manifest.ts - 16.2
bun scripts/generate-missing.ts - 16.3 Update
STATUS.mdandSUMMARY.md - 16.4
bunx markdownlint-cli2 --fix - 16.5 Fold
specs/storage-mux/spec.md→openspec/specs/storage-mux/spec.md - 16.6 Move change folder →
openspec/archive/<yyyy-mm-dd>-complete-storage-mux/