Commit Graph

144 Commits

Author SHA1 Message Date
Julien Calixte
5c97e019ec docs(kaizen): drop the after-kaizen bar until step 6 measures it
Step 1 is baseline + target only; the target line stays, the bar would
fake a measurement that doesn't exist yet.
2026-07-13 11:07:25 +02:00
Julien Calixte
7712de6153 docs(kaizen): size the xychart so its labels stop clipping
Explicit 900x500 canvas, tighter x-axis labels, unit-only y-axis title
(the long vertical title collided with the tick numbers in Remanso).
2026-07-13 11:06:44 +02:00
Julien Calixte
1df25f75d6 docs(kaizen): chart the improvement potential as a mermaid xychart
Before/after bars with the target as a line series; the caption keeps
the nuance the chart can't draw (true before value is ∞, not 611 s).
2026-07-13 11:03:43 +02:00
Julien Calixte
acbafa3d6b docs(kaizen): retell the real-repo sync fix as a six-step kaizen
The tradeoff-curves doc stays the chronological data layer; the kaizen
is the story layer — value model, 8-factor hypothesis table, ideas
ranked by verified cause, and an evaluation left PENDING until the
end-to-end on-device :sync lands.
2026-07-13 10:56:05 +02:00
Julien Calixte
e801d2d480 docs(palette): note the two on-device boot-log measurements pending
Walk time after the d_type fix, and the file-list internal-DRAM cost
with the decision rule for interning paths into one PSRAM buffer.
2026-07-13 10:26:25 +02:00
Julien Calixte
79fad4689c docs(palette): amend v0.5 with the recursive walk and search threshold 2026-07-13 00:55:34 +02:00
Julien Calixte
2166b932b6 docs(sync): update the wiring section to how-it-landed
The merged plan section now records the shipped design: single path
set (working tree as truth) instead of {changed, deleted}, the dirty
journal, stranded-commit recovery, radio-free up-to-date, and the
soft-reset reconcile with its carried-files side win.
2026-07-13 00:53:50 +02:00
Julien Calixte
e86a3b8254 docs(sync): merge the commit handoff into the staging tradeoff curve
The bench phase the handoff was written for is closed (splice benched,
fast-seek landed, cache removed, decision made), so the note's live half —
the firmware plumbing plan — moves into sync-commit-staging.md as "The fix —
wiring the O(depth) splice into the firmware", reconciled to the run-5 state.
The duplicated TL;DR/measurement summaries are dropped in favor of the
curve's own trail; inbound references (notes index, git_bench comments)
now point at the curve.
2026-07-13 00:29:07 +02:00
Julien Calixte
9309f3f239 docs(sync): record the esp_map v2 verdict and cache removal
Run 4: memory discipline verified (1833 KB flat, no OOM) but 0 hits
with the small maps demonstrably retained — window-repetition theory
refuted, sub-second bar failed (splice 2.83 s cold / ~2 s steady).
Decision: wire the splice in anyway (~9-10 s cold real-repo :sync vs
611 s/OOM for every alternative). Run 5: cache removal confirmed
free; the ~1.85 MB "resident" was mwindow's live window set, which
makes the mwindow opts in shipping git_sync.rs load-bearing.
2026-07-13 00:20:12 +02:00
Julien Calixte
ce3204a350 docs(sync): record fast-seek root cause and splice bench trail
Splice bench (6.5 s, O(depth) shape confirmed), FatFS cluster-chain
root cause with elm-chan/ESP-IDF references, on-device fast-seek
verification, second localization round (strict-creation refuted,
read_header 470 ms), esp_map v2 design, and the two firmware plumbing
gaps (mwindow opts + 16-FD mount).
2026-07-13 00:02:55 +02:00
Julien Calixte
dade5e6bb3 docs(sync): record real-repo commit bench and TreeBuilder handoff
The real jcalixte/notes clone (570 MB pack, 1179 files) proved both index
strategies are O(N_tree) and unshippable: index.write re-hashes the tree
(611 s), and the index-free read_tree is 77 s cold and OOMs the mmap cache
(zlib crash). Record the run in the tradeoff curve, revise the verdict to an
O(depth) TreeBuilder walk, and add a handoff note with the design, firmware
call sites, and bench steps for the next session.
2026-07-12 15:04:59 +02:00
Julien Calixte
456c4c43e7 perf(sync): instrument and benchmark commit-staging latency
Break the stage+commit window into sub-phases (FAT working-tree walk vs
object writes) via `commit split —` log lines, and add two micro-benchmarks
(sd_bench for SD/FAT primitive ops, git_bench for libgit2 object overhead)
with justfile recipes. Documents the walk-vs-writes cost model in
tradeoff-curves/sync-commit-staging.md to decide whether explicit-path
staging over the editor's dirty set is worth replacing add_all(["*"]).
2026-07-12 12:24:50 +02:00
Julien Calixte
56f5d18bd8 docs(macroplan): record v0.6 markdown complete in core (0.6.0)
Mark v0.6 delivered (core, host-tested; on-device gate pending): the
snippet engine, the Cmd-P/>/$ palette split retiring :e, and the just
init catalog. Note the →/≠ ISO-8859-15 caveat.
2026-07-12 10:42:56 +02:00
Julien Calixte
767742ba12 docs(v0.6): mark boot-read + catalog done, finalise the catalog list
Record the firmware boot-read (serde_json builds for xtensa) and the
just-init catalog as delivered, and replace the proposed French catalog
with the finalised 17-snippet English set (three groups). Note the
→/≠ base-font caveat and the no-clobber seeding guard.
2026-07-12 10:36:58 +02:00
Julien Calixte
5a076e3226 docs(v0.6): mark the palette generalisation delivered in core
Record the > command registry, one-shot/two-step dispatch, and the :e
retirement as done in core; note the ISO-8859-15 label constraints
(ASCII `...`, `»` hint marker).
2026-07-12 10:22:24 +02:00
Julien Calixte
baf9715570 feat(editor): hint the matching snippet in the panel on typing pause
Snapshot the snippet name inline Tab would expand into a panel field in
refresh_stats, so it rides the typing-pause throttle rather than
repainting per keystroke. Draw it as `» name` on the row above the mode
line (Latin-9 has no tab glyph), sharing the slot with the NO KBD flag,
which can't co-occur since the hint means you're typing.
2026-07-12 10:09:43 +02:00
Julien Calixte
221135cd9b docs(v0.6): specify the snippet library and $/> palette split
Reshape v0.6 snippets from a hard-coded table into a git-synced,
Zed-compatible JSON library (.typoena.snippets.json) with an inline Tab
path and a $ palette launcher. Add the file-format reference and
document the Cmd-P/>/$ verb split and the just init catalog.
2026-07-12 10:03:38 +02:00
Julien Calixte
93f3a43b34 docs(prefs): document theme + auto_sync presets, override v0.5 deferral
Reference doc gains a theme key, an Options column, and the e-paper dark-mode
ghosting caveat. The v0.5 spec gets an amendment note superseding the two
reversed "decide-before-build" calls (auto_sync now a set-ahead palette
command; theme shipped early) without rewriting the verified-on-device
history; macroplan updated to match.
2026-07-12 09:02:21 +02:00
Julien Calixte
fdd59093db docs(v0.5): document the trailing-newline display model
Record the d14d9e7 behaviour the doc didn't cover: format-on-save keeps at
most one trailing blank line, and load-verbatim + guarded-save render a
file's POSIX terminator as a visible trailing empty line.
2026-07-12 02:25:24 +02:00
Julien Calixte
55a8d21e0f docs(macroplan): split each version into its own page
Move each version's scope checklist and status out of the monolithic
macroplan into a dedicated docs/vX.Y-<slug>.md page; macroplan keeps the
source block, the rollup status, and a one-line summary + link per
version. v0.1 reuses its existing product/technical pages.

