Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
a63e21e
feat(runtime): issue weak read-only database leases
ScriptedAlchemy Aug 26, 2026
e745afd
fix(graph): warm derived memory graph in background
ScriptedAlchemy Aug 26, 2026
820163c
fix(runtime): restore session graphs in background
ScriptedAlchemy Aug 26, 2026
544ba28
fix(runtime): bind late project graphs to live sessions
ScriptedAlchemy Aug 26, 2026
b13d267
fix(runtime): prioritize project core over schema audit
ScriptedAlchemy Aug 26, 2026
9f87feb
fix(runtime): late-bind native integration graph
ScriptedAlchemy Aug 26, 2026
c721bf5
test(runtime): await background graph attachment
ScriptedAlchemy Aug 26, 2026
5eaded2
fix(index): keep exact tools live during graph warming
ScriptedAlchemy Aug 26, 2026
bd1de98
fix(index): verify stale text witness without decode
ScriptedAlchemy Aug 26, 2026
d50df9c
fix(index): suppress quiet Git backstop captures
ScriptedAlchemy Aug 26, 2026
f6989cc
fix(index): keep unchanged ready queries current
ScriptedAlchemy Aug 26, 2026
72a42dc
fix(index): probe freshness without forcing capture
ScriptedAlchemy Aug 26, 2026
4ccb7b0
fix(daemon): defer schema convergence until full publication
ScriptedAlchemy Aug 26, 2026
9a5603e
perf(hotpath): distinguish status warming awaits
ScriptedAlchemy Aug 26, 2026
d74035c
fix(index): isolate text refresh from graph retry
ScriptedAlchemy Aug 26, 2026
a1ae36c
fix(index): prioritize text refresh before graph activation
ScriptedAlchemy Aug 26, 2026
e36a518
perf(mcp): detach optional tool activity writes
ScriptedAlchemy Aug 26, 2026
bea08d2
fix(index): prune history before text attachment
ScriptedAlchemy Aug 26, 2026
08b1c02
fix(index): detach graph work from text freshness
ScriptedAlchemy Aug 26, 2026
a4c9c64
perf(graph): reuse recovered digest buffer
ScriptedAlchemy Aug 26, 2026
b1074d1
perf(graph): widen native generation staging
ScriptedAlchemy Aug 26, 2026
13e5b39
fix(graph): migrate legacy native stage receipts
ScriptedAlchemy Aug 26, 2026
6f6d6e4
fix(graph): replay historical projector generations
ScriptedAlchemy Aug 26, 2026
3b1baae
Merge post-#721 catch-up delta into #707
ScriptedAlchemy Aug 26, 2026
9614cff
Merge latest #707 integration head into #733
ScriptedAlchemy Aug 26, 2026
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
2 changes: 1 addition & 1 deletion crates/tracedecay-code-index/src/graph_projection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const FILE_SYMBOL_EDGE_KIND: &str = "CodeFileContainsSymbol";
const CHUNK_SYMBOL_EDGE_KIND: &str = "CodeChunkDescribesSymbol";
const SOURCE_EDGE_KIND: &str = "CodeRelationSource";
const TARGET_EDGE_KIND: &str = "CodeRelationTarget";
pub const CODE_GRAPH_PROJECTOR_REVISION: &str = "code-graph-projector.v4";
pub const CODE_GRAPH_PROJECTOR_REVISION: &str = "code-graph-projector.v5";

