Files
StarPunk/docs/design/v1.5.0/2025-12-16-developer-questions.md
Phil Skentelbery 9dcc5c5710 docs: v1.5.0 planning - ADR-062, release plan, and design docs
- ADR-062: Timestamp-based slug format (supersedes ADR-007)
- Updated v1.5.0 RELEASE.md with 6-phase plan
- Updated BACKLOG.md with deferred N+1 query locations
- Developer questions and architect responses for Phase 1

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-16 19:38:01 -07:00

11 KiB

Developer Review Questions - v1.5.0 Release Plan

Date: 2025-12-16 Reviewer: StarPunk Developer Agent Documents Reviewed:

  • docs/decisions/ADR-062-timestamp-based-slug-format.md
  • docs/projectplan/v1.5.0/RELEASE.md
  • docs/projectplan/BACKLOG.md

Executive Summary

After thorough review of the v1.5.0 release plan and ADR-062, I have identified 8 questions that need clarification from the architect before implementation can begin. These questions fall into three categories:

  1. Slug implementation details (Questions 1-4)
  2. Test structure and expectations (Questions 5-6)
  3. Phase dependencies and ordering (Questions 7-8)

The majority of questions concern Phase 1 (Timestamp-Based Slugs), which has some ambiguities around collision handling and interaction with existing code paths.


Questions

Phase 1: Timestamp-Based Slugs

Q1: Collision handling function location and signature

Issue: ADR-062 specifies an ensure_unique_slug(base_slug: str) -> str function that checks slug_exists(base_slug), but the implementation location and database interaction pattern are unclear.

Current State:

  • starpunk/slug_utils.py has make_slug_unique_with_suffix(base_slug, existing_slugs: Set[str]) that takes a pre-fetched set
  • starpunk/utils.py has make_slug_unique(base_slug, existing_slugs: set[str]) with random suffix logic
  • starpunk/notes.py line 220 calls _get_existing_slugs(db) to fetch all slugs, then passes to uniqueness check

Questions:

  1. Should ensure_unique_slug() perform its own database queries (violates current pattern)?
  2. Or should it follow the existing pattern of accepting existing_slugs: Set[str] parameter?
  3. Should this function live in slug_utils.py or utils.py?
  4. The ADR shows slug_exists() as a separate function - should this be implemented, or is this pseudocode?

Implementation Impact: This affects the function signature and which module needs modification. The current codebase consistently passes pre-fetched slug sets to avoid N+1 queries.

Suggested Clarification: Confirm whether to:

  • Keep existing pattern: ensure_unique_slug(base_slug: str, existing_slugs: Set[str]) -> str
  • Or introduce database coupling: ensure_unique_slug(base_slug: str, db: Connection) -> str

Q2: Sequential suffix starting number

Issue: ADR-062 says "first collision: 20251216143052-1" but the examples table shows the second note as -1, implying the first note has no suffix.