Also drop the "Optional column ruler at 80" requirement from v0.6.
2026-07-12 02:10:29 +02:00
Julien Calixte
d46cdb7e7f docs(macroplan): mark v0.5 delivered, close slice-4 on-device gate
All four v0.5 slices are done and device-verified: the prefs round-trip is
confirmed both directions (boot-read + on-device palette edit -> push flipped
line_numbers on origin), and the slice-3 delete fix is recorded as confirmed on
device. Descoped items (buffer close, grey-Publish-in-Local cue, multi-file
publish count) noted, not blocking delivery.
2026-07-12 01:57:00 +02:00
Julien Calixte
c535864ee7 feat(editor): add .typoena.toml prefs and palette settings (v0.5 slice 4)
Git-tracked editor preferences read at boot and toggled live on-device:

- Prefs type (line-based TOML parse/serialize, no crate on xtensa) held on
  Editor; firmware reads /sd/repo/.typoena.toml before the first render and
  falls back to per-key defaults. Keys: save_on_idle, format_on_save,
  line_numbers (bool) + auto_sync (string, schema/default only until v0.7).
- line_numbers applied live (gutter_cols -> 0 when off).
- Palette > command mode toggles the three bools; the list stays open so
  several flip in one visit, and :settings opens it directly. Each toggle
  applies live and queues Effect::SavePrefs (host atomic-writes the file,
  which rides the next :sync).
