# Android Cast — alpha priorities (2026-06-08 renumber)

<!-- doc-meta:start -->
| Field | Value |
|---|---|
| Author | Anton Afanasyeu |
| Revision | R1 |
| Creation date | 2026-06-08 |
| Last modification date | 2026-06-08 |
| Co-authored |  |
| Severity | medium |
| State | in progress |
| Document type | pre-requisite to |
<!-- doc-meta:end -->

\newpage
\newpage

---


_Owner-agreed task order, dependencies, and implementation prep. Supersedes informal numbering in older roadmap tickets._

---

---

---

---

---


---


---

---


---

## Table of contents

<!-- toc -->
- [Bottom line (agent rules)](#bottom-line-agent-rules)
- [Priority overview](#priority-overview)
- [0.x Emergency debug (not alpha blocker)](#0x-emergency-debug-not-alpha-blocker)
  - [0.1 FR — Stream dump while casting](#01-fr-stream-dump-while-casting)
- [1.x Graphs console](#1x-graphs-console)
- [2.x Email → SMTP → 2FA → RBAC](#2x-email-smtp-2fa-rbac)
- [3.x Auth implementation (agent)](#3x-auth-implementation-agent)
- [4.x Reverse SSH alpha](#4x-reverse-ssh-alpha)
- [5.x Alpha backend validation](#5x-alpha-backend-validation)
- [6.x Alpha app LAN](#6x-alpha-app-lan)
- [9.x Landing (lowest)](#9x-landing-lowest)
- [Dependency graph](#dependency-graph)
- [Licenses & tests checklist](#licenses-tests-checklist)
- [Developer help (blocked on you)](#developer-help-blocked-on-you)
- [Source linkage](#source-linkage)
<!-- /toc -->

**Documentation index:** [README.md](README.md)

---

## Bottom line (agent rules)

Before and during alpha implementation:

| Rule | Action |
|------|--------|
| **Docs** | All specs in `docs/` — classic TOC template; PDF via `scripts/build-all-docs-pdf.sh` |
| **Alpha must-have** | RSSH (4.x), auth (2.5 + 3.x), backend validation (5.x) — see [ALPHA.md](ALPHA.md) |
| **UI/UX** | Reuse crashes console `app.css`, hub styles, EN/RU i18n — no new design system |
| **Licenses** | Update `app/.../licenses/combined.html` + `THIRD_PARTY_LICENSES.md` when adding libs/tools |
| **Tests** | Unit tests for pure logic; simulate network/SSH where E2E needs no device; run `./gradlew :app:testDebugUnitTest` + PHP scripts |
| **Build** | `./gradlew assembleDebug` after native/Gradle changes |
| **Dev input** | Blocked items → brief list in `tmp/YYYYMMDD_help_request.md` + PDF; remind at end of session |
| **Git on `next`** | Alpha sprint may commit directly on `next`; **atomic commits** per feature for easy `git revert` — [GIT_FLOW.md §4.1](GIT_FLOW.md#41-fast-track-on-next-alpha-sprint) |

---

## Priority overview

| Tier | IDs | Owner split | Alpha blocker? |
|------|-----|-------------|----------------|
| **P0 debug** | 0.1 | Agent impl; enables 6.5/6.6 | No |
| **P1** | 1.x | Agent | No |
| **P2** | 2.1–2.4 dev, 2.5+3.x agent | Mixed | **Yes** (auth path) |
| **P3** | 4.x | Agent (+ deploy assist) | **Yes** (RSSH) |
| **P4** | 5.x | 50/50 OTA/URLs; rest agent | **Yes** |
| **P5** | 6.x | ~99% dev | LAN alpha |
| **P9** | 9.x landing | Agent when idle | No |

**Effective order (agent):** 0.1 (parallel) → 4.x + 2.5/3.x + 5.3–5.5 → 1.x → 9.x when bandwidth allows.

---

## 0.x Emergency debug (not alpha blocker)

### 0.1 FR — Stream dump while casting

**Priority:** High emergency debug. **Cyclic with 6.6** (same capability; 6.6 references 0.1 for audio lag / lifecycle analysis).

**Goal:** While audio or video cast is active, optionally record what flows through the encode/send (or receive/decode) path for offline analysis.

| Sub | Mode | Deliverable |
|-----|------|-------------|
| **0.1.1** | Structured | `YYYYMMDD_HHMMSS_sess_record.zip` containing `meta.json` + streams |
| **0.1.2** | Raw quick | Same archive layout; **uncompressed** elementary streams only |
| **0.1.3** | Tooling | Update session stats / graphs ingest to read `meta.json` schema |

**Archive layout (both 0.1.1 and 0.1.2):**

```text
20260608_120422_sess_record.zip
├── meta.json
├── 20260608_audio_stream.raw      # or .aac / .opus per meta
└── 20260608_video_stream.raw      # or .h264 / annex-b per meta
```

**`meta.json` (sketch):**

```json
{
  "schema_version": 1,
  "session_id": "20260608_120422",
  "role": "sender",
  "record_mode": "raw_elementary",
  "started_at_epoch_ms": 0,
  "ended_at_epoch_ms": 0,
  "video": {
    "mime": "video/avc",
    "width": 1280,
    "height": 720,
    "frame_count": 1200,
    "file": "20260608_video_stream.raw",
    "format": "length_prefixed_avc",
    "csd0_hex": "…",
    "csd1_hex": "…"
  },
  "audio": {
    "mime": "audio/mp4a-latm",
    "sample_rate": 44100,
    "channels": 2,
    "frame_count": 800,
    "file": "20260608_audio_stream.raw",
    "format": "length_prefixed_aac"
  },
  "cast_settings_snapshot": { "transport": "udp", "protection": "NONE" }
}
```

**Implementation hooks (prep):**

| Tap point | File | Notes |
|-----------|------|-------|
| Sender video frames | `ScreenCastService` / `CastSendPump` | After `onEncodedFrame`, before UDP wrap |
| Sender audio frames | `AudioEncoderSink.Callback.onEncodedFrame` | Same |
| Receiver (optional phase 2) | `ReceiverCastService` / `AudioDecoder` | Inbound before decode |

**Dev gate:** Developer settings → **Record stream dump** (off by default); cap size/duration; write under `files/stream_dumps/`.

**Spec detail:** [20260608_STREAM_DUMP_DEBUG.md](20260608_STREAM_DUMP_DEBUG.md)

---

## 1.x Graphs console

| ID | Task | Owner |
|----|------|-------|
| **1** | Graphs dashboard — parent | Agent |
| **1.1** | All pending **fixes** (5.1 brick drill-down, perf, permalinks, etc.) | Agent |
| **1.2** | All pending **FRs** (5.2 columns 1/2/4, full-width grid) | Agent |

Depends on BE deploy (soft). Not alpha blocker.

---

## 2.x Email → SMTP → 2FA → RBAC

| ID | Task | Owner | Notes |
|----|------|-------|-------|
| **2.1** | DNS: MX + SPF for mail — **use apex `f0xx.org`** if `apps.f0xx.org` is CNAME (cannot add MX) | **Developer** | `tmp/20260608_help_request.md` |
| **2.2** | Register forward addresses (`info@`, `admin@`, `root@` → Gmail) | **Developer** | Cloudflare Email Routing or ImprovMX |
| **2.3** | Inbound forward verification | **Developer** | Send test mail |
| **2.4** | Gmail filters / reply-as (optional) | **Developer** | |
| **2.5** | Outbound SMTP from BE (`noreply@`, verification mail) | **Agent** | Symfony Mailer; `config.php` |
| **3.x** | Registration + verify + TOTP + mobile UI + migration `008` | **Agent** | See [20260607-2FA-email-mobile-auth-flow.md](20260607-2FA-email-mobile-auth-flow.md) |
| **→ RBAC** | Finish admin UI after pages stable | **Agent** | Former task 7 |

Chain: `2.1 → 2.2 → 2.3` (dev) ∥ `2.5` (agent after 2.1 DNS) → `3.x` → RBAC.

---

## 3.x Auth implementation (agent)

All items from [20260607-2FA-email-mobile-auth-flow.md §10.7](20260607-2FA-email-mobile-auth-flow.md#107-alpha-implementation-plan):

- P1 Register + verify + ALTCHA
- P2 TOTP enroll + login challenge
- P3 Admin lockout clear + audit
- P4 WebAuthn (optional alpha)
- P5 Android Custom Tab entry (optional)

**Tests:** PHP API smoke scripts; unit tests for token hash / TOTP verify helpers.

---

## 4.x Reverse SSH alpha

**Replace WireGuard as alpha deliverable** — WG stays for lab ([REMOTE_ACCESS_IMPL.md](REMOTE_ACCESS_IMPL.md)).

| ID | Task | Owner |
|----|------|-------|
| **4.1** | BE: `opt_in_mode: rssh`, bastion user, `authorized_keys` / `-R` port map | Agent |
| **4.2** | BE: nginx `stream` or SSH on 443 per [20260602_REVERSE_SSH_proposals_summary.md](20260602_REVERSE_SSH_proposals_summary.md) | Agent + deploy |
| **4.3** | Android: `RemoteAccessMode.RSSH` selectable, no `VpnService` | Agent |
| **4.4** | Android: outbound SSH client (libssh2 / dropbear JNI — TBD) + FG service | Agent |
| **4.5** | E2E: whitelist → open session → operator shell/SFTP on bastion | Agent + QA |
| **4.wg** | WireGuard fixes only if lab broken | Agent as needed |

Depends on: BE deploy (5.x). Blocks **5.3**.

---

## 5.x Alpha backend validation

| ID | Task | Owner split |
|----|------|-------------|
| **5.1** | OTA channel + artifacts on `apps.f0xx.org` | 50% dev / 50% agent |
| **5.2** | Crash + OTA URLs on device (`settings.json`, dev settings) | 50% dev / 50% agent |
| **5.3** | RSSH BE validation | Agent (deploy assist dev) — **depends 4.x** |
| **5.4** | auth-2fa validation (G2–G6) | Agent |
| **5.5** | RBAC validation | Agent |

---

## 6.x Alpha app LAN

| ID | Task | Owner | Deps |
|----|------|-------|------|
| **6.1** | Opus/Speex E2E | Dev + agent JNI | native `.a` |
| **6.2** | LAN soak A/B/C | Dev | — |
| **6.3** | App lifecycle (notifications, recents) | Dev | |
| **6.4** | Rotation + preview crash | Dev | ↔ 6.3 cyclic |
| **6.5** | Audio lag — buffers, handshake, graphs | Dev | **0.1 helps** |
| **6.6** | Debug stream analysis | Dev | **= 0.1** |

Agent: fixes / urgent FRs only (~1%).

---

## 9.x Landing (lowest)

Renumbered from former 6.x landing track:

| ID | Task |
|----|------|
| **9** | Landing hub parent |
| **9.1** | Hub cards (graphs, builder, RA) |
| **9.2** | Globe / earth animations |
| **9.3** | Mobile chrome validation (LOW) |

---

## Dependency graph

```mermaid
flowchart TB
    subgraph P0["P0 debug"]
        S01["0.1 stream dump"]
    end

    subgraph P2["P2 auth — dev"]
        D21["2.1 DNS"]
        D22["2.2 forward"]
        D23["2.3 verify inbound"]
    end

    subgraph P2a["P2 auth — agent"]
        A25["2.5 SMTP"]
        A3["3.x 2FA"]
        RBAC["RBAC"]
    end

    subgraph P3["P3 RSSH"]
        R4["4.x reverse SSH"]
    end

    subgraph P4["P4 backend alpha"]
        B51["5.1 OTA"]
        B52["5.2 URLs"]
        B53["5.3 RSSH validate"]
        B54["5.4 auth validate"]
    end

    subgraph P5["P5 app LAN — dev"]
        A61["6.1 Opus"]
        A62["6.2 soak"]
        A63["6.3 lifecycle"]
        A64["6.4 rotation"]
        A65["6.5 audio lag"]
    end

    subgraph P9["P9 landing"]
        L9["9.x"]
    end

    ALPHA["FULL_ALPHA"]

    S01 -.-> A65
    S01 -.-> A64

    D21 --> D22 --> D23
    D21 --> A25 --> A3 --> RBAC --> B54
    A3 --> ALPHA

    R4 --> B53 --> ALPHA
    B51 --> ALPHA
    B52 --> ALPHA

    A62 --> ALPHA
    A63 -.-> A64
    A64 -.-> A63

    L9 -.-> RBAC
```

---

## Licenses & tests checklist

| When adding… | Update |
|--------------|--------|
| libssh2 / dropbear / Symfony Mailer | `combined.html`, `THIRD_PARTY_LICENSES.md` |
| Stream dump (no new deps if pure Java) | — |
| RSSH BE scripts | BE licenses doc |

| Area | Test command |
|------|----------------|
| Android unit | `./gradlew :app:testDebugUnitTest` |
| RSSH API | `BASE=… ./scripts/ra_e2e_cli.sh` (extend for RSSH) |
| Auth API | `scripts/test_rbac_api.sh` + new `test_auth_api.sh` (TBD) |
| Stream dump | Unit test `StreamDumpWriter` framing + `meta.json` schema |

---

## Developer help (blocked on you)

**Email/DNS (2.1–2.4):** hands-on checklist with record examples:

→ **[tmp/20260608_help_request.md](../tmp/20260608_help_request.md)** (PDF: `tmp/20260608_help_request.pdf`)

Please complete 2.1–2.3 before agent enables production verification mail (2.5).

---

## Source linkage

| Doc | Topic |
|-----|--------|
| [20260608_STREAM_DUMP_DEBUG.md](20260608_STREAM_DUMP_DEBUG.md) | 0.1 implementation spec |
| [20260607-2FA-email-mobile-auth-flow.md](20260607-2FA-email-mobile-auth-flow.md) | 2.x / 3.x |
| [OPEN_TASKS_GRAPH.md](OPEN_TASKS_GRAPH.md) | Ticket-level graph |
| [20260602_REVERSE_SSH_proposals_summary.md](20260602_REVERSE_SSH_proposals_summary.md) | 4.x |
| [ALPHA.md](ALPHA.md) | Sign-off F/G |
