Commit Graph

15 Commits

Author SHA1 Message Date
92b17f7d64 feat(core-shared): add Analyzed brand check to assertFeatureConformance
Mirrors the existing Audited check: when a use case declares
analyticsEvents.length > 0 and the bound function lacks the __analyzed
brand, assertFeatureConformance throws ConformanceError at boot time.

Adds three synthetic conformance tests: passes when brand present +
events declared, throws naming Analyzed when events declared + brand
missing, passes when events empty + brand absent.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 15:19:29 +00:00
32018e8a7b feat(core-shared): extend wireUseCase with analytics arg and Analyzed brand propagation
Add AnalyticsProtocol to bind-protocols, extend WireUseCaseOptions with
optional analytics field, and compose the __analyzed brand inline in
wireUseCase (innermost, before withAudit) when analytics is provided.

Propagate __analyzed through withCapture and withSpan PROPAGATED_BRANDS
so the outermost container binding carries the brand for boot-time
assertion checks (Story 05).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 15:12:57 +00:00
0ee0355f5e feat(core-shared): add analyticsEvents field to UseCaseManifest
Add optional `analyticsEvents?: readonly string[]` to `UseCaseManifest`
in `define-feature.ts` so manifests can declare which analytics events a
use case emits. Field defaults to absent (treated as []) — all existing
manifests remain valid without changes.

Update the feature generator template to emit `analyticsEvents: []` so
newly scaffolded features are analytics-declaration-ready from day one.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 11:57:49 +00:00
d128106fd2 feat(core-shared): add Analyzed brand and isAnalyzed type guard
Adds the `Analyzed<F>` phantom-type brand to brands.ts and the
`isAnalyzed` type-guard to brand-runtime.ts, mirroring the existing
Instrumented/Captured/Audited pattern. Exports both from the
conformance index so Story 04 (wireUseCase) can key off the brand
without a circular dep.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 11:41:48 +00:00
1bbe866a5c feat(core-shared): add wireUseCase helper to conformance barrel
Encapsulates withSpan(withCapture(withAudit?(factory(deps)))) composition
and container binding into a single helper, eliminating the structural
boilerplate clone groups repeated across every feature binder pair.

Callers pass { container, symbol, factory, deps, feature, layer, name,
tracer, logger, auditLog? } and get back a fully brand-stacked, container-
bound wired value. Idempotent: unbinds an existing symbol before rebinding.

withAudit lives in core-audit which core-shared cannot import (dependency
inversion: core-audit depends on core-shared). The audit path here replicates
the same semantics — forwarding wrapper + __audited brand — without the
circular dependency.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 17:28:57 +00:00
f7baa8bfd1 feat(core-shared/conformance): manifest coverage schema + vitest helper
First implementation milestone of the agent-first coverage architecture
(ADR-020, PRD 2026-05-13). Lands the keystone — coverage bands as a
typed declaration in feature.manifest.ts plus a helper that derives
vitest threshold shapes from them.

New file packages/core-shared/src/conformance/coverage.ts (self-
contained, no relative imports — loadable at vitest config time):
- CoverageBand / CoverageBands / CoverageManifest / VitestThresholds
  types
- DEFAULT_COVERAGE_BANDS (baseline 80/75/80/80; entities 100/100/100/
  100; use-cases + controllers 100/95/100/100) — matches ADR-011
- DEFAULT_MUTATION_SCORE (80) + DEFAULT_MUTATION_TARGETS (entities +
  use-cases)
- getCoverageBands / getMutationConfig — manifest -> resolved bands,
  with default fallback for missing layers
- vitestThresholdsFromBands / vitestThresholdsFromManifest — convert
  to vitest's coverage.thresholds shape with the layer-to-glob
  mapping

define-feature.ts gains the optional coverage field on FeatureManifest
(imports its type from coverage.ts to avoid a relative-import cycle
at config-load time).

Exposed via two subpaths: @repo/core-shared/conformance (re-exports
for source/test code) and @repo/core-shared/conformance/coverage
(direct subpath safe to load from vitest configs, bypasses the index
re-export chain that Node ESM doesn't auto-extension-resolve).

Auth wired as proof-of-concept:
- packages/auth/src/feature.manifest.ts declares its coverage section
- packages/auth/vitest.config.ts imports the helper +
  DEFAULT_COVERAGE_BANDS and emits thresholds via
  vitestThresholdsFromBands(DEFAULT_COVERAGE_BANDS) — no more
  hand-maintained per-glob thresholds block.

Verified: 175/175 tests pass; 14/14 typechecks clean; auth coverage
green (21 tests, 93.77% overall, all per-layer 100% bands hold).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 13:51:13 +02:00
83f135b5e1 fix(conformance): withCapture propagates inner brands + chain test + docstring fixes 2026-05-12 23:00:50 +02:00
5e32074c2e feat(core-shared/conformance): assertFeatureConformance helper
Adds boot-time check that every manifest-declared use case is bound
through withSpan (__instrumented) + withCapture (__captured), with
withAudit (__audited) enforced when audits[] is non-empty. Propagates
inner brands through withSpan so the outermost container-resolved
binding carries all brand markers.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 22:49:18 +02:00
bbd9c1e856 feat(core-shared/conformance): re-export ConformanceError 2026-05-12 22:43:57 +02:00
49bd7e0782 feat(core-shared/conformance): ConformanceError class 2026-05-12 22:43:15 +02:00
a593962b3d feat(core-shared/conformance): runtime brand markers + isX predicates 2026-05-12 22:37:43 +02:00
c7bd9a2f8a feat(core-shared/conformance): barrel + ./conformance subpath export 2026-05-12 21:37:18 +02:00
82cfde9c93 feat(core-shared/conformance): ProductionUseCase<I, O, M> branded slot type 2026-05-12 21:35:59 +02:00
b3784ce255 feat(core-shared/conformance): defineFeature helper + manifest types 2026-05-12 21:34:19 +02:00
5f5db546ae feat(core-shared/conformance): Instrumented<F> and Captured<F> brand types 2026-05-12 21:27:05 +02:00