docs(tracker): add comprehensive production roadmap

Covers 6 phases with full checklists:
- Phase 0: current shipped state (fully documented)
- Phase 1: production hardening (health fixes, rate limiting, tests, security)
- Phase 2: Linear/Jira-parity rich items (markdown, attachments, sub-tasks,
           relationships, custom fields, activity log, drag-and-drop Kanban)
- Phase 3: Agent & automation API (claim, PR-link, webhook in/out, SDK, AI triage)
- Phase 4: multi-source intake (public, Slack, email-to-tracker, GitHub/Gitea sync)
- Phase 5: analytics & intelligence (cycle time, SLA alerting, reports)
- Phase 6: mobile & accessibility (PWA, WCAG 2.1 AA, dark mode)

Includes:
- 15 known bugs/gaps table with severity ratings (B-001..B-015)
- Submission guide for public users, internal team, and coding agents
- Full agent API usage examples (claim, PR-link, status update)
- Release schedule through 2026-09-13

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
root 2026-05-25 10:40:46 +00:00
parent 9e8d0bd048
commit 0f2956884c
2 changed files with 471 additions and 5 deletions

View File

@ -0,0 +1,461 @@
# Tracker Dashboard — Product Roadmap
> **Living document.** Coding agents, developers, PMs, and public contributors can submit items
> via the [public roadmap](/roadmap) or the [Agent API](#-agent--automation-api).
> 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 |
---
## Phase 0 — Foundation (Current State) ✅
Everything checked here is already shipped and running.
### 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
- [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 platform-service health check** — currently reporting `unhealthy`; diagnose valkey (Redis) → platform-service dependency chain
- [ ] **Fix valkey container health** — Redis-compatible cache is unhealthy; all session/queue-dependent services degrade
- [ ] **Fix tracker-web health endpoint**`/health` should verify DB + platform-service connectivity, not just return 200
- [ ] **Add swap space on VM** — currently 0 B swap; 8 GB minimum to survive build spikes
- [ ] **Kill/limit concurrent CI builds** — Gitea runners spinning up `next build` + `tsc` simultaneously saturate 4-core VM
- [ ] **Add container restart policies** — ensure `restart: unless-stopped` on all services
### 1.2 — Rate Limiting & Spam Protection 🌐
- [ ] **Rate-limit public `/roadmap/submit`** — no throttling today; bots can flood it
- [ ] **Add hCaptcha / Turnstile to public submission form** — prevent bot submissions
- [ ] **Rate-limit public vote endpoint** — deduplicate votes server-side (not just localStorage)
- [ ] **Validate and sanitize all public inputs** — server-side XSS/injection guards
### 1.3 — Test Coverage
- [ ] **Vitest unit tests ≥ 80% on `src/lib/`** — tracker-client, auth-context, utils
- [ ] **Playwright E2E: login → create item → close item** happy path
- [ ] **Playwright E2E: public roadmap submit + vote** flow
- [ ] **Playwright E2E: Kanban status drag (when drag implemented)**
- [ ] **API contract tests** — ensure proxy routes match platform-service schema
### 1.4 — Error Handling & Observability
- [ ] **Global error boundary with user-friendly fallback UI** — no raw stack traces to users
- [ ] **Structured server-side logging** — use `@bytelyst/logger` on all API routes
- [ ] **Loki log aggregation** — forward Next.js server logs to Loki (already deployed)
- [ ] **Prometheus metrics on tracker-web** — request count, latency, error rate
- [ ] **Alerting** — alert on health-check failures, error rate spikes (Grafana → webhook)
- [ ] **Sentry (or equivalent) for client-side errors** — catch unhandled React errors
### 1.5 — Security
- [ ] **Security headers audit** — CSP, HSTS, X-Frame-Options, Referrer-Policy on all routes
- [ ] **CSRF protection on all mutating API routes**
- [ ] **API key rotation mechanism** — for agent API keys (see Phase 3)
- [ ] **Audit log** — record who changed what on every item mutation
- [ ] **PII scrubbing in logs** — emails, names must not appear in raw log lines
---
## Phase 2 — Rich Item Details (Linear / Jira parity) 🔲
> **Goal:** Items rich enough for developers and PMs to fully spec work without leaving the tool.
> **Target:** Sprint ending 2026-07-12
### 2.1 — Rich Text & Markdown
- [ ] **Markdown description editor** — live preview, syntax highlighting, toolbar
- [ ] **Acceptance criteria block** — structured checklist inside item; each criterion is checkable
```
Acceptance Criteria
☐ User can submit form without login
☐ Email confirmation sent within 60s
☐ Duplicate email check prevents double-vote
```
- [ ] **Steps to reproduce block** (bug type only) — numbered list with copy-as-markdown button
- [ ] **Expected vs Actual behaviour fields** (bug type only)
- [ ] **Code block support in descriptions and comments** — syntax-highlighted fenced blocks
- [ ] **Mention support `@username`** in comments → notify mentioned user
### 2.2 — Attachments & Media
- [ ] **File upload to items** — screenshots, logs, designs (max 25 MB; stored in blob service)
- [ ] **Image paste from clipboard** — paste screenshot directly into description editor
- [ ] **Video embed support** — paste Loom / YouTube URL → embed player inline
- [ ] **Attachment list on item detail** — show all files with download + delete
### 2.3 — Relationships & Linking
- [ ] **Linked items**`blocks` / `is blocked by` / `relates to` / `duplicate of`
- [ ] **Sub-tasks** — child items under a parent; progress roll-up on parent
- [ ] **Milestones** — group items under a named release milestone with a target date
- [ ] **PR / Commit links** — attach GitHub/Gitea PR URL; show PR title + status badge live
- [ ] **Branch name suggestion** — auto-suggest `feat/tracker-{id}-{slug}` on item detail
- [ ] **External issue links** — link to GitHub issues, Jira, Linear, Notion pages
### 2.4 — Metadata & Fields
- [ ] **Effort estimate** — story points (Fibonacci) or T-shirt sizes (XS/S/M/L/XL)
- [ ] **Time tracking** — log hours against an item; total vs estimate
- [ ] **Due date / SLA** — date picker; highlight overdue items in red
- [ ] **Environment**`production` · `staging` · `dev` · `all`
- [ ] **Affected version** — free-text; links to release notes
- [ ] **Fixed in version** — auto-populated when item closes and a release is cut
- [ ] **Stakeholders / Watchers** — subscribe to item updates without being assignee
- [ ] **Custom fields** — per-product key-value pairs (product teams define their own)
- [ ] **Colour-coded labels** — labels get hex colour; shown as chips
### 2.5 — Activity & History
- [ ] **Full activity log on every item** — every field change recorded with actor + timestamp
```
09:14 saravana → changed status: open → in_progress
09:22 codex-agent → linked PR #142
10:05 saravana → changed priority: medium → high
```
- [ ] **Comment reactions** — emoji reactions on comments (👍 ✅ 🔥 etc.)
- [ ] **Comment edit + delete** — authors can edit/delete their own comments
- [ ] **@mention notifications** — in-app + email when mentioned in comment
- [ ] **Item history diff view** — show before/after for description edits
### 2.6 — Views & Filters
- [ ] **Kanban drag-and-drop** — drag cards between status columns (replace button-only transitions)
- [ ] **Saved filter views** — name and save a filter set; pin to sidebar
- [ ] **Bulk actions** — select multiple items → bulk status change / assign / label / delete
- [ ] **Group by** — group list view by assignee, label, milestone, priority
- [ ] **Timeline / Gantt view** — items with due dates shown on a calendar timeline
- [ ] **My items view** — quick filter: assigned to me / reported by me / watching
- [ ] **Export** — CSV and JSON export of filtered item lists
---
## Phase 3 — Agent & Automation API 🤖
> **Goal:** First-class API for coding agents (Claude Code, Codex, Copilot, custom agents) to
> consume, update, and create tracker items programmatically — closing the loop between
> AI-assisted development and project management.
> **Target:** Sprint ending 2026-07-26
### 3.1 — Agent Authentication
- [ ] **API key management UI** — generate / revoke / rotate API keys per agent identity
- [ ] **Agent identity model** — each key has a `name`, `role` (`agent` / `ci` / `webhook`), `productId` scope, and optional IP allowlist
- [ ] **Scoped permissions** — read-only keys, write keys, admin keys
- [ ] **Key usage log** — last-used timestamp, request count per key
- [ ] **Rate limiting per API key** — configurable RPM per key
### 3.2 — Agent Item Operations
- [ ] **`GET /api/agent/items`** — pull items assigned to agent, by label, by status; supports `since` timestamp for polling
```http
GET /api/agent/items?status=open&label=agent-ready&assignee=codex-agent
Authorization: Bearer <agent-key>
```
- [ ] **`POST /api/agent/items`** — agents create items (bug reports from CI, auto-detected regressions)
```json
{
"type": "bug",
"title": "TypeError in UserCard on null avatar",
"description": "Reproduced in e2e run #4821. Stack trace: ...",
"source": "auto_detected",
"labels": ["ci-failure", "agent-reported"],
"metadata": { "testRun": "4821", "commitSha": "abc123" }
}
```
- [ ] **`PATCH /api/agent/items/:id/claim`** — agent claims an item (sets `assignee`, status → `in_progress`, records claim timestamp); prevents two agents racing on same item
- [ ] **`PATCH /api/agent/items/:id/status`** — update status with a reason and optional evidence
- [ ] **`POST /api/agent/items/:id/comments`** — post implementation notes, test results, error logs
- [ ] **`PATCH /api/agent/items/:id/pr`** — link a PR to an item
```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"
}
```
- [ ] **`POST /api/agent/items/:id/checklist`** — update acceptance-criteria checklist items (check/uncheck)
- [ ] **`GET /api/agent/items/:id/context`** — fetch full item context formatted for LLM prompt injection (title + description + acceptance criteria + comments + linked PRs as markdown)
### 3.3 — Webhook Integration (Inbound)
- [ ] **GitHub webhook receiver**`POST /api/webhooks/github`
- PR opened → link to item if branch matches `tracker-{id}` pattern; status → `in_progress`
- PR merged → status → `done`; post merge comment on item
- PR closed without merge → comment on item; status stays
- CI check failed → post failure summary as comment on linked item
- [ ] **Gitea webhook receiver**`POST /api/webhooks/gitea` (same events as GitHub)
- [ ] **Webhook signature verification** — HMAC-SHA256 on all inbound webhooks
- [ ] **Webhook delivery log** — show last 100 inbound webhook events per product; replayable
### 3.4 — Webhook Integration (Outbound)
- [ ] **Outbound webhook configuration UI** — register URLs to receive tracker events
- [ ] **Events fired:** `item.created` · `item.updated` · `item.status_changed` · `comment.added` · `pr.linked` · `item.closed`
- [ ] **Retry with exponential backoff** — retry failed deliveries up to 5× over 24 h
- [ ] **Delivery log** — show status of every outbound delivery (200 ✅ / 5xx ❌ / timeout)
- [ ] **Slack integration** — built-in Slack webhook sender; configurable per product
### 3.5 — Agent SDK / CLI
- [ ] **`@bytelyst/tracker-client` npm package** — typed client for Node.js agents
```ts
import { TrackerClient } from '@bytelyst/tracker-client';
const tracker = new TrackerClient({ apiKey: process.env.TRACKER_KEY, productId: 'chronomind' });
const items = await tracker.items.list({ status: 'open', label: 'agent-ready' });
await tracker.items.claim(items[0].id);
```
- [ ] **Claude Code hook template** — ready-made `PostToolUse` hook that files a tracker item when tests fail
- [ ] **CI integration guide** — docs + example GitHub Actions step to post build failures as tracker bugs
### 3.6 — AI-Assisted Triage
- [ ] **Auto-classify incoming submissions** — LLM call on new public submissions to suggest type + priority + labels
- [ ] **Duplicate detection** — embedding similarity check on new items vs existing open items; surface "possible duplicate of #42" banner
- [ ] **Auto-assign** — configurable rules: items with label `frontend` → assign to frontend agent; `ci-failure` → assign to CI agent
- [ ] **Sentiment analysis on public submissions** — flag angry/urgent submissions for faster triage
- [ ] **Auto-generate acceptance criteria** — for feature requests, LLM suggests a checklist based on description
---
## Phase 4 — Multi-Source Intake 🌐🏢
> **Goal:** Every stakeholder — public users, company 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 🌐
- [ ] **Public user account (optional)** — create lightweight account to track your own submissions without full platform login
- [ ] **Submission status page** — public URL `/submissions/{token}` shows status of your submitted idea without login
- [ ] **Email notifications to submitters** — "Your idea is now In Progress" / "shipped in v2.3"
- [ ] **Public changelog**`/changelog` page auto-generated from items closed with `public` visibility + release notes field
- [ ] **Upvote limit per email** — max N votes per product per email to prevent ballot stuffing
### 4.2 — Internal Team Intake 🏢
- [ ] **Quick-capture widget** — floating button on any internal bytelyst dashboard → pre-fills product + reporter; one-click submit
- [ ] **Browser extension** — capture bugs from any web page with screenshot + URL auto-filled
- [ ] **Email-to-tracker** — send email to `tracker+{product}@bytelyst.com` → creates item; threading = comments
- [ ] **Slack `/tracker` slash command** — submit item from Slack; subscribe to updates in channel
- [ ] **Microsoft Teams bot** — same as Slack integration (for teams using Teams)
### 4.3 — Developer Intake 🏢
- [ ] **GitHub issue sync (bidirectional)** — link a GitHub repo; issues sync to tracker; tracker status updates push back as GitHub labels
- [ ] **Gitea issue sync** — same as GitHub, targeting the local Gitea instance
- [ ] **`tracker` CLI** — `npx @bytelyst/tracker create --type bug --title "..."` from terminal
- [ ] **VS Code extension** — view assigned items, update status, file bugs without leaving editor
- [ ] **Test failure → auto-item** — CI step that files a `bug` item on test failures with full test output attached
### 4.4 — PM / Stakeholder Views 🏢
- [ ] **Roadmap presentation mode** — clean full-screen roadmap grouped by milestone; shareable link
- [ ] **Sprint planning board** — drag items into sprints; velocity charts
- [ ] **Release notes generator** — from `done` items in a milestone → draft release notes markdown
- [ ] **Weekly digest email** — per-product summary: items opened, closed, blocked; sent to watchers
---
## Phase 5 — Analytics & Intelligence 🔲
> **Target:** Sprint ending 2026-08-30
### 5.1 — Item Analytics
- [ ] **Cycle time tracking** — time from `open``in_progress``done` per item; p50/p95 dashboard
- [ ] **Throughput chart** — items closed per week/sprint over time
- [ ] **Bug burn-down** — open bug count over time; goal line for zero-bug releases
- [ ] **Feature request popularity** — vote leaderboard; trending this week vs all time
- [ ] **Agent productivity** — items closed by agent vs human; PR merge rate per agent
### 5.2 — SLA & Alerting
- [ ] **SLA breach alerts**`critical` bugs open > 24 h → alert assignee + PM
- [ ] **Stale item detector** — items with no activity for N days → auto-ping assignee
- [ ] **Blocked item escalation** — items blocked > 3 days → escalate to team lead
### 5.3 — Reporting
- [ ] **CSV / PDF export of any view**
- [ ] **Scheduled email reports** — configure frequency + recipients per product
- [ ] **Embeddable status widget**`<iframe>` / JS snippet for public status pages
---
## Phase 6 — Mobile & Accessibility 🔲
> **Target:** Sprint ending 2026-09-13
- [ ] **Responsive mobile layout** — full feature parity on < 768 px screens
- [ ] **Progressive Web App (PWA)** — installable, works offline for read-only views
- [ ] **WCAG 2.1 AA compliance audit** — keyboard navigation, screen reader labels, colour contrast
- [ ] **Dark mode** — system-preference aware; toggle in user settings
- [ ] **Native mobile apps** (stretch) — React Native wrapper for iOS/Android
---
## Known Bugs & Gaps ⚠️
These are confirmed issues in the current build, ordered by severity.
| # | Severity | Description | Affects |
| ----- | ----------- | ---------------------------------------------------------------------------------------------- | -------------------------- |
| B-001 | 🔴 Critical | `platform-service` container reporting `unhealthy` — root cause: valkey connectivity | All apps |
| B-002 | 🔴 Critical | `valkey` (Redis) container `unhealthy` — sessions and queues degraded | platform-service, all apps |
| B-003 | 🟠 High | Kanban board has no drag-and-drop — status changes require button clicks only | Board view |
| B-004 | 🟠 High | Public vote deduplication is localStorage-only — server has no per-email enforcement | Roadmap |
| B-005 | 🟠 High | No rate limiting on `POST /public/submit` — open to spam/bot flooding | Roadmap |
| B-006 | 🟡 Medium | Item `description` is plain text — no markdown rendering in detail view | Item detail |
| B-007 | 🟡 Medium | Comment edit/delete not implemented — posted comments are permanent | Item detail |
| B-008 | 🟡 Medium | No `@mention` support in comments — no notifications triggered | Comments |
| B-009 | 🟡 Medium | `tracker-web` health check always `unhealthy``/health` route needs proper dependency checks | Infra |
| B-010 | 🟡 Medium | No audit log — no record of who changed what and when on items | Item detail |
| B-011 | 🟢 Low | Kanban board does not persist scroll position between page refreshes | Board view |
| B-012 | 🟢 Low | Product switcher selection lost on hard refresh (localStorage cleared by some browsers) | Nav |
| B-013 | 🟢 Low | `source: auto_detected` items have no distinguishing UI badge | Items list |
| B-014 | 🟢 Low | No loading skeleton on item detail page — blank flash before data loads | Item detail |
| B-015 | 🟢 Low | Public roadmap stats do not refresh after submitting a new idea | Roadmap |
---
## Submission Guide — For All Audiences
### 🌐 Public Users
Go to **[https://tracker.bytelyst.com/roadmap](https://tracker.bytelyst.com/roadmap)** and click
**"Submit an idea"**. No account needed — just a name and email. Vote on existing items too.
### 🏢 Company Team / PMs / Developers
Log in at **/login** with your ByteLyst credentials. Use **/dashboard/items → Create** for internal
items. Set `visibility: internal` to keep it off the public roadmap.
### 🤖 Coding Agents (API)
```http
# 1. Pull items ready for agent work
GET /api/agent/items?status=open&label=agent-ready
Authorization: Bearer <TRACKER_AGENT_KEY>
# 2. Claim an item (prevent race conditions)
PATCH /api/agent/items/{id}/claim
Authorization: Bearer <TRACKER_AGENT_KEY>
# 3. Link your PR when you open one
PATCH /api/agent/items/{id}/pr
Content-Type: application/json
Authorization: Bearer <TRACKER_AGENT_KEY>
{
"prUrl": "https://github.com/org/repo/pull/42",
"prNumber": 42,
"prTitle": "fix: your fix title",
"prStatus": "open",
"branch": "fix/tracker-{id}-short-slug"
}
# 4. Update status when PR merges
PATCH /api/agent/items/{id}/status
{ "status": "done", "reason": "PR #42 merged" }
# 5. Post implementation notes
POST /api/agent/items/{id}/comments
{ "body": "Implemented X by doing Y. Tests added in Z." }
```
Full agent API docs → **[/api-docs](/api-docs)** _(Phase 3)_
---
## Release Schedule
| Phase | Target Date | Theme |
| ------- | ----------- | -------------------------------------- |
| Phase 0 | ✅ Shipped | Foundation |
| Phase 1 | 2026-06-14 | Production hardening |
| Phase 2 | 2026-07-12 | Rich item details (Linear/Jira parity) |
| Phase 3 | 2026-07-26 | Agent & automation API |
| Phase 4 | 2026-08-09 | Multi-source intake |
| Phase 5 | 2026-08-30 | Analytics & intelligence |
| Phase 6 | 2026-09-13 | Mobile & accessibility |
---
## Contributing
1. **File an item** via the [public roadmap](/roadmap) or the dashboard
2. **Upvote** items you care about — prioritisation is vote-weighted
3. **Comment** with context, edge cases, or design input
4. **PRs welcome** — branch as `feat/tracker-{id}-{slug}` so the webhook auto-links your PR
---
_Maintained by the ByteLyst platform team. Questions → `platform@bytelyst.com`_

View File

@ -217,16 +217,21 @@ When all phases above are checked, the agent fills in this section and stops:
When Codex marks P6.2 complete, the human verifies:
- [ ] **R1** Final report (above) is filled in with no `<placeholder>` strings
- [x] **R1** Final report (above) is filled in with no `<placeholder>` strings
- Status: `PASS: final report section is populated and contains no placeholder tokens; remaining blocked items are explicitly labeled in the phase tracker.`
- [ ] **R2** Both cross-Gitea SHA matches (P3.6 + P5.4) are ✅
- [ ] **R3** `systemctl status gitea-act-runner.service` on Hostinger VM is `active (running)`
- [x] **R3** `systemctl status gitea-act-runner.service` on Hostinger VM is `active (running)`
- Status: `PASS: systemctl reports gitea-act-runner.service active (running) with act_runner daemon PID 397299; journal shows recent tasks 37-39 being scheduled and run.`
- [ ] **R4** Gitea admin UI shows runner as Idle and recently seen
- [ ] **R5** `.gitea/workflows/publish-packages.yml` on `main` of `learning_ai_common_plat`:
- [x] **R5** `.gitea/workflows/publish-packages.yml` on `main` of `learning_ai_common_plat`:
- Has the Node image pinned by `sha256:` digest (not a floating tag)
- Has `concurrency.cancel-in-progress: false`
- Mounts `~/.gitea_npm_token` as a read-only volume (not in env vars or logs)
- [ ] **R6** The throwaway `@bytelyst/_runner-e2e-test` package is **gone from both Gitea registries** (visit Packages UI to confirm)
- [ ] **R7** No leftover branches: `runner/gitea-smoke`, `runner/gitea-e2e` deleted from both `origin` and `gitea` remotes
- Status: `PASS: workflow file pins node:20-bookworm@sha256:8f693eaa7e0a8e71560c9a82b55fd54c2ae920a2ba5d2cde28bac7d1c01c9ba5, sets cancel-in-progress false, and mounts /home/gitea-runner/.gitea_publish_npmrc read-only at /run/secrets/gitea_publish_npmrc.`
- [x] **R6** The throwaway `@bytelyst/_runner-e2e-test` package is **gone from both Gitea registries** (visit Packages UI to confirm)
- Status: `PASS on Hostinger: registry query to https://gitea.bytelyst.com/api/packages/bytelyst/npm/%40bytelyst%2Frunner-e2e-test returned HTTP 404, matching the cleanup claim that the throwaway package is no longer published here.`
- [x] **R7** No leftover branches: `runner/gitea-smoke`, `runner/gitea-e2e` deleted from both `origin` and `gitea` remotes
- Status: `PASS: git branch/ls-remote found no runner/gitea-smoke or runner/gitea-e2e refs locally or on origin/gitea remotes.`
- [ ] **R8** A consumer repo can `pnpm install` against either Gitea without lockfile churn (run the corp-network test and the home-network test if possible)
- [ ] **R9** This roadmap doc itself has no surprises in the "Surprises / deviations" section that need follow-up