---
id: 05-assert-feature-conformance-analyzed
epic: product-analytics-channel
title: Extend assertFeatureConformance to check Analyzed brand
type: technical-story
status: done
feature: core-shared
depends-on: [04-manifest-schema-and-wire-use-case]
blocks:
  [
    06-analytics-protocol-bind-context,
    07-eslint-rule-no-undeclared-analytics-event,
  ]
created: 2026-05-18T12:04:00Z
updated: 2026-05-18T15:36:52.400Z
---

## Goal

Extend `assertFeatureConformance` to reject a binding at boot time when the manifest's use case declares `analyticsEvents.length > 0` but the bound function does not carry the `Analyzed` brand. Error message names the use case and the missing brand.

## Why

This is the boot-time gate that prevents analytics events from being declared in the manifest but silently skipped at runtime. Mirrors the existing `Audited` check for the same guarantee at the same latency.

## Done when

- `assertFeatureConformance` throws `ConformanceError` naming the missing `Analyzed` brand when `analyticsEvents.length > 0` and the bound function is not `isAnalyzed`.
- A synthetic conformance test (parallel to `assert-bindings.test.ts`) covers: passes when Analyzed present + events declared, throws with message naming `Analyzed` when events declared + brand missing, passes when events empty + brand absent.
- All gates pass.

## In scope

- `packages/core-shared/src/conformance/assert-bindings.ts` — Analyzed check addition.
- Conformance test file for the new assertion path.

## Out of scope

- `BindContext.analytics` field (Story 06).
- ESLint rule (Story 07).
- Any template feature wiring analytics (out of scope per PRD).

## Tasks

- [x] Add `Analyzed` brand check to `assertFeatureConformance` when `manifest.useCases[name].analyticsEvents.length > 0` + synthetic conformance test asserting `ConformanceError` with message naming `Analyzed` for unwrapped bindings — all gates pass on this commit.
