Gap
specs/behaviors/slug-handles.md specifies that when a person/project/tag slug changes, the old slug 301-redirects to the new one for 90 days. The write path creates SlugHistory records correctly, but no route reads them to serve redirects — old slugs just 404.
Related
Builds on the documented gitsheets dataTree-staleness limitation from #47 (now closed; see specs/behaviors/storage.md → "Direct gitsheets reads after a transact"). The recommended fix path is to load slug-history into the typed in-memory Store (same pattern as people/projects), so post-write reads stay correct and queries are fast.
Scope
- Add
slugHistory: Map<entityType+oldSlug, newSlug> to InMemoryState
- Load at boot via
loadInMemoryState; mutate via StateApply.applySlugHistory on rename transacts
- Route handler at the relevant paths checks the in-memory map for unknown slugs; 301s when found, falls through to 404 when not
- 90-day TTL enforcement (per spec): drop entries where
createdAt < now - 90d at boot or via background sweeper
Out of scope
Gap
specs/behaviors/slug-handles.mdspecifies that when a person/project/tag slug changes, the old slug 301-redirects to the new one for 90 days. The write path creates SlugHistory records correctly, but no route reads them to serve redirects — old slugs just 404.Related
Builds on the documented gitsheets dataTree-staleness limitation from #47 (now closed; see
specs/behaviors/storage.md→ "Direct gitsheets reads after a transact"). The recommended fix path is to load slug-history into the typed in-memoryStore(same pattern aspeople/projects), so post-write reads stay correct and queries are fast.Scope
slugHistory: Map<entityType+oldSlug, newSlug>toInMemoryStateloadInMemoryState; mutate viaStateApply.applySlugHistoryon rename transactscreatedAt < now - 90dat boot or via background sweeperOut of scope