Skip to content

rivet next-id allocates from the local working tree only — hands out IDs already claimed by open PRs/branches (logical collision, distinct from #422) #479

@avrabe

Description

@avrabe

Friction (hit while dogfooding the hourly loop)

rivet next-id allocates the next ID by scanning only the current working tree, so in any multi-branch / parallel-PR workflow it silently hands out IDs that are already claimed by in-flight branches — producing two different artifacts with the same ID.

Reproduced just now (verified)

This loop has three open PRs that each added a requirement: #474 (REQ-201), #475 (REQ-202), #477 (REQ-203) — none merged yet, so none are on main. A fresh agent branching off main asks for the next ID:

$ git checkout main      # main's requirements.yaml ends at REQ-200
$ rivet next-id --type requirement
REQ-201                  # ← already live in open PR #474

So the agent files its REQ-201, and now two PRs define different REQ-201s. They don't even textually conflict if they land in different files — validate would later flag a duplicate ID, or worse, one silently shadows the other after a merge. I only avoided it this iteration by manually tracking that 201–203 were taken and jumping to REQ-204.

Why this is distinct from #422

#422 is about textual merge conflicts (same EOF lines in CHANGELOG.md / requirements.yaml). This is about ID allocation: next-id confidently returns a colliding ID with no warning, even when there would be no textual conflict (e.g. the two artifacts live in different files). Fixing #422 (per-artifact files, a merge driver) would not fix this — next-id would still hand out REQ-201 to a second branch.

Related: #447 (next-id must scan all files) fixed the intra-tree half; this is the cross-branch half.

Suggested fixes (pick per appetite)

  1. Warn loudly: rivet next-id and rivet add could check unmerged refs — e.g. git log --all -G'id: <PREFIX>-' or the IDs present on origin/* PR branches — and print note: REQ-201 is also claimed on branch fix/...; next free across all refs is REQ-205.
  2. --across-refs flag (opt-in, git-aware): compute the max ID across git for-each-ref blobs, not just the working tree.
  3. Reservation ledger: a tiny append-only .rivet/reserved-ids (or a rivet reserve REQ) that agents bump atomically; cheap and merge-friendly (append-only with union merge).
  4. Documentation stopgap: AGENTS.md could tell parallel agents to allocate disjoint ID ranges per worktree.

Option 1 (a warning) is the cheapest high-value step — it turns a silent collision into a visible one. Reported from the hourly dogfooding loop; verified against rivet next-id at 970cea1.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions