Understanding the Review Session Model in Tuicr: Architecture and Implementation

Tuicr's review session model is a serializable Rust structure that tracks which files and hunks have been reviewed, stores file-level and line-level comments, and persists state to JSON for seamless resumption of code review sessions.

The review session model in Tuicr serves as the central data structure that enables both interactive TUI and non-interactive CLI workflows. According to the agavra/tuicr source code, this model captures complete review state—from individual hunk approvals to session-wide metadata—in a robust, version-tolerant format defined in src/model/review.rs.

Core Components of the Review Session Model

Tuicr implements its review session model through three primary types that work together to capture the complete state of a code review.

FileReview: Per-File State Tracking

The FileReview struct manages review progress for individual files. Defined in src/model/review.rs at lines 17-28, it tracks both aggregate and granular review status:

pub struct FileReview {
    pub path: PathBuf,                         // File location
    pub reviewed: bool,                        // Entire file marked reviewed
    pub status: FileStatus,                    // Added / Modified / Deleted
    pub file_comments: Vec<Comment>,           // Comments attached to file
    pub line_comments: HashMap<u32, Vec<Comment>>, // Line-specific comments
    pub reviewed_hunks: BTreeSet<String>,      // Hunk keys marked reviewed
    pub content_hash: Option<u64>,             // Hash for change detection
}

Key behaviors implemented for FileReview include:

  • add_file_comment – Appends a comment to the entire file
  • add_line_comment – Associates a comment with a specific line number
  • toggle_hunk_reviewed – Flips the reviewed status of a specific hunk by adding or removing its key from reviewed_hunks
  • comment_count – Returns the total number of comments for the file

ReviewSession: Session-Wide Aggregation

The ReviewSession struct aggregates all FileReview instances and maintains metadata about the review context. Located in src/model/review.rs at lines 89-123, it serves as the root container:

pub struct ReviewSession {
    pub id: String,                         // UUID of the session
    pub version: String,                    // Schema version
    pub repo_path: PathBuf,                 // Repository root
    pub branch_name: Option<String>,
    pub base_commit: String,                // Commit diff is based on
    pub diff_source: SessionDiffSource,     // Origin of the diff
    pub commit_range: Option<Vec<String>>,  // For commit-range diffs
    pub pr_session_key: Option<PrSessionKey>, // PR-specific identifier
    pub remote_comments_visibility: PrCommentsVisibility,
    pub commit_selection_range: Option<(usize, usize)>,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
    pub review_comments: Vec<Comment>,      // Session-wide comments
    pub files: HashMap<PathBuf, FileReview>, // Per-file state
    pub session_notes: Option<String>,
}

The ReviewSession type provides several critical methods for managing the review lifecycle:

  • new – Creates a fresh session with a generated UUID and timestamps
  • add_file – Registers a file; automatically clears the reviewed flag if the file's content_hash changes (preventing stale reviews)
  • add_diff_file – Adds a DiffFile from the VCS and prunes invalid hunk keys
  • clear_comments – Removes comments with optional scope control via ClearScope enum
  • Query helpers – reviewed_count, has_reviewed_state, is_file_reviewed, and is_hunk_reviewed support UI state rendering

SessionDiffSource: Diff Origin Abstraction

Tuicr supports multiple diff sources through the SessionDiffSource enum (lines 66-87 in src/model/review.rs), enabling the review session model to handle various Git workflows:

pub enum SessionDiffSource {
    WorkingTree,
    Staged,
    Unstaged,
    StagedAndUnstaged,
    CommitRange,
    WorkingTreeAndCommits,
    StagedUnstagedAndCommits,
    PullRequest,   // PR-mode sessions
    Pristine,      // Whole-repo annotation mode
}

Persistence and Change Detection

The review session model implements automatic persistence to ensure review progress survives application restarts. Sessions serialize to JSON and store in .local/share/tuicr/reviews/*.json, with the persistence/storage.rs module handling atomic write operations.

A critical safety feature prevents stale approvals: when add_file detects that a file's content_hash differs from the stored hash, it automatically resets the reviewed flag. This ensures that modifications made after a review are not incorrectly marked as approved. The model also maintains forward compatibility through serde's default field handling, allowing legacy JSON files to load into newer schema versions.

Working with the Review Session Model in Practice

The following example demonstrates creating a session, registering files, adding comments, and persisting state:

use tuicr::model::{review::ReviewSession, review::SessionDiffSource, comment::Comment, comment::CommentType};
use std::path::PathBuf;

// Create a new session for the working tree
let mut sess = ReviewSession::new(
    PathBuf::from("/my/repo"),
    "HEAD".to_string(),
    None,
    SessionDiffSource::WorkingTree,
);

// Register a file (normally done while parsing the diff)
let file_path = PathBuf::from("src/main.rs");
sess.add_file(file_path.clone(), tuicr::model::diff_types::FileStatus::Modified, 0xdeadbeef);

// Add a file-level comment
let comment = Comment::new(
    "Consider refactoring this module".into(),
    CommentType::from_id("suggestion"),
    None,
);
sess.files
    .get_mut(&file_path)
    .unwrap()
    .add_file_comment(comment);

// Add a line comment
let line_comment = Comment::new(
    "Potential off-by-one error".into(),
    CommentType::from_id("issue"),
    None,
);
sess.files
    .get_mut(&file_path)
    .unwrap()
    .add_line_comment(42, line_comment);

// Mark a specific hunk as reviewed
let hunk_key = "src/main.rs@@-10,1 +10,1@@".to_string();
sess.files
    .get_mut(&file_path)
    .unwrap()
    .toggle_hunk_reviewed(hunk_key);

// Persist the session (automatic in UI, manual here for demonstration)
tuicr::persistence::storage::save_session(&sess).expect("save failed");

Summary

  • The review session model in Tuicr centers on two main structures: FileReview for per-file state and ReviewSession for aggregate session management.
  • Granular tracking supports both file-level and hunk-level review states, with line-specific comments stored in a HashMap<u32, Vec<Comment>>.
  • Change detection uses content hashing to automatically invalidate reviews when files modify, preventing approval of outdated code.
  • Multi-source support via SessionDiffSource enables reviews of working tree, staged, unstaged, commit ranges, and pull requests.
  • JSON persistence in .local/share/tuicr/reviews/ enables session resumption across TUI and CLI invocations.

Frequently Asked Questions

What data does the Tuicr review session model store?

The model stores session metadata (UUID, timestamps, repository path, base commit), per-file review states (reviewed flags, hunk keys, content hashes), and all comments (both file-level and line-level). It also tracks the diff source type and PR-specific identifiers when applicable, as defined in src/model/review.rs.

How does Tuicr handle file changes during a review session?

When ReviewSession::add_file detects that a file's content_hash differs from the previously stored hash, it automatically clears the reviewed flag for that file. This ensures that modifications made after initial review are explicitly re-reviewed, preventing stale approvals from persisting.

Where does Tuicr persist review session data?

Sessions serialize to JSON format and store in the .local/share/tuicr/reviews/ directory, with each session saved as a separate .json file. The src/persistence/storage.rs module handles atomic serialization and deserialization using serde, ensuring data integrity across application restarts.

Can the review session model handle different types of diffs?

Yes. The SessionDiffSource enum supports eight distinct diff origins including WorkingTree, Staged, Unstaged, CommitRange, and PullRequest. This allows the same review session model to manage everything from local uncommitted changes to multi-commit PR reviews.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →