Skip to content
Closed
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
2 changes: 0 additions & 2 deletions crates/tracedecay-application/src/primitives/symbol_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1078,8 +1078,6 @@ pub(crate) fn symbol_record(
qualified_name: metadata.qualified_name,
kind: metadata.kind,
file,
start_line_zero_based: metadata.start_line,
end_line_zero_based: end_line,
line: metadata.start_line.saturating_add(1),
end_line: end_line.saturating_add(1),
is_async: metadata.is_async,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1157,8 +1157,6 @@ impl NativeRecordReadPortV1 for LatestCompleteCodeIndexV1 {
},
|chunk| chunk.anchor.source_span,
),
start_line_zero_based: lineage.start_line,
end_line_zero_based,
line,
end_line,
signature: lineage.signature.clone(),
Expand Down Expand Up @@ -1208,8 +1206,6 @@ fn graph_projection_symbol_record(
kind: metadata.kind,
path,
span,
start_line_zero_based: metadata.start_line,
end_line_zero_based,
line: metadata
.start_line
.checked_add(1)
Expand Down Expand Up @@ -1311,8 +1307,6 @@ fn application_symbol_record(record: NativeSymbolRecordV1) -> SymbolPrimitiveRec
qualified_name: record.qualified_name,
kind: record.kind,
file: record.path,
start_line_zero_based: record.start_line_zero_based,
end_line_zero_based: record.end_line_zero_based,
line: record.line,
end_line: record.end_line,
signature: record.signature,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4544,8 +4544,6 @@ async fn callable_application_operations_consume_exact_lexical_and_graph_owners(
assert_eq!(callee.edge_kind, "calls");
assert_eq!(callee.symbol.name, "callee");
assert_eq!(callee.symbol.file, "src/lib.rs");
assert_eq!(callee.symbol.start_line_zero_based, 13);
assert_eq!(callee.symbol.end_line_zero_based, 13);
assert_eq!(callee.symbol.line, 14);
assert_eq!(callee.symbol.end_line, 14);
}
Expand Down
22 changes: 20 additions & 2 deletions crates/tracedecay-contracts/src/retrieval/callable_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -718,8 +718,6 @@ mod tests {
"qualified_name": "crate::worker::work",
"kind": "function",
"file": "src/worker.rs",
"start_line_zero_based": 4,
"end_line_zero_based": 8,
"line": 5,
"end_line": 9,
"signature": null,
Expand All @@ -730,5 +728,25 @@ mod tests {
)
.is_err()
);
assert!(
serde_json::from_str::<SymbolPrimitiveRecord>(
r#"{
"node_id": "node.fixture",
"name": "work",
"qualified_name": "crate::worker::work",
"kind": "function",
"file": "src/worker.rs",
"start_line_zero_based": 4,
"end_line_zero_based": 8,
"line": 5,
"end_line": 9,
"signature": null,
"is_async": false,
"score": null
}"#,
)
.is_err(),
"zero-based line fields are not part of the symbol record contract"
);
}
}
11 changes: 6 additions & 5 deletions crates/tracedecay-contracts/src/retrieval/catalog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,10 +202,11 @@ fn primitive_read_surfaces(spec: &PrimitiveReadSpec) -> &'static [BindingSurface
}
}

