From e919cb082be162983e7eafb46c79424c6a6086e0 Mon Sep 17 00:00:00 2001 From: Axel Meyer Date: Sun, 17 May 2026 01:29:01 +0200 Subject: [PATCH] feat(api-discovery): add tier=module for module-repo lints Modules differ from libs structurally: they have no consumable public API (their hooks like M.update are engine-contract, documented in the engine spec, not in the module). The README convention for modules replaces the ## API section with ## Controls + ## Demonstrates. This adds tier=module validation in validate_readme_structure with MUST-sections H1, Abstract via Module-ID badge, Topology + Topology- Block markers, Controls, Demonstrates, References. Order-check ensures Demonstrates precedes References (no API exists to check). Co-Authored-By: Claude Opus 4.7 (1M context) --- init.lua | 64 ++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 18 deletions(-) diff --git a/init.lua b/init.lua index 1070c7b..e4a1877 100644 --- a/init.lua +++ b/init.lua @@ -144,6 +144,10 @@ end -- Tier "core" enforces: H1, Abstract, Badges, Topology, Topology-Block, API, References. -- Tier "engine" enforces the same MUST-sections, but the Badges check accepts -- any bold key:value line (engine README has no Lib-ID; instead Version/License). +-- Tier "module" enforces: H1, Abstract via Module-ID badge, Topology + Topology-Block, +-- Controls, Demonstrates, References. Modules have no consumable public API +-- (engine-hooks are documented in the engine spec), so ## API is replaced by +-- ## Controls + ## Demonstrates. -- Tier "community" enforces nothing (returns empty result). -- Returns: { missing_sections = [...], section_order_ok = bool } function M.validate_readme_structure(markdown_string, tier) @@ -151,22 +155,38 @@ function M.validate_readme_structure(markdown_string, tier) return { missing_sections = {}, section_order_ok = true } end - -- Both "core" and "engine" tiers use the same MUST-sections list. - -- Difference is handled upstream (engine tier skips parse_lua_surface etc.). local missing = {} - local checks = { - { name = "H1", pattern = "^#%s+%S" }, - { name = "Badges", pattern = "\n%*%*Lib%-ID:%*%*%s*lib%-" }, - { name = "Topology", pattern = "\n##%s+Topology[%s\n]" }, - { name = "Topology-Block", pattern = "