This branch removes the legacy "pika-news" compatibility surface from the pika-git service. The project was previously renamed from pika-news to pika-git, and temporary shims were left in place (a /news URL alias, dual localStorage key fallbacks, Option-wrapped PR fields on inbox items, a legacy database migration ledger name, legacy state directory migration logic, and legacy secret key names). This branch drops all of that: it adds a new SQL migration to remove orphaned PR-related tables, renames the migrations ledger from _pika_news_migrations to pika_git_migrations with a safe transition path, simplifies the InboxItem struct to non-optional branch-only fields, strips the /news route alias and localStorage compat helpers, removes the Nix pre-start database/directory migration script, and re-keys the SOPS secrets under their canonical pika_git names.
Tutorial Steps
Add SQL migration to drop legacy PR-related tables
Intent: Remove database tables that belonged to the old pull-request-centric review surface (chat_messages, chat_sessions, artifact_user_states, artifact_versions, inbox_dismissals, inbox, generated_artifacts, pull_requests, poll_markers). These tables are no longer referenced anywhere in the codebase.
A new migration (0025_drop_legacy_pr_surface.sql) is added that unconditionally drops nine tables left over from the legacy PR review workflow. PRAGMA foreign_keys is toggled off/on around the drops to avoid FK constraint errors during teardown.
The migration is registered in the migrations() vec as version 25 in storage.rs:668-672.
Rename the migrations ledger table from _pika_news_migrations to _pika_git_migrations
Intent: Complete the pika-news → pika-git rename at the database metadata level. The migration ledger table that tracks which SQL migrations have been applied is renamed, with a safe three-way transition: rename if only the legacy table exists, merge-and-drop if both exist, or create fresh if neither exists.
A new function ensure_migrations_table (storage.rs:459-491) runs before the main migration loop and handles three cases:
Both tables exist — merge rows from legacy into current with INSERT OR IGNORE, then drop the legacy table.
Only legacy exists — ALTER TABLE … RENAME TO the current name.
Neither exists — no-op; the subsequent CREATE TABLE IF NOT EXISTS in run_migrations will create it.
All SQL strings in run_migrations that previously hard-coded _pika_news_migrations now use the MIGRATIONS_TABLE constant via format!.
Simplify InboxItem struct — remove Option wrappers and PR fields
Intent: Since the legacy PR surface is gone, InboxItem no longer needs to represent both branch reviews and PR reviews. Fields that were Option-wrapped for dual-mode compatibility (branch_id, branch_name) become non-optional, and PR-only fields (pr_id, pr_number, url) are deleted entirely.
The InboxItem struct (storage.rs:358-367) is slimmed down:
Removed
Changed
pr_id: Option<i64>
branch_id: Option<i64> → branch_id: i64
pr_number: Option<i64>
branch_name: Option<String> → branch_name: String
url: Option<String>
The query-mapping code in inbox_store.rs:111-120 is updated in tandem — it no longer wraps values in Some(…) or sets PR fields to None.
Remove the /news route alias from the web server
Intent: The /news path was kept as a temporary redirect alias while the rename from pika-news to pika-git rolled out. That transition period is over, so the alias is removed.
Affected files: crates/pika-git/src/web.rs
Evidence
@@ -784,8 +784,6 @@
let app = Router::new()
.route("/", get(|| async { Redirect::permanent("/git") }))
.nest("/git", git_routes.clone())
- // Keep `/news` alive as a compatibility alias during the rename rollout.
- .nest("/news", git_routes)
In web.rs:784-787, the .nest("/news", git_routes) line and its explanatory comment are deleted. The router now only mounts routes under /git.
Remove localStorage legacy-key migration helpers from the frontend
Intent: The base HTML template contained JavaScript helpers that read/wrote values under both pika_git_ and pika_news_ localStorage prefixes so users wouldn't lose their auth tokens during the rename. With the transition complete these shims are removed.
@@ -97,25 +97,16 @@
- function oldAuthKey(key) {
- if (!key.startsWith('pika_git_')) return key;
- return 'pika_news_' + key.slice('pika_git_'.length);
- }
-
function getAuthValue(key) {
- const current = authStorage.getItem(key);
- if (current !== null) return current;
- return authStorage.getItem(oldAuthKey(key));
+ return authStorage.getItem(key);
}
@@ -272,10 +263,7 @@
window.addEventListener('storage', function (event) {
- if (
- !event.key
- || (!event.key.startsWith('pika_git_') && !event.key.startsWith('pika_news_'))
- ) return;
+ if (!event.key || !event.key.startsWith('pika_git_')) return;
Three functions in base.html are simplified:
oldAuthKey() — deleted entirely.
getAuthValue(key) — no longer falls back to the legacy prefix; just calls authStorage.getItem(key).
setAuthValue(key, value) / removeAuthValue(key) — no longer clean up the legacy-prefixed key.
The cross-tab storage event listener now only reacts to keys starting with pika_git_, dropping the pika_news_ check.
Simplify inbox template — remove PR vs. branch rendering fork
Intent: The inbox item rendering previously branched on whether the item was a PR review or a branch review. With only branch reviews remaining, the template is simplified to a single code path.
In inbox.html:134-140, the isBranch boolean check and the ternary expression that chose between branch and legacy-PR title formats are collapsed into a single format string:
The || ('#' + reviewId) fallback is also no longer needed because branch_name is now always a non-empty string.
Remove legacy state-directory and database migration logic from Nix module
Intent: The Nix pre-start script contained ~70 lines of shell code to handle migrating the state directory from /var/lib/pika-news to /var/lib/pika-git, choosing the richer database when duplicates existed, and creating a compatibility symlink. All of this is removed since the migration has long since completed on all deployments.
@@ -6,90 +6,17 @@
- count_table_rows() {
- local db_path="$1"
- local table_name="$2"
- ...
- db_richness_score() {
- local db_path="$1"
- ...
The prepareCanonicalRepo script in pika-git.nix is reduced from ~90 lines to ~10. Removed logic includes:
The legacyServiceStateDir variable (/var/lib/pika-news).
count_table_rows and db_richness_score helper functions that compared old vs. new databases.
Directory contents migration from legacy to current state dir.
Database file selection based on richness scoring.
Symlink creation from old to new path.
What remains is just mkdir -p, chown, and the canonical git repo existence check.
Rename SOPS secret keys from pika_news_ to pika_git_
Intent: The encrypted secrets file and the Nix expressions that reference them still used the legacy pika_news_ prefix for three secrets (GitHub token, Claude OAuth token, webhook secret). These are renamed to pika_git_ and the secrets file is re-encrypted.
Three SOPS secret declarations in pika-git.nix are renamed:
Old key
New key
pika_news_github_token
pika_git_github_token
pika_news_claude_oauth_token
pika_git_claude_oauth_token
pika_news_webhook_secret
pika_git_webhook_secret
The environment file template (content = ''…'') is updated to reference the new placeholder paths. The SOPS-encrypted YAML file (infra/secrets/pika-git.yaml) is re-encrypted with the renamed top-level keys — the ciphertext changes but the plaintext values remain the same.
Update tests to verify legacy table cleanup and ledger rename
Intent: Ensure that after running all migrations, the legacy tables are gone, the new migrations ledger exists, and the old one does not. Also update existing tests that simulated a database with the old ledger name to use the LEGACY_MIGRATIONS_TABLE constant.
The test suite in storage.rs receives several updates:
Fresh-database test (storage.rs:783-793) — after running all migrations on a blank DB, asserts that _pika_git_migrations exists, _pika_news_migrations does not, and all nine legacy PR tables are absent.
Legacy-ledger upgrade tests — tests that previously hard-coded _pika_news_migrations now use the LEGACY_MIGRATIONS_TABLE constant (imported at storage.rs:685). After Store initialization, they assert the ledger was renamed to MIGRATIONS_TABLE and the legacy table no longer exists.
Inbox item assertions (storage.rs:1032-1033) — branch_name comparisons drop .as_deref() and Some(…) wrappers since the field is now a plain String.