# Pad documentation Three documents, kept at the level of *what, why, and invariants* — not line-by-line code — so they stay true as the implementation evolves. | Doc | What it is | |---|---| | [`spec.md`](./spec.md) | What the app **actually does**, measured performance, the code layout, and an explicit list of deferred features. | | [`architecture.md`](./architecture.md) | How it works: single-owner concurrency model, channel topology, Frame handoff contract, ownership rules, editor/browser/render internals. | | [`development_plan.md`](./development_plan.md) | The active plan: completed phases, remaining work, and the on-device observation loop. | ## Package inventory | Package | Role | |---------|------| | `internal/editor` | Chunked buffer, line index, virtualized viewport, IME ops, autosave, logic goroutine, state, Frame | | `internal/browser` | Directory browsing, search, sort, pagination, browser state machine | | `internal/ui` | Element tree, frame layout, renderer (op-based), IME wiring, gestures | | `internal/perf` | Default-off performance profiler (per-logic-frame cadence + scroll state → CSV) | | `internal/io/pool` | Worker pool (8 workers, 2 priority lanes) + file/dir tasks | | `internal/test/e2e` | Harness driving the real `Logic` + `Inspect` | | `cmd/pad` | `main.go` (entry), `impl_android.go` (base path) | ## Documentation policy 1. **Docs describe invariants and contracts, not code lines.** If a document has to change on every refactor, it is too detailed — delete it or raise its level of abstraction. Point-in-time implementation plans are deleted once implemented (the previous `*_implementation_plan.md`, `touch.md`, `element_model.md`, `layout_rendering.md`, `virtual_scroll_render_optimization.md`, and `conflict_resolution.md` were removed in the 2026-08 doc reorganization for this reason). 2. **Unbuilt behavior is not spec'd.** Requirements that are not in the code live in `spec.md` §7 (deferred), never as if they worked. 3. **Code wins.** When doc and code disagree, fix the doc. ## Build & install (Android, this workstation) Prereqs on this box (already installed): JDK 17, Go, Android SDK at `~/android-sdk` (platform-tools, build-tools 35.0.0, emulator, NDK), `gogio@v0.10.0` in `~/go/bin`, `apktool` at `/tmp/apktool.jar`, debug keystore at `~/.android/debug.keystore`. Env vars are set in `~/.bashrc`. The full recipe is `/tmp/build_pad.sh` (machine-local). Steps: 1. `gogio -target android -targetsdk 35 -arch amd64 -o /tmp/pad-raw.apk .` (from `cmd/pad/`) 2. `apktool d /tmp/pad-raw.apk -o /tmp/pad_decoded -f` 3. Inject `` into the decoded `AndroidManifest.xml` (Android 15 needs it for `/storage/emulated/0`). 4. `apktool b /tmp/pad_decoded -o /tmp/pad-unsigned.apk` 5. `apksigner sign --ks ~/.android/debug.keystore --ks-pass pass:android --key-pass pass:android --ks-key-alias androiddebugkey --out cmd/pad/pad-emu.apk /tmp/pad-unsigned.apk` 6. `adb install -r cmd/pad/pad-emu.apk` Run the emulator (headless, AVD `pad_avd`, API 35): ``` nohup emulator -avd pad_avd -no-window -no-audio -no-boot-anim \ -gpu swiftshader_indirect >/tmp/emulator.log 2>&1 & ``` App package/activity: `pad.pad / org.gioui.GioActivity`. Default root directory: `/storage/emulated/0/Notes` (push test files there with `adb push file /storage/emulated/0/Notes/`). ## On-device observation loop (quick reference) Gio renders into one GL surface, so the authoritative debug signals are data, not pixels: - `adb logcat -s pad.pad` — app log (IME commits, open-file timing, errors). - `adb shell input tap|swipe|text` — drive the UI (see `development_plan.md` for the tap coordinates and IME-tap cadence that works). - Autosave debounce is 1 s: **wait ~1.6 s before reading a file back from disk** after typing. - Memory: `adb shell dumpsys meminfo pad.pad` (watch PSS/RSS; the 3.8 GB emulator OOMs the app above ~2.5 GB RSS). - Screenshots (`adb exec-out screencap -p > /tmp/x.png`) are an auxiliary check only — state, logcat, and file diffs are authoritative.