From 930f97ff63aeaed76747876e09343af1714dbc94 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 25 May 2026 11:28:55 +0000 Subject: [PATCH] docs(tracker): move ROADMAP to docs/ + scaffold NoteLett-style structure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reorganises tracker-web docs to match the NoteLett + FlowMonk sibling-repo convention. Old root ROADMAP.md replaced by full docs/ scaffold: docs/ ├── ROADMAP.md (master phase tracker, v3) ├── PRD.md (product requirements doc) ├── PRODUCTION_READINESS_HANDOFF_ROADMAP.md (adapted from NoteLett) ├── IMPLEMENTATION_TRACKER.md (per-slice tracker w/ commit SHAs) └── roadmaps/ ├── 00_MASTER_EXECUTION_PLAN.md └── 01_FOUNDATIONS_AND_DECISIONS.md Incorporates production-readiness learnings from recent work in sibling repos (May 22-23, 2026): From learning_ai_notes: - UI primitives migration via Primitives.tsx adapter (UI5-UI8 pattern) - UI drift ratchet CI gate (one-way enforcement, hard-zero categories) - Docker hardening: NEXT_PUBLIC bake-time, standalone static-chunks fix, corp-proxy build args, tarball-based docker-prep.sh - Cosmos emulator smoke job for partition-key path coverage - Live shared-service smoke (pnpm smoke:local) - MEK rotation + secret-management runbooks - React+React-DOM pnpm.overrides pin - Backend domain events emission (item.created, status_changed, etc.) - Workspace-path canonicalization From learning_ai_flowmonk: - @axe-core/playwright accessibility tests in CI - E2E cleanup traps (prevent orphan resource accumulation) - Playwright deployed-stack support (BASE_URL switch) - IPv4 healthcheck (127.0.0.1, not localhost) - Mobile palette centralization (theme/colors.ts) - Release guards CI workflow - Runtime replay preview pattern (for webhook event replay) Adds 5 new bugs to known-issues table (B-019..B-023) for hardcoded colors, direct ui imports, NEXT_PUBLIC runtime hardcoding, no mobile layout, no i18n. New Phase 6 expanded to cover mobile + a11y + i18n + theming. Phase 4 expanded with cross-product routing + import wizard. Co-Authored-By: Claude Sonnet 4.6 --- dashboards/tracker-web/ROADMAP.md | 623 ----------------- .../docs/IMPLEMENTATION_TRACKER.md | 171 +++++ dashboards/tracker-web/docs/PRD.md | 151 ++++ .../PRODUCTION_READINESS_HANDOFF_ROADMAP.md | 222 ++++++ dashboards/tracker-web/docs/ROADMAP.md | 656 ++++++++++++++++++ .../docs/roadmaps/00_MASTER_EXECUTION_PLAN.md | 127 ++++ .../roadmaps/01_FOUNDATIONS_AND_DECISIONS.md | 270 +++++++ 7 files changed, 1597 insertions(+), 623 deletions(-) delete mode 100644 dashboards/tracker-web/ROADMAP.md create mode 100644 dashboards/tracker-web/docs/IMPLEMENTATION_TRACKER.md create mode 100644 dashboards/tracker-web/docs/PRD.md create mode 100644 dashboards/tracker-web/docs/PRODUCTION_READINESS_HANDOFF_ROADMAP.md create mode 100644 dashboards/tracker-web/docs/ROADMAP.md create mode 100644 dashboards/tracker-web/docs/roadmaps/00_MASTER_EXECUTION_PLAN.md create mode 100644 dashboards/tracker-web/docs/roadmaps/01_FOUNDATIONS_AND_DECISIONS.md diff --git a/dashboards/tracker-web/ROADMAP.md b/dashboards/tracker-web/ROADMAP.md deleted file mode 100644 index fe012b90..00000000 --- a/dashboards/tracker-web/ROADMAP.md +++ /dev/null @@ -1,623 +0,0 @@ -# Tracker Dashboard — Product Roadmap - -> **Living document.** Coding agents, developers, PMs, and public contributors can submit items -> via the [public roadmap](https://tracker.bytelyst.com/roadmap) or the [Agent API](#-agent--automation-api). -> Deployed at **https://tracker.bytelyst.com** · Last updated: 2026-05-25. - ---- - -## Legend - -| Symbol | Meaning | -| ------ | ----------------------------- | -| ✅ | Shipped / complete | -| 🔄 | In progress | -| 🔲 | Planned — not started | -| 🤖 | Agent-targeted feature | -| 🌐 | Public-facing feature | -| 🏢 | Internal / team feature | -| ⚠️ | Known bug / gap | -| 🔗 | Depends on another phase item | - ---- - -## Permissions Matrix - -| Action | Public (no login) | Auth User | PM / Admin | Agent (API key) | -| -------------------- | :---------------: | :-------: | :--------: | :-------------: | -| View public roadmap | ✅ | ✅ | ✅ | ✅ | -| Submit public idea | ✅ | ✅ | ✅ | ✅ | -| Vote on public item | ✅ | ✅ | ✅ | ✅ | -| View internal items | ❌ | ✅ | ✅ | ✅ (scoped) | -| Create internal item | ❌ | ✅ | ✅ | ✅ (write key) | -| Edit any item | ❌ | own only | ✅ | ✅ (write key) | -| Delete item | ❌ | ❌ | ✅ | ❌ | -| Change status | ❌ | ✅ | ✅ | ✅ (write key) | -| Claim item | ❌ | ❌ | ❌ | ✅ (write key) | -| Link PR to item | ❌ | ✅ | ✅ | ✅ (write key) | -| Manage API keys | ❌ | ❌ | ✅ | ❌ | -| Configure webhooks | ❌ | ❌ | ✅ | ❌ | -| Access analytics | ❌ | ❌ | ✅ | 🔲 (read key) | - ---- - -## Phase 0 — Foundation (Current State) ✅ - -Everything checked here is already shipped and running at **https://tracker.bytelyst.com**. - -### Core Item Management ✅ - -- [x] Create / read / update / delete tracker items -- [x] Item types: `bug` · `feature` · `task` -- [x] Statuses: `open` → `in_progress` → `done` → `closed` · `wont_fix` -- [x] Priority levels: `critical` · `high` · `medium` · `low` -- [x] Visibility toggle: `internal` vs `public` -- [x] Labels (free-text array) -- [x] Assignee field -- [x] Reporter / `reportedBy` tracking -- [x] Target release field -- [x] Source tracking: `internal` · `user_submitted` · `auto_detected` -- [x] Vote count per item -- [x] Comment count per item - -### Views ✅ - -- [x] Dashboard overview with stats (by type / status / priority) -- [x] Items list with search, filter, paginate -- [x] Kanban board (4-column status board) -- [x] Item detail page with inline edits - -### Public Roadmap ✅ - -- [x] Public `/roadmap` page — no auth required -- [x] Board / list view toggle -- [x] Submit idea form (name + email + type + description) -- [x] Email-based voting (stored in localStorage) -- [x] Stats bar (total · votes · in-progress · completed) -- [x] Search and filter by type - -### Authentication ✅ - -- [x] Email + password login via platform-service -- [x] MFA (multi-factor authentication) -- [x] Google OAuth -- [x] JWT token refresh -- [x] Product switcher (multi-product support via `x-product-id` header) - -### Infrastructure ✅ - -- [x] Dockerised (standalone Next.js build) -- [x] Caddy reverse proxy with HTTPS (`tracker.bytelyst.com`) -- [x] PostHog analytics integration -- [x] Vitest unit tests -- [x] Playwright E2E scaffolding -- [x] ESLint + Prettier + Husky git hooks - ---- - -## Phase 1 — Production Hardening 🔄 - -> **Goal:** Make everything that's built actually reliable in production. -> **Target:** Sprint ending 2026-06-14 - -### 1.1 — Infrastructure Health ⚠️ - -- [ ] **Fix valkey (Redis) container health** — currently `unhealthy`; root cause of most downstream container failures; all session/queue-dependent services degrade -- [ ] **Fix platform-service health check** — reports `unhealthy` due to valkey connectivity; fix after valkey is stable -- [ ] **Fix tracker-web `/health` route** — must actively probe DB + platform-service reachability, not just return HTTP 200 -- [ ] **Add 8 GB swap space on VM** — currently 0 B swap; build spikes cause OOM-kills of running services -- [ ] **Limit concurrent Gitea CI runner jobs** — cap to 1–2 simultaneous `next build` + `tsc` jobs; 4-core VM cannot survive 4+ parallel builds -- [ ] **Ensure `restart: unless-stopped`** on all docker-compose services — several containers don't auto-recover after VM reboot - -### 1.2 — Rate Limiting & Spam Protection 🌐 - -- [ ] **Rate-limit `POST /public/submit`** — no throttling today; minimum 10 req/min per IP -- [ ] **Add Cloudflare Turnstile (or hCaptcha) to public submission form** — bot-proof without user friction -- [ ] **Server-side vote deduplication per email** — current dedup is localStorage-only and trivially bypassed -- [ ] **Validate and sanitise all public inputs server-side** — XSS / injection guard on title, description, name, email - -### 1.3 — Test Coverage - -- [ ] **Vitest unit tests ≥ 80 % on `src/lib/`** — `tracker-client.ts`, `auth-context.tsx`, `utils.ts` -- [ ] **Playwright E2E: login → create item → transition to done** happy path -- [ ] **Playwright E2E: public roadmap submit + vote** flow -- [ ] **Playwright E2E: Kanban status transitions** (update after drag-and-drop ships in Phase 2) -- [ ] **API contract tests** — verify proxy routes match platform-service OpenAPI schema - -### 1.4 — Error Handling & Observability - -- [ ] **Global React error boundary with friendly fallback** — no raw stack traces leaked to users -- [ ] **Structured server-side logging** via `@bytelyst/logger` on all Next.js API routes -- [ ] **Loki log aggregation** — forward Next.js server logs into the already-deployed Loki instance -- [ ] **Prometheus metrics** — expose `/metrics`; scrape request count, latency p50/p95, error rate -- [ ] **Grafana alert** on health-check failure and error rate > 1 % -- [ ] **Sentry (or `@bytelyst/diagnostics-client`)** for client-side unhandled React errors - -### 1.5 — Security - -- [ ] **Security headers audit** — CSP, HSTS, X-Frame-Options, Referrer-Policy, Permissions-Policy -- [ ] **CSRF tokens on all mutating API routes** -- [ ] **API key rotation mechanism** — prerequisite for Phase 3 agent keys -- [ ] **Audit log on every item mutation** — `{ actor, action, field, before, after, timestamp }` written to append-only log -- [ ] **PII scrubbing in logs** — emails and names must not appear in plaintext log lines - ---- - -## Phase 2 — Rich Item Details (Linear / Jira parity) 🔲 - -> **Goal:** Items rich enough for developers, PMs, and agents to fully spec, reproduce, and track -> work without leaving the tool. -> **Target:** Sprint ending 2026-07-12 - -### 2.1 — Expanded Item Types & Statuses - -- [ ] **New item types:** `improvement` (enhances existing feature) · `chore` (infra / maintenance / dependency bumps) -- [ ] **Custom status workflows** — products can define extra statuses beyond the default five (e.g., `needs_review`, `blocked`, `in_qa`) -- [ ] **`wont_fix` reason field** — free-text explanation required when closing as `wont_fix` -- [ ] **Reopen flow** — explicit "Reopen" action with mandatory comment; audit-logged - -### 2.2 — Rich Text & Markdown - -- [ ] **Markdown description editor** — live side-by-side preview, toolbar, keyboard shortcuts (bold, italic, code, link) -- [ ] **Acceptance criteria checklist** — structured `- [ ]` items inside description; individually checkable by any team member or agent - ```markdown - ## Acceptance Criteria - - - [ ] User can submit form without login - - [ ] Email confirmation sent within 60 s - - [ ] Duplicate-email server-side check prevents double vote - - [ ] Rate limit returns 429 with `Retry-After` header - ``` -- [ ] **Steps to reproduce** (bug type only) — numbered list; "Copy as markdown" button -- [ ] **Expected vs Actual behaviour fields** (bug type only) — separate text areas shown side-by-side -- [ ] **Code blocks in descriptions and comments** — syntax-highlighted fenced blocks (Shiki) -- [ ] **`@username` mention in comments** → in-app + email notification to mentioned user -- [ ] **`source: auto_detected` UI badge** — distinct chip on items filed by CI/agents (fixes B-014) - -### 2.3 — Attachments & Media - -- [ ] **File uploads** — screenshots, logs, designs up to 25 MB; stored via `@bytelyst/blob` service -- [ ] **Clipboard paste into description** — paste screenshot → auto-upload → embed as `![image](url)` -- [ ] **Video embed** — paste Loom / YouTube URL → inline player in description -- [ ] **Attachment list on item detail** — filename, size, uploader, uploaded-at, download, delete - -### 2.4 — Relationships & Linking - -- [ ] **Linked items** — `blocks` / `is blocked by` / `relates to` / `duplicate of` with bidirectional display on both items -- [ ] **Sub-tasks** — child items nested under parent; parent shows `3/5 done` progress chip -- [ ] **Milestones** — named groupings with a target date; items can be assigned to one milestone -- [ ] **PR / commit links** — attach GitHub or Gitea PR URL; show live PR title + open/merged/closed badge _(prerequisite for Phase 3 webhook auto-linking)_ -- [ ] **Branch name chip** — auto-suggest `feat/tracker-{id}-{slug}` with one-click copy -- [ ] **External links** — arbitrary URL + label pairs (Notion doc, Figma frame, Confluence page, CI run) - -### 2.5 — Metadata & Custom Fields - -- [ ] **Effort estimate** — Fibonacci story points (1 2 3 5 8 13 21) or T-shirt sizes (XS S M L XL); picker on item detail -- [ ] **Time tracking** — log hours per session; show logged vs estimate; per-sprint burndown -- [ ] **Due date** — date picker; overdue items highlighted red in list and Kanban -- [ ] **Environment** — `production` · `staging` · `dev` · `all` -- [ ] **Affected version** — free-text; displayed as chip; links to changelog -- [ ] **Fixed in version** — auto-populated when item closes within a milestone -- [ ] **Watchers / stakeholders** — subscribe to all item updates without being the assignee -- [ ] **Custom fields** — per-product admin defines field name + type (text, number, date, single-select); stored in `metadata` map -- [ ] **Colour-coded labels** — each label gets a hex colour; rendered as chips in list, Kanban card, and detail views -- [ ] **`metadata` map for agent data** — agents write arbitrary KV pairs (`{ testRunId, commitSha, ciJobUrl }`) without polluting core fields - -### 2.6 — Activity, History & Notifications - -- [ ] **Full activity log per item** — every field change, status transition, comment, attachment, PR link recorded with actor + timestamp - ``` - 09:14 saravana status: open → in_progress - 09:22 codex-agent linked PR #142 (open) - 09:45 codex-agent checklist: "Email confirmation sent within 60 s" ✅ - 10:05 saravana priority: medium → high - 10:31 codex-agent PR #142 status: open → merged - 10:31 codex-agent status: in_progress → done (reason: PR #142 merged) - ``` -- [ ] **Comment reactions** — emoji reactions (👍 ✅ 🔥 💡 ❓) on any comment -- [ ] **Comment edit + delete** — authors can edit within 15 min; admins can delete any comment -- [ ] **Item history diff view** — expandable before/after diff for description edits -- [ ] **Notification preferences** — per user, per item: all activity · mentions only · status changes · none -- [ ] **In-app notification centre** — bell icon with unread count; mark-all-read action - -### 2.7 — Real-Time Updates - -- [ ] **Server-Sent Events (SSE) on item detail** — status, comments, and activity log refresh live without polling -- [ ] **Kanban board live updates** — card moves and new cards appear in real-time for all active viewers -- [ ] **Optimistic UI** — status/priority changes apply instantly client-side; roll back on server error with toast - -### 2.8 — Views, Filters & Search - -- [ ] **Kanban drag-and-drop** — drag cards between status columns; persist to server immediately (fixes B-003) -- [ ] **Saved filter views** — name, save, and pin a filter combination to the sidebar -- [ ] **Bulk actions** — checkbox-select multiple items → bulk status change / assign / label / milestone / delete -- [ ] **Group by** — group list view by assignee · label · milestone · priority · type -- [ ] **Timeline / Gantt view** — items with due dates on a horizontal calendar; milestones as vertical markers -- [ ] **My items view** — quick filter tabs: assigned to me · reported by me · watching · mentioned in -- [ ] **Global search** — Ctrl+K full-text search across title + description for all products (admin); per-product search for members -- [ ] **Export** — CSV and JSON download of any filtered view; includes all metadata and custom fields - ---- - -## Phase 3 — Agent & Automation API 🤖 - -> **Goal:** First-class REST API for coding agents (Claude Code, Codex, Copilot Workspace, custom -> agents) to consume, update, and create tracker items — closing the loop between AI-assisted -> development and project management. -> **Target:** Sprint ending 2026-07-26 -> **Dependency:** Phase 2 acceptance-criteria checklist and PR link fields must ship first. - -### 3.1 — Agent Authentication - -- [ ] **API key management UI** (admin) — generate, revoke, rotate keys; set name + role + product scope + optional IP allowlist -- [ ] **Agent roles:** `agent-read` · `agent-write` · `ci` · `webhook` — minimum necessary permissions per role (see Permissions Matrix) -- [ ] **Key usage log** — last-used timestamp, request count, error count per key -- [ ] **Rate limits per key** — configurable RPM; `429 Too Many Requests` with `Retry-After` header on breach -- [ ] **Key expiry** — optional expiry date; keys auto-revoked on expiry -- [ ] **API versioning** — all agent routes under `/api/agent/v1/`; breaking changes bump version; old versions supported 6 months with `Deprecation` + `Sunset` headers - -### 3.2 — Agent Item Operations - -All routes require `Authorization: Bearer ` and `X-Product-Id: {productId}`. - -**Pull & Claim** - -- [ ] **`GET /api/agent/v1/items`** — list items with filters; cursor-based pagination; `since` for incremental sync - - ```http - GET /api/agent/v1/items?status=open&label=agent-ready&limit=20&cursor=&since=2026-05-20T00:00:00Z - Authorization: Bearer - X-Product-Id: chronomind - - # 200 Response - { - "items": [...], - "next_cursor": "eyJpZCI6IjEyMyJ9", - "has_more": true, - "total": 47 - } - ``` - -- [ ] **`PATCH /api/agent/v1/items/:id/claim`** — atomically assign to calling agent + transition to `in_progress`; returns `409 Conflict` if already claimed (prevents parallel agent races) - -**Create & Update** - -- [ ] **`POST /api/agent/v1/items`** — create item; `source` auto-set to `auto_detected` - ````json - { - "type": "bug", - "title": "TypeError: Cannot read properties of null (reading 'avatar')", - "description": "Reproduced in E2E run #4821 on `main` at commit `abc123`.\n\n```\nTypeError at UserCard.tsx:42\n```", - "source": "auto_detected", - "priority": "high", - "labels": ["ci-failure", "agent-reported", "frontend"], - "metadata": { - "testRun": "4821", - "commitSha": "abc123def456", - "ciJobUrl": "https://gitea.bytelyst.com/org/repo/actions/runs/4821" - } - } - ```` -- [ ] **`PATCH /api/agent/v1/items/:id/status`** — update status with mandatory `reason` and optional `evidenceUrl` - ```json - { - "status": "done", - "reason": "PR #142 merged", - "evidenceUrl": "https://github.com/org/repo/pull/142" - } - ``` -- [ ] **`PATCH /api/agent/v1/items/:id/checklist`** — check/uncheck acceptance-criteria items by text match 🔗 _(requires Phase 2)_ - ```json - { "item": "Email confirmation sent within 60 s", "checked": true } - ``` -- [ ] **`POST /api/agent/v1/items/:id/comments`** — post implementation notes, test results, diffs, error logs - -**PR Integration** - -- [ ] **`PATCH /api/agent/v1/items/:id/pr`** — link or update a PR; callable multiple times as PR status evolves - ```json - { - "prUrl": "https://github.com/org/repo/pull/142", - "prNumber": 142, - "prTitle": "fix: null-check avatar in UserCard", - "prStatus": "open", - "branch": "fix/tracker-789-null-avatar", - "commitSha": "abc123def456", - "ciStatus": "pending" - } - ``` - `prStatus`: `open` · `merged` · `closed` · `draft` - `ciStatus`: `pending` · `success` · `failure` · `cancelled` - -**Context** - -- [ ] **`GET /api/agent/v1/items/:id/context`** — full item as LLM-ready markdown: title, description, acceptance criteria, comments, linked PRs, activity log; ideal for agent system-prompt injection - - ```markdown - # Tracker #789: TypeError in UserCard on null avatar - - **Status:** open **Priority:** high **Assignee:** unassigned - - ## Description - - ... - - ## Acceptance Criteria - - - [ ] Null-check avatar before rendering - - [ ] Unit test covers null case - - [ ] No snapshot regression - - ## Recent Activity - - 2026-05-25 09:14 saravana: opened - ``` - -### 3.3 — Inbound Webhooks - -- [ ] **GitHub webhook receiver** — `POST /api/webhooks/github` - - PR opened → auto-link to item if branch matches `tracker-{id}` or `feat/tracker-{id}-*`; status → `in_progress` - - PR merged → status → `done`; post commit SHA + PR URL as comment - - PR closed without merge → post closure comment; status unchanged - - CI check failed → post failure summary + job URL as comment on linked item - - CI check passed → update `ciStatus` on linked PR -- [ ] **Gitea webhook receiver** — `POST /api/webhooks/gitea` (identical event handling, targeting `localhost:3300`) -- [ ] **HMAC-SHA256 signature verification** — reject unsigned inbound webhooks -- [ ] **Webhook event log** — last 100 inbound events per product; each replayable via UI - -### 3.4 — Outbound Webhooks - -- [ ] **Outbound webhook configuration UI** — register target URLs per product; choose subscribed event types -- [ ] **Events emitted:** `item.created` · `item.updated` · `item.status_changed` · `comment.added` · `pr.linked` · `pr.status_changed` · `checklist.checked` · `item.closed` -- [ ] **Retry with exponential backoff** — up to 5 retries over 24 h on non-2xx; final failure fires `webhook.delivery_failed` alert -- [ ] **Delivery log UI** — timestamp · target URL · event type · HTTP status · duration · response body snippet -- [ ] **Built-in Slack integration** — send formatted item cards to a Slack channel; configurable per product + per event type - -### 3.5 — Agent SDK & Tooling - -- [ ] **`@bytelyst/tracker-client` npm package** — typed Node.js client; auto-handles pagination cursor, retry, rate-limit backoff - - ```ts - import { TrackerClient } from '@bytelyst/tracker-client'; - - const tracker = new TrackerClient({ - apiKey: process.env.TRACKER_AGENT_KEY, - productId: 'chronomind', - }); - - for await (const item of tracker.items.stream({ status: 'open', label: 'agent-ready' })) { - await tracker.items.claim(item.id); - // ... implement fix ... - await tracker.items.linkPr(item.id, { prUrl, prNumber, prTitle, prStatus: 'open' }); - } - ``` - -- [ ] **Claude Code hook template** — ready-made `PostToolUse` hook that auto-files a tracker `bug` when tests fail; add to `.claude/settings.json` -- [ ] **CI integration guide** — GitHub Actions + Gitea Actions example steps to file bugs and update PR status -- [ ] **OpenAPI spec** — auto-generated; browsable at `/api-docs` - -### 3.6 — AI-Assisted Triage - -- [ ] **Auto-classify new submissions** — LLM call on every new item suggests `type`, `priority`, `labels`; shown as "AI suggestions" (human confirms or dismisses; never auto-applied) -- [ ] **Duplicate detection** — embedding similarity vs open items; surface "Possible duplicate of #42" if cosine similarity > 0.85 -- [ ] **Auto-assign rules** — configurable routing table: label `frontend` → `frontend-agent`; label `ci-failure` → `ci-agent`; editable by PM in settings -- [ ] **Sentiment analysis on public submissions** — flag angry/urgent submissions for fast-lane triage queue -- [ ] **Auto-generate acceptance criteria** 🔗 _(requires Phase 2 checklist)_ — LLM suggests starter `- [ ]` checklist for `feature` and `improvement` items; editable before saving - ---- - -## Phase 4 — Multi-Source Intake 🌐🏢 - -> **Goal:** Every stakeholder — public users, internal team, developers, and agents — has a -> frictionless native path to submit and track items. -> **Target:** Sprint ending 2026-08-09 - -### 4.1 — Public Submission Enhancements 🌐 - -- [ ] **Optional public account** — lightweight sign-up (email only) to track your own submissions; no access to internal items -- [ ] **Submission status page** — `/submissions/{token}` shows item status without login; token emailed on submit -- [ ] **Email notifications to submitters** — "Your idea moved to In Progress" / "Shipped in v2.3! Thanks for the report." -- [ ] **Public changelog** — `/changelog` auto-generated from `done` + `visibility: public` items grouped by milestone -- [ ] **Vote cap** — max 5 votes per email per product; server-enforced (proper fix for B-004) - -### 4.2 — Internal Team Intake 🏢 - -- [ ] **Quick-capture widget** — floating "Report issue" button embeddable in any internal dashboard via `