- Add withRateLimit(rateLimit, fn) in rate-limit/with-rate-limit.ts,
attaching the RateLimited brand at DI bind time
- Extend wireUseCase to accept optional rateLimit?: IRateLimit and
compose withRateLimit innermost (before analytics/audit); propagate
__rateLimited through analytics + audit inline wrappers
- Extend withSpan and withCapture PROPAGATED_BRANDS to include
__rateLimited so the outermost binding carries the brand
- Extend assertFeatureConformance to require __rateLimited brand when
manifest.useCases[name].rateLimit.length > 0; refactored into
helper functions to stay within complexity thresholds
- Add rateLimit?: IRateLimit to BindContext; default to NoopRateLimit
in web-next bindAllProduction and bindAllDevSeed aggregators
- Unit tests for withRateLimit brand attachment, factory passthrough,
and composition; synthetic fixture tests for conformance errors
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds IRateLimit, RateLimitBudget, RateLimitDecision to a new
rate-limit sub-module; adds RateLimited<F> brand and isRateLimited
predicate following the Captured/ConsentChecked pattern; extends
UseCaseManifest with rateLimit?: readonly RateLimitBudget[] so
features can declare rate-limit gates in their manifests.
Exports new types from @repo/core-shared/rate-limit and
@repo/core-shared/conformance. Blocks stories 02, 03, and 04.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add packages/core-consent with ConsentCategory, ConsentState,
UserConsentState types and IConsent interface
- Add withConsent wrapper attaching __consentChecked brand at bind time;
unit tests assert brand attachment and factory passthrough
- Add ConsentChecked<F> type to core-shared/conformance/brands.ts and
isConsentChecked helper to brand-runtime.ts
- Extend FeatureManifest with requiresConsent?: readonly string[] field
- Extend assertFeatureConformance to require __consentChecked brand when
requiresConsent.length > 0; synthetic fixture tests cover pass/fail cases
- Propagate __consentChecked in withSpan PROPAGATED_BRANDS so the outermost
binding carries the brand
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>
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>
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>
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>
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>
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>
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>