Lays out Velox Download Manager (IDM-class download manager for Ubuntu 26.04) as a monorepo ready for parallel lane development. No implementation code by design. - docs/: architecture, roadmap M0-M7, IDM-parity GUI spec, engine design, Firefox extension spec, risks/spikes, packaging - contracts/: wire-contract skeleton (JSON Schema + fixture templates) — the single synchronization point between lanes - docs/agents/: one brief per lane (PROTO, CORE, DAEMON, GUI, EXT, PKG/QA) with owned directories, build order and definition of done - CLAUDE.md: rules of engagement — lane ownership, layering, non-negotiables - CMake scaffolding with dev/tsan/release/ci presets Two environment findings shape the design: Firefox here is the Mozilla snap (native-messaging risk, so the extension carries a loopback-WebSocket fallback), and Wayland forbids passive clipboard monitoring (so clipboard capture is explicit-action-first). Co-Authored-By: Claude Opus 5 <[email protected]>
142 lines
6.6 KiB
Markdown
142 lines
6.6 KiB
Markdown
# 02 — Roadmap
|
||
|
||
Eight milestones. **M0 is the only serialized one** — after the contract freeze, four
|
||
lanes run in parallel and only re-synchronize at integration gates.
|
||
|
||
Durations are given in "lane-weeks" for a focused agent. Treat them as sequencing weight,
|
||
not a delivery promise.
|
||
|
||
---
|
||
|
||
## M0 — Foundations & contract freeze *(everything is blocked on this; keep it short)*
|
||
|
||
| # | Task | Lane |
|
||
|---|---|---|
|
||
| 0.1 | Toolchain bootstrap (`apt` list in README), `git init`, branch policy | PKG |
|
||
| 0.2 | CMake presets, top-level targets, clang-format/tidy, ASan/UBSan/TSan CI | PKG |
|
||
| 0.3 | **Write every schema in `contracts/schema/`** for the v1 method surface | PROTO |
|
||
| 0.4 | `gen_cpp.py` + `gen_ts.py`, generated code committed | PROTO |
|
||
| 0.5 | Golden fixtures for every method; `tests/conformance/` runner (C++ + TS) | PROTO |
|
||
| 0.6 | `tools/mockd` serving fixtures + synthetic progress events | PROTO |
|
||
| 0.7 | `tools/testserver` — a *hostile* HTTP server: no-Range, flaky, redirect chains, 401, slow-loris, changing ETag | QA |
|
||
| 0.8 | Decide product name + icon set licence; ADR for each M0 decision | PKG |
|
||
|
||
**Exit gate:** `tools/mockd` answers every fixture; the generated C++ and TS clients both
|
||
round-trip every fixture; CI is green on an empty repo. **Freeze `VERSION` at 1.0.0.**
|
||
|
||
---
|
||
|
||
## M1 — Four lanes in parallel *(the long stretch)*
|
||
|
||
### 1A · CORE — engine ⏱ 4–5
|
||
Probe → segmentation → dynamic stealing → sparse preallocation → ring-buffered `pwrite`
|
||
→ `.veloxpart.meta` resume → token-bucket limiter → retry policy.
|
||
**DoD:** downloads a 5 GB file at line rate; kill `-9` at 60 % and resume finishes with a
|
||
byte-identical SHA-256; every `tools/testserver` hostile mode handled; ASan/TSan clean;
|
||
`tools/bench` numbers recorded as the baseline.
|
||
|
||
### 1B · DAEMON — RPC + state ⏱ 3–4
|
||
Unix socket + WS listeners, JSON-RPC dispatcher, subscriptions and event batching, SQLite
|
||
schema + migrations, queues, scheduler, settings, pairing/token store, systemd user units.
|
||
**DoD:** passes the full conformance suite as a *server*; `velox` CLI can add/list/pause/
|
||
resume; survives daemon restart with all tasks intact.
|
||
|
||
### 1C · GUI — Qt shell against `mockd` ⏱ 4–5
|
||
Main window, model/delegate table, category tree, Add-URL + File-Info dialogs, progress
|
||
dialog with segment bars and speed graph, Options tabs wired to `settings.*`, tray, drop
|
||
target, QSS theming.
|
||
**DoD:** every screen in `docs/03-gui-spec.md` exists and is driven **entirely** by
|
||
`mockd`; 10 000 synthetic rows scroll at 60 fps; zero download logic in the GUI tree.
|
||
|
||
### 1D · EXT — extension against `mockd` ⏱ 3–4
|
||
Capture pipeline, both transports + pairing, context menus, popup with live progress,
|
||
options page, media detection.
|
||
**DoD:** intercepts a real download in real Firefox and hands it to `mockd`; **fail-open
|
||
verified by test** (daemon killed → Firefox downloads normally); `web-ext lint` clean.
|
||
|
||
> Lanes touch **only their own directories**. The sole shared surface is `contracts/`, and
|
||
> only PROTO writes there. See `CLAUDE.md`.
|
||
|
||
---
|
||
|
||
## M2 — First vertical slice ⏱ 1–2 *(all lanes, one week, together)*
|
||
|
||
Swap `mockd` for the real `veloxd`. Click a link in Firefox → extension captures →
|
||
File-Info dialog appears → download runs multi-segment → progress in GUI *and* popup →
|
||
file lands in the right category folder → checksum verified.
|
||
|
||
**Exit gate:** that flow works end-to-end on a clean Ubuntu 26.04 VM, from a `.deb`, with
|
||
**snap Firefox**. This is the moment the snap native-messaging risk is settled for real.
|
||
|
||
---
|
||
|
||
## M3 — IDM parity ⏱ 3–4 *(parallel again)*
|
||
|
||
Categories & automatic file distribution · rules engine (extension/MIME/host/size → folder)
|
||
· queues + scheduler UI · speed limiter · batch download (wildcards + clipboard blob) ·
|
||
Site Grabber wizard · Site Logins via Secret Service · proxy/SOCKS5 · duplicate handling ·
|
||
"Refresh download address" · post-download commands · virus-scan hook.
|
||
|
||
**Exit gate:** the IDM feature checklist in this doc's appendix is ticked or has a written
|
||
"won't do, because…".
|
||
|
||
---
|
||
|
||
## M4 — Media grabber ⏱ 2–3
|
||
HLS/DASH manifest parsing in the daemon, variant enumeration, segment-parallel fetch, mux
|
||
via ffmpeg, in-page video panel in the extension. DRM streams detected and clearly refused.
|
||
|
||
## M5 — Polish ⏱ 2
|
||
Theming light/dark, i18n + RTL, accessibility pass, notifications, sounds, global shortcut
|
||
via the portal, Wayland clipboard spike resolved, first-run wizard, tray/drop-target
|
||
behaviour, `--help` and man pages.
|
||
|
||
## M6 — Packaging & release ⏱ 1–2
|
||
`.deb` + PPA, Flatpak manifest, native-messaging manifests installed to all four locations,
|
||
AMO submission (signed XPI), autostart, upgrade/migration test from a previous DB version,
|
||
uninstall leaves no orphan sockets or manifests.
|
||
|
||
## M7 — Hardening ⏱ 2
|
||
libFuzzer on every parser (`Content-Disposition`, HLS, DASH, meta file, JSON-RPC), 72-hour
|
||
soak with 500 queued tasks, perf targets from `docs/04` §8 enforced in CI, threat-model
|
||
review of the WS transport, crash reporting (local only, opt-in, no telemetry).
|
||
|
||
---
|
||
|
||
## Dependency graph
|
||
|
||
```
|
||
M0 ──┬──► 1A CORE ──┐
|
||
├──► 1B DAEMON ─┼──► M2 ──► M3 ──► M4 ──► M5 ──► M6 ──► M7
|
||
├──► 1C GUI ────┤
|
||
└──► 1D EXT ────┘
|
||
(all four against mockd, no cross-lane blocking)
|
||
```
|
||
|
||
Critical path: **M0 → 1A/1B → M2**. GUI and EXT can absorb schedule slack because `mockd`
|
||
never blocks them. If you must cut scope, cut M4 (media) before anything else — it is the
|
||
largest chunk of work with the least effect on core parity.
|
||
|
||
---
|
||
|
||
## Appendix — IDM feature checklist
|
||
|
||
| IDM feature | Milestone | Notes |
|
||
|---|---|---|
|
||
| Multi-segment accelerated download | M1 | Dynamic stealing, not static split |
|
||
| Resume broken/interrupted downloads | M1 | With `If-Range` revalidation |
|
||
| Browser integration / auto-capture | M1D+M2 | Firefox first; Chrome later if wanted |
|
||
| Download categories + auto file distribution | M3 | Rules engine |
|
||
| Queues + scheduler | M3 | Per-queue time windows |
|
||
| Speed limiter | M1/M3 | Engine in M1, UI in M3 |
|
||
| Batch downloads / wildcards | M3 | |
|
||
| Site Grabber | M3 | Depth-limited crawler with filters |
|
||
| Video/media grabber | M4 | HLS/DASH; no DRM |
|
||
| Drag-and-drop drop target | M1C | |
|
||
| Clipboard monitoring | M5 | Wayland-limited; see risks |
|
||
| Proxy / SOCKS5 / site logins | M3 | Credentials in Secret Service |
|
||
| Checksum verification | M1 | MD5/SHA-256 |
|
||
| On-completion actions (open/shutdown) | M1C/M3 | Shutdown via logind, confirmed |
|
||
| ZIP preview | — | **Won't do.** Low value on Linux |
|
||
| Dial-up / VPN auto-redial | — | **Won't do.** Obsolete |
|