# Extending beyond a file **What this answers:** how to change this repository's own machinery, rather than add another document to it: a new class of artifact, a reference family, the frontmatter or the metadata contract, the budget that governs the always-loaded file, a new gate and its CI wiring, and the procedure for demoting a claim when a measurement disagrees with it. **When to load this:** when the change you want is not covered by the extension points in [CONTRIBUTING.md](../CONTRIBUTING.md), or when it changes what a green build means. Everything here rests on one distinction. Part of this repository's contract is enforced by scripts at the root; the rest can only be judged by a reader. A change that moves a rule from the second half into the first is a real improvement, and a change that looks machine-checked but is not is how a guarantee rots. Where a class is maintained by a reader, this document says so. ## Ordinary, or a discussion first | Change | Status | Why | |---|---|---| | A reference, a script, a pitfall entry, a case precedent, a measurement record, a capability row | Ordinary. Follow `CONTRIBUTING.md` | Each has a registration point and a gate that notices if the registration is missing | | A new gate script, additive and read-only | Ordinary, if it cannot fail a change that used to pass | A gate that only adds a signal is cheap to review | | Wiring an existing gate into CI | Ordinary | The sequence is in `.github/workflows/ci.yml`, and a missing gate is a visible gap | | Recording a downgrade of a claim | Ordinary, and expected | The repository states that a measurement which disagrees re-opens the conclusion | | A reference family (a subdirectory with its own index) | Ordinary, with one condition stated below | Its files are not resolved by any gate, so its index is the only entry point that exists | | A whole new artifact class (a new tree, or a new format the tooling reads) | Discussion first | It changes what a reader must check by hand, and possibly what an installed skill ships | | Adding a key to the `metadata` frontmatter block | Ordinary | No gate resolves those paths, so nothing depends on the key existing | | Changing what an existing `metadata` key means, or the strength-label vocabulary | Discussion first | Every document in the corpus grades against that vocabulary | | Changing a budget threshold, or the method that measures it | Discussion first, with a measurement | A threshold moved without a measurement is a preference with a number on it | | Adding a new failure mode for contributors | Discussion first | A gate that blocks a reasonable change is bypassed, and then it protects nothing | ## What the tooling actually reads Five facts about the layout decide how a new artifact is discovered, and none of them is stated in the file you are adding. 1. `check_repo.py` discovers every `skills/*/SKILL.md` up to three levels deep, and a shallower `SKILL.md` shadows anything nested below it, which is the installer's own rule. Adding a second skill needs no change to the gates. 2. `check_repo.py` and `check_routing.py` look at `references/*.md` and `scripts/*.py|.js` **non-recursively**. A file in a subdirectory of either is invisible to the routing comparison. 3. `check_budget.py` counts the corpus recursively: `references/**/*.md`, plus every file under `scripts/`. The corpus note fires at 110 files or 26,000 lines, so a family is visible to the budget before it is visible to routing. 4. The path resolver patterns match `references/.md` and `scripts/.py` with no separator anywhere in the name, so a nested path such as `references/coverage/route-inventory.md` is not resolved by any gate. A dangling nested pointer fails nothing. 5. `check_commands.py` scans `README.md` and every `.md` under `skills/` and `docs/`, skipping directories named `fixtures`. A command in a nested file is still validated; a command in a file that no walker reaches is not. The consequence is the rule for everything below: a new class needs one file that an existing gate already walks, and that file must state honestly what is checked and what is not. ## Adding a whole new artifact class A class is a set of files with a shared shape that a reader is expected to keep consistent: the evidence companions, the coverage inventory and the case library are three examples of what is already here. 1. **Decide whether it ships.** Inside `skills/exe-reverse/` is shipped to anyone who installs the skill; the repository root is maintenance tooling. `README.md`'s structure block states the split, and a class that ships belongs in that block with an explicit `skills/exe-reverse/...` path, because the README's path check fails a bare relative path. 2. **Find out whether any gate walks it.** If one does, its completeness is machine-checked and the class can rely on that. If none does, the class's own index must say so in a sentence a reader can act on, because a machine-checked guarantee that does not exist is the failure this repository keeps recording. 3. **Give the class an index that is discovered.** The cheapest reliable form is a top-level `references/.md` that opens with the head shape (the title, a goal line, and `## When to load this`), registers itself in `routing.md`'s Reference index, and is named in `routing.md`'s Sub-indexes table as the class's index, which is how the coverage inventory and the case library are already registered. 4. **State the row contract in the index**, not in the individual files: what each entry must carry, which document holds the claim it supports, and which grade applies. 5. **Add the class's own test only if it has a mechanical part.** A class of prose files has nothing to test, and a test that asserts a file exists is not a guarantee about its content. Two things to avoid. A class whose only index is named inside another document's prose is not reachable, because nothing compares prose to a directory listing. And a class that duplicates a registration duty that routing already owns will drift from it. ## Adding a reference family A family is a directory of related files with an index, and it is worth the extra structure exactly when the files are read together and would be misleading in the flat library. 1. Create `skills/exe-reverse/references//` and write `README.md` as the index: what the family is for, when to load it, the register or table of its members, and the template a new member follows. Copy the shape of `references/precedents/README.md`, which is both an index and a template. 2. Register the family index in `routing.md`, in the Sub-indexes table, as `references//README.md`, saying what the file holds. 3. If the family needs a top-level touchpoint as well (a symptom, a route), add that row to `SKILL.md` and to the mirror in `routing.md` in the same pass; the routing gate compares those two tables row by row and fails when one side has a row the other lacks. 4. Add each member to the family's own register at the same time you add the file, never later. The register is the only reachability that exists for a nested file. 5. Say in the index that the members are not resolved by any gate, so a reviewer knows the index must be read against the directory. This is a one-sentence honesty cost that makes the gap visible instead of implied. Members of a family are still covered by the checks that scan every markdown file under `skills/`: a `python