Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions cli/src/services/agent_trace_db/lifecycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ struct RepositoryDatabaseSetup {
canonical_identity: String,
identity_source: String,
configured_remote: Option<String>,
checkout_id: String,
source_instance_id: String,
database_path: PathBuf,
}
Expand All @@ -107,7 +106,6 @@ fn initialize_repository_agent_trace_db(repo_root: &Path) -> Result<RepositoryDa
canonical_identity: storage.repository_identity.identity.canonical_identity,
identity_source,
configured_remote,
checkout_id: storage.checkout_id,
source_instance_id: storage.metadata.source_instance_id,
database_path: storage.db_path,
})
Expand All @@ -120,12 +118,11 @@ fn format_repository_storage_setup_message(setup: &RepositoryDatabaseSetup) -> S
.map(|remote| format!("\nAgent Trace configured remote: {remote}"))
.unwrap_or_default();
format!(
"Agent Trace repository ID: {}\nAgent Trace identity source: {}\nAgent Trace canonical identity: {}{}\nAgent Trace checkout identity: {}\nAgent Trace source-instance ID: {}\nAgent Trace repository-scoped database initialized at '{}'.",
"Agent Trace repository ID: {}\nAgent Trace identity source: {}\nAgent Trace canonical identity: {}{}\nAgent Trace source-instance ID: {}\nAgent Trace repository-scoped database initialized at '{}'.",
setup.repository_id,
setup.identity_source,
setup.canonical_identity,
remote_line,
setup.checkout_id,
setup.source_instance_id,
setup.database_path.display()
)
Expand Down Expand Up @@ -237,7 +234,6 @@ mod tests {
canonical_identity: String::from("github.com/example/repo"),
identity_source: String::from("remote_url"),
configured_remote: configured_remote.map(String::from),
checkout_id: String::from("checkout-abc"),
source_instance_id: String::from("11111111-2222-3333-4444-555555555555"),
database_path: PathBuf::from("/tmp/agent-trace.db"),
}
Expand Down
55 changes: 7 additions & 48 deletions cli/src/services/agent_trace_storage/mod.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,10 @@
//! Repository-scoped Agent Trace storage resolution.
//!
//! Resolves the active Agent Trace database for a Git repository checkout:
//! one logical Git repository maps to exactly one database at
//! `<state-root>/sce/repos/<repository-id>/agent-trace.db`. Clones and linked
//! worktrees of the same logical repository share that database while keeping
//! their own distinct checkout IDs. Legacy checkout-scoped
//! `agent-trace-<checkout-id>.db` files are never selected, created, or
//! touched by this resolver.

use std::path::{Path, PathBuf};
use std::thread;
use std::time::Duration;

use anyhow::{Context, Result};
use anyhow::Result;

use crate::services::agent_trace_db::repository::{RepositoryAgentTraceDb, RepositoryMetadata};
use crate::services::checkout::{get_or_create_checkout_id, resolve_git_dir};
use crate::services::default_paths::{
agent_trace_db_path_for_repository, agent_trace_db_path_for_repository_at,
};
Expand Down Expand Up @@ -46,9 +35,6 @@ pub struct ResolvedAgentTraceStorage {
/// Repository identity (canonical identity plus repository ID) and the
/// source it was resolved from.
pub repository_identity: ResolvedRepositoryIdentity,
/// Stable identity of this clone/worktree. Kept for diagnostics only;
/// never persisted on Agent Trace rows.
pub checkout_id: String,
/// Repository-scoped database path
/// `<state-root>/sce/repos/<repository-id>/agent-trace.db`.
pub db_path: PathBuf,
Expand All @@ -67,7 +53,7 @@ pub fn resolve_agent_trace_storage(
) -> Result<ResolvedAgentTraceStorage> {
let repository_identity = resolve_identity(context)?;
let db_path = agent_trace_db_path_for_repository(&repository_identity.identity.repository_id)?;
open_storage(context, repository_identity, db_path)
open_storage(repository_identity, db_path)
}

/// Resolution core against an explicit state root, so tests can exercise the
Expand All @@ -81,7 +67,7 @@ pub fn resolve_agent_trace_storage_at_state_root(
state_root,
&repository_identity.identity.repository_id,
)?;
open_storage(context, repository_identity, db_path)
open_storage(repository_identity, db_path)
}

/// Resolves repository-scoped Agent Trace storage for high-frequency hook
Expand All @@ -97,7 +83,7 @@ pub fn resolve_agent_trace_storage_for_hook_runtime(
) -> Result<ResolvedAgentTraceStorage> {
let repository_identity = resolve_identity(context)?;
let db_path = agent_trace_db_path_for_repository(&repository_identity.identity.repository_id)?;
open_storage_for_hook_runtime(context, repository_identity, db_path)
open_storage_for_hook_runtime(repository_identity, db_path)
}

