Skip to content

Add atomic sequential ID reservation#214

Open
iamcxa wants to merge 1 commit into
spacedock-dev:mainfrom
iamcxa:spacedock-ensign/upstream-next-id-atomic-reservation
Open

Add atomic sequential ID reservation#214
iamcxa wants to merge 1 commit into
spacedock-dev:mainfrom
iamcxa:spacedock-ensign/upstream-next-id-atomic-reservation

Conversation

@iamcxa
Copy link
Copy Markdown
Contributor

@iamcxa iamcxa commented May 16, 2026

Problem

Sequential status --next-id is a read-only scan. In parallel sessions, two creators can receive the same next numeric ID, draft different entities, and only discover the collision after links, titles, and workflow state already depend on the duplicate.

Changes

  • Add status --reserve-id --slug <slug> for sequential workflows. It acquires a workflow-local lock, scans current active and archived entities, writes an inline status: reserved stub, commits that stub, and only then prints the reserved ID.
  • Add lifecycle commands for reserved stubs: --promote-id, --release-id, and --stale-reservations.
  • Preserve --next-id as a read-only compatibility path.
  • Update commission and first-officer guidance so normal sequential creation uses --reserve-id instead of delayed manual creation after --next-id.
  • Add status/content tests covering concurrent reservation, reservation visibility, release/promote/stale behavior, and back-compatible --next-id.

Verification

  • uv run pytest tests/test_status_script.py -k 'reserve_id_concurrent or reserve_id_writes_committed_stub or reserve_id_sees_existing_reserved_stub' -q
    • 3 passed, 187 deselected
  • uv run pytest tests/test_status_script.py -k 'reserve_id or release_reserved_id or promote_reserved_id or stale_reserved_id or archive or set' -q
    • 70 passed, 120 deselected
  • uv run pytest tests/test_status_script.py tests/test_agent_content.py -k 'next_id_read_only_compat or reserve_id_guidance or creation_uses_reserve_id or reserve_id_for_sequential_creation' -q
    • 2 passed, 239 deselected
  • unset CLAUDECODE && uv run pytest tests/test_status_script.py tests/test_status_validate.py tests/test_agent_content.py -q
    • 252 passed, 15 subtests passed
  • git diff --check upstream/main...HEAD
    • no output

make test is not available in this checkout: there is no test target.

Notes

This keeps reservations in the existing entity namespace rather than introducing a second reservation directory. The reserved stub is repo-visible immediately, so later scans skip the claimed ID.

Entity: #80 upstream atomic sequential ID reservation

@clkao
Copy link
Copy Markdown
Collaborator

clkao commented May 16, 2026

thanks! this is a real problem, but I think the approach in the PR is somewhat kludgy. we probably want to have atomic entity creation (eg create with STDIN as body) for assigning id.

@iamcxa
Copy link
Copy Markdown
Contributor Author

iamcxa commented May 19, 2026

I think your feedback points to a cleaner shape than the current reservation lifecycle.

Proposed pivot for this PR:

status --create --slug <slug> --body-file <path|->

Semantics:

  • read the entity body from file/stdin
  • validate frontmatter before allocating an id
  • acquire a workflow-local lock
  • scan active + archived entities
  • assign the workflow id
  • inject the id into frontmatter
  • atomically write the entity file
  • print the assigned id/path

Two design questions before I rewrite the PR:

  1. Should --create stop at atomic id assignment + file write, leaving git add/commit to the caller? My current read is yes: Spacedock owns the race-sensitive creation primitive, while callers keep commit policy/message/signing/hooks composition.
  2. Should I remove the reservation lifecycle entirely from this PR: --reserve-id, --promote-id, --release-id, and --stale-reservations? That would avoid shipping two overlapping creation models.

I would keep --next-id read-only/advisory for compatibility and document --create as the race-safe creation path.

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.

2 participants