# Handoff — one buffer for every lowering Branch `dev-loop`, worktree `agent-a9d4028fa5752ba39`, from `f772162`. `spike/x86/dump.sh` landed at `f772162` and prints four lowerings of one function side by side: the LLVM IR the frontend emits, what `llc` makes of it at `-O0` and at `-O2`, and what the hand-written x86 backend emits. Reading one against another is the only way to check a lowering by eye. A shell script that prints all four into a scrollback is not how anyone reads them, though: three of the four are noise on any given day, and the one that is not is the one you are elbow-deep in. So the same four go into an Emacs buffer with collapsible sections, and the buffer remembers which of them you had open. `M-x flan-lowering`, `C-c C-l` in `flan-mode`. ## The three decisions ### 1. It compiles the file; it does not ask the daemon `flan-disassemble` (`C-c C-a`) asks the running program what the body it is calling for a name actually came out as. This asks a different question — what does this source compile to, through four different lowerings — and the two cannot be merged, for a concrete reason rather than a stylistic one: **the daemon has the installed body's `.ll` and its `.so`, and neither `llc -O2` nor the hand-written backend has ever been run over it.** There is no answer in the daemon to give. `llc -O2` on the installed IR would be a fifth thing, built here and never run anywhere, and the backend's output for an installed body does not exist at all unless the daemon was started `--x86`. So the two commands sit beside each other and each says which question it answers. `flan-disassemble` keeps its header, whose `showing` line is the daemon's own account of how much its answer claims. This buffer's header says the opposite thing just as plainly: it names the file and the compiler flags, and says the listing is what the source on disk compiles to and not what the program is running. Both docstrings cross-reference the other. ### 2. `outline-minor-mode`, not `magit-section` and not overlays of my own Nothing under `emacs/` requires a package that is not in Emacs — the whole client is `subr-x`, `seq`, `pcase`, `cl-lib`, `xref`, `eldoc`, `comint`, `imenu` and its own files. Taking a dependency on Magit for a four-section buffer would be the first, and it would be for folding, which Emacs has had since before Magit existed. `outline-minor-mode` on GNU Emacs 30.2.50 is the whole of what was asked for: `outline-cycle` is `TAB` on a heading, `outline-hide-body` and `outline-show-all` collapse and expand everything, and `outline-next-visible-heading` / `outline-previous-visible-heading` are `n` and `p`. Hand-rolling it would be a hundred lines re-implementing that badly. Headings are found by `outline-search-function` keyed to a text property this file puts on the four heading lines, **not** by a regexp over the text. That is not fussiness: LLVM IR has `;` comments, assembler output has `#` and `;` comments and lines that start with `.`, and `objdump` prints `:` label lines. Any regexp loose enough to match four section headers matches inside three of the four bodies, and folding then fragments in the middle of a listing. ### 3. The open/closed state is a global alist keyed by section, and nothing else One `defvar`, four entries, alive for the Emacs session and no longer. Not persisted to disk: it is four booleans, a preference file for it would one day have to be migrated, and nobody has ever wanted yesterday's fold state back. Keyed to the **section**, not to the function. The workflow is "I am working on the backend today", which is a fact about the section and holds across every function the author looks at while he is doing it. Keyed to the function it would forget on every `M-x flan-lowering` of a different name, which is exactly the thing he asked not to happen. The alist is the single source of truth. A toggle mutates it and then applies it to the buffer; a refresh applies it to the newly drawn buffer. Visibility is never read back out — that would couple this to whether outline folds with overlays or with text properties, which is a thing that has changed between Emacs versions and is none of this file's business. ## Status - [x] Handoff stub, decisions fixed - [ ] `emacs/flan-lower.el` - [ ] Key in `flan-mode`, autoloads - [ ] Tests in `emacs/test-flan-dev.el` - [ ] `emacs/MANUAL.md` - [ ] `dune test`, `@page`, `@cells`