From 00edd432da6d4aa7ba80fdc9d06b85b608112aef Mon Sep 17 00:00:00 2001 From: Axel Meyer Date: Tue, 16 Jun 2026 15:02:11 +0000 Subject: [PATCH] =?UTF-8?q?docs:=20CR-6=20=E2=80=94=20README=20auf=20Core-?= =?UTF-8?q?Tier-Template=20(Badges/Topology/API/References)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 (1M context) --- README.md | 161 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 159 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 378feb5..ddb64f8 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,162 @@ # lib-core.api-discovery -Pure-Lua-Library for surface-discovery (extract `M.*` from Lua source) and README-parsing (extract documented API from markdown). Sandbox-safe — no FS, no side-effects. Used by Sporel's `--lint` CLI mode. +Pure-Lua-Library für Surface-Discovery (extrahiert `M.*` aus Lua-Quelltext) +und README-Parsing (extrahiert die dokumentierte API aus Markdown). Außerdem +ein README-Struktur-Linter, der die API-Doc-Convention (ADR-0038) gegen die +MUST-Sections eines Tiers prüft. Sandbox-safe — kein FS-Zugriff, keine +Seiteneffekte. Verwendet vom Sporel-`--lint`-CLI-Modus. -Version: 0.1.0 +**Version:** 0.1.0 +**Lib-ID:** lib-core.api-discovery +**Requires:** (none) +**Tags:** api-discovery, lint, readme, surface, topology, tooling + +## Topology + + +```mermaid +graph LR + this["lib-core.api-discovery"] +``` + + +Reine Lua-Lib ohne Dependencies und ohne `engine.*`-Aufrufe — daher kein +`engine`-Knoten im Topology-Graphen (sandbox-safe per Design, damit der +Linter im `--lint`-CLI-Modus ohne Engine-Kontext laufen kann). + +## API + +### `api-discovery.parse_lua_surface(source_string)` + +**Syntax:** `parse_lua_surface(source_string: string) -> {public: string[], private: string[]}` + +**Example:** +```lua +local ad = require("lib-core.api-discovery") +local src = io.read_file("init.lua") +local s = ad.parse_lua_surface(src) +-- s.public == { "load", "create", ... } +-- s.private == { "_normalize", ... } +``` + +**Description:** Extrahiert die öffentliche und private Surface aus +Lua-Quelltext. Konvention: `M.` ist öffentlich, `M._` privat. +Erkennt beide Schreibweisen — explizite Zuweisung (`M.foo = function`) und +Syntax-Sugar (`function M.foo`). Lua-Zeilenkommentare (`--` bis Zeilenende) +werden vor dem Pattern-Matching entfernt, damit auskommentierte +Forward-Compat-Stubs (z. B. `DEPRECATED-MVP`-Platzhalter) keine +False-Positives erzeugen. Block-Kommentare (`--[[ ... ]]`) werden nicht +behandelt (in Sporel-Lib-Code nicht verwendet). Dedupliziert über alle +Namen. Liefert `{ public = [...], private = [...] }`. + +### `api-discovery.parse_readme_api(markdown_string)` + +**Syntax:** `parse_readme_api(markdown_string: string) -> {documented: string[]}` + +**Example:** +```lua +local r = ad.parse_readme_api(readme_text) +-- r.documented == { "bind", "unbind", ... } +``` + +**Description:** Extrahiert die dokumentierten Funktionsnamen aus dem +`## API`-Abschnitt eines READMEs. Sucht den Abschnitt zwischen `## API` und +der nächsten H2-Überschrift und parst die H3-Header darin. Konvention: ein +H3-Header öffnet mit einem Backtick, der Funktionsname folgt nach einem +optionalen Namespace-Punkt — sowohl die namespaced-Form `ns.func(...)` +(Capture `func`) als auch die namespace-lose Form `func(...)` werden +erkannt. Dedupliziert; Pattern 2 matcht +keine Namen, die Pattern 1 bereits erfasst hat. Fehlt der `## API`-Abschnitt, +ist `documented` leer. + +### `api-discovery.diff_surface(surface, readme)` + +**Syntax:** `diff_surface(surface: {public: string[]}, readme: {documented: string[]}) -> {missing_docs: string[], stale_docs: string[]}` + +**Example:** +```lua +local s = ad.parse_lua_surface(src) +local r = ad.parse_readme_api(readme_text) +local diff = ad.diff_surface(s, r) +-- diff.missing_docs == öffentliche Funktionen ohne README-Eintrag +-- diff.stale_docs == README-Einträge ohne öffentliche Funktion +``` + +**Description:** Vergleicht die Code-Surface (`surface.public`) gegen die +README-Dokumentation (`readme.documented`). `missing_docs` sind öffentliche +Funktionen ohne dokumentierten Eintrag; `stale_docs` sind dokumentierte +Einträge ohne korrespondierende öffentliche Funktion. Beide Listen sind +alphabetisch sortiert. + +### `api-discovery.grep_engine_calls(source_string)` + +**Syntax:** `grep_engine_calls(source_string: string) -> string[]` + +**Example:** +```lua +local calls = ad.grep_engine_calls(src) +-- calls == { "engine.render.draw_rect", "engine.window.size", ... } +``` + +**Description:** Extrahiert alle eindeutigen `engine..`-Aufrufe +aus Lua-Quelltext. Liefert ein dedupliziertes, alphabetisch sortiertes Array. +Wird von `generate_topology_block` genutzt, um zu entscheiden, ob ein +`engine.*`-Knoten in den Topology-Graphen aufgenommen wird. + +### `api-discovery.generate_topology_block(manifest, engine_calls)` + +**Syntax:** `generate_topology_block(manifest: {id: string, deps?: {id: string}[]}, engine_calls: string[]) -> string` + +**Example:** +```lua +local manifest = { id = "lib-core.maps", deps = {} } +local calls = ad.grep_engine_calls(src) +local mermaid = ad.generate_topology_block(manifest, calls) +-- mermaid == "graph LR\n this[\"lib-core.maps\"]\n engine[\"engine.*\"]\n this --> engine" +``` + +**Description:** Generiert den Mermaid-Topology-Block aus Manifest + +`engine_calls`. Der `this`-Knoten trägt die `manifest.id`. Für jede +Dependency in `manifest.deps` wird ein Knoten plus `this --> dep`-Kante +ausgegeben (die Dep-ID wird für den Mermaid-Variablennamen entschärft: `-` +und `.` → `_`). Enthält `engine_calls` mindestens einen Eintrag, kommt ein +`engine["engine.*"]`-Knoten mit `this --> engine`-Kante hinzu. Liefert den +reinen Mermaid-Quelltext ohne Marker — der Aufrufer wrappt ihn in die +`` / ``-Marker. + +### `api-discovery.validate_readme_structure(markdown_string, tier)` + +**Syntax:** `validate_readme_structure(markdown_string: string, tier: "core"|"engine"|"module"|"community") -> {missing_sections: string[], section_order_ok: boolean}` + +**Example:** +```lua +local res = ad.validate_readme_structure(readme_text, "core") +if #res.missing_sections > 0 or not res.section_order_ok then + -- README verletzt die API-Doc-Convention +end +``` + +**Description:** Prüft die README-Struktur gegen die MUST-Sections des +angegebenen Tiers. + +- **`core`** verlangt: `H1`, `Badges` (ein `**Lib-ID:** lib-…`-Block), + `Topology` (`## Topology`), `Topology-Block` (`