Skip to content

351 of 389 @spec anchors dangle — opsx-archive moved the specs and left every annotation behind (the @spec counterpart of #301) #309

Description

@rubenvdlinde

Summary

351 of larpingapp's 389 @spec annotations point at a path that does not exist. They were left behind by opsx-archive: archiving moves openspec/changes/<c>/… to openspec/changes/archive/<c>/…, and nothing repoints the annotations that referenced the old location.

Nothing reports this. gate-16 counts the presence of a @spec tag, never whether it resolves — so larpingapp reports perfect spec coverage while ~90% of its tags are dangling.

This is the @spec counterpart of #301, which found the same thing for 20 @e2e tags.

Measured

Resolver over every tracked .php/.ts/.js/.vue, with a positive control built in (it refuses to report unless at least one anchor resolves):

RESOLVING anchors : {'spec': 38, 'e2e': 114}     <- positive control, the matcher works
DANGLING anchors  : 374                          ({'spec': 351, 'e2e': 23})

Top dangling targets:

count target
235 openspec/changes/retrofit-2026-05-24-annotate-larpingapp/tasks.md
25 openspec/changes/event-checkin-roster/specs/event-checkin-roster/spec.md
19 openspec/changes/skill-requirement-enforcement/specs/skill-requirement-enforcement/spec.md
17 openspec/changes/skill-tree-visualization/specs/skill-tree-visualization/spec.md
15 openspec/changes/retrofit-2026-05-25-larpingapp-frontend/tasks.md
12 openspec/changes/event-runsheet-export/specs/pdf-export/spec.md

Worst files: CharactersController.php 38, CharacterService.php 30, RegisterObjectFetcher.php 29, DeepLinkRegistrationListener.php 23, SettingsController.php 21.

Confirmation that archiving is the cause — for skill-requirement-enforcement:

openspec/changes/skill-requirement-enforcement/specs/…/spec.md          -> does NOT exist  (19 anchors point here)
openspec/changes/archive/skill-requirement-enforcement/specs/…/spec.md  -> exists
openspec/specs/skill-requirement-enforcement/spec.md                    -> exists  (the correct target)

There are 32 archived changes in this repo.

gate-16 measurement, for the record

Re-measured with an explicit base per ConductionNL/.github#361, on 526bbc5f (= origin/development = the headSha of full-scope run 31490125155):

HYDRA_GATE_BASE_REF # count=
origin/development 0
origin/beta 0
empty tree 4b825dc… (full tree) 0
--mode report (not diff-scoped) uncovered_count: 0

Proven alive with a committed planted true positive (IdListNormaliser::countProbeIds(), no @spec) → # count=1 at all three bases, naming the plant; reverted. So gate-16's PASS here is honest about tag presence — and that is a different claim from "traceability works".

Suggested resolution

Do not bulk-rewrite changes/changes/archive/. The project rule is that @spec targets the canonical openspec/specs/<capability>/spec.md, never a change directory — and the largest block (235) points at a tasks.md#task-N, which is the wrong kind of artifact regardless of the path.

  1. Repoint to the canonical openspec/specs/… spec, per file, verifying the target section actually describes what the annotated method does.
  2. The 235 retrofit-…/tasks.md#task-N anchors need a decision: they encode "this method was annotated during the retrofit", not a requirement, and arguably should be replaced by a real spec reference or dropped.
  3. Worth raising in ConductionNL/.github: opsx-archive should either repoint annotations or refuse to archive while annotations reference the change path. A git mv of a spec tree is a silent mass-dangling event and no gate in the suite reports it.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions