An index for docs/, and a .gitignore that explains itself

This commit is contained in:
Joseph Ferano 2026-09-14 07:16:46 +07:00
parent 9d5689ffa2
commit 0afa530295
3 changed files with 160 additions and 1 deletions

16
.gitignore vendored
View File

@ -50,7 +50,18 @@ old-ocaml/
/sand.html
/sand.js
/sand.wasm
# The agent harness: its settings, its transcripts and the worktrees it
# registers all live here, and none of them are this repository's business.
.claude/
# A stale unix socket left behind by `flan dev`. The daemon writes one beside
# the program it is serving and unlinks it on a clean exit; a killed daemon
# does not, and the leftover is a socket, not a file worth keeping.
.flan-dev.sock
# Hand-run scratch: a `probe` executable and the C it was compiled from, from
# poking at codegen by hand rather than through a test.
probe
probe.c
@ -68,5 +79,10 @@ test/web-files-out.txt
# Python bytecode from the tools directory
__pycache__/
*.pyc
# Two more hand-run leftovers: a shared object built beside a form experiment,
# and the history directory a spike driver writes when it is run from the
# source tree. Anchored where they appear, and nothing in the build makes
# either one.
/forms.so
_hist/

61
docs/README.md Normal file
View File

@ -0,0 +1,61 @@
# What is in here, and what is still true
These are the documents that are written once and read occasionally: the reasons behind the code, the
reports from finished investigations, and the record of individual work sessions. The documents that are
edited every day stay at the repository root, because source comments cite them by bare filename from
dozens of places and a path that moves is a path that rots. So `plan.org`, `NEXT.md`, `spec-memory.md`
and `spec-conditions.md` are one directory up, and everything here points back at them.
A note on how to read the citations below: a document in this directory that says `plan.org` means the
one at the repository root. Nothing in `docs/` is named for a file at the root, so there is no ambiguity,
and rewriting a hundred prose mentions into `../plan.org` would have cost more in readability than it
bought in precision.
## If you have thirty seconds
Read **`BUILT.md`**. It is by far the largest document here and it is the one that pays: it holds the
reason behind every part of the compiler that exists, from why nothing is ever `dlclose`d to why the
printer is a compile-time walk over a type rather than a runtime function. It is current, it is
maintained, and deleting it would mean deriving all of it again. If you want to know why a thing is the
shape it is, the answer is in here.
After that, **`../NEXT.md`** at the root for what is actually in flight, and **`REFERENCES.md`** here for
where the evidence comes from — the reference clones on this machine, what each one answers, and the
standing rule that a claim in these notes was read out of a clone rather than recalled.
## The current documents
| File | What it is |
|---|---|
| `BUILT.md` | Why the parts that exist are shaped the way they are. The longest and the most load-bearing document in the repository. **Current.** |
| `DISCUSS.md` | Open questions, raised and deliberately not answered. Nothing in it is a decision or a task; entries that have since been answered say so and point at where the answer landed. **Current**, though it is half archive by now. |
| `PORTING.md` | What the author's game, `siam-farmer`, needs from Flan that Flan does not have yet, measured against the code that exists rather than against a plan. It is the requirements document the language is actually steering by. **Current.** |
| `REFERENCES.md` | The reference clones under `~/Repositories`, what each one is consulted for, and the specific files and lines already cited from them. **Current.** |
## The reports
| File | What it is |
|---|---|
| `SPIKE-GENERICS.md` | Milestone 5's parametric polymorphism, run early and out of order as a spike. The spike succeeded and generics landed, so this is the report of finished work rather than a live plan — but its findings about where the cost falls are still the reason the implementation looks the way it does. **Historical, findings still stand.** |
| `overview.md` | The first brainstorm, from before the language had S-expressions. It says in its own first line that it is superseded and no longer accurate. Kept for history only; its table of what changed is the only part worth reading. **Superseded.** |
## `handoffs/`
One report per work session, each written by whoever held the branch at the time. They are the
operational record: what was attempted, what was measured, what was decided without being able to ask,
and what was left open for the next lane. They are all historical the moment they are written — a handoff
describes a session that has ended — but they are cited by name from source comments and from `NEXT.md`,
because the reasoning behind a guard or a calling convention is often only written down once and this is
where it was written.
Six of them are the hand-written x86-64 backend, read in the order the work happened:
`HANDOFF-x86-rt.md` set the remaining-items list that the four after it close, `HANDOFF-x86-redef.md`
built the redefinition emitter, `HANDOFF-x86-aggregates.md` took that across the struct boundary,
`HANDOFF-x86-guards.md` settled the two guards nothing reaches, `HANDOFF-x86-debug.md` added debug
information, and `HANDOFF-x86-cost.md` measured what the backend costs and set the survey running on its
own so a refusal cannot sit unnoticed again.
The other three sessions are unrelated to each other. `HANDOFF-arith.md` is why a divide by zero is a condition
rather than a `SIGFPE`. `HANDOFF-raylib-ports.md` is the running record of the last two raylib example
ports, whose lasting findings were folded into `PORTING.md`. `HANDOFF-devtest-noise.md` is the linker
error `dune test` used to print on every run. `HANDOFF-tidy.md` is this reorganisation.

