# Audio Vault TODO

Check a task only when its **implementation or verification evidence** exists. A recorded decision in [DECISIONS.md](DECISIONS.md) does not check a box. Keep AV-T IDs stable when reordering.

[Requirements](REQUIREMENTS.md) define scope; [DECISIONS.md](DECISIONS.md) record chosen defaults; [CONFIG.md](CONFIG.md) lists environment variables; [PLAN](PLAN.md) gives phase steps; [AGENTS.md](../../AGENTS.md) governs agent safety. Policy drafts: [docs/legal/](../legal/README.md) (counsel review required).

---

## Cursor Agent Execution Guide

**Before starting any task**

1. Read [AGENTS.md](../../AGENTS.md), applicable [DECISIONS.md](DECISIONS.md) rows, [WEB.md](WEB.md) for browser/PWA/security work, and [CONFIG.md](CONFIG.md) keys for that task.
2. Run `git status --short`. Preserve existing edits; never reset or stash user work.
3. Pick **one** task whose **Status** is `ready` or `ready-local` and whose **Blocked by** tasks are done (or waived in the task note).
4. **Red-green first for code:** For any task that adds or changes executable behavior, write **failing tests before production code** (see [Red-Green Workflow](#red-green-workflow-test-first)). Confirm red, then implement until green.
5. Execute the task **Prompt**; produce every **Deliverable**; record evidence in [VALIDATION.md](VALIDATION.md).
6. Run **Verify** commands; fix failures before checking the box.
7. Update this file only to check the box and add a one-line evidence link (commit SHA, VALIDATION section, or URL).

**Documentation map (same order as [README](../../README.md#documentation-map)):** DECISIONS → CONFIG → WEB → REQUIREMENTS → TODO → PLAN. Legal drafts are evidence for AV-T40–T42, not substitutes for AV-T22 counsel sign-off.

**Human decision questions:** Ask **one question at a time** with lettered multiple-choice options; put the **recommended option first** and label it `Recommended:`. See [AGENTS.md](../../AGENTS.md#ask-human-decision-questions). Wait for an answer before the next question. Record answers in DECISIONS.md / CONFIG.md — do not implement unset defaults.

**Status legend**

| Status | Meaning |
|---|---|
| `ready` | Agent can implement end-to-end in repo (may use local/docker fixtures). |
| `ready-local` | Agent implements locally; production deploy is **Human only**. |
| `ready-draft` | Agent drafts docs/markdown in repo; publication or counsel is **Human only**. |
| `blocked-human` | Needs product, finance, legal, or ops input before coding. |
| `deferred` | Explicitly post-MVP per decisions; do not start without user request. |
| `done` | Evidence recorded; box checked. |

**Default verify (always run after doc or calculator edits)**

```sh
npm ci --ignore-scripts
npm run check
```

**Default verify (after Go code exists)**

```sh
go test ./...
go test -race ./...
npm run check
```

**Human only (never without explicit authorization for that action)**

Production deploy, DNS/nameserver changes, Stripe live mode, live charges, destructive infra, committing secrets, counsel sign-off, Hostinger/Cloudflare console changes, Apple iCloud email setup.

### Red-Green Workflow (Test First)

Agents **must** use red-green (test-driven) development for TODO items that ship **executable** behavior (Go service, PWA scripts, calculator logic, integration tests). **Do not** implement production code first and add tests afterward.

**Required loop for each AV-T code task**

1. **Read** the task **Prompt**, **Done when**, and linked [PLAN.md](PLAN.md) phase steps. Identify the behavior to prove.
2. **Red — write a failing test** that encodes the requirement (happy path + at least one failure or isolation case when the task implies it). Run the test command; **confirm it fails** for the expected reason (missing feature, not a typo).
3. **Green — implement the smallest change** that makes that test pass. No extra refactors or scope outside the AV-T.
4. **Refactor** only with tests still green; rerun **Verify** commands.
5. **Record** in [VALIDATION.md](VALIDATION.md): AV-T id, test file(s), red output (failure snippet), green output (pass), and commands run.

**Where tests live**

| Area | Test location | Red command (examples) |
|---|---|---|
| Go API / uploads / auth | `internal/*/*_test.go`, `tests/` | `go test ./internal/... -run TestName -count=1` |
| Calculator / static JS | [docs/calculator.test.cjs](../calculator.test.cjs) | `node docs/calculator.test.cjs` |
| Docs / links / headings | `test/` suite (e.g. [test/docs.test.mjs](../../test/docs.test.mjs)) | `npm run check` |
| Browser / PWA journeys | Task **Deliverables** (e.g. VALIDATION matrix) | Manual or harness per AV-T12/AV-T05; still **define expected results before** exploratory testing |

**Exemptions (no red-green code step required)**

- **`ready-draft`** legal or architecture markdown only (AV-T40–T42 drafts, AV-T37 SVG copy).
- **Pure documentation** edits with no new executable behavior — `npm run check` only.

**Do not check a box** without red-green evidence for code tasks: either linked test files with a recorded failing-then-passing run, or an explicit waiver in VALIDATION.md signed off in the task note.

### Recommended Execution Order (Priority a Path)

`AV-T21` (or local `.env`) → `AV-T08` → `AV-T18` + `AV-T36` → `AV-T16` → `AV-T11` → `AV-T10` → `AV-T12`–`T13` → `AV-T14`/`AV-T15` → `AV-T17` → `AV-T20` → `AV-T19` → `AV-T40`–`T42`

### Kick Off the Next Task in Cursor

Use this section when you want Cursor (Desktop Agent or Cloud Agent) to pick up **one** AV-T task and finish it with evidence.

#### 1. Pick the Next Task

Work top-down. Do not skip ahead unless a **Blocked by** dependency is done or explicitly waived in the task note.

1. Open [MVP ASAP Priority Order](#mvp-asap-priority-order) — start with **Priority A**, then **B**.
2. Find the first **unchecked** `- [ ] **AV-T…**` whose **Status** is `ready`, `ready-local`, or `ready-draft`.
3. Skip tasks marked `blocked-human` or `deferred` unless you (Dani) just supplied the missing decision or asked to start anyway.
4. Confirm every task listed under **Blocked by** is checked done (or waived).
5. Read that task’s **Decisions**, **Prompt**, **Deliverables**, **Done when**, and **Verify** lines before prompting the agent.

**Likely next tasks (Sep 2026):**

| If… | Start with | Status | Notes |
|---|---|---|---|
| No local `.env` yet | Copy `.env.example` → `.env` for local Go/PWA work | — | AV-T08 agent-complete; see [VALIDATION § AV-T08](VALIDATION.md#av-t08-sign-off-september-7-2026) |
| Infra not provisioned | **AV-T21** | `blocked-human` | Human provisions VPS/R2; agent writes checklist |
| Legal publication | **AV-T40**–**T42** | `ready-draft` | Agent wiring done; counsel ([AV-T22](TODO.md)) + mailboxes ([AV-T43](TODO.md)) before live publication |

On the Priority A path, **AV-T40**–**T42** counsel publication is the main remaining agent-runnable draft work; production deploy and apex DNS are human-only ([AV-T21](TODO.md), [AV-T34](TODO.md)).

#### 2. Open the Right Context in Cursor

**Attach or @-mention these files** (adjust for the task’s **Decisions** line):

- [AGENTS.md](../../AGENTS.md)
- [docs/mvp/TODO.md](TODO.md) — the specific AV-T block
- [docs/mvp/DECISIONS.md](DECISIONS.md) — rows cited on the task
- [docs/mvp/WEB.md](WEB.md) — browser baseline, PWA, CORS, Core Web Vitals (when building shell/uploads/player)
- [docs/mvp/CONFIG.md](CONFIG.md) — env keys the task touches
- [docs/mvp/PLAN.md](PLAN.md) — linked phase section
- [.env.example](../../.env.example) — when the task needs server defaults (never commit a populated `.env`)

Optional: [docs/mvp/VALIDATION.md](VALIDATION.md) when the task records test evidence.

#### 3. Paste a Starter Prompt (Desktop Agent or Cloud Agent)

Replace `AV-T08` and the decision IDs with your chosen task.

```text
Execute exactly one task: AV-T08 from docs/mvp/TODO.md.

Read AGENTS.md first, then DECISIONS.md (D-10–D-12, D-20–D-26), CONFIG.md, PLAN.md Phase 2, and the full AV-T08 block (Prompt, Deliverables, Done when, Verify, Human only).

Rules:
- Red-green required: write failing tests BEFORE implementation; confirm red, then implement to green (see Red-Green Workflow in TODO.md).
- Implement only this task; do not start other AV-T items.
- Do not invent defaults — link [DECISIONS.md](DECISIONS.md) or ask when a task cites a missing row.
- Do not deploy production, change DNS, enable Stripe live mode, or commit secrets.
- Record evidence in docs/mvp/VALIDATION.md before checking the box in TODO.md (include red then green test output for code).
- Run every command in the task’s Verify section plus npm run check for doc edits.

When finished: check the AV-T08 box only if Done when is satisfied, commit with a clear message, and summarize changed files + verify results.
```

**Shorter prompt** (when the agent already knows the repo):

```text
Do AV-T08 per docs/mvp/TODO.md (Prompt + Deliverables + Verify). One task only. Red-green: failing tests first, then implementation. Evidence in VALIDATION.md. Follow AGENTS.md and cited DECISIONS rows.
```

**Human-only task** (blocked-human — e.g. AV-T21, AV-T43, AV-T22):

```text
Document human steps for AV-T43 per docs/mvp/TODO.md. Do not change production DNS or mail. Record checklist in VALIDATION.md when complete.
```

**Draft-only task** (ready-draft — e.g. legal or architecture):

```text
Execute AV-T40 per docs/mvp/TODO.md. Draft in repo only; do not publish or link from the live site. Counsel review remains human-only (AV-T22).
```

#### 4. Cloud Agent Vs Desktop Agent

| | **Cursor Cloud Agent** | **Cursor Desktop (Agent mode)** |
|---|---|---|
| Best for | Multi-file implementation, PR + push, long verify loops | Local Go/tests, quick doc edits, `.env` on your machine |
| Branch | Create/use `cursor/<short-name>-8675` off `main` | Your local branch; push when ready |
| Secrets | Never put secrets in repo; use env on VM or ask human to fill local `.env` | Copy `.env.example` → `.env` locally; keep untracked |
| PR | Agent should commit, push, and open/update a draft PR | You commit/push or ask agent to prepare commits |
| Stop conditions | Human only actions in the task — stop and list what Dani must do in Cloudflare/Stripe/Apple | Same |

Cloud agents must not use production consoles without explicit authorization. Desktop agents should run `go test` and `npm run check` locally when the task’s **Verify** section lists them.

#### 5. While the Agent Runs

The agent should:

1. Run `git status --short` before editing.
2. For code tasks: **write failing tests first**; run them and capture **red** output before implementing.
3. Follow the task **Prompt** literally; produce every **Deliverable**.
4. Implement the **smallest** green fix; rerun tests and **Verify** commands.
5. Stop at **Human only** lines and report blockers instead of guessing.
6. Update **only** the completed task’s checkbox plus a one-line evidence note (commit SHA, VALIDATION section, or PR link).

The agent must **not**:

- Implement production code before a failing test exists (except exempt tasks in [Red-Green Workflow](#red-green-workflow-test-first)).
- Check a box because a DECISIONS row exists (decisions ≠ evidence).
- Reset, stash, or overwrite unrelated local work.
- Expand scope to the next AV-T without a new user request.

#### 6. When the Task Finishes — Your Checklist

- [ ] **Red-green evidence** for code: failing test run recorded, then passing run after implementation ([VALIDATION.md](VALIDATION.md)).
- [ ] **Verify** commands passed (agent pasted output or CI green).
- [ ] Evidence exists in [VALIDATION.md](VALIDATION.md) or linked paths named in **Deliverables**.
- [ ] TODO checkbox checked with evidence pointer (not just “done”).
- [ ] No secrets in Git; `.env` remains untracked.
- [ ] If the task changed headings or docs layout: `npm run docs:fix && npm run check`.

**Kick off the next task:** repeat from [§1 Pick the Next Task](#1-pick-the-next-task) using the [Recommended execution order](#recommended-execution-order-priority-a-path) when dependencies allow.

#### 7. Example: Chain After Av-T08

```text
Next: AV-T40–T42 counsel publication — drafts and PWA wiring exist; record counsel sign-off in VALIDATION.md after AV-T22. See [VALIDATION § AV-T40–T42](VALIDATION.md#av-t40t42-legal-drafts-and-pwa-wiring-september-7-2026). One task only.
```

Use the same pattern for AV-T11 → AV-T12 → AV-T14 on the Priority A path.

---

## MVP ASAP Priority Order

- [x] **Priority A — agent-complete:** AV-T08, AV-T18, AV-T36, AV-T11, AV-T12, AV-T13, AV-T14, AV-T15, AV-T16, AV-T17, AV-T19
- [ ] **Priority A — remaining:** AV-T40, AV-T41, AV-T42 (counsel + AV-T43 mailboxes before live publication)
- [ ] **Priority B (provision + ops):** AV-T10, AV-T20, AV-T21, AV-T43, AV-T22
- [ ] **Priority C (after music MVP — calculator):** AV-T04, AV-T05, AV-T06, AV-T07
- [ ] **Priority D (post-MVP product):** AV-T25, AV-T26, AV-T27, AV-T28, AV-T29, AV-T30, AV-T31, AV-T32, AV-T33
- [ ] **Priority E (public launch only — not freeze):** AV-T34, AV-T35, AV-T37, AV-T38

Build the website/PWA first. Calculator and vendor refresh follow the music MVP ([DECISIONS.md](DECISIONS.md) D-90–D-92). Policy **drafts** exist under [docs/legal/](../legal/README.md); publication and signup links wait on AV-T22 and AV-T43.

---

## Calculator and Documentation Baseline

- [x] **AV-T01.** Recover calculator, user story, plan, PNG, and verbatim DNS export. **Status:** done · baseline artifacts recovered.

- [x] **AV-T02.** Consolidate decisions into REQUIREMENTS.md. **Status:** done · REQUIREMENTS links to [DECISIONS.md](DECISIONS.md); does not duplicate state.

- [x] **AV-T03.** README, `.env.example`, static entry page, price snapshot. **Status:** done · baseline docs in repo.

- [ ] **AV-T04.** Calculator price refresh job
  - **Priority:** C · **Phase:** [1](PLAN.md#phase-1--finish-storage-economics-and-the-static-calculator) · **Status:** `deferred` (D-90)
  - **Decisions:** D-90, D-91
  - **Blocked by:** Music MVP complete; user request to start calculator phase
  - **Prompt:** Add a server-side or CI static feed job that updates `docs/prices.json` daily (D-91). Never embed vendor credentials in static assets.
  - **Deliverables:** Feed fetcher script or workflow, updated `docs/prices.json` with source URL + timestamp, failure fallback behavior
  - **Done when:** Refresh runs on schedule; calculator shows source/time; VALIDATION.md records a sample run
  - **Verify:** `npm run check`; manual calculator refresh test
  - **Human only:** Approving any hosted cron/service account and vendor API keys

- [ ] **AV-T05.** Calculator browser matrix tests
  - **Priority:** C · **Phase:** 1 · **Status:** `deferred` (D-92)
  - **Decisions:** D-92
  - **Blocked by:** AV-T04 or explicit waiver
  - **Prompt:** Run persistence, import/export, and refresh tests in Safari, Chrome, Firefox, and Edge; document results.
  - **Deliverables:** VALIDATION.md browser matrix section with versions and pass/fail
  - **Done when:** All four browsers tested or waivers recorded with reason
  - **Verify:** `npm run check`; `node docs/calculator.test.cjs`

- [ ] **AV-T06.** Vendor price/policy reverify
  - **Priority:** C · **Phase:** 1 · **Status:** `deferred`
  - **Decisions:** D-30, D-31
  - **Prompt:** Refresh sourced vendor quotes (R2, B2, Wasabi, partner) with URL, date, currency, and region notes before any commercial calculator claim.
  - **Deliverables:** Research appendix in VALIDATION.md or linked doc; no change to product price ($49/mo, 2 TB) without decision update
  - **Done when:** Each cited provider has retrieval date + URL
  - **Verify:** `npm run check`

- [ ] **AV-T07.** Price feed operations runbook
  - **Priority:** C · **Phase:** 1 · **Status:** `deferred`
  - **Decisions:** D-91
  - **Blocked by:** AV-T04
  - **Prompt:** Write ownership, daily cadence, parser update process, and alert/runbook for feed failures.
  - **Deliverables:** Runbook section in VALIDATION.md or `docs/mvp/operations.md`
  - **Done when:** On-call steps and failure alerts defined
  - **Verify:** `npm run check`

---

## Before Product Code Freeze

- [x] **AV-T08.** Go service foundation (Servarica + Postgres + R2 + auth)
  - **Priority:** A · **Phase:** [2](PLAN.md#phase-2--establish-the-webpwa-and-go-service-boundary) · **Status:** `done`
  - **Evidence:** [VALIDATION.md § AV-T08 Sign-Off](VALIDATION.md#av-t08-sign-off-september-7-2026); PRs #13–#17, commit `2261993` (R2 presigns)
  - **Decisions:** D-10–D-12, D-20–D-26, D-131, D-135–D-136, D-138, D-144–D-145, D-152
  - **Blocks:** AV-T11, AV-T14, AV-T15, AV-T17, AV-T19 (unblocked)
  - **Deliverables:** Go module, migrations `00001`–`00006`, health/readiness, password + magic-link auth, MFA/TOTP, R2 upload/playback presigns, tenant isolation tests, `api/openapi.yaml`
  - **Done when:** `go test ./...` and `-race` pass; isolation test proves B cannot access A; VALIDATION.md lists commands — **met**
  - **Verify:** `go test ./...`, `go test -race ./...`, `npm run check`
  - **Human only:** Servarica deploy ([AV-T21](TODO.md)), production secrets, TLS on public API host

- [x] **AV-T09.** Open scale limits (track count, uplink, soak volume)
  - **Priority:** B · **Phase:** [0](PLAN.md#phase-0--establish-the-baseline-and-resolve-release-inputs) · **Status:** `done` *(decisions recorded Sep 7, 2026 — s2/s5/s7)*
  - **Decisions:** D-31, D-32, D-50–D-53, **D-125–D-128**
  - **Evidence:** [VALIDATION.md § Scale limits](VALIDATION.md#scale-limits-approved-sep-7-2026); CONFIG + `.env.example`; AV-T09 max tracks = **A configurable** ([D-127](DECISIONS.md#account-limits-and-settings))

- [x] **AV-T10.** R2 multipart/checksum qualification
  - **Priority:** B · **Phase:** [3](PLAN.md#phase-3--prove-reliable-uploads-before-broadening-the-ui) · **Status:** `done`
  - **Evidence:** [VALIDATION.md § AV-T10](VALIDATION.md#av-t10-r2-multipart-qualification-september-7-2026); `internal/storage/r2_qualification_test.go`
  - **Decisions:** D-54
  - **Blocked by:** R2 test bucket credentials in local `.env`
  - **Blocks:** AV-T11 verified publication path
  - **Prompt:** Against a disposable R2 bucket, prove multipart upload, part resume, and SHA-256 + size + path identity (D-54). Document whether multipart ETags are whole-file checksums (expect: not).
  - **Deliverables:** Go or script integration test + VALIDATION.md findings
  - **Done when:** Documented verification path matches implementation choice in AV-T11
  - **Verify:** Integration test pass; `npm run check`
  - **Human only:** Production bucket credentials

- [x] **AV-T11.** Upload pipeline (inventory, multipart, quota, trash accounting)
  - **Priority:** A · **Phase:** 3 · **Status:** `done`
  - **Evidence:** [VALIDATION.md § AV-T11](VALIDATION.md#av-t11-upload-pipeline-september-7-2026); `internal/uploads/`, migration `00004_upload_manifest.sql`
  - **Decisions:** D-50–D-61, D-80–D-81
  - **Blocked by:** AV-T08, AV-T10
  - **Blocks:** AV-T12, AV-T14
  - **Prompt:** Implement Phase 3 upload state machine per PLAN: resumable multipart, quota reservation, idempotent finalize, trash counts toward quota (D-81), per CONFIG upload keys.
  - **Deliverables:** `internal/uploads/`, server-side manifest, UI queue in `docs/assets/`, failure states visible
  - **Done when:** Failing tests from PLAN Phase 3 pass; no silent missing files in fixture runs
  - **Verify:** `go test ./internal/uploads/...`, `npm run check`

- [x] **AV-T12.** Upload failure matrix (browser + PWA)
  - **Priority:** A · **Phase:** 3 · **Status:** `done` *(API matrix + PWA resume; full 4-browser matrix deferred — see VALIDATION)*
  - **Evidence:** [VALIDATION.md § AV-T12](VALIDATION.md#av-t12-upload-failure-matrix-september-7-2026); `scripts/upload-failure-smoke.sh`
  - **Decisions:** (behavior per PLAN Phase 3)
  - **Blocked by:** AV-T11
  - **Prompt:** Execute and document the failure matrix: browser close, lost acks, offline/reselect, source mutation, corruption, expired auth, throttling, quota exhaustion, duplicates.
  - **Deliverables:** VALIDATION.md matrix with browser/version, scenario, expected/actual
  - **Done when:** Every listed scenario has a row; failures remain visible/recoverable
  - **Verify:** `npm run check`; attach test logs to VALIDATION.md

- [x] **AV-T13.** Backup, restore, and customer guidance
  - **Priority:** A · **Phase:** 3 · **Status:** `done`
  - **Evidence:** [VALIDATION.md § AV-T13](VALIDATION.md#av-t13-backup-restore-september-7-2026); [BACKUP-RESTORE.md](../BACKUP-RESTORE.md)
  - **Prompt:** Document source snapshot guidance, backup/restore targets (24h RPO, 4h RTO), orphan cleanup, account soft-delete; run one restore drill on disposable data.
  - **Deliverables:** Customer-facing doc section + VALIDATION.md restore drill record
  - **Done when:** Restore drill succeeds; guidance linked from README or app settings
  - **Verify:** `npm run check`

- [x] **AV-T14.** Catalog library UI (folders, edits, playback shell)
  - **Priority:** A · **Phase:** [4](PLAN.md#phase-4--complete-the-catalog-metadata-and-v1-listening-flow) · **Status:** `done`
  - **Evidence:** [VALIDATION.md § AV-T14](VALIDATION.md#av-t14-catalog-library-ui-september-7-2026); `internal/catalog/`, `docs/assets/catalog.js`
  - **Decisions:** D-70–D-74, D-06 (slip: may disable auto-match)
  - **Blocked by:** AV-T11
  - **Blocks:** AV-T15, AV-T17
  - **Prompt:** Build folder + artist/album/track views, manual catalog edits with provenance, integration hooks for metadata (AV-T15). Preserve original bytes on all edits.
  - **Deliverables:** `internal/catalog/`, library UI, pagination suitable for declared limits
  - **Done when:** Catalog tests pass; edits do not mutate stored audio
  - **Verify:** `go test ./internal/catalog/...`, `npm run check`

- [x] **AV-T15.** Metadata provider integration (AcoustID + MusicBrainz)
  - **Priority:** A · **Phase:** 4 · **Status:** `done`
  - **Evidence:** [VALIDATION.md § AV-T15](VALIDATION.md#av-t15-metadata-provider-integration-september-7-2026); `internal/catalog/metadata/`
  - **Prompt:** Integrate AcoustID + MusicBrainz: send filename/tags/fingerprint (D-72), auto-apply ≥80% (D-71), review queue below threshold, manual wins + revert (D-74). Respect `METADATA_CONSENT_MODE` (D-73).
  - **Deliverables:** `internal/catalog/metadata/`, review UI, consent link on signup
  - **Done when:** Provider timeout/rate-limit tests pass; metadata failure does not hide verified uploads
  - **Verify:** `go test ./...`, `npm run check`

- [x] **AV-T16.** Upload validation (music-only, sidecars, paths)
  - **Priority:** A · **Phase:** 3 · **Status:** `done`
  - **Evidence:** [VALIDATION.md § AV-T16](VALIDATION.md#av-t16-upload-validation-september-7-2026); `internal/validation/`
  - **Decisions:** D-55–D-59, D-61
  - **Blocked by:** AV-T08
  - **Prompt:** Implement validator: music containers only, allow `.cue`/`.log`/covers (catalog-only images), collision/overwrite confirm (D-55–D-56), corrupt reject (D-58), NFC paths max 4096 (D-59), no NAS-retention UI (D-61).
  - **Deliverables:** Validator package + rejection UX with reasons
  - **Done when:** Unit tests cover each rejection rule; batch keeps accepted files when one fails
  - **Verify:** `go test ./...`, `npm run check`

- [x] **AV-T17.** Browser playback + simulated streamer
  - **Priority:** A · **Phase:** 4 · **Status:** `done`
  - **Evidence:** [VALIDATION.md § AV-T17](VALIDATION.md#av-t17-browser-playback-september-7-2026); `internal/playback/`, `docs/assets/player.js`
  - **Decisions:** D-110, D-112 · `STREAMER_MODE=simulated`
  - **Blocked by:** AV-T14, AV-T11 playback auth
  - **Prompt:** Implement original browser playback with format capability detection; simulated streamer controls with clear “no real streamer audio” labeling (D-110); quiet-connect UX stub per D-112.
  - **Deliverables:** `internal/playback/`, player UI, simulation banner, format matrix doc
  - **Done when:** Supported formats play in test browsers; unsupported shows honest message + simulation path
  - **Verify:** Browser smoke tests documented in VALIDATION.md; `npm run check`

- [x] **AV-T18.** PWA shell (Cloudflare Pages path)
  - **Priority:** A · **Phase:** 2 · **Status:** `done` *(upload wiring; install matrix still open)*
  - **Evidence:** [VALIDATION.md § AV-T18](VALIDATION.md#av-t18-pwa-upload-wiring-september-7-2026); `docs/assets/upload.js`
  - **Decisions:** D-16, D-102
  - **Blocked by:** AV-T36 for production apex (local static OK)
  - **Prompt:** Add `docs/manifest.webmanifest`, service worker, responsive layout, installability; best-effort a11y for freeze (D-102). No secrets in static assets.
  - **Progress (scaffold):** `docs/app.html`, `docs/assets/app.{js,css}`, `docs/manifest.webmanifest`, `docs/sw.js` (shell cache only). **P0/P1 hardening:** `docs/_headers`, API base resolution, safe JSON parse, SW update prompt, manifest `id`/maskable, a11y focus/`aria-live` (branch `cursor/pwa-p0-p1-hardening-8de9`). **Next:** install evidence + browser matrix in VALIDATION.md.
  - **Deliverables:** manifest, SW, offline shell behavior, a11y notes in VALIDATION.md
  - **Done when:** Lighthouse or manual install test recorded; WCAG 2.1 AA tracked for public beta
  - **Verify:** `npm run check`; static serve smoke test

- [x] **AV-T19.** Stripe integration (test mode)
  - **Priority:** A · **Phase:** [5](PLAN.md#phase-5--finish-paid-accounts-and-operational-readiness) · **Status:** `done`
  - **Evidence:** [VALIDATION.md § AV-T19](VALIDATION.md#av-t19-stripe-test-mode-september-7-2026); `internal/billing/`; checkout smoke [AV-T20](VALIDATION.md#av-t20-stripe-test-prices-and-checkout-september-7-2026)
  - **Decisions:** D-30–D-39, D-35, D-40
  - **Blocked by:** AV-T08, AV-T20 price IDs
  - **Prompt:** Implement Checkout, Customer Portal, webhooks with signature verification and idempotent entitlement updates; enforce quota from server state; `STRIPE_MODE=test` only (D-39).
  - **Deliverables:** `internal/billing/`, webhook handler tests, test checkout journey
  - **Done when:** Billing tests pass; duplicate/out-of-order events handled; VALIDATION.md test journey
  - **Verify:** `go test ./internal/billing/...`, `npm run check`
  - **Human only:** Live mode, production webhooks URL on public host

- [x] **AV-T20.** Stripe USD Price objects
  - **Priority:** B · **Phase:** 1 · **Status:** `done`
  - **Evidence:** [VALIDATION.md § AV-T20](VALIDATION.md#av-t20-stripe-test-prices-and-checkout-september-7-2026); [STRIPE-SETUP.md](STRIPE-SETUP.md); `.env.example`; `scripts/stripe-checkout-smoke.sh`
  - **Decisions:** D-30–D-41
  - **Prompt:** **Human:** Create Stripe Dashboard products/prices ($49/mo, $490/yr USD). **Agent (after IDs exist):** Wire `STRIPE_PRICE_ID*` in untracked `.env` and config tests; verify test checkout.
  - **Setup guide:** [STRIPE-SETUP.md](STRIPE-SETUP.md) — Product catalog, monthly/annual Price IDs, API keys, webhook secret, checkout verification
  - **Deliverables:** Price IDs documented in VALIDATION.md (not secrets); config loader reads IDs
  - **Done when:** Test checkout completes with real test price IDs
  - **Verify:** AV-T19 test checkout; `npm run check`
  - **Human only:** Stripe Dashboard product/price creation

- [ ] **AV-T21.** Provision infrastructure
  - **Priority:** B · **Phase:** [0](PLAN.md#phase-0--establish-the-baseline-and-resolve-release-inputs) · **Status:** `blocked-human`
  - **Decisions:** D-10–D-19, D-13–D-15, **D-121**
  - **Prompt:** **Human:** Provision Servarica VPS, private R2 (US), observability (logs, uptime, Sentry, Prometheus/Grafana), daily backups, Cloudflare DNS/TLS. **Agent:** Maintain [ansible/README.md](../../ansible/README.md), `scripts/install-ansible.sh`, and `scripts/setup-server.sh` for Postgres + Go API prerequisites on the VPS; document `.env` mapping from CONFIG.md; add deploy notes to VALIDATION.md when complete.
  - **Deliverables:** Ansible server baseline (Postgres localhost, Go toolchain, systemd unit template), infra checklist, populated local `.env` template (secrets untracked), backup-restore drill record
  - **Done when:** `./scripts/setup-server.sh` succeeds against production VPS; API reachable after binary deploy; backup restore drill passes
  - **Verify:** `ansible-playbook --syntax-check` (see `test/ansible-syntax.test.mjs`); health check curl; VALIDATION.md
  - **Human only:** Cloud console provisioning (VPS, R2, DNS, TLS, observability, backups)

- [ ] **AV-T22.** Counsel review (pre–public launch)
  - **Priority:** B · **Phase:** 5 · **Status:** `blocked-human`
  - **Decisions:** D-40, D-100
  - **Blocked by:** AV-T40–T42 drafts
  - **Prompt:** **Human/legal:** Review worldwide Stripe-supported launch (tax, cross-border, policies). **Agent:** Prepare counsel packet from AV-T40–T42 drafts + DECISIONS billing/geo rows.
  - **Deliverables:** Counsel sign-off recorded in VALIDATION.md (date, reviewer, scope)
  - **Done when:** Written approval before public paid launch
  - **Human only:** Qualified legal review

- [x] **AV-T23.** Remaining account UX decisions
  - **Priority:** B · **Phase:** 0 · **Status:** `done` *(B/S/A batch + revisions Sep 7, 2026)*
  - **Decisions:** D-80 (trash); **D-120** (no export until beta); **D-122** (no integrations at freeze); **D-124** (freeze settings scope)
  - **Evidence:** [DECISIONS.md](DECISIONS.md#legal-policies-and-accessibility) D-120, D-122, D-124; [VALIDATION.md § Master interview catalog](VALIDATION.md#master-interview-catalog)

- [x] **AV-T24.** Acknowledge schedule and capacity plan
  - **Priority:** B · **Phase:** 0 · **Status:** `done` *(a3 A — Sep 7, 2026)*
  - **Decisions:** D-01–D-06, **D-132**
  - **Evidence:** [VALIDATION.md § Schedule acknowledgment](VALIDATION.md#schedule-acknowledgment-a3-a--sep-7-2026)

- [ ] **AV-T40.** Privacy policy draft
  - **Priority:** A · **Phase:** [5](PLAN.md#phase-5--finish-paid-accounts-and-operational-readiness) · **Status:** `ready-draft` *(markdown draft in repo; PWA links wired)*
  - **Decisions:** D-100, D-73, D-72
  - **Prompt:** Maintain [docs/legal/privacy.md](../legal/privacy.md) against DECISIONS; add signup/settings link when UI exists.
  - **Deliverables:** [docs/legal/privacy.md](../legal/privacy.md), [docs/legal/README.md](../legal/README.md) source attribution, signup link placeholder
  - **Done when:** Counsel approval (AV-T22); published URL at go-live
  - **Remaining:** Counsel edits, production URL (agent: footer/settings/signup links + backup cross-ref — see [VALIDATION.md § AV-T40–T42](VALIDATION.md#av-t40t42-legal-drafts-and-pwa-wiring-september-7-2026))
  - **Verify:** `npm run check`
  - **Human only:** Counsel approval; production URL

- [ ] **AV-T41.** Terms of service draft
  - **Priority:** A · **Phase:** 5 · **Status:** `ready-draft` *(markdown draft in repo; signup acceptance wired)*
  - **Decisions:** D-100, D-110
  - **Prompt:** Maintain [docs/legal/terms.md](../legal/terms.md); wire acceptance checkbox at signup/checkout when UI exists.
  - **Deliverables:** [docs/legal/terms.md](../legal/terms.md), acceptance checkbox flow
  - **Done when:** Counsel approval; acceptance wired in signup/checkout
  - **Remaining:** Stripe checkout withdrawal checkbox, governing-law placeholders, counsel edits (agent: signup checkbox + API `terms_accepted` — see [VALIDATION.md § AV-T40–T42](VALIDATION.md#av-t40t42-legal-drafts-and-pwa-wiring-september-7-2026))
  - **Verify:** `npm run check`
  - **Human only:** Counsel approval

- [ ] **AV-T42.** Uploaded-content / abuse policy draft
  - **Priority:** A · **Phase:** 5 · **Status:** `ready-draft` *(markdown draft in repo; footer/settings linked)*
  - **Decisions:** D-100, D-101
  - **Blocked by:** AV-T43 for live `abuse@audiovau.lt` mailbox
  - **Prompt:** Maintain [docs/legal/content-policy.md](../legal/content-policy.md); register DMCA agent before public launch if claiming §512 safe harbor.
  - **Deliverables:** [docs/legal/content-policy.md](../legal/content-policy.md)
  - **Done when:** Counsel approval; abuse mailbox live; linked from site footer/settings
  - **Remaining:** AV-T43 mailbox, Copyright Office agent registration, counsel edits (agent: footer/settings/signup links — see [VALIDATION.md § AV-T40–T42](VALIDATION.md#av-t40t42-legal-drafts-and-pwa-wiring-september-7-2026))
  - **Verify:** `npm run check`

---

## Streamer Integration — Post-MVP

- [ ] **AV-T25.** DLC manufacturer package
  - **Priority:** D · **Phase:** [7](PLAN.md#phase-7--highest-priority-follow-up-real-streamer-integration) · **Status:** `deferred` (D-111)
  - **Decisions:** D-111
  - **Prompt:** Obtain manufacturer identity, models, SDK/API, licensing, test hardware. Record in VALIDATION.md.
  - **Human only:** Manufacturer liaison, hardware purchase

- [ ] **AV-T26.** Local discovery feasibility
  - **Priority:** D · **Phase:** 7 · **Status:** `deferred`
  - **Prompt:** Prove or disprove LAN discovery/pairing from HTTPS PWA; document trust boundaries per browser.
  - **Deliverables:** VALIDATION.md feasibility memo

- [ ] **AV-T27.** Quiet connect (hardware)
  - **Priority:** D · **Phase:** 7 · **Status:** `deferred`
  - **Decisions:** D-112
  - **Blocked by:** AV-T25–T26
  - **Prompt:** Implement auto-select one authorized device; prompt when several; clear zero-device state on real hardware.

- [ ] **AV-T28.** Device adapter (hardware)
  - **Priority:** D · **Phase:** 7 · **Status:** `deferred`
  - **Blocked by:** AV-T25
  - **Prompt:** Replace simulation with authorized original delivery, format checks, expiring URLs; verify on device.

- [ ] **AV-T29.** Hardware playback matrix
  - **Priority:** D · **Phase:** 7 · **Status:** `deferred`
  - **Blocked by:** AV-T28
  - **Prompt:** Test home/remote control, offline, revocation, recovery on physical streamers; update support matrix.

---

## Version 2 and Later

- [ ] **AV-T30.** Go companion (macOS → Windows → Linux → NAS)
  - **Priority:** D · **Phase:** [8](PLAN.md#phase-8--version-2-background-uploader-os-drive-and-later-mirroring) · **Status:** `deferred` (D-113)

- [ ] **AV-T31.** OS drive (read-write)
  - **Priority:** D · **Phase:** 8 · **Status:** `deferred` (D-114)

- [ ] **AV-T32.** NAS/desktop packaging
  - **Priority:** D · **Phase:** 8 · **Status:** `deferred` (D-113)

- [ ] **AV-T33.** Mirroring design
  - **Priority:** D · **Phase:** 8 · **Status:** `deferred` (D-115) · **Prompt:** Separate product decision before any implementation.

- [x] **AV-T39.** BYO storage out of scope. **Status:** done · company-managed storage only.

---

## Domain and DNS

- [ ] **AV-T34.** Hostinger → Cloudflare nameservers
  - **Priority:** E · **Phase:** [6](PLAN.md#phase-6--documentation-release-verification-and-code-freeze) · **Status:** `blocked-human` (D-18: public launch only)
  - **Human only:** Nameserver change at registrar

- [ ] **AV-T35.** Review DNS export before import
  - **Priority:** E · **Phase:** 6 · **Status:** `ready`
  - **Prompt:** Review `config/dns/records.txt`: title/record count; **`*.dev.audiovau.lt` retired** ([D-155](DECISIONS.md#infrastructure-and-operations)); sign off in VALIDATION.md before AV-T34.
  - **Deliverables:** VALIDATION.md DNS review note
  - **Done when:** Export reviewed; discrepancies documented or resolved
  - **Verify:** `npm run check`

- [x] **AV-T36.** Deploy static site to Cloudflare Pages
  - **Priority:** A · **Phase:** 6 · **Status:** `done` *(agent; apex cutover human-only)*
  - **Evidence:** [VALIDATION.md § AV-T36](VALIDATION.md#av-t36-cloudflare-pages-september-7-2026); [PAGES-DEPLOY.md](PAGES-DEPLOY.md); PRs #26–#27; live [https://audiovault.pages.dev](https://audiovault.pages.dev)
  - **Decisions:** D-16, D-146, D-150
  - **Deliverables:** `wrangler.jsonc`, `.github/workflows/pages-deploy.yml`, `scripts/pages-smoke.sh`, preview/production URLs in VALIDATION.md
  - **Done when:** Preview deploy loads calculator + shell; TLS OK on preview — **met** on `*.pages.dev`
  - **Remaining (human):** Apex `audiovau.lt` custom domain — [AV-T34](TODO.md); retire `docs/CNAME` after cutover
  - **Verify:** `npm run check`; `./scripts/pages-smoke.sh https://audiovault.pages.dev`
  - **Human only:** Production apex cutover ([AV-T34](TODO.md))

- [ ] **AV-T37.** Architecture: audio off apex
  - **Priority:** E · **Phase:** 6 · **Status:** `ready-draft`
  - **Decisions:** D-17, D-12, **D-121**
  - **Prompt:** Update architecture SVG/PNG: apex = static/PWA only; API on Servarica; private R2 for audio. No customer audio on apex.
  - **Deliverables:** Updated `docs/audio-vault-architecture.svg` + regenerated PNG if changed
  - **Verify:** `npm run check`

- [ ] **AV-T38.** DNS export setup checklist
  - **Priority:** E · **Phase:** 6 · **Status:** `ready`
  - **Prompt:** Checklist from export notes (R2, Bunny, Tunnel, origin TLS, domain verification) against AV-T21 infra.
  - **Deliverables:** VALIDATION.md checklist with checked/unchecked items

- [ ] **AV-T43.** Email domain setup (iCloud inbound + Resend outbound)
  - **Priority:** B · **Phase:** 6 · **Status:** `blocked-human`
  - **Decisions:** D-19, D-101, **D-131**, **D-133**, **D-143**, **D-156**
  - **Prompt:** **Human:** Add MX records and verify domain with Apple; create **`abuse@audiovau.lt`**, **`privacy@audiovau.lt`**, and **`support@audiovau.lt`** (iCloud inbound). Verify **`audiovau.lt`** in **Resend**; configure **`noreply@audiovau.lt`** for auth mail ([D-131](DECISIONS.md#infrastructure-and-operations)). **Do not** create **`export@`** until public beta ([D-120](DECISIONS.md#legal-policies-and-accessibility)). **Agent:** Document DNS/MX and Resend verification steps in VALIDATION.md.
  - **Blocked by:** DNS access; blocks live abuse/privacy addresses in AV-T42
  - **Human only:** Apple iCloud custom domain + Resend domain verification

---

## Decision-to-Task Index

| Decision IDs | Tasks |
|---|---|
| D-01–D-06, D-132 | AV-T24, milestone scope for AV-T08–T19 |
| D-10–D-19, D-131, D-133, D-135–D-156 | AV-T08, AV-T21, AV-T34–T38, AV-T43 |
| D-20–D-26, D-138, D-144–D-145, D-152 | AV-T08 |
| D-30–D-41 | AV-T19, AV-T20, AV-T06 (includes D-39 test mode) |
| D-50–D-61 | AV-T09–T11, AV-T16 |
| D-70–D-74 | AV-T14, AV-T15, AV-T40 (D-73 consent) |
| D-80–D-82, D-134 | AV-T11, AV-T13, AV-T23 (trash decided) |
| D-90–D-92 | AV-T04–T07 |
| D-100–D-102 | AV-T22, AV-T40–T42, AV-T18, [docs/legal/](../legal/README.md) |
| D-116–D-130, D-137, D-140, D-148, D-154 | AV-T23, AV-T09, AV-T10–T12, AV-T21, AV-T37, AV-T19, AV-T05, AV-T18, AV-T08, AV-T36, [WEB.md](WEB.md) |
| D-125–D-128 | AV-T09, AV-T11, PLAN Phase 0 soak |
| D-110–D-112 | AV-T17, AV-T25–T27 |
| D-113–D-115 | AV-T30–T33 |
