Flagging for a decision rather than proposing a fix, because the current behaviour may be intended.
// services/auth/github.go:306 and :311, services/auth/api_hooks.go:175 and :180
srv.db.Put(ctx, repo_key+"/project", []byte(projectID))
One key per repository holding a project id. The store is a CRDT with last-write-wins per key, so two nodes assigning the same repository to different projects concurrently will silently resolve to one, with no error to either caller.
Why this may be fine
Unlike a claim index, nothing is orphaned. A repository belongs to exactly one project, so this is a mutable single-valued field and "last write wins" is defensible update semantics — re-registering a repository to a new project is a legitimate operation that should overwrite.
Why it might not be
The write happens on a path a user triggers (repository registration, hooks), and there is no read-back or confirmation that the assignment that landed is the one the caller asked for. A user could register a repo, get a success response, and have it belong to a different project.
The question
Either:
- Accept it as intended overwrite semantics, and note it at the call site so the next reader doesn't have to re-derive that it's deliberate; or
- Return the effective assignment to the caller after the write, so a losing writer at least learns the outcome differs from what they asked for.
See AGENTS.md, "Designing around kvdb" — rule 1 covers contended keys, and this is the case the rule deliberately does not condemn, which is exactly why it's worth writing down which side of the line it sits on.
Flagging for a decision rather than proposing a fix, because the current behaviour may be intended.
One key per repository holding a project id. The store is a CRDT with last-write-wins per key, so two nodes assigning the same repository to different projects concurrently will silently resolve to one, with no error to either caller.
Why this may be fine
Unlike a claim index, nothing is orphaned. A repository belongs to exactly one project, so this is a mutable single-valued field and "last write wins" is defensible update semantics — re-registering a repository to a new project is a legitimate operation that should overwrite.
Why it might not be
The write happens on a path a user triggers (repository registration, hooks), and there is no read-back or confirmation that the assignment that landed is the one the caller asked for. A user could register a repo, get a success response, and have it belong to a different project.
The question
Either:
See
AGENTS.md, "Designing around kvdb" — rule 1 covers contended keys, and this is the case the rule deliberately does not condemn, which is exactly why it's worth writing down which side of the line it sits on.