# Capability consumer experience baseline Correctness inside a reusable capability is not sufficient. The platform is also evaluated by how much of that correctness a normal feature developer must understand. These measurements are baselines, not score targets. A lower line count is not automatically better if it hides business semantics or creates a universal repository abstraction. ## Scenario A — reference REST feature The existing reference feature is the executable REST consumer. It covers list/detail/create behavior, mapping, typed operation inputs, application ports and an optimistic mutation path. Current source size: | Feature-owned area | LOC | | --- | ---: | | `application/reference-feature-api.ts` | 91 | | `contracts/reference-mapper.ts` | 109 | | `adapters/reference-http-gateway.ts` | 65 | | `adapters/create-reference-feature-input.ts` | 41 | | Total measured boundary/application source | 306 | The important boundary metric is not the raw total. It is what those files need to know about the platform. Current result: - HTTP platform imports in the feature adapter layer: 2 files, - canonical import path used by both: `src/adapters/http/index.ts`, - direct imports of `http-execution-v3.ts`, retry scheduler, response reader, auth admission or effect-certainty internals: 0, - feature gateway owns transport failure projection: 0, - feature gateway chooses operation ID, route ID, exact input/value type and mapper: yes, - central installed files own feature-specific adapter/runtime wiring: no; feature-owned contributions are aggregated centrally. The reusable HTTP capability now owns execution-outcome normalization through `createFeatureHttpBinding`. A feature may still implement a custom outbound adapter behind its application port when the reusable contract does not match its business requirement. ## Scenario B — IndexedDB local draft The original executable consumer probe remains at: `tests/contract/consumer-experience/indexeddb-local-draft.test.ts` with its isolated fixture: `tests/contract/consumer-experience/fixtures/local-draft-feature.ts` The architecture is now also exercised by a real vertical slice under: `src/features/local-draft-feature` It owns the Local Draft domain/application API and binds an `IndexedDbRepositoryPort` in its feature adapter. The cross-capability composition contract lives at: `tests/contract/reusable-capability/feature-adapter-composition.test.ts` That test composes one HTTP-only contribution and the IndexedDB-only Local Draft contribution through the same generic catalog path. The browser-level composition proof lives at: `tests/browser-capabilities/local-draft-composition.spec.ts` It runs against native browser IndexedDB. The test creates the platform `createIndexedDbRuntime`, exposes that runtime through the typed `createIndexedDbRepositoryProvider`, composes `LOCAL_DRAFT_FEATURE_ADAPTER_CONTRIBUTION`, then executes Local Draft save/find/remove through the feature API. The Local Draft feature still does not import the IndexedDB runtime or native browser API. Measured probe result: | Metric | Result | | --- | ---: | | feature-owned fixture LOC | 97 | | platform import statements | 1 | | native IndexedDB API references | 0 | | `src/adapters/storage/indexeddb/**` imports | 0 | | runtime-internal IndexedDB types imported by feature | 0 | The feature depends only on the public application boundary: `src/application/ports/browser-file-storage/index.ts` and specifically `IndexedDbRepositoryPort`. The contract test rejects feature source that reaches for `globalThis.indexedDB`, `IDBFactory`, `IDBDatabase`, `IDBTransaction`, `IDBObjectStore` or the concrete IndexedDB adapter directory. ## What this does and does not prove The contract probe confirms that **feature business code does not need native IndexedDB knowledge** once an `IndexedDbRepositoryPort` has been composed. The browser-capability proof additionally confirms that the same feature contribution works when that port is backed by the repository's real `createIndexedDbRuntime` and native IndexedDB implementation. It does not prove that composition of `createIndexedDbRuntime` is cheap. That constructor still owns substantial infrastructure policy: - dataset scope and storage policy, - physical store governance, - retention/idempotency stores, - schema migrations, - codec and query policy, - lifecycle authority, - durability, scheduling and observation. That complexity belongs at the composition/platform boundary, not in the feature. The Local Draft vertical slice is now the second concrete consumer, and it confirms that the stable seam is the typed repository provider plus a feature-owned repository identity. It does **not** show that dataset scope, retention, migration, codec or lifecycle-authority configuration can be safely collapsed into one universal `create...Repository` factory. A convenience profile should therefore be introduced only after another IndexedDB-backed product feature repeats the same infrastructure policy, not merely because two features consume the same repository port. ## Consumer-quality review checklist For each new product feature, record: - feature-owned adapter LOC, - platform glue LOC, - files changed, - central catalog edits, - direct imports from capability-internal modules, - native browser/network API references, - duplicated failure/retry/lifecycle policy. A healthy feature path should look like: 1. domain type and invariant, 2. use case, 3. business port, 4. feature-owned mapper/codec and policy, 5. capability-specific binding, 6. presentation controller/page. The feature should not need the retry scheduler, abort ownership, effect-certainty machinery, IndexedDB transaction lifecycle, OPFS journal, reconnect coordinator or provider process model.