docs: bootstrap vault, roadmap and research

This commit is contained in:
2026-10-17 21:14:19 +03:00
parent 749afadcd4
commit 8fa0632d69
34 changed files with 1508 additions and 0 deletions
+196
View File
@@ -0,0 +1,196 @@
# viexp Roadmap — Rust + English in 20-hour sprints
Method: Josh Kaufman, **"The First 20 Hours"** — rapid skill acquisition. The project is split
into isolated 20-hour sprints (~45 min/day for a month each). Every sprint: one Rust sub-skill,
one working app increment, one English artifact. The goal of each sprint is to cross the
frustration barrier and ship something that runs — not perfect code.
**Kaufman's rules, adapted**
| Kaufman principle | How this roadmap applies it |
|---|---|
| Deconstruct the skill | The table below: each sprint = one sub-skill + one app increment |
| Learn just enough to self-correct | Per-sprint "Rust focus — the vital 20%": the minimum theory to *read your own compiler errors*. Every error goes to the ErrorJournal with a self-correction cue |
| Remove barriers to practice | Sprint 0 sets up the whole environment: toolchain, linters, fast feedback (`bacon`), Gitea board, CI. Never debug your setup during practice time |
| Fast feedback loops | `cargo check`/bacon on save, unit tests per session, immediate AI code review of each session's diff (commit → review → fix) |
| Quantity over quality | Many small commits, many small drills. Working ugly code beats beautiful unfinished code. No over-engineering before v0.1 |
## Skill deconstruction
**Rust sub-skills** (learned in order): cargo & project layout → types & control flow →
ownership/borrowing → structs, enums, pattern matching → `Option`/`Result` & `?` →
modules & crates → traits & generics → iterators → `Path`/`fs` & error handling (`thiserror`/`anyhow`) →
serde/TOML → lifetimes → trait objects & dynamic dispatch → threads & channels →
async/await & tokio → process spawning → caching & performance.
**App increments** (each demoable): `vls` CLI → 3-pane TUI → navigation & file ops →
config & openers → text previews → image previews → document previews → media & async →
script plugins → power features → performance → release.
**English track**: every commit message, every issue, all docs — English only. One written
artifact per sprint. Daily DevLog (3–5 sentences). See [[workflows/english-workflow|English workflow]].
## Session rhythm (45 min, every day)
1. **5 min** — read yesterday's DevLog + ErrorJournal; `git pull`, `bacon` starts.
2. **30 min** — today's drill or feature slice (one drill = one commit).
3. **10 min** — get the diff reviewed, fix what the reviewer flags, write the DevLog entry.
**Frustration rules**: stuck >20 min on one error → ask for a review instead of grinding;
never end a session with broken code (revert to green); a slow day is a reading day
(Rust Book chapter in English) — log it, no guilt.
## Sprints
Legend: 🎯 milestone. Each sprint gets a `docs/sprints/sprint-NN-*.md` note (Sprint template)
and a Gitea milestone with issues created from its Definition of Done.
---
### Sprint 0 — Setup & deconstruction (≈6 h, short)
- **App deliverable**: empty `viexp` cargo project that compiles, `cargo test` runs one trivial
test, CI (Gitea Actions) is green, `bacon` + `clippy` + `rustfmt` wired, Gitea board ready.
- **Rust focus**: toolchain mental model — what cargo, rustc, crates.io, `Cargo.toml` are;
read your first compiler error on purpose (break a program, fix it).
- **English**: README "Status" section + the vault (this roadmap counts).
- **DoD**: `cargo bacon` shows check+test on save; first commit pushed; Sprint-1 issues exist.
### Sprint 1 — Rust core via `vls` (20 h)
- **App deliverable**: `viexp ls` subcommand — a better `ls`: colored names by type,
human-readable sizes, `--sort name|size|mtime`, `--hidden`, `--long`; ≥10 unit tests.
- **Rust focus (vital 20%)**: variables & types, functions, `if`/`match`, loops, `Vec`/`String`
vs `&str`, structs & enums, `Option`/`Result` + `?`, modules, `#[cfg(test)]`.
Rust Book ch. 1–9 (skim 7/8), rustlings `intro→enums`.
- **English**: README usage section; article "Why build a file manager in Rust" (draft).
- **DoD**: `vls ~/` output beats `ls` for your eyes; clippy clean; tests green.
### Sprint 2 — First TUI (20 h) — the borrow-checker sprint
- **App deliverable**: three-pane Miller layout (parent / current / placeholder preview),
`j/k/gg/G` cursor movement, `:q` quits, resize-safe redraw, no flicker.
- **Rust focus**: **ownership & borrowing in anger** (the state struct owns everything),
references vs clones, lifetimes as they appear in ratatui calls, the event-loop pattern
(poll event → mutate state → redraw). Rust Book ch. 4, 10.3 (skim), ratatui official docs.
- **English**: keymap reference table in docs (precise imperative phrasing).
- **DoD**: navigate a 10k-file directory smoothly; panic-free for 15 min of use.
### Sprint 3 — Navigation & file ops (20 h) 🎯 **M1: personal daily driver**
- **App deliverable**: enter/leave directories, hidden toggle, sort cycling, `Space`/`V`
selection, `yy`/`dd`/`pp` copy/cut/paste, delete → **first-class trash** (freedescompliant)
with undo, `:mkdir :touch :rename`, status bar (path, size, free space — **not** per-frame
`statvfs`; 1 Hz poll).
- **Rust focus**: `Path`/`PathBuf`, `fs::read_dir`/`metadata`, real error handling
(`thiserror` for lib-style internals, `anyhow` at main), iterators (`map/filter/sort_by`
chains), `Display` impls.
- **English**: article "Week one of dogfooding my own file manager".
- **DoD**: use viexp instead of ranger for real work for 3 days; log every pain point as an issue.
### Sprint 4 — Config & openers (20 h)
- **App deliverable**: `viexp.toml` (defaults, theme colors, sort) + `modules.toml` registry
v0 (ADR-003): mime/glob → opener, per-module `enabled`, user rules prepend/append;
opener engine (infer + xdg-mime → rule table → `xdg-open` fallback), `r` "open with" menu,
`:open_with`.
- **Rust focus**: serde derive on enums/structs, `Default` + merge semantics, `HashMap`/
`BTreeMap`, first **trait design** (`Opener`), builder-ish config loading with helpful errors.
- **English**: configuration guide draft (reference-style writing).
- **DoD**: any file opens with your preferred app from config alone; broken TOML produces a
friendly error, not a panic.
### Sprint 5 — Text previews & bulk rename (20 h)
- **App deliverable**: preview pane v1 — syntax-highlighted text (syntect) with line numbers
and scrolling, directory preview, file metadata panel, zip/tar listing, `:bulkrename` via
`$EDITOR` (ranger's killer feature), `n/N` plain search, `:` command history.
- **Rust focus**: lifetimes in real signatures, **trait objects** (`Box<dyn Previewer>` registry),
advanced iterators, caching keyed by `(path, mtime)`.
- **English**: article "How a TUI paints text" (explaining rendering → strongest writing practice).
- **DoD**: preview parity with ranger for text/code/archive files.
### Sprint 6 — Image previews (20 h) 🎯 **M2a**
- **App deliverable**: image module through the registry; **kitty graphics adapter first**
(owner's terminal), chafa/halfblocks floor; thumbnail disk cache + LRU; runtime
disable/replace via `modules.toml` proven on images.
- **Rust focus**: the `image` crate, decode/resize pipeline, `#[cfg(feature)]` modules,
pixel data, spawning helper processes safely.
- **English**: article "How terminals display images" (kitty protocol, sixel, ueberzug++ —
your best future blog post; research notes already hold the material).
- **DoD**: PNG/JPEG/WebP/GIF preview instantly in kitty; `enabled=false` kills it in one line.
### Sprint 7 — Document previews (20 h) 🎯 **M2b: full ranger replacement**
- **App deliverable**: PDF (pdfium-render, Apache-2.0), EPUB (hand-rolled zip+XML — **GPL
trap avoided**), Markdown (comrak/termimad), DJVU (djvu-rs + `ddjvu` fallback config).
All as registry modules, all runtime-disableable.
- **Rust focus**: binary data & byte streams, feature-gated crates, error taxonomy design,
more trait objects; reading crate docs as a skill.
- **English**: module documentation pages (PDF/EPUB/DJVU) in user-guide style.
- **DoD**: your entire document library previews; ranger uninstalled.
### Sprint 8 — Media & async (20 h) 🎯 **M2c**
- **App deliverable**: video thumbnail (spawn `ffmpeg -ss … -vframes 1`), audio metadata +
cover art (`ffprobe` JSON), **background preview pipeline**: std threads + mpsc now,
generation-counter cancellation, large-directory pagination; adopt **tokio** for the
pipeline by sprint end (ADR-005).
- **Rust focus**: `std::thread`, `mpsc`, `Arc`/`Mutex`, then async/await, `tokio::spawn`,
`select!`, cancellation patterns. Rust Book ch. 16 + async book chapters (English only!).
- **English**: article "Async Rust for a skeptic" — explain threads-vs-tokio in your own words.
- **DoD**: 4K-video directory scrolls at full speed; huge directory never blocks input.
### Sprint 9 — Script plugin protocol (20 h) 🎯 **M3a: extensible**
- **App deliverable**: freeze the **external plugin contract** (ADR-002 phase 2): previewer
argv `(path, w, h, x, y)` + env context + FIFO write-back + `cleaner` hook; documented
exit codes & SIGPIPE; opener scripts; `plugins/` dir discovery; two reference plugins
(bash: torrent info; python: git repo summary).
- **Rust focus**: process spawning & pipes, timeouts, safe command construction (no shell
injection), protocol design & semver, integration tests with fixture scripts.
- **English**: **plugin author guide** — the sprint's main artifact; write it as if for strangers.
- **DoD**: a script written only from the guide (no source peeking) works.
### Sprint 10 — Power features (20 h) 🎯 **M3b: feature parity with your ranger config**
- **App deliverable**: tabs, bookmarks + marks, fuzzy finder (nucleo) with **interruptible**
search (broot lesson), `:commands` set (`:find :delete :copy…`), `push` key-simulation,
shell integration `--choosefile/--choosedir/--selectfile`, cd-on-exit wrapper script,
session restore.
- **Rust focus**: state machines (modes), Rc-free architecture review, `macro_rules!` for
keymap tables, API refactoring under tests.
- **English**: article "Vim-style UX patterns in file managers".
- **DoD**: your shell rc sources the viexp wrapper; fuzzy find feels instant.
### Sprint 11 — Performance & robustness (20 h)
- **App deliverable**: `notify`-based live directory updates, virtual scrolling, startup
<50 ms, one-week dogfood with zero panics, `tracing` logs to file, panic hook restores
the terminal, criterion benchmarks committed, crash-fix buffer.
- **Rust focus**: profiling (`cargo flamegraph`, `perf`), benchmarking (criterion), reading
someone else's code (yazi's) for patterns, hardening.
- **English**: article "Profiling a TUI app: making viexp start in 40 ms".
- **DoD**: benchmark numbers in README; a week of daily use logged.
### Sprint 12 — Release & docs (20 h) 🎯 **M4: v0.1.0 public**
- **App deliverable**: `v0.1.0` — cargo-dist release builds, AUR PKGBUILD, Gitea release +
changelog, **user guide** (mdBook in-repo), plugin examples gallery, install docs.
- **Rust focus**: release engineering, MSRV policy, feature matrix testing, rustdoc comments
on the public plugin API.
- **English**: the user guide is the largest English artifact of the project; polish it hard.
- **DoD**: a stranger installs from AUR and writes a plugin using only the docs.
### Backlog (post-1.0, priority order)
Embedded Lua plugins (mlua, ADR-002 phase 3) · sixel/iTerm2/ueberzug++ adapters · DDS-style
inter-instance pub/sub · `NNN_FIFO`-style hover event stream · themes gallery · zoxide jump ·
archive mount/browsing depth.
## Milestones
| Milestone | After sprint | Meaning |
|---|---|---|
| M1 | 3 | daily driver for basic navigation/file ops |
| M2a–c | 6–8 | full ranger replacement (images, docs, media) |
| M3a–b | 9–10 | extensible by scripts, feature parity |
| M4 | 12 | v0.1.0 released publicly |
At 45 min/day this is roughly a 12–13 month journey to v0.1.0 — the point is a working
product **and** durable skills, in that order, every single sprint.
## Cadence & safety nets
- Sprint notes live in `docs/sprints/`; each sprint's DoD becomes Gitea issues (milestone per
sprint) — see [[workflows/gitea-workflow|Gitea workflow]].
- If a sprint overruns by >30%, cut scope from the bottom of its DoD — never silently skip tests.
- One "buffer week" is allowed between sprints; more than one means the sprint was too big —
re-decompose in the retro.