fix(phpcs): stop the SpecTagSniff instructing the pattern gate-46 rejects - #71
Conversation
…ects
Two tools in the same pipeline gave OPPOSITE instructions about where an
`@spec` tag should point, and following the one that runs FIRST manufactured
findings for the one that runs SECOND.
`SpecTagSniff` runs as a blocking `PHP Quality (phpcs)` job and told every
developer, in its file docblock and in its own warning text:
@SPEC openspec/changes/{change-name}/tasks.md#task-N
A change directory is temporary by definition — completing a change moves it
to `openspec/changes/archive/<date>-<name>/`, and renaming or dropping one
removes the target outright. Every tag written to that instruction dangles
from that moment on, and gate-46 (spec-anchor-existence) reports it. The
developer who wrote the tag had followed this sniff's own advice.
Measured on portaliq: 100 unresolved gate-46 targets, and 260 of its 385 live
tags pointing into a change directory. The sniff ships identically in 20
ConductionNL repos, so grinding the tags without fixing the sniff regenerates
them at the rate changes are archived.
This changes the docblock example and BOTH warning messages to the canonical
form gate-46 and the project rule agree on:
@SPEC openspec/specs/{capability}/spec.md#requirement-{slug}
The method-level message previously carried no guidance at all, so a developer
reading it had only the class message to copy from; it now names the same
canonical shape.
Behaviour is unchanged: severity stays WARNING (verified via phpcs — an
untagged class and public method still report 0 errors / 2 warnings, and a
tagged file still reports nothing), and an `openspec/changes/...` target is
still accepted, since this sniff only checks that a tag is PRESENT.
No `@spec` tags are repointed here — this repo's existing tags are untouched.
Refs ConductionNL/.github#228
Quality Report — ConductionNL/launchpad @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| composer | ✅ | ✅ 102/102 | |||
| npm | ✅ | ✅ 548/548 | |||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ✅ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-08-08 14:03 UTC
Download the full PDF report from the workflow artifacts.
|
Merging with This PR changes exactly one file — That file is not in any failing job's scope. This repo's The sniff still works. Verified by running real phpcs with the modified sniff: an untagged class and public method report 0 errors / 2 warnings (severity unchanged — still WARNING, not ERROR), and a file whose class and method both carry The failing checks are unrelated to this diff: Newman / Playwright / Merging to |
Two tools in the same pipeline gave OPPOSITE instructions about where an
@spectag should point, and following the one that runs FIRST manufacturedfindings for the one that runs SECOND.
SpecTagSniffruns as a blockingPHP Quality (phpcs)job and told everydeveloper, in its file docblock and in its own warning text:
A change directory is temporary by definition — completing a change moves it
to
openspec/changes/archive/<date>-<name>/, and renaming or dropping oneremoves the target outright. Every tag written to that instruction dangles
from that moment on, and gate-46 (spec-anchor-existence) reports it. The
developer who wrote the tag had followed this sniff's own advice.
Measured on portaliq: 100 unresolved gate-46 targets, and 260 of its 385 live
tags pointing into a change directory. The sniff ships identically in 20
ConductionNL repos, so grinding the tags without fixing the sniff regenerates
them at the rate changes are archived.
This changes the docblock example and BOTH warning messages to the canonical
form gate-46 and the project rule agree on:
The method-level message previously carried no guidance at all, so a developer
reading it had only the class message to copy from; it now names the same
canonical shape.
Behaviour is unchanged: severity stays WARNING (verified via phpcs — an
untagged class and public method still report 0 errors / 2 warnings, and a
tagged file still reports nothing), and an
openspec/changes/...target isstill accepted, since this sniff only checks that a tag is PRESENT.
No
@spectags are repointed here — this repo's existing tags are untouched.Refs ConductionNL/.github#228