Commit 0662371
authored
docs: write down the rule that every gate here presupposes (#799)
## Description
Every gate in this repository runs on a diff that already exists. `make
gate`, the api-surface snapshot, PHPStan, the CHANGELOG check and the
ADR checkbox all need code before they can say anything. Measured: a
grep over all eight `AGENTS.md` files finds no specification obligation
— only false positives like "Specify PHP version" — and the documented
Development Workflow begins with "Branch off `main`", which is after the
design decisions have been taken. The repository has unusually strict
post-implementation control and no pre-implementation control at all.
That gap is the actual defect. This PR writes the missing rule down,
moves the one existing design obligation to where it belongs, and adds
the part of it that can be mechanically enforced.
### 1. The rule (`AGENTS.md`, Development Workflow step 1)
Write down what the change must do, what it explicitly does **not** do,
and which suite proves each requirement — before choosing where the code
goes. With a table naming the classes of change it applies to, so it
does not become "write a document for every typo":
| Change | Specify first |
|--------|---------------|
| Bugfix, dependency update, small internal refactor, documentation only
| no |
| New provider | usually |
| New feature, new public API contract, breaking or deprecating change,
security or credential topic, a change spanning several layers, large
compatibility rework | yes |
**The format is deliberately not prescribed.** Which document that is
remains open —
[#798](#798) trials one
answer — and this rule should not depend on settling it. If that trial
is dropped, the rule stands.
**And it says plainly that it is not machine-checked.** `ci:test:repo`
sees the working tree, not the pull request; the job that could see one
is `pr-quality`, which belongs to the shared `netresearch/.github`
workflow and is not this repository's to extend. A rule that implies a
gate it does not have is worse than one that admits it has none.
### 2. The ADR obligation moves before the implementation PR
It was a PR checkbox — "I have added an ADR … if this changes the public
surface" — evaluated against a diff that already existed. The decision
is what the implementation follows from, and `api-surface.txt` already
tells you when the surface is being touched, so there is nothing to wait
for. The PR template is updated to match, because a template
contradicting `AGENTS.md` is exactly the defect
[#797](#797) just fixed.
### 3. `AdrReferenceIntegrityTest` — the enforceable part
`AdrLifecycleTest` already binds the records to each other: status
words, the `:Amended:` / `:Superseded:` pairing, and that the index
resolves every record it names. All of that stays inside
`Documentation/Adr`. Nothing checked a reference from **outside** it —
which is where four dead pointers sat until
[#795](#795), one of them
published on the landing page as a security control's `evidence` URL,
where it rendered as a public 404.
The test asserts existence only. It deliberately does not judge whether
the record says what the citing sentence claims, because nothing
mechanical can: both references #795 fixed pointed at the *wrong
record*, not at a misspelling of the right one. It also does not address
[#793](#793) — a drifted
line number still points at a line that exists.
**Probed in both directions.** Green on the current tree. With the
pre-#795 `AGENTS.md` restored it fails, naming both dead references and
nothing else. Re-proved after the Rector refactor below, because the
earlier proof described code that no longer existed.
Two mistakes worth recording rather than quietly fixing. The first
version failed on its own docblock: it scans `.php` and I had spelled
the dead filenames out in full — the docblock now omits the extension
and says why, so nobody "completes" them. And `ci / Rector` was red on
the first push, because I carried over a conclusion from the sibling PR
where the file sat in `Build/Scripts`, which Rector does not analyse;
this one sits in `Tests/`, which `Build/rector/rector.php` lists
explicitly. `LocallyCalledStaticMethodToNonStaticRector` wanted both
private static helpers as instance methods, the second only after fixing
the first cascaded into it.
## Related Issue
None. Found while reviewing this repository's governance.
## Type of Change
- [x] Documentation update
## Checklist
- [x] My code follows the project's coding standards
- [x] I have run `make gate` — in full, and it passes: `cgl`, `phpstan`,
`unit`, `fuzzy`, `rector -n -p 8.2` and `functional -d sqlite`, plus the
CHANGELOG check. It needed a dependency resolution at 8.2 in this
worktree first: the `.Build` copied from `main` made the pinned Rector
run die in `platform_check.php` before Rector started, and made the full
unit suite fatal on `InMemoryVaultService` against a newer nr-vault than
CI installs. Both disappeared after `runTests.sh -s composerUpdate -p
8.2`, which confirms by resolution what I had first only inferred — the
fatal was the environment, not this branch.
- [x] I have added tests that prove my fix/feature works — the new test
is the deliverable; it was verified red against the defect it exists
for.
- [x] I have updated the documentation accordingly — `AGENTS.md` is the
documentation here.
- [ ] I have added a `CHANGELOG.md` entry — no user-facing change;
docs-only commits in this repo do not carry one.
- [ ] If this changes the public surface, the ADR landed before this PR
— no public surface change.
- [x] My changes generate no new warnings
_Assisted by claude-code:claude-opus-5 —
[Session](https://claude.ai/code/session_015QXXkquh2eQNBiTYA39Wss)_3 files changed
Lines changed: 171 additions & 8 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
24 | | - | |
| 24 | + | |
25 | 25 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
76 | 76 | | |
77 | 77 | | |
78 | 78 | | |
79 | | - | |
80 | | - | |
81 | | - | |
82 | | - | |
83 | | - | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
84 | 107 | | |
85 | 108 | | |
86 | 109 | | |
| |||
92 | 115 | | |
93 | 116 | | |
94 | 117 | | |
95 | | - | |
| 118 | + | |
96 | 119 | | |
97 | 120 | | |
98 | 121 | | |
| |||
170 | 193 | | |
171 | 194 | | |
172 | 195 | | |
173 | | - | |
| 196 | + | |
174 | 197 | | |
175 | 198 | | |
176 | 199 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
0 commit comments