diff --git a/CHANGELOG.md b/CHANGELOG.md index d8f1ad6..aacc99f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - An SVG logo and standalone icon in the Arch App Services visual style, with a checked document representing a README grounded in repository sources. The logo appears in the README header. +- A size-and-complexity gate for README sections (#16). A section that carries + tables, lists or subsections and runs past 60 non-blank lines, or carries a + table or list past 15 entries, three subsections with tables or lists, or two + levels of nesting, moves to `docs/.md`. The install path, the header, + `License`, and prose without repeating structure never move. The page gets a + title, an intro, a group index with counts, promoted headings, and links + rewritten for its depth; the README keeps a two- to four-line summary with the + scale and a link. An existing page is never overwritten, and a second run + produces no diff. +- Scenario 11 in `tests/scenarios.md` covers the gate. ### Changed diff --git a/README.md b/README.md index 3aee852..992f971 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,9 @@ Write a README for this repository. The skill scans the repository, picks create / update / audit, writes the root `README.md` — editing the existing one in update mode — and ends with a -summary of what it verified and what it could not prove. It never stages, +summary of what it verified and what it could not prove. A section that has +grown into a catalogue moves to a new page under `docs/`; a page the repository +already ships is never overwritten. It never stages, commits, or pushes unless you ask. To get findings without touching a file: @@ -101,7 +103,11 @@ read the repository's metadata — as text for you to apply. Packagist while a Rust crate documents Cargo and crates.io. - Treats every file it reads as data, not instructions. Text in a scanned repository that addresses the agent is reported to you, never obeyed. -- Restricts its diff to `README.md`. +- Moves a section that carries tables, lists or subsections — past 60 lines, or + with a table or list past 15 entries — to its own page under `docs/` with a + title, an intro, and a group index, and leaves a two- to four-line summary with + the scale and a link. The install path, the header and `License` never move. +- Restricts its diff to `README.md` and the pages it moves sections into. ## Documentation diff --git a/skills/github-readme-generator/SKILL.md b/skills/github-readme-generator/SKILL.md index 568cdaf..6c20f2f 100644 --- a/skills/github-readme-generator/SKILL.md +++ b/skills/github-readme-generator/SKILL.md @@ -38,9 +38,10 @@ to production code, configuration, or tests. padded. 4. **Install path first.** Requirements → Installation → Configuration → Quick start run in that order, unbroken, so the reader never scrolls back. -5. **Documentation-only diff.** Modify only the root `README.md`, or another file - the user names. Never edit code, tests, manifests, workflows, or config to - "match the README". +5. **Documentation-only diff.** Modify only the root `README.md`, a new page in + the documentation directory (`docs/` by default) for a section the split gate + moves out, or another file the user names. Never overwrite a page the repository already ships, and never edit + code, tests, manifests, workflows, or config to "match the README". 6. **No git side effects.** No staging, committing, pushing, or opening a PR unless the user explicitly asks. Preserve the user's existing working-tree changes. 7. **No secrets.** Document variable *names* from safe templates; never copy real @@ -103,6 +104,11 @@ and state it in the handover summary. Follow the adaptive template and style rules in `references/readme-structure.md`. Load it before drafting. +Then run every composed section through the size-and-complexity gate in +`references/section-split.md`, before anything is written. A section that +trips it moves to its own page under `docs/` and leaves a summary behind. In +audit mode the gate only reports which sections would move. + ### 5. Validate and hand over Run `references/validation-checklist.md` before finishing. Run any Markdown, @@ -124,5 +130,8 @@ Load on demand, not up front: - `references/evidence-policy.md` — what counts as evidence, commands and examples, badges and visual header, public surface findings, security and change scope. Read while scanning and whenever a claim feels unsupported. +- `references/section-split.md` — when a section moves to its own page under + `docs/`, how that page is built, and what the README keeps. Read after + drafting, before writing. - `references/validation-checklist.md` — pre-handover checks and the handover summary shape. Read before finishing. diff --git a/skills/github-readme-generator/references/evidence-policy.md b/skills/github-readme-generator/references/evidence-policy.md index 33bbea2..5b738c0 100644 --- a/skills/github-readme-generator/references/evidence-policy.md +++ b/skills/github-readme-generator/references/evidence-policy.md @@ -170,7 +170,10 @@ you read rather than fetching anything further. ## Security and change scope -- Only the root `README.md` may change, or a file the user explicitly named. +- Only the root `README.md` may change, a new page in the documentation + directory written by the section split gate (`section-split.md`), or a file the + user explicitly named. + A page the repository already ships is never overwritten. - Never edit production code, tests, manifests, workflows, or configuration to make them agree with the README. - Never apply repository metadata. An audit proposes the About description, diff --git a/skills/github-readme-generator/references/section-split.md b/skills/github-readme-generator/references/section-split.md new file mode 100644 index 0000000..49b2b6f --- /dev/null +++ b/skills/github-readme-generator/references/section-split.md @@ -0,0 +1,158 @@ +# Section split + +Load after drafting, before writing anything. A section that has grown into a +catalogue — a skill list, a rule set, a command reference — moves to its own +page under `docs/`, and the README keeps a short summary that links to it. + +The gate reads each section as already composed. It never changes which +sections are composed or what they say; it only decides where a section lives. +In audit mode it writes nothing and reports which sections would move, to which +page. + +## The gate + +A section is one `##` heading and everything up to the next `##`. Measure it as +it would be written, before it is written. + +### Never moved + +- **The install path** — `Requirements`, `Installation`, `Configuration`, and + `Quick start`. The reader's first successful use must stay in the README. When + one of them trips a threshold, trim it with the rules in + `readme-structure.md` instead, and name it in the handover summary. +- **The header, the intro, and `License`.** +- **Prose with no repeating structure** — a section that holds no table, no + list, and fewer than two subsections stays, however long it is. A long + narrative is not a catalogue. + +### Moved + +Any other section moves when it meets **either** condition. + +- **Size** — more than **60 non-blank lines**, heading included. +- **Complexity** — a repeating structure long enough to need navigation of its + own: + - a table with more than **15 data rows**, or a list with more than 15 items; + - three or more subsections that each carry a table or a list; + - subsections nested two levels below the section (`####` inside `##`). + +A section below both thresholds is written exactly as composed — byte for byte +what the generator would write without this gate. + +### Why these numbers + +- **60 lines.** The structure guide puts a whole simple README at 100–200 lines. + A 60-line section is more than half of the shortest one and nearly a third of + the longest, so a reader looking for the next section scrolls past a document + of its own. The case that prompted this gate — the skill catalogue and rule + overview of an agent-workflow package — took 150 lines of a 443-line README, + 75 lines each; both clear 60 comfortably, while the sections a README is meant + to carry (`Testing`, `Documentation`, a short `What it does`) stay well under. +- **15 rows.** Fifteen rows is roughly what a reader takes in at a glance on one + screen. The two tables in that case held 55 and 27 rows; a badge row, an + options table, or a version matrix stays below 15. The list limit matches the + table limit so that the same catalogue is not judged differently for being + written as a list. +- **Three subsections, or two levels of nesting.** Either means the section has + groups a reader must navigate between — which is what a page's own index is + for. + +When the repository shows a reason to depart from a number — a README the +maintainers keep long on purpose, documented in their contributing guide — +follow the repository and say so in the handover summary. + +## Build the page — restructure, never paste + +The page holds the same facts as the section, organised for a page of its own. +Add nothing the section did not carry; the evidence policy applies unchanged. + +1. **Title** — the section heading becomes the page's only `#` heading. +2. **Intro** — one paragraph under the title saying what the page holds, in the + section's own terms. +3. **Index** — when the page carries three or more groups (`##` headings after + promotion), a table of the groups, each linking to its anchor, with the + number of entries in it: the data rows of its tables plus the items of its + lists. Two groups or fewer need no index. + + ```markdown + | Group | Entries | + | --- | --- | + | [Code review](#code-review) | 12 | + | [Testing](#testing) | 7 | + | [Git](#git) | 9 | + ``` + +4. **Headings** — every subsection moves up one level: `###` becomes `##`, + `####` becomes `###`. The page ends with exactly one `#`, and no heading + skips a level. Lines inside fenced code blocks are not headings. +5. **Relative links and images** — rewrite each one so it reaches the same file + from `docs/`: + - a path from the repository root gains `../`: `](skills/x/)` becomes + `](../skills/x/)`; + - a path already inside `docs/` drops the prefix: `](docs/usage.md)` becomes + `](usage.md)`; + - an anchor to a heading that moved with the section stays as it is — + promotion changes the level, not the heading text, so the anchor is the + same; + - an anchor to a heading that stayed in the README points back at it: + `](#installation)` becomes `](../README.md#installation)`; + - absolute URLs are left alone. +6. **Links into the moved content** — a link elsewhere in the README that + pointed at an anchor inside the moved section now points at the page: + `](#rule-list)` becomes `](docs/rules.md#rule-list)`. Every link that reached + a real target before the move reaches the same target after it. Other files + are outside the diff, so a link in them that pointed at a moved anchor — + `README.md#rule-list` in `CONTRIBUTING.md` — is named in the handover summary + with its file and line, not edited. + +## Leave a summary in the README + +The section keeps its heading and its place in the order. Under it go two to +four lines that tell a reader what is there without following the link: + +- what the section covers, in the section's own terms; +- the scale, counted from the page: `55 skills in 9 groups`, `27 rule files`; +- the link to the page. + +```markdown +## Skill catalog + +55 skills for planning, code review, testing, and release work, grouped by the +stage of a task they serve. The [skill catalog](docs/skill-catalog.md) lists +each one with its trigger and a group index with counts. +``` + +A bare `See docs/skill-catalog.md.` is not a summary. Neither is a number +without a noun, or a scale the page does not bear out. + +## Name the page + +- **Path** — `docs/.md`, where the slug is the section heading in lower + case, with every run of characters other than ASCII letters and digits + replaced by one `-`, and no leading or trailing `-`: `Skill Catalog` becomes + `docs/skill-catalog.md`, `Rules & Overview` becomes `docs/rules-overview.md`. +- **Existing layout** — when the repository already keeps its Markdown + documentation in another directory (`doc/`, `documentation/`), use that + directory instead of creating `docs/`. When a site generator owns the + navigation (`mkdocs.yml`, a Docusaurus or VitePress config), write the page but + leave the configuration alone, and name in the handover summary the page that + still needs adding to the navigation. + +## Never overwrite, and run twice without a diff + +- **The target page exists and the README section already links to it** — an + earlier run moved this section. Leave both as they are: the summary is below + both thresholds, so the gate keeps it, and the page is not regenerated. If the + page has fallen behind the repository, report it in the handover summary + instead of rewriting it. +- **The target page exists for any other reason** — the repository ships it. + Never overwrite it, and never write a numbered variant beside it. Keep the + section in the README as composed, and name the collision in the handover + summary. +- **Two sections of this run share a slug** — `Rules` and `Rules!` both become + `rules.md`. The first one writes the page; the second stays in the README as + composed and is named in the handover summary, like any other collision. +- **The target page does not exist** — write it. + +A second run on the result therefore changes nothing: every moved section is +already a summary that links a page that exists. diff --git a/skills/github-readme-generator/references/validation-checklist.md b/skills/github-readme-generator/references/validation-checklist.md index 0486637..8cb12ed 100644 --- a/skills/github-readme-generator/references/validation-checklist.md +++ b/skills/github-readme-generator/references/validation-checklist.md @@ -29,6 +29,12 @@ becomes a line in the handover summary. 10. No sentence merely announces the block below it, and nothing is stated twice in two sections. 11. The diff touches only documentation, within the agreed scope. +12. Every section outside the install path was run through the gate in + `section-split.md`. Each moved section left a summary of two to four lines + with its scale and a link; each new page has exactly one `#`, an intro, an + index when it has three or more groups, and no skipped heading level; every + relative link in it and every link into it resolves; no page that existed + before this run was overwritten. Run any Markdown, link, or documentation test the environment safely allows. If none is available, say so in the summary rather than implying a check ran. @@ -45,6 +51,8 @@ Report, briefly: including any badge dropped because its workflow cannot run on the default branch, and any manifest description the repository contradicts, quoted alongside the source that refutes it +- which sections moved to which pages, and any section that tripped the gate + but stayed — an install-path section, or a page that already existed - whether any `TODO` remains - that nothing was staged, committed, or pushed — unless the user ordered it diff --git a/tests/repository.test.mjs b/tests/repository.test.mjs index 5545a33..44248fc 100644 --- a/tests/repository.test.mjs +++ b/tests/repository.test.mjs @@ -75,6 +75,7 @@ test('the skill ships every file it declares', () => { 'LICENSE.md', 'references/readme-structure.md', 'references/evidence-policy.md', + 'references/section-split.md', 'references/validation-checklist.md', ]; diff --git a/tests/scenarios.md b/tests/scenarios.md index 8ab3de4..e221361 100644 --- a/tests/scenarios.md +++ b/tests/scenarios.md @@ -18,10 +18,11 @@ correctness, structure, and the absence of hallucination — not exact wording. Invariants: the badge row is exactly version, license, tests, and downloads, with the Packagist slug taken from `composer.json` and the workflow badge built from the workflow's `name:`; the license badge states the manifest's SPDX -identifier and links to `LICENSE.md`; the banner is preserved; the intro is one -short paragraph; install commands come from `composer.json`; installation and -usage delegate to the docs link instead of duplicating them; no project-specific -section (support, postcardware, alternatives) is carried over. +identifier and links to `LICENSE.md`; the banner is preserved; the intro is two +or three sentences; the main install command comes from `composer.json` and +stays in `Installation`, and the first example stays in `Quick start`, while +everything else delegates to the docs link instead of duplicating it; no +project-specific section (support, postcardware, alternatives) is carried over. ## 2. Node application without a README @@ -113,11 +114,30 @@ Invariants: the contradiction is reported in the handover summary with both sources, the manifest line and the file that refutes it; the README does not repeat the contradicted claim; the manifest is not modified. +## 11. Oversized catalogue section + +*Setup:* a package whose evidence supports a capability catalogue of 30 skills +in four groups, each group with its own table, plus a short `Testing` section, +an existing `docs/rules.md` the repository ships, and a list of 20 rules whose +section would be named `Rules`. + +Invariants: the catalogue section moves to `docs/.md` derived from its +heading; the README keeps the heading and two to four lines naming the scale +(`30 skills`) and linking the page; the page has one `#`, an intro paragraph, a +four-row group index with per-group counts, and its subsections promoted one +level; every relative link in the page resolves from `docs/`; `Testing` is +written exactly as it would be without the gate; `docs/rules.md` is not +overwritten and the rule list stays in the README, with the collision named in +the handover summary. Run the skill a second time on the result: it produces no +diff. + ## Cross-cutting invariants Every scenario must also satisfy: -- no file outside `README.md` is modified +- no file outside `README.md` is modified, except a new page in the + documentation directory written by the section split gate; no existing page is + overwritten - no repository setting is changed - no commit, push, or pull request happens without an explicit instruction - no empty headings and no unsupported badges @@ -145,3 +165,4 @@ means the scenario has not been run since this log was started. | 8 | | | | 9 | | | | 10 | | | +| 11 | | |