# Capability Spec Delta: env-spec-conformance **Package**: `@suaveplan/env` **Change**: env-spec-conformance **Date**: 2026-04-26 ## MODIFIED Requirements This change does two things in scope: 1. **Folds `**Verified by:**` lines** into every `### ENV-NN —` block of `openspec/specs/env/spec.md` (ENV-01 through ENV-17). Each annotation points at real tests — there are no `deferred` / `follow-up` markers. The new `src/core/create-env/create-env.spec-conformance.test.ts` pins the implicit type-level and wire-level scenarios the original suite did not (literal-type narrowing, loader-chain merge order, cross-loader `${VAR}` interpolation, unresolved-token default, Zod boundary failures for the three public APIs, OTel non-throwing instrumentation, `EnvValidationError.code === ENV.VALIDATION_FAILED`, and `ENV_CODES.*` literal typing). 2. **Realigns spec ↔ impl** for the nine divergences the original audit flagged, plus ENV-12 and ENV-14: | Divergence | Direction | Change | |---|---|---| | `objectLoader` signature | spec → impl | ENV-04 documents the single-options `objectLoader({ source, sourceName })` form. | | `parseDotenv` malformed-line handling | spec → impl | ENV-05 documents silent-skip for lines without `=` (dotenv-ecosystem convention). | | `DotenvLoaderOptions.override` default | spec → impl | ENV-05 specifies `false` (safer; explicit `source` wins). | | `createEnv` interpolation pass | impl → spec | ENV-06 contract restored: `createEnv` runs a fixpoint interpolation pass over the merged values map before coercion. | | `BaseField.rules()` naming | spec → impl | ENV-07 specs `addRule()` on the base; `optional()`/`default()` lifted per subclass (return-type narrows). | | `ValidationResult` shape | spec → impl | ENV-09 specs `{ success, data, errors: ReadonlyArray }`. | | `maskSensitive` arg-order / glyph | spec → impl | ENV-10 specs `maskSensitive(schema, values)` and the `'****'` glyph. | | `CoercionError` code | impl → spec | `CoercionError` now uses `ENV.INVALID_FORMAT`. The dead `ENV.COERCE_ERROR` registry entry is removed. | | Zod-schema boundary wiring (ENV-12) | impl → spec | `createEnv`, `dotenvLoader`, `objectLoader` invoke `CreateEnvOptionsSchema`, `DotenvLoaderOptionsSchema`, `ObjectLoaderOptionsSchema` respectively; invalid options throw `EnvValidationError` with code `ENV.VALIDATION_FAILED`. Remaining schemas are marked `// schema: boundary-only` (consumer-facing). | | OTel instrumentation (ENV-14) | impl → spec | `createEnv` records `env.validation.total` (counter, `outcome` label), `env.validation.errors` (counter, `field` label), and `env.load.duration_ms` (histogram, ms) via `metrics.getMeter('suaveplan.env')`. `@opentelemetry/api` added as a runtime dep. | After this change: - `bun scripts/openspec-conformance.ts @suaveplan/env` exits 0 with no `error` findings. - `bunx turbo lint typecheck test --filter=@suaveplan/env` is green. - `bunx turbo test:coverage --filter=@suaveplan/env` meets the 100/100/100/100 threshold. - The historical `retroactively ticked` hazard in `openspec/archive/2026-04-19-enterprise-env/tasks.md` is recognised as resolved by this change.