View File

@ -22,4 +22,86 @@ newcomer at that. This is the plan and, below it, what actually happened.
## What happened
(filled in as the work lands)
**The moves.** Fifteen files, all with `git mv` so `git log --follow` still
reaches their history. Nothing else moved.
**The citations.** 238 of them across 52 files, rewritten by zone. The zones
matter and a repository-wide substitution would have corrupted two of them:
| Citing file lives in | `DISCUSS.md` and its siblings | `HANDOFF-*.md` |
|---|---|---|
| the root, `lib/`, `test/`, `emacs/`, `spike/`, `examples/`, `vendor/` | `docs/DISCUSS.md` | `docs/handoffs/HANDOFF-x.md` |
| `docs/` | unchanged — they are siblings | `handoffs/HANDOFF-x.md` |
| `docs/handoffs/` | `../DISCUSS.md` | unchanged — siblings again |
Most of the citations are prose inside a source comment rather than a link;
there is not a single markdown link among the fifteen moved documents. So the
rewrite is a rewrite of comments, and in `lib/x86.ml`, `lib/build.ml` and
`test/test_reload.ml` — which another lane is editing at the same time — every
touched line is a comment line.
**The verification.** Grep cannot tell you a rewrite is finished, because a grep
for `DISCUSS.md` matches `docs/DISCUSS.md` too. So the check resolves instead:
every path-shaped citation in the repository is looked up relative to the file
that wrote it and relative to the root, and anything that resolves to neither is
reported. 817 citations checked. The only failures are seven mentions of
`HANDOFF-f1.md`, `HANDOFF-f2.md` and `HANDOFF-f3.md` in `../../NEXT.md`, which were
already dangling before this work — the prose around each one says the file was
deleted — and one false positive where the pattern caught `"$root/NEXT.md"` out
of a shell variable.
### The judgement calls
**`MY-NOTES.org` and `conditions.org` stay at the root.** `MY-NOTES.org` is the
author's scratch — questions to himself about the standard library, in the
second person. `conditions.org` is a live cheatsheet, not a report, and it is
the entry point to `conditions-play.flan` beside it. Neither is a document that
belongs in a directory of finished reports, and personal files are best left
where their owner put them.
**`conditions-play.flan` stays at the root.** The brief said to move it to
`spike/` if nothing referenced it. Three things do: `conditions.org:5` tells the
reader to run it, `NEXT.md:1306` lists it as the program to poke conditions
with, and `.gitignore` has an anchored `/conditions-play` for the executable it
builds to. It is also not shaped like the rest of `spike/`, which is four
self-contained experiment directories with their own runners, not a home for a
loose `.flan` file. It is a demonstration that belongs next to the cheatsheet
that points at it.
**`.flan-dev.sock` is not in this worktree.** The stale one is in the author's
main checkout, which a worktree-isolated lane cannot reach. The ignore pattern
is added here so the next one never shows up in `git status`; the existing
socket is the author's to remove.
**`.gitignore`.** Five entries at the bottom of the file — `.claude/`, `probe`,
`probe.c`, `/forms.so`, `_hist/` — were uncommented stragglers in a file where
everything else explains itself. They are grouped and explained now, and
`.flan-dev.sock` is added. No pattern was removed or changed in meaning.
### Verification
- `dune build --root .` exits 0.
- `dune test --root . --force` reports 232 checks, 0 failures.
- `spike/x86/survey.sh`, run detached, reports 103 MATCH / 0 DIFFER / 0 REFUSED.
### The branch clutter — reported, not acted on
`git branch --list 'worktree-agent-*'` returns **113** branches. **111** are
fully merged into `dev-loop`. **89** of them have a worktree currently
registered under `.claude/worktrees/`, and deleting one of those would break the
harness. The two unmerged branches are the two lanes running right now.
That leaves **24** branches that are both merged and have no live worktree, and
those are the only ones safe to delete:
```sh
comm -23 \
<(git branch --merged dev-loop --format='%(refname:short)' --list 'worktree-agent-*' | sort) \
<(git worktree list --porcelain | sed -n 's|^branch refs/heads/||p' | sort) \
| xargs -r git branch -d
```
`git branch -d` rather than `-D` on purpose: it refuses anything that turns out
not to be merged after all. The 89 with live worktrees want
`git worktree prune` and a decision about the directories first, which is the
author's call and not a cleanup to run blind.