Skip to content
Draft
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
50 changes: 31 additions & 19 deletions crates/tracedecay-usecases/src/advisory/ci_runtime/stores.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ impl ProjectCiRetainedObservationStoreV1 {

/// Loads only the canonical, structurally validated inventory for the
/// exact admitted scope. Point records remain behind bounded entry reads.
#[hotpath::measure(label = "usecases.advisory.ci.load_inventory", future = true)]
pub async fn load_inventory_manifest(
&self,
context: &RequestContext,
Expand Down Expand Up @@ -264,6 +265,7 @@ impl ProjectCiRetainedObservationStoreV1 {
/// Loads one manifest-selected point record within the caller's remaining
/// byte budget. The encoded size is checked before deserialization and the
/// decoded record is bound back to both immutable identities in the entry.
#[hotpath::measure(label = "usecases.advisory.ci.load_entry", future = true)]
pub async fn load_bounded_entry(
&self,
context: &RequestContext,
Expand Down Expand Up @@ -321,6 +323,7 @@ impl ProjectCiRetainedObservationStoreV1 {

/// Loads the exact-scope bounded inventory and verifies every retained
/// record against the manifest's canonical content identity.
#[hotpath::measure(label = "usecases.advisory.ci.load_manifest", future = true)]
pub async fn load_manifest(
&self,
context: &RequestContext,
Expand Down Expand Up @@ -407,19 +410,22 @@ impl CiRetainedProviderObservationAuthorityV1 for ProjectCiRetainedObservationSt
context: &'a RequestContext,
request: &'a CiFailureLocalizationRequestV1,
) -> FeedbackPortFuture<'a, Option<CiRetainedProviderRecordV1>> {
Box::pin(async move {
if !context_allows_feedback_operation(
context,
&self.scope,
CI_FAILURE_LOCALIZE_CAPABILITY_ID_V1,
CI_FAILURE_LOCALIZE_USE_CASE_ID_V1,
) {
return None;
}
let key = self.key(request)?;
let encoded = self.database.get_metadata(&key).await.ok()??;
Self::decode_record(request, &encoded)
})
Box::pin(hotpath::future!(
async move {
if !context_allows_feedback_operation(
context,
&self.scope,
CI_FAILURE_LOCALIZE_CAPABILITY_ID_V1,
CI_FAILURE_LOCALIZE_USE_CASE_ID_V1,
) {
return None;
}
let key = self.key(request)?;
let encoded = self.database.get_metadata(&key).await.ok()??;
Self::decode_record(request, &encoded)
},
label = "usecases.advisory.ci.load_record"
))
}

fn retain<'a>(
Expand All @@ -430,8 +436,9 @@ impl CiRetainedProviderObservationAuthorityV1 for ProjectCiRetainedObservationSt
state: CiFailureLocalizationStateV1,
coverage: CiFailureCoverageV1,
) -> FeedbackPortFuture<'a, Option<CiRetainedProviderObservationV1>> {
Box::pin(async move {
if !context_allows_feedback_operation(
Box::pin(hotpath::future!(
async move {
if !context_allows_feedback_operation(
context,
&self.scope,
CI_FAILURE_LOCALIZE_CAPABILITY_ID_V1,
Expand Down Expand Up @@ -551,7 +558,9 @@ impl CiRetainedProviderObservationAuthorityV1 for ProjectCiRetainedObservationSt
return None;
}
Some(observation)
})
},
label = "usecases.advisory.ci.retain_observation"
))
}
}

Expand Down Expand Up @@ -601,8 +610,9 @@ impl CiCodeAnchorStoreV1 for ProjectCiCodeAnchorStoreV1 {
request: &'a CiFailureLocalizationRequestV1,
record: &'a CiRetainedProviderRecordV1,
) -> FeedbackPortFuture<'a, Option<CiExactCodeEvidenceV1>> {
Box::pin(async move {
if !context_allows_feedback_operation(
Box::pin(hotpath::future!(
async move {
if !context_allows_feedback_operation(
context,
&self.scope,
CI_FAILURE_LOCALIZE_CAPABILITY_ID_V1,
Expand Down Expand Up @@ -796,7 +806,9 @@ impl CiCodeAnchorStoreV1 for ProjectCiCodeAnchorStoreV1 {
callers,
tests,
})
})
},
label = "usecases.advisory.ci.resolve_code_anchor"
))
}
}

Expand Down
17 changes: 14 additions & 3 deletions crates/tracedecay-usecases/src/advisory/github_runtime/anchors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ impl ProjectGitHubAnchorAuthorityV1 {
self
}

#[hotpath::measure(label = "usecases.advisory.github.resolve_seeds", future = true)]
async fn resolve_seeds(
&self,
request: &GitHubReviewReadRequestV1,
Expand Down Expand Up @@ -244,6 +245,7 @@ impl ProjectGitHubAnchorAuthorityV1 {
Some(resolved)
}

#[hotpath::measure(label = "usecases.advisory.github.resolve_stored_seed", future = true)]
async fn resolve_stored_seed(
&self,
request: &GitHubReviewReadRequestV1,
Expand All @@ -270,6 +272,7 @@ impl ProjectGitHubAnchorAuthorityV1 {
self.persist_body(&body).await.then_some(anchors)
}

#[hotpath::measure(label = "usecases.advisory.github.resolve_new_seed", future = true)]
async fn resolve_new_seed(
&self,
request: &GitHubReviewReadRequestV1,
Expand Down Expand Up @@ -309,6 +312,7 @@ impl ProjectGitHubAnchorAuthorityV1 {
self.persist(&stored, &body).await.then_some(anchors)
}

#[hotpath::measure(label = "usecases.advisory.github.remap_original", future = true)]
async fn remap_original(
&self,
context: &RequestContext,
Expand All @@ -326,6 +330,7 @@ impl ProjectGitHubAnchorAuthorityV1 {
.await
}

#[hotpath::measure(label = "usecases.advisory.github.remap_seed", future = true)]
async fn remap_seed(
&self,
context: &RequestContext,
Expand Down Expand Up @@ -388,6 +393,7 @@ impl ProjectGitHubAnchorAuthorityV1 {
)
}

#[hotpath::measure(label = "usecases.advisory.github.load_anchor", future = true)]
async fn load(&self, anchor_id: &RetrievalAnchorId) -> Option<Option<StoredGitHubAnchorV1>> {
let key = anchor_key(anchor_id);
match self.database.get_metadata(&key).await.ok()? {
Expand All @@ -396,6 +402,7 @@ impl ProjectGitHubAnchorAuthorityV1 {
}
}

#[hotpath::measure(label = "usecases.advisory.github.persist_anchor", future = true)]
async fn persist(
&self,
candidate: &StoredGitHubAnchorV1,
Expand Down Expand Up @@ -475,6 +482,7 @@ impl ProjectGitHubAnchorAuthorityV1 {
transaction.commit().await.is_ok()
}

#[hotpath::measure(label = "usecases.advisory.github.persist_body", future = true)]
async fn persist_body(&self, body: &StoredGitHubReviewBodyV1) -> bool {
let key = body_key(&body.body_anchor);
let Ok(encoded) = serde_json::to_string(body) else {
Expand Down Expand Up @@ -525,8 +533,9 @@ impl ProjectGitHubAnchorAuthorityV1 {
where
A: GitHubSourceAccessAuthorityV1 + Sync + ?Sized,
{
Box::pin(async move {
if request.validate().is_err()
Box::pin(hotpath::future!(
async move {
if request.validate().is_err()
|| request.scope != self.scope
|| !context_matches_scope(context, &self.scope)
|| body_anchor.validate().is_err()
Expand Down Expand Up @@ -591,7 +600,9 @@ impl ProjectGitHubAnchorAuthorityV1 {
sanitization_receipt,
retained_body: body.retained_body,
}))
})
},
label = "usecases.advisory.github.read_body"
))
}
}

Expand Down
13 changes: 10 additions & 3 deletions crates/tracedecay-usecases/src/advisory/github_runtime/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ impl ProjectGitHubReviewStoreV1 {
Ok(Some((Box::new(state), encoded_bytes)))
}

#[hotpath::measure(label = "usecases.advisory.github.load_state", future = true)]
async fn load_state(
&self,
request: &GitHubReviewReadRequestV1,
Expand Down Expand Up @@ -217,6 +218,7 @@ impl ProjectGitHubReviewStoreV1 {
/// Loads the bounded exact-scope inventory and verifies every referenced
/// point record. A partial or corrupt inventory is never reported as an
/// empty or complete source.
#[hotpath::measure(label = "usecases.advisory.github.load_manifest", future = true)]
pub async fn load_manifest(
&self,
context: &RequestContext,
Expand Down Expand Up @@ -246,6 +248,7 @@ impl ProjectGitHubReviewStoreV1 {
/// Loads only the bounded, structurally validated exact-scope inventory.
/// Point records remain caller-budgeted and are loaded separately through
/// [`Self::load_bounded_entry`].
#[hotpath::measure(label = "usecases.advisory.github.load_inventory", future = true)]
pub async fn load_inventory_manifest(
&self,
context: &RequestContext,
Expand Down Expand Up @@ -303,6 +306,7 @@ impl ProjectGitHubReviewStoreV1 {
/// Loads one inventory-bound point without decoding bytes beyond the
/// caller's remaining budget. `None` covers absent, malformed, oversized,
/// revision-mismatched, or no-longer-authorized records.
#[hotpath::measure(label = "usecases.advisory.github.load_entry", future = true)]
pub async fn load_bounded_entry(
&self,
context: &RequestContext,
Expand Down Expand Up @@ -410,8 +414,9 @@ impl GitHubReviewAtomicRefreshStoreV1 for ProjectGitHubReviewStoreV1 {
expected_revision: Option<&'a ManifestDigest>,
next: &'a GitHubReviewRefreshStateV1,
) -> FeedbackPortFuture<'a, GitHubReviewRefreshStoreCommitOutcomeV1> {
Box::pin(async move {
if !next.validate_for(request)
Box::pin(hotpath::future!(
async move {
if !next.validate_for(request)
|| !context_allows_feedback_operation(
context,
&self.scope,
Expand Down Expand Up @@ -546,7 +551,9 @@ impl GitHubReviewAtomicRefreshStoreV1 for ProjectGitHubReviewStoreV1 {
return GitHubReviewRefreshStoreCommitOutcomeV1::Unavailable;
}
GitHubReviewRefreshStoreCommitOutcomeV1::Recorded
})
},
label = "usecases.advisory.github.record_refresh"
))
}
}

Expand Down
6 changes: 6 additions & 0 deletions crates/tracedecay-usecases/src/diagnostics_publication.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ impl CleanGenerationDiagnosticSnapshotBuilderV1 {
/// Every field of canonical identity comes from the scope or the
/// contribution; the message digest is recomputed so the record validates
/// against its own sanitized text.
#[hotpath::measure(label = "usecases.diagnostics.contribute")]
pub fn contribute(
&mut self,
pillar: DiagnosticPillarV1,
Expand Down Expand Up @@ -426,6 +427,7 @@ impl CleanGenerationDiagnosticSnapshotBuilderV1 {
/// Republishing an identical snapshot converges (the store treats it as a
/// no-op), so a repeated production cycle over an unchanged generation is
/// safe.
#[hotpath::measure(label = "usecases.diagnostics.publish_snapshot", future = true)]
pub async fn publish(&self, store: &DiagnosticsStore<'_>) -> Result<(u64, u64)> {
store
.publish_clean_generation(&self.scope.generation_id, &self.records())
Expand Down Expand Up @@ -651,6 +653,7 @@ impl std::fmt::Display for CompilerDiagnosticResolutionSkipV1 {
///
/// The span runs from the reported column to the end of the reported line —
/// the honest extent of what `cargo` reports without re-parsing the source.
#[hotpath::measure(label = "usecases.diagnostics.resolve_compiler", future = true)]
pub async fn resolve_compiler_diagnostics_v1(
project_root: &Path,
identity: &CodeIndexPublicationIdentityV1,
Expand Down Expand Up @@ -710,6 +713,7 @@ pub async fn resolve_compiler_diagnostics_v1(
}

/// Reads one repository-relative file, refusing paths that escape the root.
#[hotpath::measure(label = "usecases.diagnostics.load_project_file", future = true)]
async fn load_project_file(project_root: &Path, relative: &str) -> Option<(ContentDigest, String)> {
let path = Path::new(relative);
if path.is_absolute()
Expand Down Expand Up @@ -759,6 +763,7 @@ fn line_column_span(text: &str, line: u32, column: u32) -> Option<SourceSpan> {
///
/// Contributions that cannot form a valid record are reported, never silently
/// dropped.
#[hotpath::measure(label = "usecases.diagnostics.publish_compiler", future = true)]
pub async fn publish_compiler_diagnostics_v1(
store: &DiagnosticsStore<'_>,
scope: CleanGenerationDiagnosticScopeV1,
Expand Down Expand Up @@ -831,6 +836,7 @@ pub enum CompilerDiagnosticPublicationOutcomeV1 {
/// generation. Both identities the LSP feedback projection compares —
/// `file_occurrence_id` and `generation_id` — therefore come from the same mint
/// as the saved-edit cycle's impact target.
#[hotpath::measure(label = "usecases.diagnostics.publish_compiler_indexed", future = true)]
pub async fn publish_compiler_diagnostics_through_code_index_v1(
project_root: &Path,
resolver: Option<&dyn CodeIndexPublicationIdentityPortV1>,
Expand Down
6 changes: 6 additions & 0 deletions crates/tracedecay-usecases/src/diagnostics_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ impl<'a> DiagnosticsStore<'a> {
/// Runs `work` inside an immediate transaction, committing on success and
/// rolling back on error or cancellation. The transactional store routes
/// every statement through that exact transaction.
#[hotpath::measure(label = "usecases.diagnostics_store.immediate_tx", future = true)]
async fn with_immediate_tx<T>(
&self,
operation: &str,
Expand Down Expand Up @@ -919,6 +920,7 @@ impl<'a> DiagnosticsStore<'a> {
})
}

#[hotpath::measure(label = "usecases.diagnostics_store.insert_record", future = true)]
async fn insert_record(&self, record: &GenerationDiagnosticV1) -> Result<()> {
let operation = "diagnostics insert_record";
let (state, state_generation) = state_columns(&record.state);
Expand Down Expand Up @@ -984,6 +986,7 @@ impl<'a> DiagnosticsStore<'a> {
Ok(())
}

#[hotpath::measure(label = "usecases.diagnostics_store.publication_state", future = true)]
async fn generation_publication_state(
&self,
generation: &CodeGenerationId,
Expand All @@ -1006,6 +1009,7 @@ impl<'a> DiagnosticsStore<'a> {
.transpose()
}

#[hotpath::measure(label = "usecases.diagnostics_store.query_generation", future = true)]
async fn query_generation(
&self,
generation: &CodeGenerationId,
Expand Down Expand Up @@ -1036,6 +1040,7 @@ impl<'a> DiagnosticsStore<'a> {
collect_rows(&mut rows, operation).await
}

#[hotpath::measure(label = "usecases.diagnostics_store.find_successor", future = true)]
async fn find_logical_successor(
&self,
prior: &GenerationDiagnosticV1,
Expand Down Expand Up @@ -1346,6 +1351,7 @@ const SELECT_RECORDS: &str = "SELECT diagnostic_anchor, generation_id, repositor
collected_at, record_state, state_generation
FROM generation_diagnostics";

#[hotpath::measure(label = "usecases.diagnostics_store.collect_rows", future = true)]
async fn collect_rows(rows: &mut Rows, operation: &str) -> Result<Vec<GenerationDiagnosticV1>> {
let mut records = Vec::new();
while let Some(row) = rows.next().await.map_err(|e| db_error(operation, e))? {
Expand Down
Loading
Loading