## 1. Foundation & Database Migrations

- [x] 1.1 Create migration `023_add_analytics_events.sql` — `analytics_events(id, tenant_id, date, metric_type, count, PRIMARY KEY(tenant_id, date, metric_type))`
- [x] 1.2 Create migration `024_add_tenant_tiers.sql` — `tenant_tiers(tenant_id FK, tier ENUM('free','pro','enterprise'), created_at, updated_at)`
- [x] 1.3 Add `TIER_CONFIG` constant to `src/config/tiers.ts` with free/pro/enterprise limits
- [x] 1.4 Add `ANALYTICS_ENABLED`, `TIER_ENFORCEMENT`, `COMPLIANCE_ENABLED` env vars to `.env.example` and `src/config/env.ts`
- [x] 1.5 Run migrations in test environment and verify table creation

## 2. WS3 — Analytics Backend

- [x] 2.1 Create `src/services/AnalyticsService.ts` — `recordEvent(tenantId, metricType)`, `getTokenTrend(tenantId, days)`, `getAgentActivity(tenantId)`, `getAgentUsageSummary(tenantId)` with JSDoc
- [x] 2.2 Add analytics event recording to `OAuth2Service.issueToken()` — fire-and-forget (non-blocking)
- [x] 2.3 Add analytics event recording to `AgentService.create()` and `AgentService.deactivate()`
- [x] 2.4 Create `src/controllers/AnalyticsController.ts` — GET /api/analytics/tokens, GET /api/analytics/agents/activity, GET /api/analytics/agents
- [x] 2.5 Create `src/routes/analytics.ts` and register under `/api/analytics` in `src/app.ts` (guarded by `ANALYTICS_ENABLED` flag)
- [x] 2.6 Add input validation: `days` param capped at 90, tenant scoping enforced on all queries

## 3. WS3 — Analytics Portal Pages

- [x] 3.1 Add `recharts` and `date-fns` to `portal/package.json`
- [x] 3.2 Create `portal/src/components/charts/TokenTrendChart.tsx` — recharts LineChart, lazy-loadable
- [x] 3.3 Create `portal/src/components/charts/AgentHeatmap.tsx` — recharts custom heatmap, lazy-loadable
- [x] 3.4 Create `portal/src/pages/analytics/index.tsx` — uses `next/dynamic` for chart components, fetches from `/api/analytics/*`
- [x] 3.5 Add `/analytics` route to portal navigation (`portal/src/components/Sidebar.tsx` or equivalent)
- [x] 3.6 Verify `next build` succeeds and analytics chunk is separate from main bundle

## 4. WS4 — API Gateway Tiers Backend

- [x] 4.1 Create `src/middleware/tierEnforcement.ts` — reads `req.tenant.tier`, checks Redis `rate:tier:calls:<tenant_id>` against `TIER_CONFIG`, sets rate limit headers on all responses
- [x] 4.2 Register `tierEnforcement` middleware in `src/app.ts` after auth middleware, before routes (skip when `TIER_ENFORCEMENT=false`)
- [x] 4.3 Add agent count enforcement in `AgentService.create()` — query active agent count vs. tier limit, throw typed `TierLimitError` if exceeded
- [x] 4.4 Create `src/services/TierService.ts` — `getStatus(tenantId)`, `initiateUpgrade(tenantId, targetTier)`, `applyUpgrade(tenantId, tier)` (called from Stripe webhook)
- [x] 4.5 Create `src/controllers/TierController.ts` — GET /api/tiers/status, POST /api/tiers/upgrade
- [x] 4.6 Create `src/routes/tiers.ts` and register under `/api/tiers` in `src/app.ts`
- [x] 4.7 Update Stripe webhook handler (`src/services/BillingService.ts`) to call `TierService.applyUpgrade()` on `checkout.session.completed` for tier upgrade events
- [x] 4.8 Add `TierLimitError` to error hierarchy in `src/errors/index.ts` — HTTP 429, `tier_limit_exceeded` code

## 5. WS4 — Tier Portal Page

- [x] 5.1 Create `portal/src/pages/settings/tier.tsx` — displays current tier, limits, usage, upgrade button
- [x] 5.2 Upgrade button calls `POST /api/tiers/upgrade` and redirects to Stripe checkout URL
- [x] 5.3 Enterprise tier view shows "Unlimited" with no upgrade button
- [x] 5.4 Add `/settings/tier` to portal navigation

## 6. WS6 — AGNTCY Compliance Backend

- [x] 6.1 Create `src/services/ComplianceService.ts` — `generateReport(tenantId)` building all compliance sections, `exportAgentCards(tenantId)`, Redis cache with 5-minute TTL
- [x] 6.2 Implement `agent-identity` section: check all active agents for valid DID, non-expired credential, agent card presence
- [x] 6.3 Implement `audit-trail` section: verify Merkle chain integrity for tenant's audit events
- [x] 6.4 Implement agent card export: map agent records to AGNTCY agent card JSON schema v1.0
- [x] 6.5 Create `src/controllers/ComplianceController.ts` — GET /api/compliance/report, GET /api/compliance/agent-cards
- [x] 6.6 Create `src/routes/compliance.ts` and register under `/api/compliance` in `src/app.ts` (guarded by `COMPLIANCE_ENABLED` flag)

## 7. WS6 — AGNTCY Conformance Test Suite

- [x] 7.1 Create `tests/agntcy-conformance/` directory with Jest config
- [x] 7.2 Write conformance test: agent registration creates DID:WEB identifier
- [x] 7.3 Write conformance test: token issuance for agent client
- [x] 7.4 Write conformance test: A2A delegation chain create + verify
- [x] 7.5 Write conformance test: compliance report generation returns valid structure
- [x] 7.6 Add `test:agntcy-conformance` npm script to `package.json`

## 8. QA & Release

- [x] 8.1 Write unit tests for `AnalyticsService` — event recording, trend query, heatmap query, usage summary (>80% coverage)
- [x] 8.2 Write unit tests for `TierService` — tier status, upgrade initiation, tier limit enforcement
- [x] 8.3 Write unit tests for `ComplianceService` — report generation, agent card export, cache hit/miss
- [x] 8.4 Write integration tests for all analytics endpoints (`/api/analytics/*`)
- [x] 8.5 Write integration tests for all tier endpoints (`/api/tiers/*`) including Stripe webhook
- [x] 8.6 Write integration tests for compliance endpoints (`/api/compliance/*`) including feature flag behavior
- [x] 8.7 Run full test suite — verify >80% coverage on all new services
- [x] 8.8 Run `tsc --noEmit` across API, portal, and CLI — zero errors
- [x] 8.9 Run `next build` for portal — verify clean build and code-split chunks
- [x] 8.10 Verify feature flags: `ANALYTICS_ENABLED=false` → 404 on analytics routes; `TIER_ENFORCEMENT=false` → no 429s; `COMPLIANCE_ENABLED=false` → 404 on compliance routes
- [x] 8.11 Run AGNTCY conformance suite — all tests pass
- [x] 8.12 Commit Phase 6 with message `feat(phase-6): WS3+WS4+WS6 — Analytics, Tiers, AGNTCY Compliance`
