Skip to content

Resolve archived changes by their original slug - #143

Merged
androidand merged 1 commit into
mainfrom
fix-archived-slug-resolution
Aug 28, 2026
Merged

androidand merged 1 commit into
mainfrom
fix-archived-slug-resolution

Conversation

@androidand

Copy link
Copy Markdown
Owner

Summary

Fixes #128. openspec archive renames a change's folder with a date prefix (changes/archive/<YYYY-MM-DD>-<slug>); specsync assumed slug resolution against that folder was always an exact match. That broke four related things:

  • LoadChangeBySlug errored with "no change found" for any already-archived change.
  • Change.Slug silently became the date-prefixed folder name instead of staying stable across the active → archived transition.
  • resolveEntry (links.md slug resolution) had the identical exact-path bug.
  • Find/ResolveLiveRefs search for an issue by its marker keyed off Change.Slug, so the same drift broke live GitHub resolution on any checkout with no local ref cache — every fresh CI run. This is what silently emptied v0.13.0's changelog/release notes and caused sync.yml to create a duplicate issue ([duplicate of #139] Sync design.md into the issue body #141) for sync-design-notes (Sync design.md into the issue body #139) instead of finding its existing one.

Fix

  • LoadChange strips a leading date prefix from an archived change's Slug (Dir keeps the real, date-prefixed path).
  • LoadChangeBySlug and resolveEntry both fall back to a date-prefix-aware glob against changes/archive/* when the exact path doesn't exist, erroring on ambiguous matches rather than guessing.

Testing

  • 8 new tests: dated-archive-folder resolution, Slug stripping (with and without a date prefix), ambiguous-match error, not-found error, links.md resolution across an archive rename, and — the direct regression for the incident — Find/ResolveLiveRefs locating an archived change's issue by its pre-archive marker with no local ref cache.
  • Manual repro: archived a scratch change, confirmed specsync -change <slug> (same original slug) no longer errors.
  • go build, go vet, go test ./..., release-plan -fail-on-archive-candidates, changelog -fail-on-unlinked-commits, audit-tasks -fail-on-mismatch, and validate all pass locally.

🤖 Generated with Claude Code

openspec archive renames a change's folder with a date prefix
(changes/archive/<YYYY-MM-DD>-<slug>), but specsync assumed slug
resolution against that folder was always an exact match:

- LoadChangeBySlug's archived fallback checked only the exact
  changes/archive/<slug> path, so `specsync -change <slug>` errored
  with "no change found" for any already-archived change.
- LoadChange derived Change.Slug from the folder's literal basename,
  so an archived change's logical identity silently became its
  date-prefixed name instead of staying the slug it was created and
  worked under.
- resolveEntry (links.md slug resolution) had the identical exact-path
  bug, so a links.md entry naming a sibling change went silently
  unresolved the moment that sibling was archived.
- Because Find/ResolveLiveRefs search for an issue's identity marker
  keyed off Change.Slug, the same date-prefix drift broke live GitHub
  resolution on any checkout with no local ref cache — every fresh CI
  run. This is what silently emptied v0.13.0's changelog/release notes
  and caused sync.yml to create a duplicate issue (#141) for
  sync-design-notes (#139) instead of finding its existing one.

Fixes all four: LoadChange now strips a leading date prefix from an
archived change's Slug (Dir keeps the real path), and
LoadChangeBySlug/resolveEntry both fall back to a date-prefix-aware
glob when the exact archive path doesn't exist, erroring on ambiguous
matches instead of guessing.

Closes #128
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying specsync with  Cloudflare Pages  Cloudflare Pages

Latest commit: a84ff37
Status: ✅  Deploy successful!
Preview URL: https://f6503d4c.specsync.pages.dev
Branch Preview URL: https://fix-archived-slug-resolution.specsync.pages.dev

View logs

@androidand
androidand merged commit ce5bf72 into main Aug 28, 2026
2 checks passed
@androidand
androidand deleted the fix-archived-slug-resolution branch August 28, 2026 09:51
androidand added a commit that referenced this pull request Aug 28, 2026
…resolution

Left behind by a `git reset --hard origin/main` between archiving the
change locally and committing the archive move — it restored the
pre-archive folder (already merged via #143) alongside the new
archived copy, so both existed on main at once and doubled the
v0.13.1 changelog entry (same normalized slug, counted twice).

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Resolve archived changes by their original slug

1 participant