# Tasks — `@suaveplan/streams-metadata` - **Change ID**: enterprise-streams-metadata - **Package**: `@suaveplan/streams-metadata` - **Target path**: `packages/foundation/flow/streams-metadata` ## 0. Pre-flight (non-negotiable) - [x] 0.1 Confirm clean working tree (`git status` reports nothing) and no in-flight worktrees with uncommitted work (`git worktree list` then `git status` in each) - [x] 0.2 Worktree under `.claude/worktrees/agent-a9864414c72f2d392` is the active migration worktree branched off `genesis@ea6e6df5d`; branch renamed to `feat/streams-metadata` before any code was written - [x] 0.3 Confirm the package set in `MANIFEST.md` matches the actual package tree; regenerate via `bun scripts/folder-reorg/generate-manifest.ts` before archive ## 1. Spec authoring - [x] 1.1 Read upstream source at `/mnt/s/web/suaveplan/packages/universal/streams-metadata/` end to end - [x] 1.2 Read upstream enterprise audit `/mnt/s/web/suaveplan/enterprise/streams-metadata.md` - [x] 1.3 Read genesis reference packages: `@suaveplan/streams` (parent `BaseTransform`), `@suaveplan/mime` (detection API), `@suaveplan/exif` (`readMetadata` semantics) - [x] 1.4 Draft `proposal.md` with parity checklist + design upgrades - [x] 1.5 Draft `specs/streams-metadata/spec.md` — every requirement carries a `**Verified by:**` line at authoring time ## 2. Implementation — scaffold - [ ] 2.1 Create `packages/foundation/flow/streams-metadata/` with `package.json` (`@suaveplan/streams-metadata`, version `0.1.0`, `sideEffects: false`) - [ ] 2.2 Workspace deps: `@suaveplan/error workspace:^`, `@suaveplan/events workspace:^`, `@suaveplan/exif workspace:^`, `@suaveplan/mime workspace:^`, `@suaveplan/streams workspace:^`, `@suaveplan/types workspace:^`, `tslib catalog:build` - [ ] 2.3 Dev deps: `@suaveplan/testing workspace:^`, `@types/node catalog:`, `@vitest/coverage-istanbul catalog:testing`, `typescript catalog:`, `vite catalog:build`, `vite-plugin-dts catalog:build`, `vitest catalog:testing` - [ ] 2.4 `tsconfig.lib.json` extends `../../../../tsconfig.base.json`; `vite.config.ts` mirrors `@suaveplan/streams`; `vitest.config.ts` enforces 100/100/100/100 thresholds (`provider: 'istanbul'`) - [ ] 2.5 All test files import runner primitives from `@suaveplan/testing/runner` per CLAUDE.md §11 ## 3. Implementation — features - [ ] 3.1 `src/errors/errors.ts` — `defineCodes("STREAMS_METADATA", [...])` registry + `StreamsMetadataError` base + factory subclasses - [ ] 3.2 `src/types/payload.ts` — `MetadataMode`, `MetadataPayload`, `MimeDetectionResult`, `EnrichedPayload` - [ ] 3.3 `src/types/process-options.ts` — `ProcessOptions` shape (signal + clock + logger) structurally compatible with `BaseTransform` - [ ] 3.4 `src/events/events.ts` — `StreamsMetadataEvents` type alias - [ ] 3.5 `src/mime/mime.ts` — `MimeTransform extends BaseTransform<{}, StreamsMetadataEvents>` + `MimeTransformOptions`; module-load registration of JPEG / PNG signatures via `@suaveplan/mime::registerSignature` to defeat the upstream mime dist tree-shake - [ ] 3.6 `src/exif/exif.ts` — `ExifTransform extends BaseTransform<{}, StreamsMetadataEvents>` + `ExifTransformOptions` (with `read?: ReadOptions` pass-through) - [ ] 3.7 `src/metadata/metadata.ts` — `MetadataTransform extends BaseTransform<{}, StreamsMetadataEvents>` composing children; forwards `mime:detected` + `exif:detected`; emits `metadata:complete` or `metadata:error` ## 4. Tests - [ ] 4.1 Sibling `.test.ts` for every implementation file under `src/`; every `it(...)` carries `{ timeout: 5000 }` - [ ] 4.2 `errors.test.ts` — every code resolves through the registry, error chain preserves `cause` - [ ] 4.3 `mime.test.ts` — magic-bytes wins over extension, extension fallback, octet-stream fallback, event emission, passthrough, listener errors swallowed - [ ] 4.4 `exif.test.ts` — JPEG / PNG happy path, gibberish raises `ExifFailedError`, read options forwarded, passthrough, abort handling - [ ] 4.5 `metadata.test.ts` — happy path composes, child failure emits `metadata:error` + returns original input, event forwarding, passthrough, dispose chains children ## 5. Documentation - [ ] 5.1 Sibling `.md` per implementation `.ts` with all six required sections - [ ] 5.2 Root `README.md` linking every co-located `.md` ## 6. Pre-publish gate - [ ] 6.1 `bunx biome check src/` exits clean - [ ] 6.2 `bunx tsc --noEmit --composite false -p tsconfig.lib.json` exits clean - [ ] 6.3 `bunx vitest run --coverage` at 100/100/100/100 - [ ] 6.4 `bun ../../../../scripts/docs-check.ts .` exits clean - [ ] 6.5 Zero direct `vitest` / `bun:test` imports in `src/` ## 7. Archive - [ ] 7.1 Fold `specs/streams-metadata/spec.md` into `openspec/specs/streams-metadata/spec.md` - [ ] 7.2 `git mv openspec/changes/enterprise-streams-metadata openspec/archive/2026-05-23-enterprise-streams-metadata` - [ ] 7.3 Regenerate `MANIFEST.md` (`bun scripts/folder-reorg/generate-manifest.ts`)