Skip to content

fix(github): extend repo-rename identity migration to analytics tables - #5953

Merged
JSONbored merged 1 commit into
mainfrom
fix/repo-rename-caches-analytics
Jul 15, 2026
Merged

fix(github): extend repo-rename identity migration to analytics tables#5953
JSONbored merged 1 commit into
mainfrom
fix/repo-rename-caches-analytics

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Summary

Follow-up to #5918 (repo-rename webhook handler) and #5950 (review/audit tables). Extends renameRepositoryIdentity to 14 more repo_full_name-keyed tables — the caches/analytics side of the data model.

What changed

  • burden_forecasts, repo_queue_trend_snapshots, repo_sync_state: repo_full_name itself IS the primary key (single row per repo) — same fold-then-rename shape as the anchor tables (repositories/repository_settings).
  • repo_sync_segments (unique on segment), contributor_repo_stats (unique on login), repo_labels (unique on name): each has an id that embeds the repo name and a unique index pairing repo_full_name with one other column — folds on that column.
  • collision_edges: id embeds the repo name but is built in packages/loopover-engine and passed through verbatim, with no unique index — folds on the id collision the rename would produce, same shape as pull_request_reviews from fix(github): extend repo-rename identity migration to review/audit tables #5950.
  • notification_deliveries, github_agent_command_answers, repo_snapshots, repo_github_totals_snapshots, github_rate_limit_observations, product_usage_events, signal_snapshots: id is always a random UUID with no unique constraint tied to repo_full_name (several are nullable) — plain renames. notification_deliveries.deeplink and github_agent_command_answers.response_url are also rewritten, matching the anchor tables' own html_url treatment (their own canonical GitHub link, not incidental content).

Deliberately out of scope

The request-scoped AI/LLM result caches (ai_review_cache, ai_slop_cache, linked_issue_satisfaction_cache, grounding_file_content_cache) and the RAG chunk cache (repo_chunks) are excluded. Every one of these is a rebuildable cache, not identity data: a miss after a rename just re-runs one LLM call or one re-index pass at the new name — graceful, self-healing, and cheap, unlike an orphaned PR/issue/audit row a maintainer would otherwise need a full GitHub API backfill to recover. repo_chunks additionally stores its cache key as a lowercased, truncated-to-64-chars hash, so a safe in-place string rename isn't even mechanically available without real risk of corrupting a truncated id. Documented inline in the code so the omission reads as a deliberate call, not an oversight.

Test plan

  • npm run typecheck — clean
  • npx vitest run test/unit/repo-identity-rename.test.ts — 54/54 passing (24 new: a rename test for all 14 tables, plus a collision-fold regression test for the 7 that have a real fold path)
  • npm run test:ci — full local gate, green
  • npm audit --audit-level=moderate — 0 vulnerabilities

Follow-up to #5918/#5950: extends renameRepositoryIdentity to 14 more
repo_full_name-keyed tables:

- burden_forecasts, repo_queue_trend_snapshots, repo_sync_state:
  repo_full_name itself IS the primary key (single row per repo) --
  same fold-then-rename shape as the anchor tables.
- repo_sync_segments (unique on segment), contributor_repo_stats
  (unique on login), repo_labels (unique on name): each has an id that
  embeds the repo name and a unique index pairing repo_full_name with
  one other column -- folds on that column.
- collision_edges: id embeds the repo name but is built in
  packages/loopover-engine and passed through verbatim, with no unique
  index -- folds on the id collision the rename would produce, same
  shape as pull_request_reviews.
- notification_deliveries, github_agent_command_answers,
  repo_snapshots, repo_github_totals_snapshots,
  github_rate_limit_observations, product_usage_events,
  signal_snapshots: id is always a random UUID with no unique
  constraint tied to repo_full_name (several nullable) -- plain
  renames. notification_deliveries.deeplink and
  github_agent_command_answers.response_url are also rewritten, same
  as the anchor tables' own html_url treatment (their own canonical
  GitHub link, not incidental content).

Deliberately excludes the request-scoped AI/LLM result caches
(ai_review_cache, ai_slop_cache, linked_issue_satisfaction_cache,
grounding_file_content_cache) and the RAG chunk cache (repo_chunks) --
every one is a rebuildable cache, not identity data: a miss after a
rename just re-runs one LLM call or one re-index pass at the new name,
which is graceful and self-healing, unlike an orphaned PR/issue/audit
row a maintainer would otherwise need a GitHub API backfill to
recover. Documented inline so the omission reads as deliberate, not
forgotten.

24 new tests: a rename test for all 14 tables, plus a collision-fold
regression test for the 7 that have a real fold path (three
PK-is-repo_full_name tables, three single-column-unique-index tables,
and the id-collision fold for collision_edges).
@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@JSONbored JSONbored self-assigned this Jul 15, 2026
@JSONbored
JSONbored merged commit 0c82e76 into main Jul 15, 2026
15 checks passed
@JSONbored
JSONbored deleted the fix/repo-rename-caches-analytics branch July 15, 2026 00:22
@loopover-orb loopover-orb Bot added the gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. label Jul 15, 2026
JSONbored added a commit that referenced this pull request Jul 15, 2026
Follow-up to #5918/#5950/#5953: extends renameRepositoryIdentity to
review_audit, contributor_gate_history, and submitter_stats -- raw-SQL-
only REES/parity tables, never added to the Drizzle schema (see each
migration's own header comment), so these three blocks use
env.DB.prepare() directly instead of the query builder, matching how
every real writer (parity-wire.ts, outcomes-wire.ts, contributor-
calibration.ts, submitter-reputation.ts) already accesses them.

- review_audit, contributor_gate_history: PK `id` alone, no separate
  unique index. `project` IS the repo full name at every live writer;
  `target_id` (`${project}#${pullNumber}`) and `id` both embed it.
  Fold on the id collision the rename would produce -- same
  PK-collision-only shape as pull_request_reviews/collision_edges.
- submitter_stats: no id column -- PRIMARY KEY (project, submitter)
  directly. Fold on the other half of the composite key, `submitter`.

Deliberately excludes two other raw-SQL REES tables:
- review_targets: has NO live writer anywhere in this codebase
  (explicitly confirmed orphaned by src/review/public-stats.ts's own
  comment). Its `project` column is an agent/install-level slug that
  must NEVER be renamed (not a per-repo value), and its `repo` column's
  real on-disk semantics for that historical, one-time-bulk-copied data
  can't be independently verified from current code alone -- mutating
  identity columns on data no writer would ever repair carries real
  corruption risk for uncertain benefit.
- repo_chunks: a rebuildable RAG chunk/embedding cache (same reasoning
  as the AI/LLM caches #5953 excluded), whose project/repo columns hold
  the bare owner and bare repo name SEPARATELY (not a single owner/repo
  string) and whose id is a lowercased, truncated-to-64-chars hash of
  the two -- a safe in-place string rename isn't mechanically available
  without risking a silently-corrupted truncated id.

7 new tests: a rename test for all 3 tables, a collision-fold
regression test for each, plus an unrelated-row-untouched check for
submitter_stats.
This was referenced Jul 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant