feat(slugs): Implement timestamp-based slugs per ADR-062

Replaces content-based slug generation with timestamp format YYYYMMDDHHMMSS.
Simplifies slug generation and improves privacy by not exposing note content in URLs.

Changes:
- Add generate_timestamp_slug() to slug_utils.py
- Update notes.py to use timestamp slugs for default generation
- Sequential collision suffix (-1, -2) instead of random
- Custom slugs via mp-slug continue to work unchanged
- 892 tests passing (+18 new timestamp slug tests)

Per ADR-062 and v1.5.0 Phase 1 specification.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-12-17 09:49:30 -07:00
parent 92e7bdd342
commit 3f1f82a749
6 changed files with 580 additions and 20 deletions

View File

@@ -226,15 +226,9 @@ def create_note(
if not success:
raise InvalidNoteDataError("slug", custom_slug, error)
else:
# Generate base slug from content
base_slug = generate_slug(content, created_at)
# Make unique if collision
slug = make_slug_unique(base_slug, existing_slugs)
# Validate final slug (defensive check)
if not validate_slug(slug):
raise InvalidNoteDataError("slug", slug, f"Generated slug is invalid: {slug}")
# Generate timestamp-based slug (ADR-062)
from starpunk.slug_utils import generate_timestamp_slug
slug = generate_timestamp_slug(created_at, existing_slugs)
# 4. GENERATE FILE PATH
note_path = generate_note_path(slug, created_at, data_dir)