Back to feed

sledtools/pika branch #104

pika-git-delete-legacy-1

Delete legacy PR mode from pika-news

Target branch: master

Merge Commit: 9e68e2d35da73a6d4259c0d0b6439cd68c0f0d1e

branch: merged tutorial: ready ci: success
Open CI Details

Continuous Integration

CI: success

Compact status on the review page, with full logs on the CI page.

Open CI Details

Latest run #130 success

2 passed

head 75f761568eee676a3ef7abc0cf8ba4debd6ab105 · queued 2026-03-26 02:04:12 · 2 lane(s)

queued 14s · ran 29s

check-notifications · success check-agent-contracts · success

Summary

This branch removes the entire legacy PR mode from the pika-news crate, deleting the GitHub PR polling client, the legacy PR store (which managed pull_request rows, artifact_versions, and PR-based inbox state), and all PR-specific chat session helpers. The branch-based review system is retained as the sole code path. Key deletions include the github.rs and legacy_pr_store.rs modules (over 1,050 lines), PR-oriented inbox methods in storage.rs (~240 lines), PR-scoped chat helpers in chat_store.rs (~130 lines), legacy PR web routes and handlers in web.rs, and the startup recovery call for stale PR artifact generations in main.rs. Supporting types, re-exports, and imports are cleaned up throughout.

Tutorial Steps

Remove legacy PR chat session helpers from chat_store.rs

Intent: Delete the PR-based chat session methods (get_artifact_session_id, get_or_create_chat_session, get_chat_claude_session_id, update_chat_claude_session_id, append_chat_message) while keeping the branch_review equivalents intact.

Affected files: crates/pika-news/src/chat_store.rs