/// Similar/redundancy cut over to the family wire schema. Protocol revisions
/// share one (surface, operation) key; `ProtocolRevisionRange` carries the
/// accepted revisions. Do not mint a second binding for the same spelling;
/// `index_bindings` rejects duplicate surface-operation keys.
/// Similar and redundancy expose one current family schema. Callers already
/// use that schema, so the binding is the current protocol revision only —
/// not a revision window for a retired request shape. Do not mint a second
/// binding for the same spelling; `index_bindings` rejects duplicate
/// surface-operation keys.
fn clone_family_surface_bindings(
capability_id: &CapabilityId,
operation: &str,
Expand All @@ -226,7 +227,7 @@ fn clone_family_surface_bindings(
capability_id: capability_id.clone(),
surface,
operation: SurfaceOperationName::new(operation)?,
protocol_revisions: ProtocolRevisionRange::new(1, 2)?,
protocol_revisions: ProtocolRevisionRange::new(1, 1)?,
required_features: Vec::new(),
status: BindingStatus::Current,
alias_of: None,
Expand Down
28 changes: 13 additions & 15 deletions crates/tracedecay-contracts/src/retrieval/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,23 +96,21 @@ pub use ports::{
pub use primitive_surface::{
CalleeV1, CalleesResultV1, CalleesSurfaceRequestV1, ContextCodeBlockV1, ContextModeV1,
ContextResultV1, ContextSearchMatchV1, ContextSurfaceRequestV1, ImpactNodeV1, ImpactResultV1,
ImpactSurfaceRequestV1, LegacyRedundancySurfaceRequestV1, LegacySimilarSurfaceRequestV1,
MAX_REDUNDANCY_FAMILIES_V1, MAX_REDUNDANCY_PULL_REQUEST_PATHS_V1, MAX_REDUNDANCY_WORK_V1,
NodeDepthSurfaceRequestV1, NodeDetailsV1, NodeExpansionCostV1, NodeResultV1,
NodeSurfaceRequestV1, PortCycleAnchorV1, PortCycleFileV1, PortCycleSymbolV1, PortCycleV1,
PortMatchedSymbolV1, PortOrderLevelV1, PortOrderResultV1, PortOrderSurfaceRequestV1,
PortOrderSymbolV1, PortStatusResultV1, PortStatusSurfaceRequestV1, PortTargetOnlySymbolV1,
PortUnmatchedSymbolV1, PrimitiveFreshnessStateV1, PrimitiveIndexingStateV1,
PrimitiveLaneCompleteV1, PrimitiveLaneStateV1, PrimitiveLaneStatusV1, PrimitiveNotFoundV1,
PrimitiveRecallV1, PrimitiveSearchCoverageV1, PrimitiveSearchFreshnessV1,
ImpactSurfaceRequestV1, MAX_REDUNDANCY_FAMILIES_V1, MAX_REDUNDANCY_PULL_REQUEST_PATHS_V1,
MAX_REDUNDANCY_WORK_V1, NodeDepthSurfaceRequestV1, NodeDetailsV1, NodeExpansionCostV1,
NodeResultV1, NodeSurfaceRequestV1, PortCycleAnchorV1, PortCycleFileV1, PortCycleSymbolV1,
PortCycleV1, PortMatchedSymbolV1, PortOrderLevelV1, PortOrderResultV1,
PortOrderSurfaceRequestV1, PortOrderSymbolV1, PortStatusResultV1, PortStatusSurfaceRequestV1,
PortTargetOnlySymbolV1, PortUnmatchedSymbolV1, PrimitiveFreshnessStateV1,
PrimitiveIndexingStateV1, PrimitiveLaneCompleteV1, PrimitiveLaneStateV1, PrimitiveLaneStatusV1,
PrimitiveNotFoundV1, PrimitiveRecallV1, PrimitiveSearchCoverageV1, PrimitiveSearchFreshnessV1,
PrimitiveSymbolLocationV1, PrimitiveUnavailableEvidenceV1, PrimitiveUnavailableStatusV1,
RedundancyCoverageV1, RedundancyFamilyV1, RedundancyPartialReasonV1, RedundancyRankingV1,
RedundancyResultV1, RedundancyScopeV1, RedundancySurfaceRequestV1,
RedundancySurfaceRequestWireV1, RenamePreviewNodeV1, RenamePreviewPrimitiveOutcomeV1,
RenamePreviewPrimitiveRequestV1, RenamePreviewPrimitiveResultV1, RenamePreviewReferenceV1,
RenamePreviewTextOnlyMatchV1, SimilarCoverageV1, SimilarFamilyV1, SimilarMatchClassV1,
SimilarOccurrenceV1, SimilarResultV1, SimilarSurfaceRequestV1, SimilarSurfaceRequestWireV1,
SimilarTargetV1, TodoMarkerV1, TodosResultV1, TodosSurfaceRequestV1,
RedundancyResultV1, RedundancyScopeV1, RedundancySurfaceRequestV1, RenamePreviewNodeV1,
RenamePreviewPrimitiveOutcomeV1, RenamePreviewPrimitiveRequestV1,
RenamePreviewPrimitiveResultV1, RenamePreviewReferenceV1, RenamePreviewTextOnlyMatchV1,
SimilarCoverageV1, SimilarFamilyV1, SimilarMatchClassV1, SimilarOccurrenceV1, SimilarResultV1,
SimilarSurfaceRequestV1, SimilarTargetV1, TodoMarkerV1, TodosResultV1, TodosSurfaceRequestV1,
};
pub use requests::{
AffectedTestAttributionV1, AffectedTestsRequest, AffectedTestsResult, AnchorExpandRequest,
Expand Down
136 changes: 67 additions & 69 deletions crates/tracedecay-contracts/src/retrieval/primitive_surface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,31 +156,12 @@ pub struct SimilarSurfaceRequestV1 {
pub repository_id: RepositoryId,
pub target: SimilarTargetV1,
pub match_classes: Vec<SimilarMatchClassV1>,
/// Preferred result page size. Accepts legacy `limit` as a wire alias.
#[serde(alias = "limit")]
/// Preferred result page size.
pub result_limit: u32,
pub work_limit: u32,
pub cursor: Option<String>,
}

/// Pre-family similar request shape (`{symbol, limit}`) retained for decode
/// so cutover clients get a typed migration error instead of opaque serde noise.
#[derive(Clone, Debug, Deserialize, PartialEq, Eq)]
#[serde(deny_unknown_fields)]
pub struct LegacySimilarSurfaceRequestV1 {
pub symbol: String,
pub limit: Option<u32>,
}

/// Runtime decode envelope for `tracedecay_similar`: current family schema or
/// the retired `{symbol, limit}` spelling.
#[derive(Clone, Debug, Deserialize, PartialEq, Eq)]
#[serde(untagged)]
pub enum SimilarSurfaceRequestWireV1 {
Current(SimilarSurfaceRequestV1),
Legacy(LegacySimilarSurfaceRequestV1),
}

#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Eq, Serialize)]
#[serde(deny_unknown_fields)]
pub struct RenamePreviewPrimitiveRequestV1 {
Expand Down Expand Up @@ -227,35 +208,13 @@ pub struct RedundancySurfaceRequestV1 {
pub match_classes: Vec<SimilarMatchClassV1>,
pub scope: RedundancyScopeV1,
pub include_generated_paths: bool,
/// Preferred family page size. Accepts legacy `max_pairs` / `limit` aliases.
#[serde(alias = "max_pairs", alias = "limit")]
/// Preferred family page size.
pub family_limit: u32,
pub member_limit: u32,
pub work_limit: u32,
pub cursor: Option<String>,
}

/// Pre-family redundancy request shape retained for decode so cutover clients
/// get a typed migration error instead of opaque serde noise.
#[derive(Clone, Debug, Deserialize, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct LegacyRedundancySurfaceRequestV1 {
pub path: Option<String>,
pub min_lines: Option<u32>,
pub max_pairs: Option<u32>,
pub similarity_threshold: Option<f64>,
pub include_naming_only: Option<bool>,
pub include_generated_paths: Option<bool>,
}

/// Runtime decode envelope for `tracedecay_redundancy`.
#[derive(Clone, Debug, Deserialize, PartialEq)]
#[serde(untagged)]
pub enum RedundancySurfaceRequestWireV1 {
Current(RedundancySurfaceRequestV1),
Legacy(LegacyRedundancySurfaceRequestV1),
}

#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Eq, Serialize)]
#[serde(deny_unknown_fields)]
pub struct TodosSurfaceRequestV1 {
Expand Down Expand Up @@ -764,7 +723,7 @@ mod tests {
ContextModeV1, ContextResultV1, ContextSurfaceRequestV1, PrimitiveFreshnessStateV1,
PrimitiveIndexingStateV1, PrimitiveLaneCompleteV1, PrimitiveLaneStatusV1,
PrimitiveRecallV1, PrimitiveSearchCoverageV1, PrimitiveSearchFreshnessV1,
RedundancySurfaceRequestWireV1, SimilarSurfaceRequestWireV1,
RedundancySurfaceRequestV1, SimilarSurfaceRequestV1,
};
use crate::memory::{FactSearchGraphCoverageV1, FactSearchGraphDegradationV1};

Expand Down Expand Up @@ -901,38 +860,77 @@ mod tests {
}

#[test]
fn similar_and_redundancy_accept_legacy_request_shapes_on_the_wire() {
let legacy_similar = json!({"symbol": "foo", "limit": 5});
let wire: SimilarSurfaceRequestWireV1 =
serde_json::from_value(legacy_similar).expect("legacy similar decodes");
assert!(matches!(wire, SimilarSurfaceRequestWireV1::Legacy(_)));

let legacy_redundancy = json!({
"path": "src/",
"min_lines": 10,
"max_pairs": 20,
"similarity_threshold": 0.9,
"include_naming_only": false,
"include_generated_paths": true
});
let wire: RedundancySurfaceRequestWireV1 =
serde_json::from_value(legacy_redundancy).expect("legacy redundancy decodes");
assert!(matches!(wire, RedundancySurfaceRequestWireV1::Legacy(_)));

fn similar_and_redundancy_reject_retired_request_shapes() {
let current_similar = json!({
"project_id": "project.demo",
"repository_id": "repo.demo",
"target": {"kind": "symbol_occurrence", "symbol_occurrence_id": "symbol.v1.demo"},
"match_classes": ["conservative_exact"],
"limit": 3,
"result_limit": 3,
"work_limit": 100,
"cursor": null
});
let wire: SimilarSurfaceRequestWireV1 = serde_json::from_value(current_similar)
.expect("current similar decodes with limit alias");
match wire {
SimilarSurfaceRequestWireV1::Current(request) => assert_eq!(request.result_limit, 3),
SimilarSurfaceRequestWireV1::Legacy(_) => panic!("expected current family schema"),
}
let request: SimilarSurfaceRequestV1 =
serde_json::from_value(current_similar).expect("current similar schema decodes");
assert_eq!(request.result_limit, 3);

assert!(
serde_json::from_value::<SimilarSurfaceRequestV1>(json!({"symbol": "foo", "limit": 5}))
.is_err(),
"retired {{symbol, limit}} is not a similar request"
);
assert!(
serde_json::from_value::<SimilarSurfaceRequestV1>(json!({
"project_id": "project.demo",
"repository_id": "repo.demo",
"target": {"kind": "symbol_occurrence", "symbol_occurrence_id": "symbol.v1.demo"},
"match_classes": ["conservative_exact"],
"limit": 3,
"work_limit": 100
}))
.is_err(),
"limit is not an alias of result_limit"
);

let current_redundancy = json!({
"project_id": "project.demo",
"repository_id": "repo.demo",
"match_classes": ["conservative_exact"],
"scope": {"kind": "repository"},
"include_generated_paths": false,
"family_limit": 4,
"member_limit": 2,
"work_limit": 8,
"cursor": null
});
let request: RedundancySurfaceRequestV1 =
serde_json::from_value(current_redundancy).expect("current redundancy schema decodes");
assert_eq!(request.family_limit, 4);
assert!(
serde_json::from_value::<RedundancySurfaceRequestV1>(json!({
"path": "src/",
"min_lines": 10,
"max_pairs": 20,
"similarity_threshold": 0.9,
"include_naming_only": false,
"include_generated_paths": true
}))
.is_err(),
"retired path/min_lines/max_pairs shape is not a redundancy request"
);
assert!(
serde_json::from_value::<RedundancySurfaceRequestV1>(json!({
"project_id": "project.demo",
"repository_id": "repo.demo",
"match_classes": ["conservative_exact"],
"scope": {"kind": "repository"},
"include_generated_paths": false,
"max_pairs": 4,
"member_limit": 2,
"work_limit": 8
}))
.is_err(),
"max_pairs is not an alias of family_limit"
);
}
}
38 changes: 35 additions & 3 deletions crates/tracedecay-contracts/src/retrieval/requests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,11 +303,9 @@ pub struct QualifiedNamePrimitiveResult {
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
#[serde(deny_unknown_fields)]
pub struct CallChainPrimitiveRequest {
#[serde(alias = "from_id")]
pub from_node_id: String,
#[serde(alias = "to_id")]
pub to_node_id: String,
#[serde(default = "default_call_chain_depth", alias = "max_depth")]
#[serde(default = "default_call_chain_depth")]
pub maximum_depth: u32,
}

Expand Down Expand Up @@ -489,3 +487,37 @@ pub struct PrimitiveInvocation {
pub operation: ApplicationOperation,
pub request: PrimitiveRequest,
}

#[cfg(test)]
mod tests {
use super::CallChainPrimitiveRequest;

#[test]
fn call_chain_rejects_retired_field_names() {
let current = serde_json::from_value::<CallChainPrimitiveRequest>(serde_json::json!({
"from_node_id": "node.from",
"to_node_id": "node.to",
"maximum_depth": 3
}))
.expect("current call-chain schema decodes");
assert_eq!(current.maximum_depth, 3);

for retired in [
serde_json::json!({
"from_id": "node.from",
"to_id": "node.to",
"max_depth": 3
}),
serde_json::json!({
"from_node_id": "node.from",
"to_node_id": "node.to",
"max_depth": 3
}),
] {
assert!(
serde_json::from_value::<CallChainPrimitiveRequest>(retired).is_err(),
"retired call-chain field names are not aliases"
);
}
}
}
3 changes: 0 additions & 3 deletions crates/tracedecay-contracts/src/retrieval/symbol_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,6 @@ pub struct SymbolPrimitiveRecord {
pub qualified_name: String,
pub kind: String,
pub file: String,
/// Canonical tree-sitter row retained for compatibility adapters.
pub start_line_zero_based: u32,
pub end_line_zero_based: u32,
/// One-based user-facing line.
pub line: u32,
pub end_line: u32,
Expand Down
Loading
Loading