# atlas — Task Board Source of truth: [docs/PLAN-atlas.md](../docs/PLAN-atlas.md), [docs/adr/ADR-0001-atlas-cluster-visualization.md](../docs/adr/ADR-0001-atlas-cluster-visualization.md) Blocking decisions (must answer before Phase 1): [00-decisions.md](00-decisions.md) Rules carried from the ADR: - I1: `riotpiao.com` is the only public hostname, ever - I2: browser never talks to an internal API directly — atlas is the only origin - I3: redaction is allowlist-only, enforced by DTO construction - I4: no free-form string reaches an internal system (closed enum, snapshot-membership validation) - I5: GPU chat concurrency capped at 6 of 8 sequence slots, disconnect cancels upstream immediately - TDD: RED (tests named before code) -> GREEN (minimal code) -> REFACTOR, per phase - Playwright e2e is a hard requirement for every UI-shipping phase (2, 3, 4, 5) — no surface merges without a passing spec ## 0 — Unblock | Task | Description | |---|---| | [0.1](0.1-gitops-repo.md) | Resolve GitOps repo ownership | | [0.2](0.2-fix-nxdomain.md) | Fix NXDOMAIN repoURL/image reference | | [0.3](0.3-immutable-tags.md) | Replace :latest with commit-SHA tag | | [0.4](0.4-forgejo-init-stuck.md) | Diagnose forgejo-gitea stuck Init:0/3 — done | | [0.5](0.5-apex-403.md) | Diagnose apex 403 | | [0.6](0.6-vitest-setup.md) | Add Vitest + Testing Library + msw | | [0.6a](0.6a-playwright-setup.md) | Add Playwright (hard requirement) | | [0.7](0.7-triage-unrelated.md) | Triage unrelated cluster issues | ## 1 — Atlas Core | Task | Description | |---|---| | [1.1](1.1-redact-test.md) | redact_test.go (RED) | | [1.2](1.2-rbac-test.md) | rbac_test.go (RED) | | [1.3](1.3-snapshot-test.md) | snapshot_test.go (RED) | | [1.4](1.4-clusterrole.md) | ClusterRole (GREEN) | | [1.5](1.5-informers.md) | client-go informers (GREEN) | | [1.6](1.6-reducer.md) | Reducer: informer events -> snapshot (GREEN) | | [1.7](1.7-dto-allowlist.md) | DTO construction, allowlist only (GREEN) | | [1.8](1.8-redis-publish.md) | Redis publish (GREEN) | | [1.9](1.9-networkpolicy.md) | NetworkPolicy on atlas (GREEN) | | [1.10](1.10-container-hardening.md) | Container hardening (GREEN) | | [1.11](1.11-simplify-pass.md) | simplify skill pass (REFACTOR) | | [1.12](1.12-go-hygiene.md) | Go error-handling / context hygiene (REFACTOR) | ## 2 — Topology (Surface B) | Task | Description | |---|---| | [2.1](2.1-stream-test.md) | stream_test.go (RED) | | [2.2](2.2-topology-component-test.md) | topology.test.tsx (RED) | | [2.3](2.3-topology-e2e.md) | topology.e2e.ts (RED, Playwright — hard requirement) | | [2.4](2.4-api-topology.md) | GET /api/topology (GREEN) | | [2.5](2.5-api-stream.md) | GET /api/stream (GREEN) | | [2.6](2.6-frontend-react-flow.md) | Frontend: React Flow topology graph (GREEN) | | [2.7](2.7-security-headers.md) | Security headers (GREEN) | | [2.8](2.8-rate-limiting-tier1-2.md) | Rate limiting Tier 1 + Tier 2 (GREEN) | | [2.9](2.9-simplify-pass.md) | simplify skill pass (REFACTOR) | ## 3 — Delivery Tree (Surface E) | Task | Description | |---|---| | [3.1](3.1-delivery-test.md) | delivery_test.go (RED) | | [3.2](3.2-delivery-component-test.md) | delivery.test.tsx (RED) | | [3.3](3.3-delivery-e2e.md) | delivery.e2e.ts (RED, Playwright — hard requirement) | | [3.4](3.4-api-delivery.md) | GET /api/delivery (GREEN) | | [3.5](3.5-api-delivery-resources.md) | GET /api/delivery/{app}/resources (GREEN) | | [3.6](3.6-frontend-wave-columns.md) | Frontend: wave columns + resource tree (GREEN) | | [3.7](3.7-live-sync-animation.md) | Live sync animation (GREEN) | | [3.8](3.8-redaction-check.md) | Redaction check specific to delivery surface (GREEN) | | [3.9](3.9-simplify-pass.md) | simplify skill pass (REFACTOR) | | [3.10](3.10-landing-page-cleanup.md) | Landing page: remove fabricated stats and dead links (GREEN) | ## 4 — Terminal (Surface C) | Task | Description | |---|---| | [4.1](4.1-exec-parse-test.md) | exec_parse_test.go (RED) | | [4.2](4.2-exec-test.md) | exec_test.go (RED) | | [4.3](4.3-terminal-e2e.md) | terminal.e2e.ts (RED, Playwright — hard requirement) | | [4.4](4.4-api-exec.md) | POST /api/exec (GREEN) | | [4.5](4.5-command-set.md) | Command set (GREEN) | | [4.6](4.6-namespace-validation.md) | Namespace/resource-name validation by snapshot membership (GREEN) | | [4.7](4.7-no-shell-in-image.md) | No shell, no exec, no kubectl binary in image (GREEN) | | [4.8](4.8-frontend-terminal-wiring.md) | Frontend: wire InteractiveTerminal to /api/exec (GREEN) | | [4.9](4.9-structured-logging.md) | Structured logging of rejections (GREEN) | | [4.10](4.10-simplify-pass.md) | simplify skill pass (REFACTOR) | ## 5 — Chat + Rate Limiter (Surface D) | Task | Description | |---|---| | [5.1](5.1-ratelimit-test.md) | ratelimit_test.go (RED) | | [5.2](5.2-disconnect-test.md) | disconnect_test.go (RED) | | [5.3](5.3-budget-test.md) | budget_test.go (RED) | | [5.4](5.4-injection-test.md) | injection_test.go (RED) | | [5.5](5.5-context-test.md) | context_test.go (RED) | | [5.6](5.6-chat-e2e.md) | chat.e2e.ts (RED, Playwright — hard requirement) | | [5.7](5.7-api-chat.md) | POST /api/chat (GREEN) | | [5.8](5.8-rate-limiting-tier3.md) | Rate limiting Tier 3 (atlas) (GREEN) | | [5.9](5.9-queue-position-sse.md) | Queue position streamed as SSE (GREEN) | | [5.10](5.10-prompt-injection-defenses.md) | Prompt injection defenses (GREEN) | | [5.11](5.11-context-budget.md) | Context budget (GREEN) | | [5.12](5.12-chat-sse-events.md) | Chat SSE event types (GREEN) | | [5.13](5.13-frontend-chat-component.md) | Frontend: chat component (GREEN) | | [5.14](5.14-prometheus-metrics.md) | Prometheus metrics (GREEN) | | [5.15](5.15-alertmanager-rule.md) | Alertmanager rule (GREEN) | | [5.16](5.16-audit-ci-gate.md) | pnpm audit + govulncheck CI gate (GREEN) | | [5.17](5.17-simplify-pass.md) | simplify skill pass (REFACTOR) | ## Progress Not started, Phase 0 partially unblocked. 5 decisions still block Phase 1 — see [00-decisions.md](00-decisions.md). Status as of 2026-08-18: - 0.4 (forgejo-gitea Init stuck) — resolved, pod Running 1/1 - 0.7 (`longhorn-config` OutOfSync) — resolved, now Synced/Healthy; `sms` Degraded still open - `*.riotpiao.homelab.com` fully retired, replaced by `*.riotpiao.com` — confirmed root cause for 0.2 (dead-domain `repoURL`, not a broken forgejo pod) - 0.1/0.2 (portfolio GitOps repo, dead-domain repoURL) — still open, `application portfolio` not found in cluster, fix is now a known domain swap - 0.5 (apex 403) — still open, `curl riotpiao.com` returns 403; no in-cluster ingress exists for bare apex, still need Cloudflare-side confirmation