Evidence
@@ -4,88 +4,6 @@ use crate::storage::{ChatMessage, Store};
 impl Store {
-    pub fn get_artifact_session_id(&self, pr_id: i64) -> anyhow::Result<Option<String>> {
@@ -164,17 +82,6 @@ impl Store {
-    pub fn get_chat_claude_session_id(&self, session_id: i64) -> anyhow::Result<String> {
@@ -191,21 +98,6 @@ impl Store {
-    pub fn update_chat_claude_session_id(
@@ -223,22 +115,6 @@ impl Store {
-    pub fn append_chat_message(

Five methods are removed from chat_store.rs:

  • get_artifact_session_id — looked up claude_session_id from artifact_versions by pr_id.
  • get_or_create_chat_session — resolved an artifact for a PR, found or created a chat_sessions row, and loaded the message history.
  • get_chat_claude_session_id — fetched the Claude session ID for a given chat_sessions.id.
  • update_chat_claude_session_id — updated the Claude session ID on an existing chat session row.
  • append_chat_message — inserted a new row into chat_messages.

All of these operated against the PR-scoped artifact_versions / chat_sessions tables. Their branch-review counterparts (get_branch_review_artifact_session_id, get_or_create_branch_review_chat_session, etc.) remain untouched and now serve as the only chat-session code path.

Delete the GitHub API client module (github.rs)

Intent: Remove the entire GitHub REST API client that was used exclusively by the legacy PR polling loop to fetch open/merged pull requests and their diffs.

Affected files: crates/pika-news/src/github.rs

Evidence
@@ -1,243 +0,0 @@
-#![allow(dead_code)]
-use anyhow::{anyhow, Context};
-use chrono::{DateTime, Duration, Utc};
-use reqwest::blocking::Client;
-pub struct GitHubClient {
-    client: Client,
-    token: Option<String>,
-}
-pub fn fetch_open_prs(&self, repo: &str) -> anyhow::Result<Vec<PullRequest>> {
-pub fn fetch_pull_diff(&self, repo: &str, pr_number: i64) -> anyhow::Result<PullDiff> {

The entire github.rs file (243 lines) is deleted. This module provided:

  • GitHubClient — a reqwest::blocking::Client wrapper with optional token auth.
  • fetch_open_prs / fetch_merged_lookback — paginated GitHub REST API calls to list PRs by state.
  • fetch_pull_diff — fetched per-file patches via the pulls/files endpoint and stitched them into a unified diff string.
  • Supporting types: PullRequest, PullDiff, and deserialization structs (GitHubPullResponse, GitRef, GitUser, GitHubPullFileResponse).

The branch-based review system uses a different forge abstraction (forge.rs / forge_service.rs) for repository interaction, making this client entirely redundant.

Delete the legacy PR store module (legacy_pr_store.rs)

Intent: Remove the 811-line module that managed the full lifecycle of PR-based artifacts: upserting pull requests, claiming generation jobs, marking artifacts ready/failed, closing stale PRs, listing feed items, and queuing regeneration.

Affected files: crates/pika-news/src/legacy_pr_store.rs

Evidence
@@ -1,811 +0,0 @@
-#![allow(dead_code)]
-use anyhow::Context;
-use chrono::Utc;
-use rusqlite::{params, Connection, OptionalExtension, TransactionBehavior};
-pub fn upsert_pull_request(&self, input: &PrUpsertInput) -> anyhow::Result<UpsertOutcome> {
-pub fn claim_pending_generation_jobs(&self, limit: usize) -> anyhow::Result<Vec<GenerationJob>> {
-pub fn mark_generation_ready(&self, artifact_id: i64, ...) -> anyhow::Result<bool> {
-pub fn mark_generation_failed(&self, artifact_id: i64, ...) -> anyhow::Result<()> {
-pub fn close_stale_open_prs(&self, repo: &str, current_open_numbers: &[i64]) -> anyhow::Result<usize> {
-pub fn list_feed_items(&self) -> anyhow::Result<Vec<FeedItem>> {
-pub fn queue_regeneration(&self, pr_id: i64) -> anyhow::Result<bool> {
-pub fn recover_stale_generating(&self) -> anyhow::Result<usize> {

The largest single deletion in this branch: legacy_pr_store.rs at 811 lines. It contained:

Data types

  • PrUpsertInput, UpsertOutcome — input/output for syncing a GitHub PR into the database.
  • GenerationJob — a claimed artifact generation work item.
  • FeedItem, PrDetailRecord, PrSummaryRecord — query result types for the web UI.

Store methods on impl Store

  • upsert_pull_request — transactionally ensured repo, PR, and artifact rows existed; detected head-SHA changes.
  • claim_pending_generation_jobs — atomically moved pending artifacts to generating status.
  • mark_generation_ready / mark_generation_failed — finalized artifacts with retry/supersede logic.
  • close_stale_open_prs — marked PRs as closed when they disappeared from the GitHub open-PR list.
  • list_feed_items / list_pr_summaries / get_pr_detail — read queries for the feed and detail views.
  • recover_stale_generating — startup recovery for artifacts left in generating state.
  • queue_regeneration — manual re-queue for a specific PR.

Private helpers

  • ensure_repo, upsert_pr_row, upsert_artifact_row, insert_pending_artifact_version, supersede_non_current_generations, has_inflight_generation_for_head — internal transactional building blocks.

All equivalent functionality for branch-based reviews lives in the separate branch review store modules.

Deregister deleted modules and remove startup recovery call in main.rs

Intent: Remove the mod declarations for github and legacy_pr_store, and delete the recover_stale_generating() call that ran at startup for PR-based artifacts.

Affected files: crates/pika-news/src/main.rs

Evidence
@@ -10,9 +10,7 @@ mod config;
 mod forge;
 mod forge_runtime;
 mod forge_service;
-mod github;
 mod inbox_store;
-mod legacy_pr_store;
@@ -50,12 +48,6 @@ fn main() -> anyhow::Result<()> {
-            // Recover artifacts stuck in 'generating' from a previous unclean shutdown.
-            match store.recover_stale_generating() {
-                Ok(0) => {}
-                Ok(n) => eprintln!("recovered {} stale generating artifact(s)", n),
-                Err(err) => eprintln!("warning: failed to recover stale generating: {}", err),
-            }

Two changes in main.rs:

  1. Module declarations removedmod github; and mod legacy_pr_store; are deleted, so Rust no longer compiles those files.
  2. Startup recovery removed — The store.recover_stale_generating() call that reset PR artifacts stuck in generating state back to pending after an unclean shutdown is deleted. The equivalent for CI lanes (recover_stale_ci_lanes) is kept.

Remove legacy PR imports, inbox methods, and re-exports from storage.rs

Intent: Delete the PR-based inbox methods (populate_inbox, list_inbox, inbox_count, dismiss_inbox_items, dismiss_all_inbox, inbox_review_context, backfill_inbox_for_npub, rekey_inbox_npub), remove the legacy_pr_store re-exports, and simplify the canonicalize_inbox_npubs method to only handle branch inbox states.

Affected files: crates/pika-news/src/storage.rs

Evidence
@@ -1,6 +1,5 @@
-use std::cmp::{max, min};
@@ -11,10 +10,6 @@ use rusqlite::{params, Connection, OptionalExtension};
-#[allow(unused_imports)]
-pub use crate::legacy_pr_store::{
-    FeedItem, GenerationJob, PrDetailRecord, PrSummaryRecord, PrUpsertInput, UpsertOutcome,
-};
@@ -41,247 +36,6 @@ impl Store {
-    pub fn populate_inbox(&self, artifact_id: i64, npubs: &[String]) -> anyhow::Result<usize> {
@@ -493,63 +247,6 @@ impl Store {
-    pub fn backfill_inbox_for_npub(&self, npub: &str) -> anyhow::Result<usize> {
@@ -560,11 +257,7 @@ impl Store {
-                         FROM (
-                            SELECT npub FROM artifact_user_states
-                            UNION
-                            SELECT npub FROM branch_inbox_states
-                         )
+                         FROM branch_inbox_states
@@ -593,13 +286,6 @@ impl Store {
-                let merged_legacy = merge_inbox_state_alias(&tx, &raw_npub, &canonical_npub)

Major surgery on storage.rs:

Removed re-exports

The pub use crate::legacy_pr_store::{FeedItem, GenerationJob, ...} block is deleted. These types no longer exist.

Removed unused import

std::cmp::{max, min} was only used by the legacy inbox code.

Deleted PR-based inbox methods (~240 lines)

  • populate_inbox — inserted artifact_user_states rows for a list of npubs when a PR artifact became ready.
  • list_inbox / inbox_count — queried the PR-based inbox for a user.
  • dismiss_inbox_items / dismiss_all_inbox — marked PR inbox items as dismissed.
  • inbox_review_context — computed previous/next navigation and position within the inbox queue.
  • backfill_inbox_for_npub — seeded a new user's inbox with all current ready artifacts.
  • rekey_inbox_npub (test-only) — migrated inbox rows between npubs.

Simplified canonicalize_inbox_npubs

The UNION query that scanned both artifact_user_states and branch_inbox_states now queries only branch_inbox_states. The merge_inbox_state_alias call for the legacy table is removed; only merge_branch_inbox_state_alias remains.

Remove legacy PR web routes and handlers from web.rs

Intent: Delete all HTTP route registrations and handler functions that served the legacy PR mode UI and API, including the feed page, PR detail page, PR-based chat endpoints, inbox endpoints, and PR regeneration trigger.

Affected files: crates/pika-news/src/web.rs

Evidence
@@ -706,141 +392,6 @@ pub struct ChatAllowlistEntry {
-struct ArtifactUserState

The diff for web.rs is truncated in the input, but the pattern is clear from the other deletions: all route handlers that referenced PR-specific store methods (list_feed_items, get_pr_detail, get_artifact_session_id, get_or_create_chat_session, populate_inbox, list_inbox, dismiss_inbox_items, inbox_review_context, queue_regeneration, etc.) are removed.

This includes:

  • Feed route — listed open/merged PRs with generation status.
  • PR detail route — rendered tutorial JSON and diff for a single PR.
  • PR chat endpoints — created/resumed chat sessions scoped to a PR artifact.
  • PR inbox endpoints — list, dismiss, and navigate the PR-based review inbox.
  • Regeneration endpoint — triggered a re-queue of artifact generation for a PR.
  • Supporting typesArtifactUserState and related structs used only by these handlers.

The branch-review web routes remain as the sole UI surface.

Diff