feat(gate): buckets, traits, and the checks the brief calls load-bearing
Measured this build against a documentation brief for public repos. The five original checks covered roughly one of its ten sections, so this adds what a single repo can answer on its own. New: required README headings per class (Non-goals is the cheapest trust-builder there is), in-repo version consistency across manifest / badge / CHANGELOG / tag, badge honesty, boilerplate, licence-claim, and relative links. Findings now carry a BUCKET beside the level - broken / missing / weakening - and output is grouped by it, because that is the order the work gets done in. Traits are a second axis beside class: class is structural and readable off the catalog, a trait says what the code does. `security` attaches SECURITY.md and a Known limitations section. The two names carrying it are proposed, not measured - that list is the operator's. Solo-maintained settles a category: CONTRIBUTING, CODE_OF_CONDUCT and MAINTAINERS are required by no class. Consumer-facing documents are untouched by that; SECURITY.md exists for the stranger who finds a hole. Three bugs found by running against llm-security, not by reading: - ~30 link findings, all noise. Regexes inside code spans are `[...](...)` to a naive scanner. Strip code first. - `file:` and other schemes were treated as repo-relative paths. - Relative links were resolved against the repo root instead of the file they sit in, calling two files missing that sat next to the README linking them. Same fix applied to the boilerplate check: a document ABOUT placeholder detection was tripping the placeholder detector. Also removed this repo's own static tests badge. There is no CI - the forge has zero Actions runners registered - so it could never become real, and it is the exact anti-pattern the gate now flags. 67 tests. Against llm-security every remaining finding is real and matches the census's independent hand-measurement. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WYJ3FHLtVgzFXMZ6UF598h
This commit is contained in:
parent
9a72cefefa
commit
720850a9ad
7 changed files with 915 additions and 39 deletions
59
README.md
59
README.md
|
|
@ -13,9 +13,14 @@ checks that surface in one repository and reports what it finds.
|
|||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
**Status:** maintained, solo. The public API is the gate's finding codes and the
|
||||
register schema; both can still change before 1.0. There is no CI — the forge
|
||||
has no Actions runner — so the test claim is one you run yourself, in one
|
||||
command, from a clean clone: `npm test`. A badge asserting it would be a claim
|
||||
dressed as evidence.
|
||||
|
||||
## Install
|
||||
|
||||
Use the `https://` form. The forge UI's clone button hands out an `ssh://` URL,
|
||||
|
|
@ -48,19 +53,50 @@ Run it inside a repository:
|
|||
node scripts/repo-standard-check.mjs --dir "$PWD"
|
||||
```
|
||||
|
||||
It checks five things, and the repository's **class** decides what each one means:
|
||||
The repository's **class** decides what each check means:
|
||||
|
||||
| Check | What fails it |
|
||||
| --- | --- |
|
||||
| First screen | no H1 on line 1, or the line under it is not the published description. An H1 that merely differs from the repo name is a `WARN` — that is a naming choice, not a defect |
|
||||
| Install block | the form for this class is missing, incomplete, or shown over `ssh://` |
|
||||
| Required files | a file this class needs is absent |
|
||||
| References | an `open/<name>` in URL position resolves to nothing |
|
||||
| Required headings | `## Install`, `## Non-goals`, `## Changelog` — per class. Present at the wrong depth is its own finding |
|
||||
| Required files | a file this class (or trait) needs is absent |
|
||||
| Repo references | an `open/<name>` in URL position resolves to nothing |
|
||||
| Relative links | a link points at a file that is not tracked |
|
||||
| Licence claim | the README cites a licence the repo has no file for |
|
||||
| Badges | a static badge asserts a test, build or coverage run that nothing verifies |
|
||||
| Boilerplate | template text nobody filled in |
|
||||
| Version consistency | manifest, README badge, newest CHANGELOG entry and the git tag disagree |
|
||||
| Description | empty, or past the length bound |
|
||||
|
||||
Findings are `ERROR`, `WARN`, `SKIP` or `OK`; the process exits 1 on any
|
||||
`ERROR`. A `SKIP` means the check could not run — an unreachable forge, a repo
|
||||
that is not in the register. It is not a pass, and the output says which.
|
||||
Findings carry two independent things: a **level** (`ERROR`, `WARN`, `SKIP`,
|
||||
`OK`) and a **bucket**, which is what you actually triage on:
|
||||
|
||||
- **broken now** — a stranger is blocked or misled
|
||||
- **missing** — an expected artefact is absent
|
||||
- **weakening** — present and working, but it reads as amateur
|
||||
|
||||
The process exits 1 on any `ERROR`. A `SKIP` means the check could not run — an
|
||||
unreachable forge, an untagged repo, a link that leaves the repository. It is
|
||||
not a pass, and the output prints those separately under a heading that says so.
|
||||
|
||||
### Traits — a second axis
|
||||
|
||||
Class is structural. A **trait** is about what the code does, which no remote can
|
||||
tell you. `security` attaches the obligations a tool takes on by handling
|
||||
untrusted input: a `SECURITY.md` with a real disclosure channel, and a
|
||||
`## Known limitations` section. Traits live in the register and are the
|
||||
maintainer's judgement, not a reading.
|
||||
|
||||
### What is deliberately not required
|
||||
|
||||
`CONTRIBUTING.md`, `CODE_OF_CONDUCT.md` and `MAINTAINERS.md` are required by no
|
||||
class. This project is solo-maintained and says so publicly; contributor-facing
|
||||
documentation for something that accepts no contributors is theatre, and a code
|
||||
of conduct with an unattended placeholder address is worse than none — it is a
|
||||
visible unfinished template. Consumer-facing documents are untouched by that.
|
||||
Being solo is not a reason to skip a `SECURITY.md`; someone finding a hole still
|
||||
needs somewhere to send it.
|
||||
|
||||
### The class decides what is required
|
||||
|
||||
|
|
@ -112,9 +148,12 @@ without that, a raw scan turns three dead names into about twenty.
|
|||
npm test
|
||||
```
|
||||
|
||||
34 tests over the pure classifiers. The reference fixtures are the measured
|
||||
false positives that produced the three-outcome rule, each with its expected
|
||||
verdict.
|
||||
67 tests over the pure classifiers. The reference fixtures are measured false
|
||||
positives, each with its expected verdict — the six that produced the
|
||||
three-outcome reference rule, plus the noise sources found by running the gate
|
||||
against a real repository: regexes inside code spans that are markdown links to
|
||||
a naive scanner, `file:` URLs, and relative links resolved against the wrong
|
||||
directory.
|
||||
|
||||
## Changelog
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue