docs: merge duplicate networking namespace dirs; guard against recurrence

Documentation namespace cleanup (issue #38).

Audit outcome:

- `date` vs `datetime` are NOT duplicates — `Date` is calendar days since the
  epoch, `DateTime` is instants (seconds); distinct runtime namespaces. Kept
  both.
- `network` vs `networking` WAS a real duplicate. Every other stdlib area
  documents only its namespace (`World.*`, `Screen.*`, …), never the bare
  builtins it lowers to. Networking alone also documented the low-level
  `net_*`/builtin forms under `networking/`, duplicating the `Network.*`
  pages under `network/`. Removed `networking/`; `network/` (the `Network`
  namespace, which the compiler and LSP both expose) is canonical. Folded the
  `@Sync`/`@Owned` framing into `network/_section.md` so no context is lost.
- Dropped the `networking` key from docgen inventory.json.

Guard (AC3): `tools/docgen/check.py` now fails if any `ns:` is documented from
more than one directory, or if two sections share an id or (case-folded)
title — so a duplicate-namespace split cannot silently reappear.

`gen.py` + `check.py` pass (34 sections, 365 symbols).

Closes #38

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-08-30 16:46:21 +03:00
parent 1c9235a948
commit 3bab2d2d4c
13 changed files with 34 additions and 312 deletions

View file

@ -83,6 +83,38 @@ def main(site):
if len(ids) > 1:
problems.append("token %r (%s) documented on multiple pages: %s" % (tok, kind, ", ".join(sorted(ids))))
# 2c) one docs directory per namespace / section. Two dirs covering the same
# runtime namespace (e.g. a `network`/`networking` or `date`/`datetime`
# split) invite drift — a symbol documented in one and not the other — so
# fail if any `ns:` is declared from more than one directory, or if two
# sections share a section id or (case-folded) title.
ns2dirs, id2dirs, title2dirs = {}, {}, {}
for cat in sorted(os.listdir(LANG)):
cdir = os.path.join(LANG, cat)
if not os.path.isdir(cdir):
continue
sp = os.path.join(cdir, "_section.md")
if os.path.exists(sp):
smeta, _ = parse_front(sp)
id2dirs.setdefault(smeta.get("id", cat), set()).add(cat)
title2dirs.setdefault(smeta.get("title", "").strip().lower(), set()).add(cat)
for fn in os.listdir(cdir):
if not fn.endswith(".md") or fn == "_section.md":
continue
meta, _ = parse_front(os.path.join(cdir, fn))
ns = meta.get("ns", "")
if ns:
ns2dirs.setdefault(ns, set()).add(cat)
for ns, dirs in sorted(ns2dirs.items()):
if len(dirs) > 1:
problems.append("namespace %r documented from multiple dirs: %s" % (ns, ", ".join(sorted(dirs))))
for sid, dirs in sorted(id2dirs.items()):
if len(dirs) > 1:
problems.append("section id %r declared by multiple dirs: %s" % (sid, ", ".join(sorted(dirs))))
for title, dirs in sorted(title2dirs.items()):
if title and len(dirs) > 1:
problems.append("section title %r shared by multiple dirs: %s" % (title, ", ".join(sorted(dirs))))
# 3) thin (un-expanded) symbols — warn, not fail (lets infra land before prose)
if thin:
warnings.append("%d symbols still have only seed text: %s%s"

View file

@ -187,17 +187,6 @@
"network-is_owner",
"network-local_id"
],
"networking": [
"fn-net_send",
"fn-net_poll",
"fn-owner",
"fn-set_owner",
"fn-is_server",
"fn-is_owner",
"fn-local_id",
"fn-serialize",
"fn-apply"
],
"operators": [
"op-arith",
"op-compare",
@ -417,4 +406,4 @@
"crypto-hex",
"crypto-ct_equal"
]
}
}