Files
Sylpheed/tools/re-capture/doc_link_check.py
Sylpheed RE agent 6c8ee2ee6a docs: the UI decode's own evidence images were unreachable -- 11 links repaired
The brief's rule is to commit reference data beside the finding so the
port can be built without a disc. Nothing had ever checked that the docs'
cited artifacts actually exist. doc_link_check.py walks every markdown
file under docs/, resolves each relative link, and reports targets that
are missing -- and separately targets that resolve to a ZERO-BYTE file,
which looks fine in any listing.

  links resolving   1038 -> 1049
  missing targets     16 -> 5
  empty targets        0 -> 0

+11 resolving and -11 missing against 11 edits: the counts pair, which is
the confirmation the pass did what it claimed and touched nothing else.

Two of the sixteen were the evidence for the UI layout decode itself.
structures/ui-rat-layout.md is what the port is built on, and its two
figures -- backing "the tutorial PAUSE menu rebuilds pixel-accurately
from its sprites" and "the same method reproduces the main menu" -- were
written as captures/ui-layout/... from a file in structures/, one
directory too shallow. The headline evidence for the decode could not be
opened from its own document.

Eleven links had the wrong relative depth with the target present. Each
was rewritten only where exactly one candidate path resolved, so nothing
was guessed; the first pass left three alone because equivalent spellings
(captures/../captures/x) failed to collapse, and a second pass normalised
them.

Five remain genuinely absent and are left rather than invented: two point
at MEMORY.md outside the repo, one at a header in the separate
xenia-canary-native tree, and two name documents that were never written
(weapon-datasheet-runtime.md, canary-build-verified-env-confound.md).
None is port-relevant. A missing document is a different problem from a
bad path and is not something a link fix should paper over.
2026-08-29 02:34:16 +00:00

53 lines
1.8 KiB
Python
Executable File

#!/usr/bin/env python3
"""Do the files the docs cite actually exist in the repo?
An answer whose evidence is not committed cannot be used by anyone without a
disc and an emulator, which is the whole point of the reference data. This walks
every markdown file under docs/ and resolves each relative link, reporting the
ones that point at nothing.
Skips external links (http, mailto) and pure anchors. Reports missing targets
and, separately, committed-but-EMPTY files, which are the sneakier failure --
a link that resolves to a zero-byte file looks fine in every listing.
doc_link_check.py [docs-root]
"""
import os, re, sys
ROOT = sys.argv[1] if len(sys.argv) > 1 else "docs"
LINK = re.compile(r"\[[^\]]*\]\(([^)\s]+)\)")
missing, empty, ok = [], [], 0
for dirpath, _dirs, files in os.walk(ROOT):
for f in files:
if not f.endswith(".md"):
continue
src = os.path.join(dirpath, f)
try:
body = open(src, encoding="utf-8").read()
except Exception:
continue
for target in LINK.findall(body):
if target.startswith(("http://", "https://", "mailto:", "#")):
continue
path = os.path.normpath(os.path.join(dirpath, target.split("#")[0]))
if not path:
continue
if not os.path.exists(path):
missing.append((src, target))
elif os.path.isfile(path) and os.path.getsize(path) == 0:
empty.append((src, target))
else:
ok += 1
print(f"{ok} link(s) resolve")
if missing:
print(f"\n{len(missing)} MISSING target(s):")
for s, t in sorted(missing):
print(f" {s} -> {t}")
if empty:
print(f"\n{len(empty)} link(s) resolve to an EMPTY file:")
for s, t in sorted(empty):
print(f" {s} -> {t}")
sys.exit(1 if (missing or empty) else 0)