Skip to content

db: renameRepositoryIdentity omits four more repo-identity tables, and nothing guards the list #9650

Description

@JSONbored

⚠️ 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:

table column why it matters
linked_issue_claims (schema.ts:526, migrations/0191) repo_full_name (part of the PK) The immutable first-claim ledger behind duplicate-cluster winner election.
bounty_lifecycle_events (schema.ts:1169) repo_full_name Its parent bounties is renamed (line 36 of the import list).
webhook_events (schema.ts:965) repository_full_name Its ORB sibling orb_webhook_events.repository_full_name is 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    gittensor:bugGittensor-scored bug fix — scores a 0.05x multiplier.help wantedExtra attention is needed

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions