You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
⚠️ Definition of Done: this issue must be completed in full, in a single PR. Do not split this
work across multiple PRs, and do not defer any Deliverable below to a follow-up issue. A PR that
satisfies only some of the Deliverables, stubs a required test, or leaves a checkbox
partially-done does NOT resolve this issue and will be closed.
Context
renameRepositoryIdentity (src/db/repo-identity-rename.ts:77) moves a repo's rows forward when GitHub
renames it, because this schema keys almost everything off the full_name string. Its header says: "New
tables extend this function directly, following the same shape." It has a deliberate, documented
"Deliberately OUT OF SCOPE" block at lines 578-604 naming the rebuildable caches, review_targets and repo_chunks.
Four tables with a structural repo-identity column are in neither list:
The immutable first-claim ledger behind duplicate-cluster winner election.
bounty_lifecycle_events (schema.ts:1169)
repo_full_name
Its parent bountiesis renamed (line 36 of the import list).
webhook_events (schema.ts:965)
repository_full_name
Its ORB sibling orb_webhook_events.repository_full_nameis renamed, at line 526, with an explicit comment.
score_previews (schema.ts:1045)
repo_full_name
A per-repo scoring snapshot; every sibling snapshot table (repo_snapshots, signal_snapshots, repo_github_totals_snapshots) is renamed.
linked_issue_claims is the sharpest: recordLinkedIssueClaims (src/db/repositories.ts:603) writes each (repo, PR, issue) row once, immutably, and getEarliestLinkedIssueClaim (:621) filters on repo_full_name. After a rename, every claim row orphans under the old name, so resolveScopedLinkedIssueClaimedAt (src/queue/duplicate-detection.ts:156) gets null for a contested issue
— which, by its own documented fail-closed contract, makes the election refuse to name any winner — until the
PR re-syncs and mints a new claim at today's clock. The original claim ordering the ledger exists to
preserve is destroyed and, because the row is immutable, can never be recovered. That is the precise
backdating/priority failure migrations/0191's own header says the table exists to prevent.
bounty_lifecycle_events and webhook_events are direct sibling asymmetries: the structurally identical table
next to each one is already handled.
This has now drifted three times — #8379 (7 Drizzle tables) and #8380 (7 raw-SQL tables) were both closed
fixes, and none of the four above was in either. The list is hand-maintained with no completeness check, which
is why.
Requirements
renameRepositoryIdentity renames the repo-identity column for linked_issue_claims, bounty_lifecycle_events, webhook_events and score_previews, each with its own explicit block and a
comment naming its key shape, matching the module's existing per-table convention.
linked_issue_claims has PK (repo_full_name, pull_number, issue_number), so a stray new-name row can
collide: delete the colliding new-name rows first and keep the pre-existing old-name rows, exactly as the
module already does for pullRequests/issues (lines 96-118) — history is never dropped in favor of the
new-name row.
bounty_lifecycle_events, webhook_events and score_previews have surrogate id/delivery_id primary
keys with no unique constraint on the repo column, so each is a plain `UPDATE … SET = new WHERE
= old` with no fold, matching the `orb_webhook_events` block at line 526.
A new exported RENAME_OUT_OF_SCOPE_TABLES: ReadonlySet<string> in src/db/repo-identity-rename.ts lists
every table deliberately excluded, seeded from the existing prose block at lines 578-604 (ai_review_cache, ai_slop_cache, linked_issue_satisfaction_cache, grounding_file_content_cache, impact_map_query_cache, review_targets, repo_chunks, upstream_source_snapshots). The prose block stays as the reasons.
A completeness drift guard: every Drizzle table in src/db/schema.ts declaring a column named repo_full_name or repository_full_name must either be referenced by repo-identity-rename.ts or appear
in RENAME_OUT_OF_SCOPE_TABLES; a table in RENAME_OUT_OF_SCOPE_TABLES that no longer exists in schema.ts or migrations/ is also a failure (no dead entries).
⚠️ Required pattern: mirror test/unit/retention.test.ts:713-747's describe("RETENTION_POLICY completeness (drift guard, #9472)") — the same three-assertion shape
(everything accounted for / nothing in both lists / no dead mappings), against RENAME_OUT_OF_SCOPE_TABLES instead of RETENTION_COMPOSITE_PK_TABLES, and using drizzle-orm's getTableColumns + getTableName over import * as schema the way scripts/check-schema-drift.ts:123-137
already does. What does NOT satisfy this issue: adding the four renames without the guard (the list has
already drifted three times); implementing the guard as a scripts/ CLI instead of a vitest test;
or replacing the module's explicit per-table blocks with a generic loop (the header at lines 21-24 states
that is deliberately not the shape).
Deliverables
renameRepositoryIdentity in src/db/repo-identity-rename.ts renames linked_issue_claims with the
collision fold, asserted by a test that seeds a colliding new-name row and proves the OLD-name row's claimed_at survives.
renameRepositoryIdentity renames bounty_lifecycle_events, webhook_events and score_previews, each
asserted by a test in test/unit/repo-identity-rename.test.ts that seeds rows under the old name and
asserts zero rows remain under it afterwards.
RENAME_OUT_OF_SCOPE_TABLES is exported from src/db/repo-identity-rename.ts and contains exactly the
eight tables named above.
A describe("renameRepositoryIdentity completeness (drift guard)") block in test/unit/repo-identity-rename.test.ts with three tests: every schema.ts table carrying repo_full_name/repository_full_name is covered or exempt; no table is both; no exempt table is dead.
npm run db:schema-drift:check still passes (no schema change is required by this issue).
All Deliverables above are required in a single PR. A PR that satisfies only some of them — for example adding
the four renames but omitting the drift guard in Deliverables 3-4 — does not resolve this issue.
Test Coverage Requirements
This repo enforces 99%+ Codecov patch coverage, branch-counted, on src/**, and src/db/repo-identity-rename.ts is inside coverage.include. The linked_issue_claims collision fold has two
branches (colliding rows present / absent) and both need a test. The Deliverable-1 test is the required named
regression test.
Expected Outcome
A GitHub repo rename preserves its immutable linked-issue claim ledger, its bounty lifecycle history, its
webhook dedup log and its score previews, instead of orphaning them under the old name; and a future schema.ts table with a repo-identity column cannot ship uncovered the way these four (and #8379's and #8380's fourteen before them) did.
Links & Resources
src/db/repo-identity-rename.ts (imports at 26-62; orb_webhook_events block at 524-528; out-of-scope prose at 578-604)
Context
renameRepositoryIdentity(src/db/repo-identity-rename.ts:77) moves a repo's rows forward when GitHubrenames it, because this schema keys almost everything off the
full_namestring. Its header says: "Newtables extend this function directly, following the same shape." It has a deliberate, documented
"Deliberately OUT OF SCOPE" block at lines 578-604 naming the rebuildable caches,
review_targetsandrepo_chunks.Four tables with a structural repo-identity column are in neither list:
linked_issue_claims(schema.ts:526,migrations/0191)repo_full_name(part of the PK)bounty_lifecycle_events(schema.ts:1169)repo_full_namebountiesis renamed (line 36 of the import list).webhook_events(schema.ts:965)repository_full_nameorb_webhook_events.repository_full_nameis renamed, at line 526, with an explicit comment.score_previews(schema.ts:1045)repo_full_namerepo_snapshots,signal_snapshots,repo_github_totals_snapshots) is renamed.linked_issue_claimsis the sharpest:recordLinkedIssueClaims(src/db/repositories.ts:603) writes each(repo, PR, issue)row once, immutably, andgetEarliestLinkedIssueClaim(:621) filters onrepo_full_name. After a rename, every claim row orphans under the old name, soresolveScopedLinkedIssueClaimedAt(src/queue/duplicate-detection.ts:156) getsnullfor a contested issue— which, by its own documented fail-closed contract, makes the election refuse to name any winner — until the
PR re-syncs and mints a new claim at today's clock. The original claim ordering the ledger exists to
preserve is destroyed and, because the row is immutable, can never be recovered. That is the precise
backdating/priority failure
migrations/0191's own header says the table exists to prevent.bounty_lifecycle_eventsandwebhook_eventsare direct sibling asymmetries: the structurally identical tablenext to each one is already handled.
This has now drifted three times — #8379 (7 Drizzle tables) and #8380 (7 raw-SQL tables) were both closed
fixes, and none of the four above was in either. The list is hand-maintained with no completeness check, which
is why.
Requirements
renameRepositoryIdentityrenames the repo-identity column forlinked_issue_claims,bounty_lifecycle_events,webhook_eventsandscore_previews, each with its own explicit block and acomment naming its key shape, matching the module's existing per-table convention.
linked_issue_claimshas PK(repo_full_name, pull_number, issue_number), so a stray new-name row cancollide: delete the colliding new-name rows first and keep the pre-existing old-name rows, exactly as the
module already does for
pullRequests/issues(lines 96-118) — history is never dropped in favor of thenew-name row.
bounty_lifecycle_events,webhook_eventsandscore_previewshave surrogateid/delivery_idprimarykeys with no unique constraint on the repo column, so each is a plain `UPDATE … SET = new WHERE = old` with no fold, matching the `orb_webhook_events` block at line 526.
RENAME_OUT_OF_SCOPE_TABLES: ReadonlySet<string>insrc/db/repo-identity-rename.tslistsevery table deliberately excluded, seeded from the existing prose block at lines 578-604 (
ai_review_cache,ai_slop_cache,linked_issue_satisfaction_cache,grounding_file_content_cache,impact_map_query_cache,review_targets,repo_chunks,upstream_source_snapshots). The prose block stays as the reasons.src/db/schema.tsdeclaring a column namedrepo_full_nameorrepository_full_namemust either be referenced byrepo-identity-rename.tsor appearin
RENAME_OUT_OF_SCOPE_TABLES; a table inRENAME_OUT_OF_SCOPE_TABLESthat no longer exists inschema.tsormigrations/is also a failure (no dead entries).Deliverables
renameRepositoryIdentityinsrc/db/repo-identity-rename.tsrenameslinked_issue_claimswith thecollision fold, asserted by a test that seeds a colliding new-name row and proves the OLD-name row's
claimed_atsurvives.renameRepositoryIdentityrenamesbounty_lifecycle_events,webhook_eventsandscore_previews, eachasserted by a test in
test/unit/repo-identity-rename.test.tsthat seeds rows under the old name andasserts zero rows remain under it afterwards.
RENAME_OUT_OF_SCOPE_TABLESis exported fromsrc/db/repo-identity-rename.tsand contains exactly theeight tables named above.
describe("renameRepositoryIdentity completeness (drift guard)")block intest/unit/repo-identity-rename.test.tswith three tests: everyschema.tstable carryingrepo_full_name/repository_full_nameis covered or exempt; no table is both; no exempt table is dead.npm run db:schema-drift:checkstill passes (no schema change is required by this issue).All Deliverables above are required in a single PR. A PR that satisfies only some of them — for example adding
the four renames but omitting the drift guard in Deliverables 3-4 — does not resolve this issue.
Test Coverage Requirements
This repo enforces 99%+ Codecov patch coverage, branch-counted, on
src/**, andsrc/db/repo-identity-rename.tsis insidecoverage.include. Thelinked_issue_claimscollision fold has twobranches (colliding rows present / absent) and both need a test. The Deliverable-1 test is the required named
regression test.
Expected Outcome
A GitHub repo rename preserves its immutable linked-issue claim ledger, its bounty lifecycle history, its
webhook dedup log and its score previews, instead of orphaning them under the old name; and a future
schema.tstable with a repo-identity column cannot ship uncovered the way these four (and #8379's and#8380's fourteen before them) did.
Links & Resources
src/db/repo-identity-rename.ts(imports at 26-62;orb_webhook_eventsblock at 524-528; out-of-scope prose at 578-604)src/db/schema.ts:526, 965, 1045, 1169src/db/repositories.ts:603-628,src/queue/duplicate-detection.ts:156-166migrations/0191_linked_issue_claims.sqltest/unit/retention.test.ts:713-747(the drift-guard precedent to mirror)