Current State:

  • Existing make_slug_unique_with_suffix() starts at -2 for first collision (base slug is attempt #1)
  • This matches table in ADR-062 examples

Questions:

  1. Does "first collision" mean the first duplicate attempt (which should get -1)?
  2. Or does it mean the first note gets the base slug, and second note gets -1?

Example Scenario:

# Two notes created at exactly 2025-12-16 14:30:52
Note A created first: slug = ?
Note B created second: slug = ?

# Is it:
Option 1: A = 20251216143052, B = 20251216143052-1  (matches table)
Option 2: A = 20251216143052-1, B = 20251216143052-2  (matches "first collision" text)

Implementation Impact: Determines whether sequential suffix loop starts at 1 or 2.

Suggested Clarification: Confirm that first note gets base slug (no suffix), first collision gets -1.


Q3: Two generate_slug() functions with different signatures

Issue: The codebase has two generate_slug() functions:

Current State:

  • starpunk/utils.py line 173: generate_slug(content: str, created_at: Optional[datetime]) -> str
    • Content-based slug generation (extracts words)
    • Used by notes.py line 230
  • ADR-062 specifies: generate_slug(custom_slug: str = None, created_at: datetime = None) -> str
    • Timestamp-based, no content parameter

Questions:

  1. Should I replace the function in utils.py?
  2. Should I create a new function in slug_utils.py and leave utils.py as deprecated?
  3. Should both functions coexist with different names?
  4. The removal of the content parameter is a breaking change for notes.py - should notes.py be updated to not pass content at all?

Implementation Impact:

  • If replacing utils.py function: ~15 test files will need updates
  • If creating new function: need to update all callers to use new function
  • notes.py line 230 currently calls generate_slug(content, created_at) - this will break

Suggested Clarification: Specify exact function location and migration path for callers.


Q4: Reserved slug handling in timestamp context

Issue: ADR-062 doesn't address what happens if a timestamp-based slug conflicts with a reserved slug.

Current State:

  • Reserved slugs: ['api', 'admin', 'auth', 'feed', ...] (all alphabetic)
  • Timestamp format: 20251216143052 (all numeric)
  • These can never collide

Questions:

  1. Should reserved slug validation be removed from the default slug path since timestamps can't conflict?
  2. Should it remain for safety/future-proofing?
  3. Custom slugs still need reserved validation - should this logic split?

Implementation Impact: May simplify code by removing unnecessary validation from timestamp path.

Suggested Clarification: Confirm whether reserved slug check is still needed for default slugs.


Phase 0: Test Fixes

Q5: Test update strategy for slug format changes

Issue: Phase 1 will change default slug format from content-based to timestamp-based. Many tests currently assert content-based slugs.

Current State:

  • tests/test_utils.py has 20+ tests asserting content-based slug behavior (e.g., assert slug == "hello-world-this-is-my")
  • Phase 1 acceptance criteria: "Update expected slug formats in test assertions"

Questions:

  1. Should these tests be updated to assert timestamp format (e.g., assert slug.startswith("2025"))?
  2. Should the old content-based tests be preserved but marked as testing legacy behavior?
  3. Should tests be split: "default slug generation" vs "content-based slug generation" (if we keep the old function)?
  4. Do you want all slug assertions to use pattern matching (timestamp format) or fixed timestamps in tests?

Implementation Impact:

  • Affects ~30 test assertions in test_utils.py
  • Affects ~10 integration tests in test_notes.py, test_micropub.py
  • May require test helper functions for deterministic timestamps

Suggested Clarification: Provide guidance on test update strategy.


Q6: Phase 0 priority - are tests blocking?

Issue: Phase 0 is marked "Must complete first - unblocks all other phases" but the 19 failing tests appear unrelated to slug changes.

Current State:

  • Failing tests: Migration performance, feed streaming, content negotiation, search security
  • None directly related to slug generation
  • Phase 1 (slugs) could theoretically proceed with these tests failing

Questions:

  1. Is Phase 0 truly blocking for Phase 1, or can Phase 1 proceed if slug-related tests pass?
  2. Should Phase 0 be completed before ANY other phase, or just before phases that depend on those specific test areas?
  3. If I discover that fixing some Phase 0 tests requires changes that conflict with Phase 1 work, what's the priority?

Implementation Impact: Affects work sequencing and potential merge conflicts.

Suggested Clarification: Confirm hard dependency of Phase 0 on all other phases, or allow parallel work.


General Implementation Questions

Q7: Backwards compatibility for existing notes

Issue: ADR-062 states "Existing notes retain their slugs (no data migration)" but doesn't specify how the dual slug formats coexist.

Current State:

  • Database has notes with content-based slugs (e.g., my-first-post)
  • New notes will have timestamp slugs (e.g., 20251216143052)
  • Both slug formats will exist simultaneously

Questions:

  1. Do any code paths need to detect/handle the two formats differently?
  2. Should there be a helper function is_timestamp_slug(slug: str) -> bool for future use?
  3. Are there any edge cases where code assumes slug format (e.g., sorting, display, URLs)?
  4. Does feed generation or UI need updates to handle mixed slug formats?

Implementation Impact: May require audit of all slug usages to ensure format-agnostic handling.

Suggested Clarification: Confirm if any code needs to be format-aware, or if slug format is truly opaque.


Q8: Phase ordering rationale

Issue: Phases 2-4 are all marked "Phase 0 complete" as dependency, but no interdependencies are noted between them.

Current State:

  • Phase 2: Debug file management
  • Phase 3: N+1 query fix (feed generation)
  • Phase 4: Atomic variant generation
  • All independent of each other

Questions:

  1. Can Phases 2-4 be implemented in parallel after Phase 0?
  2. Is there a preferred order (2→3→4) for any reason?
  3. Should each phase be committed separately or can they be batched?

Implementation Impact: Affects work planning and commit structure.

Suggested Clarification: Confirm whether Phases 2-4 can be parallelized or should be sequential.


Additional Observations (Not Blocking)

These observations don't block implementation but may inform architectural decisions:

O1: Code duplication between utils.py and slug_utils.py

Observation: Reserved slugs are defined in both:

  • utils.py line 24: RESERVED_SLUGS = {"admin", "api", ...} (5 items)
  • slug_utils.py line 24: RESERVED_SLUGS = frozenset([...]) (12 items, more comprehensive)

Impact: Low - but may cause confusion. Consider consolidating in v1.5.1.


O2: Timestamp format consistency

Observation: ADR-062 uses YYYYMMDDHHMMSS (no separator) but existing fallback in utils.py line 220 uses YYYYMMDD-HHMMSS (with hyphen).

Questions:

  • Is the hyphen removal intentional (shorter, more compact)?
  • Current: 20241118-143045 (15 chars)
  • ADR-062: 20241118143045 (14 chars)

Impact: Minor - affects slug length by 1 character.


O3: Test coverage gap mentioned in Phase 5

Observation: Phase 5 mentions "MPO format handling (untested)" but this is already in BACKLOG as "High priority - Scheduled for v1.5.0".

Question: Is this intentionally listed in both BACKLOG and Phase 5, or is there duplication?

Impact: None - just a clarity question.


Summary

Implementation Readiness: 6/10

The release plan is well-structured with clear phases and acceptance criteria. However, Phase 1 (Timestamp-Based Slugs) has enough ambiguity in implementation details (Questions 1-4) that I cannot confidently proceed without architect clarification.

Recommended Next Steps:

  1. Architect addresses Questions 1-4 (Phase 1 blocking issues)
  2. Architect clarifies Questions 5-8 (helps inform implementation approach)
  3. Developer proceeds with Phase 0 (test fixes) while awaiting Q1-Q4 answers
  4. Developer implements Phases 1-4 after clarifications received

Estimated Time to Implementation-Ready: 1-2 hours for architect to address questions.


Approval

Once these questions are addressed, I am confident the implementation can proceed smoothly with the 18-29 hour estimate provided in the release plan.

Developer: StarPunk Developer Agent Status: Awaiting Architect Response Next Action: Architect to review and answer questions 1-8