- save_on_idle honoured host-side as a silent, unformatted idle auto-save.
- to_toml is newline-free; save_path now appends exactly one terminator
  unconditionally so buffers round-trip byte-for-byte (trailing blanks kept).
- Firmware 0.4.0 -> 0.5.0; new docs/typoena-toml.md reference. Also refreshes
  the slice-3 macroplan status (delete fix was confirmed on device).
2026-07-12 01:48:10 +02:00
Julien Calixte
c9c07165e0 feat(editor): add :enew and :delete with real git-staging (v0.5 slice 3)
:enew <name> creates a new file (empty, dirty, added to the palette list);
:delete unlinks the current file via a new Effect::Delete and switches to a
parked buffer or scratch. Scope is read from the path (local/x, repo/x) rather
than a modal prompt, and the /sd prefix is now optional in resolve_path.

On-device testing showed deletions never reached the remote: add_all(["*"])
alone does not stage a removal on this libgit2, so the tree came back unchanged
and the push was a silent no-op. stage_and_commit now runs add_all then
update_all(["*"]) (git add -u) — together git add -A. The :delete snackbar now
confirms the scoped file and flags that a Tracked file is local until :sync.
2026-07-12 00:44:39 +02:00
Julien Calixte
e967773bd6 feat(editor): add v0.5 file palette (Cmd-P) with fuzzy match
Cmd-P opens a modal transient palette over the writing column: a bare
fuzzy-search input, the ranked file list, and the selected row in reverse
video. A pure host-testable fuzzy_score (subsequence + word-boundary and
consecutive-run bonuses) ranks results; an in-core MRU floats recently
opened files first and is shared with :e (both route through open_path).
The host feeds the file list once at boot (enumerate_files over /sd/repo
and /sd/local). Ctrl-n/Ctrl-p navigate the list; Enter opens via the same
park/evict path as :e; Esc closes.

Ctrl-n/Ctrl-p also become down/up line motions in Normal and View (vim
CTRL-N/CTRL-P, count-aware), which is why the palette opener is Cmd-P
alone. No `>` prefix on the file input — `>` is reserved for the command
palette (slice 4).

112 editor + 28 keymap tests; the no-git firmware binary builds clean.
2026-07-12 00:11:33 +02:00
Julien Calixte
2215da939d feat: add multi-file buffer foundation (v0.5 slice 1)
Rework the single Effect return into a drained effect queue
(Save{path,scope,contents} / Load / Publish / Pull) so one action can
ask the host for several ordered steps: opening a non-resident file
queues a Save of the outgoing dirty buffer then a Load of the target.

Keep the active buffer's fields inline on Editor and park inactive
buffers in a small LRU (<=3 resident = active + 2); switching back to a
resident buffer restores its caret/scroll/undo without touching the SD.
A dirty parked buffer is saved before eviction, so nothing leaves RAM
unsaved. `:e <path>` opens by prefix (/sd/repo -> Tracked, /sd/local ->
Local); `:sync` is refused in-core for a Local buffer.

Firmware drains the queue to empty each batch (a Load can cascade an
eviction Save) and persistence generalises the atomic save off the
hard-coded notes.md into load_path/save_path.

Also bump the side panel to FONT_9X15 and the `:` command line to
FONT_10X20 for legibility, word-wrapping the snackbar so a long notice
keeps its actionable tail.
2026-07-11 22:26:37 +02:00
Julien Calixte
fa0ea56e1a feat(editor): add Visual mode (v/V) with y/d/c, move View to gr
Charwise `v` and linewise `V` selection with yank/delete/change on the
span; motions and counts extend it. Read-only View moves off v/V to
`gr` (go-read). Selection renders reverse-video on the 1-bit panel.
Normal motions factored into a shared move_by. Firmware -> 0.4.0.
2026-07-11 20:50:16 +02:00
Julien Calixte
470a9d25d0 docs(macroplan): note v0.3 on-device smoke-test and paste-scroll fix 2026-07-11 20:26:15 +02:00
Julien Calixte
884c8f2e48 docs(postmortems): record the SPI-DMA OOM editor freeze
Root cause, shipped safety net, and the specced eradication (a
persistent internal DMA scratch buffer in Epd so paints never allocate
mid-sync). Tracks hardware re-test and the eradication as follow-ups.
2026-07-11 20:21:49 +02:00
Julien Calixte
f950abdc4a docs(macroplan): mark v0.3 editing complete
Records v0.3 as delivered in core (host-tested, on-device smoke-test pending)
and notes the known dot-repeat limits. Also reorders the plan so the Status
block follows the macroplan source.
2026-07-11 20:03:59 +02:00
Julien Calixte
229c259e7c docs: mark v0.2 complete and align delivered-release bookkeeping
Spike 13 (line-number gutter) verified on the panel closes the last v0.2
gate. Record v0.2 as delivered, and give v0.2.5 a delivered date + learning
note to match v0.1/v0.2 (its source-block entry still read on-track).
2026-07-11 19:41:17 +02:00
Julien Calixte
5d9591e5ea docs: rename roadmap.md to macroplan.md and refresh the plan
The file is the macroplan (plus per-version scope), so rename it to match and
retitle to "Macroplan"; update all inbound links and friendly labels across the
docs. Refresh the plan while here: v0.2 gutter built, :gl pull recorded (v0.7),
command-line editing (v0.4), and the format_on_save pref (v0.5).
2026-07-11 19:27:27 +02:00
Julien Calixte
97216db0c0 docs: record line-number gutter and v0.5 line_numbers pref
Mark the v0.2 gutter built + host-tested (Spike 13 bench check still pending),
add the v0.5 .typoena.toml line_numbers toggle, and update CONTEXT.md screen
regions for the rebalanced 63-col writing region / 25-col side panel.
2026-07-11 18:59:52 +02:00
Julien Calixte
fc83306a81 feat(keymap,editor): add Ctrl-d/u half-page scroll
Decode Ctrl+D/Ctrl+U as HalfPageDown/HalfPageUp intents (matching the existing
DeleteWord/DeleteLine chord pattern, so the editor stays ignorant of Ctrl).
They step display (soft-wrapped) rows, not logical lines, so half a page is
half the visible window regardless of how prose wraps: Normal moves the caret
and the viewport follows, View scrolls the viewport, Insert/Command are no-ops.
2026-07-11 18:32:05 +02:00
Julien Calixte
491dc57144 docs: drop relative line numbering from the v0.2 gutter
Relative numbering renumbers the whole gutter on every j/k, a tall partial
refresh per cursor move that eats the e-ink ghosting budget for no
proportionate gain. Gutter is now absolute-only; Spike 13 downgrades from a
genuine e-ink risk to a layout decision.
2026-07-11 18:31:33 +02:00
Julien Calixte
a817229ae1 docs(qfd): rebase perception and H1 targets on measured v0.1
Update the House now that v0.1 is delivered and hardware-verified:

- Perception zone: Typoena column moves from v0.1 target to measured.
  W6 3->4 (1 h soak attested), W1 4->2 (type latency measured ~630 ms,
  a visible lag). Typoena total 52->51, lead over Pomera down to one.
- H1 target: v0.1 relaxed 200->400 ms and v1.0 150->300 ms; ~630 ms
  still exceeds 400 ms, recorded as the open latency gap, not a pass.
- Fix pre-existing drift: TikZ W14 disagreed with the table/totals
  (Pomera/Smart 2/5 vs 5/1); "thirteen rows" -> "fourteen".