/// Hook-runtime resolution core against an explicit state root, so tests can
Expand All @@ -111,7 +97,7 @@ pub fn resolve_agent_trace_storage_for_hook_runtime_at_state_root(
state_root,
&repository_identity.identity.repository_id,
)?;
open_storage_for_hook_runtime(context, repository_identity, db_path)
open_storage_for_hook_runtime(repository_identity, db_path)
}

fn resolve_identity(context: &AgentTraceStorageContext<'_>) -> Result<ResolvedRepositoryIdentity> {
Expand All @@ -124,60 +110,37 @@ fn resolve_identity(context: &AgentTraceStorageContext<'_>) -> Result<ResolvedRe
}

fn open_storage(
context: &AgentTraceStorageContext<'_>,
repository_identity: ResolvedRepositoryIdentity,
db_path: PathBuf,
) -> Result<ResolvedAgentTraceStorage> {
// Opening the database creates `repos/<repository-id>/` when missing;
// directory creation is idempotent and first-time schema initialization may
// briefly race on SQLite metadata locks, so retry the fast-path/migrate
// sequence a small bounded number of times.
open_storage_with(
context,
repository_identity,
db_path,
open_repository_db_concurrently_safe,
)
}

fn open_storage_for_hook_runtime(
context: &AgentTraceStorageContext<'_>,
repository_identity: ResolvedRepositoryIdentity,
db_path: PathBuf,
) -> Result<ResolvedAgentTraceStorage> {
open_storage_with(
context,
repository_identity,
db_path,
open_repository_db_for_hook_runtime,
)
}

fn open_storage_with(
context: &AgentTraceStorageContext<'_>,
repository_identity: ResolvedRepositoryIdentity,
db_path: PathBuf,
open_db: impl FnOnce(&Path, &str) -> Result<(RepositoryAgentTraceDb, RepositoryMetadata)>,
) -> Result<ResolvedAgentTraceStorage> {
let git_dir = resolve_git_dir(context.repository_root).with_context(|| {
format!(
"failed to resolve git directory for Agent Trace repository DB from '{}'",
context.repository_root.display()
)
})?;
let checkout_id = get_or_create_checkout_id(&git_dir).with_context(|| {
format!(
"failed to get or create checkout identity under '{}'",
git_dir.display()
)
})?;

let repository_id = &repository_identity.identity.repository_id;
let (db, metadata) = open_db(&db_path, repository_id)?;

Ok(ResolvedAgentTraceStorage {
repository_identity,
checkout_id,
db_path,
db,
metadata,
Expand Down Expand Up @@ -345,7 +308,7 @@ mod tests {
}

#[test]
fn clones_of_the_same_repository_share_the_db_path_with_distinct_checkout_ids() {
fn clones_of_the_same_repository_share_the_db_path() {
let state_root = unique_temp_dir("state-clones");
// Equivalent SSH and HTTPS remotes for the same logical repository.
let clone_a = init_git_repo_with_remote("clone-a", "git@github.com:acme/widgets.git");
Expand All @@ -363,7 +326,6 @@ mod tests {
storage_b.repository_identity.identity.repository_id
);
assert_eq!(storage_a.db_path, storage_b.db_path);
assert_ne!(storage_a.checkout_id, storage_b.checkout_id);
assert_no_legacy_db_paths(&state_root);

std::fs::remove_dir_all(&state_root).expect("clean up state root");
Expand All @@ -372,7 +334,7 @@ mod tests {
}

#[test]
fn linked_worktree_shares_the_db_path_with_a_distinct_checkout_id() {
fn linked_worktree_shares_the_db_path() {
let state_root = unique_temp_dir("state-worktree");
let repo = init_git_repo_with_remote("worktree-main", "git@github.com:acme/widgets.git");
git(&repo, &["config", "user.email", "test@example.com"]);
Expand All @@ -399,7 +361,6 @@ mod tests {
.expect("worktree storage should resolve");

assert_eq!(storage_main.db_path, storage_worktree.db_path);
assert_ne!(storage_main.checkout_id, storage_worktree.checkout_id);
assert_no_legacy_db_paths(&state_root);

std::fs::remove_dir_all(&state_root).expect("clean up state root");
Expand Down Expand Up @@ -445,7 +406,6 @@ mod tests {
.expect("second resolution should succeed");

assert_eq!(first.db_path, second.db_path);
assert_eq!(first.checkout_id, second.checkout_id);
assert_eq!(
first.repository_identity.identity.repository_id,
second.repository_identity.identity.repository_id
Expand Down Expand Up @@ -551,7 +511,6 @@ mod tests {
resolve_agent_trace_storage_at_state_root(&context_for(&clone_b), &state_root)
.expect("clone B storage should resolve");
assert_eq!(storage_a.db_path, storage_b.db_path);
assert_ne!(storage_a.checkout_id, storage_b.checkout_id);

let patches = storage_b
.db
Expand Down
133 changes: 0 additions & 133 deletions cli/src/services/checkout/mod.rs

This file was deleted.

Loading
Loading