# Migrate @suaveplan/image to genesis **Package**: `@suaveplan/image` **Status**: PROPOSED **Type**: spec-conformance ## Why `@suaveplan/image` exists upstream (`../suaveplan/packages/universal/image`) but has not been migrated to genesis. It provides image format detection, metadata extraction, resize math, crop validation, and transform pipeline planning — primitives consumed by `compress-image` and downstream UI packages. Migrating it unblocks full enterprise-quality parity and brings the package into compliance with genesis conventions: `defineCodes`, Zod boundaries, OTel instrumentation, explicit barrels, and 100% coverage. ## What changes - ADDED: `IMAGE_CODES` — stable `defineCodes("IMAGE", [...])` registry replacing upstream `ErrorCodes.registerMany` side effect. - ADDED: `ImageError` — extends `SuaveplanError` with typed `ImageErrorContext`. - ADDED: Zod schemas for every public boundary (`ImageProcessorConfigSchema`, `CropRegionSchema`, `ResizeOptionsSchema`, `TransformOpSchema`, `TransformPipelineSchema`, `ImageMetadataSchema`). - ADDED: OTel counters (`image.metadata.extracted_total`, `image.transform.planned_total`) and histograms (`image.metadata.extract_duration_ms`, `image.transform.plan_duration_ms`) emitted from production paths. - ADDED: `ImageProcessor` spans for `extractMetadata` and `planTransform`. - ADDED: `AbortSignal` support on `extractMetadata` and `planTransform` (pre-abort short-circuit). - MODIFIED: `ImageProcessor` constructor now validates config via Zod and accepts optional `tracer` / `meter` from `@opentelemetry/api`. - MODIFIED: `PipelineBuilder` quality setter now clamps to `[1, 100]` and throws `IMAGE_CODES.DIMENSIONS_INVALID` on bad input. - REMOVED: Side-effect import `import "./error-codes.js"` — package is now `sideEffects: false`. - REMOVED: `@deprecated` JSDoc aliases (`unknownFormat`, `invalidDimensions`, `invalidCrop`, `metadataParseFailed`, `invalidTransform`) — replaced by prose-only backward-compat re-exports. ## Out of scope - Actual pixel buffer encoding/decoding — `compress-image` and `exif` already cover compression and metadata I/O. This package remains a metadata + transform-planning library. - Browser-specific APIs (`HTMLImageElement`, `CanvasRenderingContext2D`) — the package is universal-tier. - Network fetch helpers — callers supply `Uint8Array` directly. ## Source mapping This change derives from `../suaveplan/enterprise/image.md`. | Requirement | Source lines | Notes | |---|---|---| | Zero browser / Node / React dependencies | L37 | verbatim | | Zod schemas for public types | L38-L39 | extended: wired at every boundary | | OpenTelemetry instrumentation | L41-L42 | extended: counters + histograms + spans | | Structured errors via `@suaveplan/error` | L42 | extended: `defineCodes` + `SuaveplanError` | | `AbortSignal` propagation | L43 | extended: pre-abort on sync entrypoints | | Test coverage ≥ 95% | L50 | extended: genesis requires 100% | | No mocks | L53 | verbatim | | `sideEffects: false` | L55 | verbatim | | Biome clean | L58 | verbatim | | Error hierarchy | L61 | verbatim | ### Requirements with no source line | Requirement | Justification | |---|---| | Explicit named barrel exports (no `export *`) | Genesis-wide policy per openspec/AGENTS.md §6a | | Test imports from `@suaveplan/testing/runner` | Genesis-wide policy per openspec/AGENTS.md §7 | | Sibling `.md` for every `.ts` | Genesis-wide docs policy per openspec/AGENTS.md §4 | | Subpath exports per feature module | Genesis-wide tree-shaking policy per openspec/AGENTS.md §6 | ## Verification approach - `src/error-codes/error-codes.test.ts` — covers code registry, type assertions. - `src/errors/errors.test.ts` — covers `ImageError` construction, context, cause, legacy alias round-trips. - `src/types/image-types.test.ts` — covers format detection, aspect ratio, resize math, crop validation, MIME mapping. - `src/processor/processor.test.ts` — covers metadata extraction, dimension parsing, size limits, transform planning, pipeline builder chaining, event emission. - `src/processor/processor.spec-conformance.test.ts` — pins OTel instrument emission, Zod boundary rejection, strict-mode behaviors, AbortSignal pre-abort. - `tests/dep-graph.test.ts` — pins zero non-catalog external deps. - `tests/tree-shake.test.ts` — pins `sideEffects: false`. ## Migration impact `@suaveplan/image` has zero current consumers in genesis (it does not yet exist). Downstream packages that will consume it (`compress-image`, future `react-image`) will adopt the new API in follow-up changes. No existing code is affected. ## Impact ### Affected dependents No dependents (verified by `bunx turbo ls --filter=...@suaveplan/image` — package does not exist on disk yet).