- Hoist the House diagram above section 1 so the picture leads.
- Trim AI writing tells and thin em-dash density in the new prose.
2026-07-11 17:58:38 +02:00
Julien Calixte
17b6631310 docs(qfd): annotate H7 Publish latency with measured :sync data
Adds a ‡ footnote on H7 (mirroring the H4 boot-latency †): cold :sync ~16 s /
warm ~10 s measured 2026-07-11 — within the ≤30 s v0.1 target, marginal against
the ≤10 s v1.0 target (cold's one-time Wi-Fi+SNTP push it over). Links the
breakdown in notes/sync-latency.md.
2026-07-11 17:21:26 +02:00
Julien Calixte
fe544ccdd3 refactor(docs): merge quality-house into qfd §3
quality-house.md mirrored qfd.md's §1/§2 catalogues in a separate file,
which silently drifted (H3 cadence read 20 there vs 64 in qfd). Fold the
House diagram, perception scores, and regen notes into qfd.md §3 with no
section renumbering, so inbound #3/#6/#7 anchors still resolve. Delete
quality-house.md; re-point quality-house-empty.md and the docs index.
2026-07-11 17:17:18 +02:00
Julien Calixte
a700412773 docs: record :sync latency budget from hardware measurement
New docs/notes/sync-latency.md breaks down the measured ~16 s cold :sync
(Wi-Fi + SNTP + one TLS push), explains the optimistic-retry handshake saving,
the reconcile/last-writer-wins semantics, and why the rest is near the protocol
floor. Linked from the notes index, the docs index, and the Git row of the root
README.
2026-07-11 17:04:02 +02:00
Julien Calixte
92068f1cce docs(quality-house): sync H3 target to 1:64 after qfd change 2026-07-11 17:00:45 +02:00
Julien Calixte
9d6daf7afd docs(qfd): sync boot latency and refresh cadence to measured values 2026-07-11 16:47:12 +02:00
Julien Calixte
c206fc28e4 docs: record verified 4258 ms cold boot after refresh fix 2026-07-11 16:46:56 +02:00
Julien Calixte
ad023843e9 docs: add e-ink refresh-latency curve and boot-time budget notes 2026-07-11 16:46:50 +02:00
Julien Calixte
8dc6ee362f feat(firmware): wire SD persistence + git publish into the editor
Land the v0.1 editor integration: the git_sync module (libgit2 on the SD
/sd/repo, dedicated 96KB git thread, lazy Wi-Fi, :sync push with
synced/up-to-date/failed snackbars), the boot splash (Spike 9) plus its bin
and justfile recipes, and a power-on→cursor boot-timing log. Also re-syncs
the roadmap/spikes/v0.1-product status and adds the SD hardware reference
photo.
2026-07-11 15:30:43 +02:00
Julien Calixte
98a9d1dffe docs: flag that v0.1 keeps wifi up, link git_sync.rs
Ground the off-between-syncs assumption in the code: the shipped firmware
runs the stay-associated strategy the section argues against. Link
run_git_service so the claim is verifiable and mark teardown as v0.8 work.
2026-07-11 15:25:33 +02:00
Julien Calixte
2673a3377a docs: note wifi is off (not modem-sleep) between syncs
Make explicit that the per-sync burst assumes a full radio de-init between
pushes, and that staying associated to skip handshakes loses on energy until
~150 syncs/hr — a regime a writing appliance never reaches.
2026-07-11 15:19:18 +02:00
Julien Calixte
f4af38d8ef docs: add .typoena.toml config and auto-sync energy tradeoff
Record the git-tracked .typoena.toml preferences file (save_on_idle,
auto_sync) and the palette `>` command mode that edits it in the v0.5
roadmap. Add a tradeoff-curves note deriving Wi-Fi sync energy as a 1/T
curve, which sets auto_sync's default to 10m (opportunistic, min-clamped)
rather than a 5m wall-clock timer.
2026-07-11 14:38:07 +02:00
Julien Calixte
14967a06c6 docs: retire resolved SD risk, re-sync v0.1 status
Spike 3 (SD) is resolved (genuine 32 GB card mounts, verified on its own
SPI3 host per ADR-012) and the mount/save path is now wired into main.rs.

- README: move the SD/CMD59 open question to the retired-risks line; drop
  the stale "blocked on SD (waiting on a compatible card)" from the status
  blurb. Remaining v0.1 gate is the boot splash + wiring git publish.
- roadmap: flip the boot-load and save-to-SD v0.1 items to done, re-sync
  the status blurb and macroplan note, re-point the config-at-boot TODO
  from the (landed) SD wiring to the git-publish wiring.
2026-07-11 14:14:08 +02:00
Julien Calixte
18ed6aa599 docs(roadmap): record the panel snackbar and fix panel status
The side-panel split (writing column + panel) is already built in the
editor crate; correct the stale "not built yet" note and add the
snackbar under v0.1.
2026-07-11 14:01:02 +02:00
Julien Calixte
81d5f818cc docs(persistence): note boot-load and :w/:sync save are wired 2026-07-11 12:17:58 +02:00
Julien Calixte
7a1f25f5d1 docs(persistence): document module and refine FAT recovery to two cases
Record that persistence is now implemented and hardware-verified, and correct
the crash-recovery rule everywhere it appeared as "just promote the tmp": a
crash during the tmp write leaves a partial tmp, so recovery keeps the
committed target when both files are present and only promotes the tmp when
the target was already unlinked. Also fix the stale README heading that still
said the SD was on shared SPI2.
2026-07-11 12:02:30 +02:00