writeonce/docs/00-link-audit.md
shoney.arickathil c0b0dbb846 docs: audit all markdown against the code, fix findings, flatten status folders
- README: shipped concurrency/HTTP/WebSockets sat in the roadmap as "not yet
  available"; "no package manager" contradicted [deps]; the deps example
  would not have compiled (the key IS the module name)
- runtime/README: leads with wovm, wo-rt.c demoted to a historical section;
  dropped 2 nonexistent recipes, crates/rt, @gc refcounting, 13 suites -> 18
- employee + log-watcher READMEs claimed "does not compile"; both are gates
- error catalog: +10 emitted codes incl WO-E250, the only diagnostic the
  shipped query surface raises; recorded why the sweep rotted
- language-surface: group-by parses, then the typechecker refuses it
- 00-code-review + 00-link-audit re-run; history kept, not rewritten
- 48 dead Rust-era exploration links de-linked rather than re-pointed (their
  prose names the retired plan by number); successor map -> discarded.md
- 08-project-structure: compiler/plan/ never existed; corpus has 9 dirs, 5 empty
- releasing.md: dropped a --draft step the workflow never had
- new docs/00-doc-audit.md: findings + disposition, incl one row where the
  audit was wrong and the doc it accused was right
- status folders removed: 34 stories flat, status only in frontmatter; 252
  links recomputed from resolved paths; board/board-views/structure retaught
- story 24 -> in-progress, since frontmatter is now the only truth
- new iteration 38: fs mutation verbs + net.connect, the two capability
  families no iteration owned
- new iteration 39: gofiber/fiber v3.5.0 parity study. The ledger called
  CSRF/sessions unblocked by iteration 34's HMAC, but the runtime has no
  source of randomness at all
- linkcheck skips .dev/.superpowers: 0 broken paths, 0 bad anchors

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-26 19:20:22 +02:00

7.9 KiB
Raw Blame History

Markdown link audit — re-run 2026-08-26

Scope: every repo-authored *.md. .git, target, dist, node_modules, _build and — since 2026-08-26 — .dev/ and .superpowers/ are excluded; see the note under the table. External URLs are not fetched (no network verification).

files relative links broken paths bad anchors
first scan (2026-08-20) 207 574 97 0
after section A fixes (2026-08-20) 206 569 88* 0
re-run 2026-08-26, before fixes 235 675 77 0
re-run 2026-08-26, after fixes 237 652 23 0
after scoping the gate to repo-authored docs 149 656 0 0

* The 2026-08-20 report's prose said 88 twice while its own sections B–F summed to 77. The 77 was right; the 88 was an arithmetic slip, corrected here.

The gate is now clean: 0 broken, 0 bad anchors.

The last 23 were all in .dev/ — vendored plugin-skill copies and cloned reference projects, neither of which this repo authors. scripts/linkcheck.py now skips .dev/ and .superpowers/ alongside .git/target/dist. That was forced by adding gofiber/fiber as a reference (2026-08-26): its own docs are Docusaurus pages whose links resolve at site-build time, not on disk, so the clone alone contributed 21 broken paths and 39 bad anchors. A gate that reports the same dozens of failures forever is a gate nobody reads. Everything the repo actually ships — docs/, compiler/, runtime/, database/, tests/, bench/, scripts/, the root README — is still scanned, and is clean.

Re-check with just linkcheck.

Tool: scripts/linkcheck.py — walks the tree, strips fenced/inline code, extracts inline links and reference definitions, resolves each relative target, and validates #fragment against GitHub-style heading slugs of the target file.


What the 2026-08-26 re-run changed

Sections B and C of the 2026-08-20 report left a decision open: the studies under docs/plan/exploration/ cite the old flat docs/plan/NN-*.md numbering and the docs/runtime/database/ tree, both removed with the Rust track on 2026-08-18, and no successor map existed. That decision is now made.

De-linked, not re-pointed. The link text in these studies names the retired plan by number — [plan 09a], [plan 11], [`12-engine-disk-cutover.md`] — so aiming those at a story would have made each sentence assert something false about a document that never said it. The targets were stripped and the text kept as plain code spans. The studies still read correctly as the dated records they are, and they no longer claim a file exists.

The successor map lives in plan/discarded.md — one row per retired path, naming what carries that work now (or stating plainly that nothing does, as with 12-engine-disk-cutover.md and 08-sendfile-static-assets.md). That table is what the 2026-08-20 report's "Still open" note asked for.

Files touched: assembly/{00-overview,02-writeonce-stance}.md, c-runtime/{00-plan,01-architecture,02-single-binary}.md, linux/{01-epoll,02-eventfd,03-timerfd,04-signalfd,05-inotify,06-sendfile,07-io_uring,08-mmap,11-memfd_create,12-pwrite-fsync}.md.

prototypes/wo-db/, docs/runtime/database/03-inmemory-engine.md and docs/plan/09-concurrency-scaleout.md all went when that README was restructured to lead with wovm and demote wo-rt.c to a clearly-marked historical section. It also carried two recipes that do not exist (just rt-c-demo, just rt-c-bench) — not a link problem, fixed in the same pass. See 00-doc-audit.md §A6.

3. Two breaks the 2026-08-20 report did not have — RESOLVED

Both were caused by story files moving between status folders after that report:

Source Was Now
docs/examples/employee-list/README.md:5,6 …/refine/20-cross-program-tables.md, …/refine/21-keypair-attach-auth.md …/hold/… (both stories moved to hold/ 2026-08-21)
docs/stories/…/hold/26-blue-green-deploy.md:9 00-story.md ../00-story.md (the sibling stopped being a sibling when 26 moved into hold/)

This is the recurring shape: a story folder move breaks every relative link in and to that file. Section A of the 2026-08-20 report was nine instances of it; these are two more. Worth a check in whatever moves a story.

4. Stale paths inside the report itself — RESOLVED

The 2026-08-20 repair table cited docs/00-status.md (now docs/stories/00-status.md) and refine/{08,11,19,20,21} (now under done/ and hold/). That table has been retired into the history section below rather than carried forward with paths that no longer resolve.

docs/00-principles.md:57,77,78,87 resolved before this re-run — including the examples/blog/README.md reference that section D called a never-created file. Section D's other entries stand.


Recorded so the knowledge is not lost, but no longer reported by just linkcheck. Not ours to fix, unchanged in character from the 2026-08-20 report's section F.

  • .dev/skills/ (15 links) — flattened copies of plugin skills. The originals ship as directories with sibling references/ files; flattening dropped them. context-mode.md:297-300, subagent-driven-development.md (5), writing-skills.md (3), requesting-code-review.md (2), test-driven-development.md:206. Leave as-is, or re-vendor the skills with their subdirectories.
  • .dev/reference/ (8 links) — README.md (7) points at the removed docs/plan/{linux,assembly}/ and 15-mcp-streamable-http.md, the absent exploration/colibri/, and prototypes/llama-moe-stream; rest/README.md:76 points at docs/examples/blog/, which never existed. .dev/ is gitignored (git ls-files .dev returns only .dev/README.md), so these are per-developer notes, not repo content.

History — the 2026-08-20 first pass

Kept for the record; every path below is as it was on that date.

A. Regressions from the in-flight renumber — FIXED 2026-08-20

Nine links broke because files moved in the working tree; each had a known successor. Sources: docs/00-status.md:167,187, docs/stories/language-runtime-database/00-story.md:60,69, the 25/26 story pair (which used ../00-story.md while 00-story.md was a sibling — the refine/-relative form pasted into files one level up), refine/08-shard-actor-runtime.md:98,100, and refine/20-cross-program-tables.md:143. Link labels were renumbered with their targets, since the old IDs contradicted the new paths: 9e→22 and 9f→23.

  1. Iteration 19 was double-booked — RESOLVED. refine/19-chat-websocket-workload.md and refine/24-chat-websocket-workload.md were the same document while 19-missing-scalar-types.md also claimed 19. 00-story.md's mapping line made 24 canonical, so the 19 copy was deleted after repointing refine/11-fibers.md:13 at 24.
  2. 08-shard-actor-runtime.md existed twice — RESOLVED. 58 lines at the stories root vs 110 in refine/. The refine/ copy superseded it outright (the root copy still required @gc, retired by 7b, and cited runtime/wo-rt.c, removed with the Rust runtime). Root copy deleted.
  3. Unresolved merge-conflict markers were committed into refine/20-cross-program-tables.md:139-145, from a rename-conflicted merge — which is what produced that file's broken 09d link. Resolved in favour of HEAD. grep confirmed no other conflict markers under docs/.
  4. A status disagreement, not a link problem: docs/00-status.md:171 showed iteration 8 as ⬜ while 00-story.md:68 recorded arc stages 1+2 as landed. Both now read landed.