#[derive(Clone, Debug, Error, PartialEq, Eq)]
pub enum CodeGraphProjectionError {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -494,18 +494,17 @@ fn corrupt_import_relation_identity_and_properties_are_refused() {
}

#[test]
fn projector_v4_is_accepted_and_v3_is_a_generation_mismatch() {
assert_eq!(CODE_GRAPH_PROJECTOR_REVISION, "code-graph-projector.v4");
fn current_projector_is_accepted_and_v4_is_a_generation_mismatch() {
let (files, imports) = two_import_fixture();
let reader = import_reader(&files, &imports);
assert_eq!(reader.generation(), &generation());

let v3 = import_manifest(&files, &imports, "code-graph-projector.v3");
let snapshot = VerifiedGraphSnapshot::memory(v3, Arc::new(NeverCancelled))
let v4 = import_manifest(&files, &imports, "code-graph-projector.v4");
let snapshot = VerifiedGraphSnapshot::memory(v4, Arc::new(NeverCancelled))
.expect("open legacy-revision snapshot");
assert_eq!(
CodeGraphProjectionStore::from_verified_snapshot(snapshot, generation())
.expect_err("v3 snapshot must not satisfy the v4 reader"),
.expect_err("v4 snapshot must not satisfy the current reader"),
CodeGraphProjectionError::GenerationMismatch
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -250,30 +250,29 @@ fn sealed_generation_replay_rebuilds_identical_import_manifest_and_digest() {
}

#[test]
fn projector_v4_changes_generation_identity_without_a_v3_alias() {
assert_eq!(CODE_GRAPH_PROJECTOR_REVISION, "code-graph-projector.v4");
fn current_projector_changes_generation_identity_without_a_v4_alias() {
let generation = published_import_generation();
let v4 = current_projector_revision();
let v3 = GraphProjectorRevision::try_from("code-graph-projector.v3".to_owned())
let current = current_projector_revision();
let v4 = GraphProjectorRevision::try_from("code-graph-projector.v4".to_owned())
.expect("prior projector revision remains valid data");
let current_identity = code_graph_generation_id(&generation.manifest().generation_id, &current)
.expect("current graph generation identity");
let v4_identity = code_graph_generation_id(&generation.manifest().generation_id, &v4)
.expect("v4 graph generation identity");
let v3_identity = code_graph_generation_id(&generation.manifest().generation_id, &v3)
.expect("v3 graph generation identity");
assert_ne!(v4_identity, v3_identity);
assert_ne!(current_identity, v4_identity);

let current_manifest = projection_manifest(&generation, &current);
assert_eq!(current_manifest.generation, current_identity);
let _store = verified_store(current_manifest, &generation);

let v4_manifest = projection_manifest(&generation, &v4);
assert_eq!(v4_manifest.generation, v4_identity);
let _store = verified_store(v4_manifest, &generation);

let v3_manifest = projection_manifest(&generation, &v3);
assert_eq!(v3_manifest.generation, v3_identity);
let v3_snapshot = VerifiedGraphSnapshot::memory(v3_manifest, Arc::new(NeverCancelled))
let v4_snapshot = VerifiedGraphSnapshot::memory(v4_manifest, Arc::new(NeverCancelled))
.expect("prior graph snapshot is structurally valid");
let error = CodeGraphProjectionStore::from_verified_snapshot(
v3_snapshot,
v4_snapshot,
generation.manifest().generation_id.clone(),
)
.expect_err("a v3 graph snapshot cannot serve the v4 generation authority");
.expect_err("a v4 graph snapshot cannot serve the current generation authority");
assert_eq!(error, CodeGraphProjectionError::GenerationMismatch);
}
39 changes: 32 additions & 7 deletions crates/tracedecay-global-db/src/registered.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ pub use delivery_settlement::{
/// paths retain only [`RegisteredGlobalDbLeaseV1`].
pub struct RegisteredGlobalDbOwnerV1 {
database: DatabaseOwnerV1,
project_graph: Arc<OnceLock<VerifiedGraphRuntimeWeakProxyV1>>,
}

/// Cloneable, weak issuance route for one registered global-database owner.
Expand All @@ -41,6 +42,7 @@ pub struct RegisteredGlobalDbOwnerV1 {
#[derive(Clone)]
pub struct RegisteredGlobalDbWeakLeaseIssuerV1 {
database: DatabaseOwnerWeakLeaseIssuerV1,
project_graph: Arc<OnceLock<VerifiedGraphRuntimeWeakProxyV1>>,
}

impl RegisteredGlobalDbOwnerV1 {
Expand Down Expand Up @@ -72,7 +74,10 @@ impl RegisteredGlobalDbOwnerV1 {
registered.rearm_queued_projection_retries().await?;
super::schema_stages::converge_attached_registered_schema(&registered.database).await?;
drop(registered);
Ok(Self { database })
Ok(Self {
database,
project_graph: Arc::new(OnceLock::new()),
})
}

/// Returns the resumable convergence plan for an already admitted schema
Expand All @@ -89,7 +94,10 @@ impl RegisteredGlobalDbOwnerV1 {
registered.rearm_queued_projection_retries().await?;
drop(registered);
Ok((
Self { database },
Self {
database,
project_graph: Arc::new(OnceLock::new()),
},
super::schema_stages::RegisteredSchemaConvergence::for_existing_client(),
))
}
Expand All @@ -99,14 +107,20 @@ impl RegisteredGlobalDbOwnerV1 {
/// only that issuance.
pub fn issue_lease(&self) -> Result<RegisteredGlobalDbLeaseV1, DatabaseOwnerErrorV1> {
Ok(RegisteredGlobalDbLeaseV1::from_database(
RegisteredGlobalDb::from_database(self.database.issue_lease()?),
RegisteredGlobalDb::from_database_with_project_graph(
self.database.issue_lease()?,
Arc::clone(&self.project_graph),
),
))
}

/// Issues a mode-reduced client that can never regain write authority.
pub fn issue_read_only_lease(&self) -> Result<RegisteredGlobalDbLeaseV1, DatabaseOwnerErrorV1> {
Ok(RegisteredGlobalDbLeaseV1::from_database(
RegisteredGlobalDb::from_database(self.database.issue_read_only_lease()?),
RegisteredGlobalDb::from_database_with_project_graph(
self.database.issue_read_only_lease()?,
Arc::clone(&self.project_graph),
),
))
}

Expand All @@ -116,6 +130,7 @@ impl RegisteredGlobalDbOwnerV1 {
pub fn weak_lease_issuer(&self) -> RegisteredGlobalDbWeakLeaseIssuerV1 {
RegisteredGlobalDbWeakLeaseIssuerV1 {
database: self.database.weak_lease_issuer(),
project_graph: Arc::clone(&self.project_graph),
}
}

Expand Down Expand Up @@ -144,7 +159,10 @@ impl RegisteredGlobalDbWeakLeaseIssuerV1 {
&self,
) -> Result<RegisteredGlobalDbLeaseV1, DatabaseOwnerWeakLeaseIssuerErrorV1> {
Ok(RegisteredGlobalDbLeaseV1::from_database(
RegisteredGlobalDb::from_database(self.database.issue_lease()?),
RegisteredGlobalDb::from_database_with_project_graph(
self.database.issue_lease()?,
Arc::clone(&self.project_graph),
),
))
}

Expand Down Expand Up @@ -209,7 +227,7 @@ impl RegisteredGlobalDbLeaseV1 {

pub struct RegisteredGlobalDb {
database: Database,
project_graph: OnceLock<VerifiedGraphRuntimeWeakProxyV1>,
project_graph: Arc<OnceLock<VerifiedGraphRuntimeWeakProxyV1>>,
session_relation_graph: OnceLock<(
crate::session_temporal::relations::SessionRelationScope,
tracedecay_graph_db::GraphDbLeaseV1,
Expand Down Expand Up @@ -551,9 +569,16 @@ impl RegisteredGlobalDb {
}

fn from_database(database: Database) -> Self {
Self::from_database_with_project_graph(database, Arc::new(OnceLock::new()))
}

fn from_database_with_project_graph(
database: Database,
project_graph: Arc<OnceLock<VerifiedGraphRuntimeWeakProxyV1>>,
) -> Self {
Self {
database,
project_graph: OnceLock::new(),
project_graph,
session_relation_graph: OnceLock::new(),
}
}
Expand Down
Loading
Loading