diff --git a/crates/tracedecay-usecases/src/advisory/ci_runtime/stores.rs b/crates/tracedecay-usecases/src/advisory/ci_runtime/stores.rs index 6b0b865716..84ffd9427c 100644 --- a/crates/tracedecay-usecases/src/advisory/ci_runtime/stores.rs +++ b/crates/tracedecay-usecases/src/advisory/ci_runtime/stores.rs @@ -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, @@ -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, @@ -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, @@ -407,19 +410,22 @@ impl CiRetainedProviderObservationAuthorityV1 for ProjectCiRetainedObservationSt context: &'a RequestContext, request: &'a CiFailureLocalizationRequestV1, ) -> FeedbackPortFuture<'a, Option> { - 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>( @@ -430,8 +436,9 @@ impl CiRetainedProviderObservationAuthorityV1 for ProjectCiRetainedObservationSt state: CiFailureLocalizationStateV1, coverage: CiFailureCoverageV1, ) -> FeedbackPortFuture<'a, Option> { - 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, @@ -551,7 +558,9 @@ impl CiRetainedProviderObservationAuthorityV1 for ProjectCiRetainedObservationSt return None; } Some(observation) - }) + }, + label = "usecases.advisory.ci.retain_observation" + )) } } @@ -601,8 +610,9 @@ impl CiCodeAnchorStoreV1 for ProjectCiCodeAnchorStoreV1 { request: &'a CiFailureLocalizationRequestV1, record: &'a CiRetainedProviderRecordV1, ) -> FeedbackPortFuture<'a, Option> { - 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, @@ -796,7 +806,9 @@ impl CiCodeAnchorStoreV1 for ProjectCiCodeAnchorStoreV1 { callers, tests, }) - }) + }, + label = "usecases.advisory.ci.resolve_code_anchor" + )) } } diff --git a/crates/tracedecay-usecases/src/advisory/github_runtime/anchors.rs b/crates/tracedecay-usecases/src/advisory/github_runtime/anchors.rs index 439faed60b..b5a81caf7d 100644 --- a/crates/tracedecay-usecases/src/advisory/github_runtime/anchors.rs +++ b/crates/tracedecay-usecases/src/advisory/github_runtime/anchors.rs @@ -184,6 +184,7 @@ impl ProjectGitHubAnchorAuthorityV1 { self } + #[hotpath::measure(label = "usecases.advisory.github.resolve_seeds", future = true)] async fn resolve_seeds( &self, request: &GitHubReviewReadRequestV1, @@ -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, @@ -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, @@ -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, @@ -326,6 +330,7 @@ impl ProjectGitHubAnchorAuthorityV1 { .await } + #[hotpath::measure(label = "usecases.advisory.github.remap_seed", future = true)] async fn remap_seed( &self, context: &RequestContext, @@ -388,6 +393,7 @@ impl ProjectGitHubAnchorAuthorityV1 { ) } + #[hotpath::measure(label = "usecases.advisory.github.load_anchor", future = true)] async fn load(&self, anchor_id: &RetrievalAnchorId) -> Option> { let key = anchor_key(anchor_id); match self.database.get_metadata(&key).await.ok()? { @@ -396,6 +402,7 @@ impl ProjectGitHubAnchorAuthorityV1 { } } + #[hotpath::measure(label = "usecases.advisory.github.persist_anchor", future = true)] async fn persist( &self, candidate: &StoredGitHubAnchorV1, @@ -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 { @@ -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() @@ -591,7 +600,9 @@ impl ProjectGitHubAnchorAuthorityV1 { sanitization_receipt, retained_body: body.retained_body, })) - }) + }, + label = "usecases.advisory.github.read_body" + )) } } diff --git a/crates/tracedecay-usecases/src/advisory/github_runtime/store.rs b/crates/tracedecay-usecases/src/advisory/github_runtime/store.rs index de78e64acd..ed0c72fa5f 100644 --- a/crates/tracedecay-usecases/src/advisory/github_runtime/store.rs +++ b/crates/tracedecay-usecases/src/advisory/github_runtime/store.rs @@ -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, @@ -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, @@ -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, @@ -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, @@ -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, @@ -546,7 +551,9 @@ impl GitHubReviewAtomicRefreshStoreV1 for ProjectGitHubReviewStoreV1 { return GitHubReviewRefreshStoreCommitOutcomeV1::Unavailable; } GitHubReviewRefreshStoreCommitOutcomeV1::Recorded - }) + }, + label = "usecases.advisory.github.record_refresh" + )) } } diff --git a/crates/tracedecay-usecases/src/diagnostics_publication.rs b/crates/tracedecay-usecases/src/diagnostics_publication.rs index 97c4a9018e..d9d67d5fbd 100644 --- a/crates/tracedecay-usecases/src/diagnostics_publication.rs +++ b/crates/tracedecay-usecases/src/diagnostics_publication.rs @@ -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, @@ -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()) @@ -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, @@ -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() @@ -759,6 +763,7 @@ fn line_column_span(text: &str, line: u32, column: u32) -> Option { /// /// 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, @@ -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>, diff --git a/crates/tracedecay-usecases/src/diagnostics_store.rs b/crates/tracedecay-usecases/src/diagnostics_store.rs index 131c47a558..93971deefa 100644 --- a/crates/tracedecay-usecases/src/diagnostics_store.rs +++ b/crates/tracedecay-usecases/src/diagnostics_store.rs @@ -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( &self, operation: &str, @@ -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); @@ -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, @@ -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, @@ -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, @@ -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> { let mut records = Vec::new(); while let Some(row) = rows.next().await.map_err(|e| db_error(operation, e))? { diff --git a/crates/tracedecay-usecases/src/feedback/concrete.rs b/crates/tracedecay-usecases/src/feedback/concrete.rs index 8f9065f5bd..f1e335ceb3 100644 --- a/crates/tracedecay-usecases/src/feedback/concrete.rs +++ b/crates/tracedecay-usecases/src/feedback/concrete.rs @@ -262,6 +262,7 @@ impl ProjectFeedbackObservationSinkV1 { }) } + #[hotpath::measure(label = "usecases.feedback.close_drain", future = true)] async fn close_and_drain(&self) -> Result<(), FeedbackRuntimeError> { let terminal = { let _admission = self @@ -921,8 +922,9 @@ impl DurableFeedbackReadStoreV1 for ProjectFeedbackStore { context: &'a FeedbackReadPortContext<'a>, request: &'a FeedbackDiagnosticsReadRequestV1, ) -> FeedbackReadPortFuture<'a, FeedbackDiagnosticsReadResultV1> { - Box::pin(async move { - let domains = vec![ + Box::pin(hotpath::future!( + async move { + let domains = vec![ EvidenceDomain::Diagnostic, EvidenceDomain::Graph, EvidenceDomain::Test, @@ -957,7 +959,9 @@ impl DurableFeedbackReadStoreV1 for ProjectFeedbackStore { None, finished_at, ) - }) + }, + label = "usecases.feedback.read_diagnostics" + )) } fn get<'a>( @@ -965,8 +969,9 @@ impl DurableFeedbackReadStoreV1 for ProjectFeedbackStore { context: &'a FeedbackReadPortContext<'a>, request: &'a FeedbackGetRequestV1, ) -> FeedbackReadPortFuture<'a, FeedbackGetResultV1> { - Box::pin(async move { - let domains = vec![EvidenceDomain::Diagnostic]; + Box::pin(hotpath::future!( + async move { + let domains = vec![EvidenceDomain::Diagnostic]; if let Some(interrupted) = interruption(context.request, now_micros(), domains.clone()) { return interrupted; @@ -994,7 +999,9 @@ impl DurableFeedbackReadStoreV1 for ProjectFeedbackStore { None, finished_at, ) - }) + }, + label = "usecases.feedback.read_get" + )) } fn expand<'a>( @@ -1002,9 +1009,10 @@ impl DurableFeedbackReadStoreV1 for ProjectFeedbackStore { context: &'a FeedbackReadPortContext<'a>, request: &'a FeedbackExpandRequestV1, ) -> FeedbackReadPortFuture<'a, FeedbackExpandResultV1> { - Box::pin(async move { - let domains = vec![EvidenceDomain::Anchor]; - let started_at = now_micros(); + Box::pin(hotpath::future!( + async move { + let domains = vec![EvidenceDomain::Anchor]; + let started_at = now_micros(); if let Some(interrupted) = interruption(context.request, started_at, domains.clone()) { self.observe_expansion( context.request, @@ -1116,7 +1124,9 @@ impl DurableFeedbackReadStoreV1 for ProjectFeedbackStore { None, finished_at, ) - }) + }, + label = "usecases.feedback.read_expand" + )) } fn list<'a>( @@ -1124,8 +1134,9 @@ impl DurableFeedbackReadStoreV1 for ProjectFeedbackStore { context: &'a FeedbackReadPortContext<'a>, request: &'a FeedbackListRequestV1, ) -> FeedbackReadPortFuture<'a, FeedbackListResultV1> { - Box::pin(async move { - let domains = vec![EvidenceDomain::Diagnostic]; + Box::pin(hotpath::future!( + async move { + let domains = vec![EvidenceDomain::Diagnostic]; if let Some(interrupted) = interruption(context.request, now_micros(), domains.clone()) { return interrupted; @@ -1204,7 +1215,9 @@ impl DurableFeedbackReadStoreV1 for ProjectFeedbackStore { expires_at, finished_at, ) - }) + }, + label = "usecases.feedback.read_list" + )) } } @@ -1245,6 +1258,7 @@ impl ProjectFeedbackStore { ); } + #[hotpath::measure(label = "usecases.feedback.load_publications", future = true)] async fn load_publications( &self, ) -> Result, FeedbackRuntimeError> { @@ -1276,6 +1290,7 @@ impl ProjectFeedbackStore { /// Latest validated durable publication visible in the exact admitted /// project/repository/worktree/ref scope. Doctor consumes this mounted read /// store; it does not scan provider-local state or mutable paths. + #[hotpath::measure(label = "usecases.feedback.doctor_latest", future = true)] pub async fn doctor_latest_publication( &self, context: &RequestContext, @@ -1293,6 +1308,7 @@ impl ProjectFeedbackStore { Ok(publication) } + #[hotpath::measure(label = "usecases.feedback.record_publication", future = true)] async fn record_publication( &self, publication: FeedbackCompletedPublicationV1, @@ -1482,6 +1498,7 @@ impl ProjectFeedbackStore { /// Read the canonical durable Plan-26 observation projection from an already /// admitted project database. Doctor uses this same projection rather than /// deriving a second telemetry model. +#[hotpath::measure(label = "usecases.feedback.observation_read_model", future = true)] pub async fn feedback_observation_read_model( database: &Database, ) -> Result { @@ -1609,6 +1626,7 @@ fn interruption_outcome(context: &RequestContext, observed_at: UtcMicros) -> Fee } } +#[hotpath::measure(label = "usecases.feedback.persist_observation", future = true)] async fn persist_feedback_observation( database: &Database, envelope: FeedbackObservationEnvelopeV1, @@ -1690,6 +1708,7 @@ async fn persist_feedback_observation( .map_err(|_| FeedbackRuntimeError::Store) } +#[hotpath::measure(label = "usecases.feedback.persist_boot", future = true)] async fn persist_feedback_producer_boot( database: &Database, boot_id: ManifestDigest, @@ -1736,6 +1755,7 @@ async fn persist_feedback_producer_boot( .map_err(|_| FeedbackRuntimeError::Store) } +#[hotpath::measure(label = "usecases.feedback.load_ledger", future = true)] async fn load_observation_ledger( transaction: &DatabaseWriteTransaction<'_>, ) -> Result { diff --git a/crates/tracedecay-usecases/src/observability/emit.rs b/crates/tracedecay-usecases/src/observability/emit.rs index 7ee8405e97..83bb44d142 100644 --- a/crates/tracedecay-usecases/src/observability/emit.rs +++ b/crates/tracedecay-usecases/src/observability/emit.rs @@ -525,6 +525,7 @@ fn index_envelope( /// Records one completed retrieval query through the project-bound observation /// authority. `answered == false` is retained as an abstention, never as a /// failed or absent query. +#[hotpath::measure(label = "usecases.observability.record_query", future = true)] pub async fn record_retrieval_query( db: &RegisteredGlobalDb, observation: RetrievalQueryObservedV1, @@ -538,6 +539,7 @@ pub async fn record_retrieval_query( /// Records one adoption-eligibility census. `coverage` is required because only /// the caller knows whether it enumerated the whole eligible population; an /// incomplete census must not reach the rollup as `Known`. +#[hotpath::measure(label = "usecases.observability.record_adoption_eligibility", future = true)] pub async fn record_adoption_eligibility( db: &RegisteredGlobalDb, coverage: CoverageStateV1, @@ -553,6 +555,7 @@ pub async fn record_adoption_eligibility( /// Records one linked adoption-outcome funnel. Unresolved outcomes weaken both /// the terminal result and coverage in addition to being carried as explicit /// `censored` / `unknown` denominators. +#[hotpath::measure(label = "usecases.observability.record_adoption_outcome", future = true)] pub async fn record_adoption_outcome( db: &RegisteredGlobalDb, census_coverage: CoverageStateV1, @@ -566,6 +569,7 @@ pub async fn record_adoption_outcome( } /// Records one per-stage latency observation at an operation boundary. +#[hotpath::measure(label = "usecases.observability.record_latency", future = true)] pub async fn record_latency( db: &RegisteredGlobalDb, observation: LatencyObservedV1, @@ -579,6 +583,7 @@ pub async fn record_latency( /// Records one per-operation resource receipt. `terminal_result` is `None` when /// the operation's terminal state is genuinely unknown; the rollup projects that /// as an unknown rather than a completion. +#[hotpath::measure(label = "usecases.observability.record_operation_resource", future = true)] pub async fn record_operation_resource( db: &RegisteredGlobalDb, coverage: CoverageStateV1, @@ -598,6 +603,7 @@ pub async fn record_operation_resource( } /// Records one storage size, budget, or latency observation. +#[hotpath::measure(label = "usecases.observability.record_storage", future = true)] pub async fn record_storage( db: &RegisteredGlobalDb, observation: StorageObservedV1, @@ -609,6 +615,7 @@ pub async fn record_storage( } /// Records one code-index generation lifecycle observation. +#[hotpath::measure(label = "usecases.observability.record_index", future = true)] pub async fn record_index( db: &RegisteredGlobalDb, observation: IndexObservedV1, @@ -621,6 +628,7 @@ pub async fn record_index( /// Offers one code-index generation lifecycle observation to the mounted /// bounded producer without waiting for project-store persistence. +#[hotpath::measure(label = "usecases.observability.emit_index")] pub fn emit_index( producer: &BoundedObservabilityProducerV1, observation: IndexObservedV1, diff --git a/crates/tracedecay-usecases/src/observability/producer.rs b/crates/tracedecay-usecases/src/observability/producer.rs index 9e6cacd76b..f73068de1e 100644 --- a/crates/tracedecay-usecases/src/observability/producer.rs +++ b/crates/tracedecay-usecases/src/observability/producer.rs @@ -337,6 +337,7 @@ impl BoundedObservabilityProducerV1 { prepare_delivery_with_identity(&self.identity, envelope, sequence, delayed) } + #[hotpath::measure(label = "usecases.observability.try_emit")] pub fn try_emit( &self, envelope: ObservabilityEnvelopeV1, @@ -429,6 +430,7 @@ impl BoundedObservabilityProducerV1 { impl ObservabilityProducerCoreV1 { /// Shutdown lives only on the core: any frontend may drive it, and the /// lifecycle compare-and-swap admits exactly one drain. + #[hotpath::measure(label = "usecases.observability.producer_stop", future = true)] async fn stop( &self, cancelled: bool, @@ -867,6 +869,7 @@ fn push_drop_range(ranges: &mut Vec, range: DropRange) { ranges.push(range); } +#[hotpath::measure(label = "usecases.observability.persist_queued", future = true)] async fn record_queued( db: &RegisteredGlobalDb, durable_emission_lock: &AsyncMutex<()>, @@ -959,6 +962,7 @@ fn payload_safe_label(value: &str, max_bytes: usize) -> bool { .all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b'.' | b':' | b'-' | b'_')) } +#[hotpath::measure(label = "usecases.observability.persist_envelope", future = true)] async fn record( db: &RegisteredGlobalDb, envelope: ObservabilityEnvelopeV1, diff --git a/crates/tracedecay-usecases/src/observability/retrieval_emit.rs b/crates/tracedecay-usecases/src/observability/retrieval_emit.rs index b5d6a8922d..61daf98dad 100644 --- a/crates/tracedecay-usecases/src/observability/retrieval_emit.rs +++ b/crates/tracedecay-usecases/src/observability/retrieval_emit.rs @@ -397,6 +397,7 @@ pub struct RetrievalEmissionSummaryV1 { /// accounted, never awaited. An envelope this lane cannot even build (a /// payload the domain validator rejects) is counted as `invalid` and skipped /// rather than substituted with a permissive one. +#[hotpath::measure(label = "usecases.observability.emit_pipeline")] pub fn emit_retrieval_pipeline( producer: &BoundedObservabilityProducerV1, identity: &ObservabilityProducerIdentityV1, @@ -460,6 +461,7 @@ pub fn emit_retrieval_pipeline( /// Records one planner admission decision through the project-bound /// observation authority. +#[hotpath::measure(label = "usecases.observability.record_planner", future = true)] pub async fn record_retrieval_planner( db: &RegisteredGlobalDb, observation: ObservedWithCoverageV1, @@ -482,6 +484,7 @@ pub async fn record_retrieval_planner( } /// Records one lane's candidate accounting. +#[hotpath::measure(label = "usecases.observability.record_retriever", future = true)] pub async fn record_retriever( db: &RegisteredGlobalDb, observation: ObservedWithCoverageV1, @@ -504,6 +507,7 @@ pub async fn record_retriever( } /// Records one fusion-synthesis result. +#[hotpath::measure(label = "usecases.observability.record_synthesis", future = true)] pub async fn record_retrieval_synthesis( db: &RegisteredGlobalDb, observation: ObservedWithCoverageV1, @@ -526,6 +530,7 @@ pub async fn record_retrieval_synthesis( } /// Records one cataloged source's census for a query. +#[hotpath::measure(label = "usecases.observability.record_source", future = true)] pub async fn record_retrieval_source( db: &RegisteredGlobalDb, observation: ObservedWithCoverageV1, @@ -548,6 +553,7 @@ pub async fn record_retrieval_source( } /// Records one context packet's observed linkage to a downstream outcome. +#[hotpath::measure(label = "usecases.observability.record_context_outcome", future = true)] pub async fn record_context_outcome( db: &RegisteredGlobalDb, observation: ObservedWithCoverageV1, @@ -570,6 +576,7 @@ pub async fn record_context_outcome( } /// Records one frozen baseline-versus-candidate retrieval ablation. +#[hotpath::measure(label = "usecases.observability.record_ablation", future = true)] pub async fn record_retrieval_ablation( db: &RegisteredGlobalDb, observation: RetrievalAblationObservedV1, @@ -596,6 +603,7 @@ pub async fn record_retrieval_ablation( /// `Ok(None)` means there was no transition to record: re-asserting the mode /// already in force is a configuration no-op, and minting a consent receipt for /// it would overstate how often consent actually changed. +#[hotpath::measure(label = "usecases.observability.record_consent", future = true)] pub async fn record_analytics_consent( db: &RegisteredGlobalDb, previous: AnalyticsModeV1, @@ -655,6 +663,7 @@ impl AblationDimensionV1 { /// projection reports the value it can and drops coverage to /// [`CoverageStateV1::Unknown`] so the rollup will not publish a point value /// derived from an empty denominator. +#[hotpath::measure(label = "usecases.observability.observe_ablation")] pub fn observe_stage_ablation( descriptor_revision: &str, dimension: AblationDimensionV1, diff --git a/crates/tracedecay-usecases/src/operation_stream.rs b/crates/tracedecay-usecases/src/operation_stream.rs index 21584f2223..246128d085 100644 --- a/crates/tracedecay-usecases/src/operation_stream.rs +++ b/crates/tracedecay-usecases/src/operation_stream.rs @@ -420,6 +420,7 @@ impl CanonicalManagedTestRunReader { Self { events } } + #[hotpath::measure(label = "usecases.operation.read_test_run", future = true)] pub(crate) async fn latest_current( &self, current: &ManagedTestRunCurrentScope, @@ -460,6 +461,7 @@ impl CanonicalManagedTestRunReader { Some(current_managed_test_run(snapshot, current)) } + #[hotpath::measure(label = "usecases.operation.page_test_run", future = true)] pub(crate) async fn latest_current_page( &self, current: &ManagedTestRunCurrentScope, @@ -735,6 +737,7 @@ impl OperationEventAuthority { .await } + #[hotpath::measure(label = "usecases.operation.resolve_context", future = true)] async fn resolve_invocation_context_inner( &self, operation_id: &OperationId, @@ -806,6 +809,7 @@ impl OperationEventAuthority { } /// Registers an admitted operation and publishes its sole accepted event. + #[hotpath::measure(label = "usecases.operation.begin", future = true)] pub async fn begin( &self, context: &RequestContext, @@ -889,6 +893,7 @@ impl OperationEventAuthority { /// Starts one trusted project-local managed test run. The caller is the /// already-routed project workflow handler, so the retained authorization /// key is the canonical admitted root URI rather than client payload. + #[hotpath::measure(label = "usecases.operation.begin_test_run", future = true)] pub async fn begin_managed_test_run( &self, root_uri: String, @@ -1033,6 +1038,7 @@ impl OperationEventAuthority { } /// Requests cancellation for one exact trusted project-local test run. + #[hotpath::measure(label = "usecases.operation.cancel_test_run", future = true)] pub(crate) async fn cancel_managed_test_run( &self, operation_id: &OperationId, @@ -1068,6 +1074,7 @@ impl OperationEventAuthority { /// Replays retained events from `requested_next_sequence`, then follows /// the same bounded Tokio broadcast stream used by live producers. + #[hotpath::measure(label = "usecases.operation.subscribe", future = true)] pub async fn subscribe( &self, operation_id: &OperationId, @@ -1148,6 +1155,7 @@ impl OperationEventAuthority { /// Requests cancellation after revalidating actor, scope, grant, and /// disclosure. Subscription disconnects never call this method. + #[hotpath::measure(label = "usecases.operation.cancel", future = true)] pub async fn cancel( &self, operation_id: &OperationId, @@ -1176,12 +1184,14 @@ impl OperationEventAuthority { /// Drops all memory-retained frontiers. Existing streams close; reconnects /// receive `FrontierExpired` rather than a fabricated snapshot. + #[hotpath::measure(label = "usecases.operation.expire_all", future = true)] pub async fn expire_all(&self) { let mut state = self.inner.state.lock().await; state.operations.clear(); state.insertion_order.clear(); } + #[hotpath::measure(label = "usecases.operation.emit_progress", future = true)] async fn emit_progress( &self, operation_id: &OperationId, @@ -1211,6 +1221,7 @@ impl OperationEventAuthority { Ok(event) } + #[hotpath::measure(label = "usecases.operation.emit_test_result", future = true)] async fn emit_test_result( &self, operation_id: &OperationId, @@ -1247,6 +1258,7 @@ impl OperationEventAuthority { Ok(event) } + #[hotpath::measure(label = "usecases.operation.emit_terminal", future = true)] async fn emit_terminal( &self, operation_id: &OperationId, diff --git a/crates/tracedecay-usecases/src/semantic_runtime/config_store.rs b/crates/tracedecay-usecases/src/semantic_runtime/config_store.rs index abd187c6fd..ce522f1960 100644 --- a/crates/tracedecay-usecases/src/semantic_runtime/config_store.rs +++ b/crates/tracedecay-usecases/src/semantic_runtime/config_store.rs @@ -53,6 +53,7 @@ impl ProductionSemanticRetrievalConfigurationStoreV1 { &self.scope } + #[hotpath::measure(label = "usecases.semantic_config.install_initial", future = true)] pub async fn install_initial_state( &self, configuration: &SemanticConfigurationPinV1, @@ -107,6 +108,7 @@ impl ProductionSemanticRetrievalConfigurationStoreV1 { .map_err(|_| SemanticConfigurationBackendErrorV1::Unavailable) } + #[hotpath::measure(label = "usecases.semantic_config.read_committed", future = true)] pub async fn current_committed_state( &self, ) -> Result, SemanticConfigurationBackendErrorV1> { @@ -141,6 +143,7 @@ impl ProductionSemanticRetrievalConfigurationStoreV1 { })) } + #[hotpath::measure(label = "usecases.semantic_config.read_present", future = true)] pub async fn current_state_if_present( &self, ) -> Result, SemanticConfigurationBackendErrorV1> { @@ -154,6 +157,7 @@ impl ProductionSemanticRetrievalConfigurationStoreV1 { .map(|stored| stored.state)) } + #[hotpath::measure(label = "usecases.semantic_config.read_profile", future = true)] pub async fn current_profile_state( &self, ) -> Result { @@ -164,6 +168,7 @@ impl ProductionSemanticRetrievalConfigurationStoreV1 { .map_err(|_| SemanticConfigurationBackendErrorV1::Rejected) } + #[hotpath::measure(label = "usecases.semantic_config.preview_mutation", future = true)] pub(crate) async fn preview_central_mutation( &self, authority: &ConfigurationMutationAuthority, @@ -236,6 +241,7 @@ impl ProductionSemanticRetrievalConfigurationStoreV1 { } #[allow(clippy::too_many_arguments)] + #[hotpath::measure(label = "usecases.semantic_config.stage_activation", future = true)] pub async fn stage_activation( &self, base_configuration: SemanticConfigurationPinV1, @@ -299,6 +305,7 @@ impl ProductionSemanticRetrievalConfigurationStoreV1 { } #[allow(clippy::too_many_arguments)] + #[hotpath::measure(label = "usecases.semantic_config.stage_rollback", future = true)] pub async fn stage_rollback( &self, base_configuration: SemanticConfigurationPinV1, @@ -372,6 +379,7 @@ impl ProductionSemanticRetrievalConfigurationStoreV1 { .ok_or(SemanticConfigurationBackendErrorV1::Unavailable) } + #[hotpath::measure(label = "usecases.semantic_config.persist_pending", future = true)] async fn persist_pending( &self, base_epoch: i64, @@ -451,6 +459,7 @@ impl ProductionSemanticRetrievalConfigurationStoreV1 { } } + #[hotpath::measure(label = "usecases.semantic_config.read_committed_profile", future = true)] pub async fn current_committed_profile_state( &self, configuration: &SemanticConfigurationPinV1, diff --git a/crates/tracedecay-usecases/src/semantic_runtime/configuration_operation.rs b/crates/tracedecay-usecases/src/semantic_runtime/configuration_operation.rs index 63a5ae2371..6fe3a6d556 100644 --- a/crates/tracedecay-usecases/src/semantic_runtime/configuration_operation.rs +++ b/crates/tracedecay-usecases/src/semantic_runtime/configuration_operation.rs @@ -236,6 +236,7 @@ impl SemanticEvaluationAuthorityPublicationV1 { self.accepted_profile.compatibility().semantic.as_ref() } + #[hotpath::measure(label = "usecases.semantic_config.commit_publication", future = true)] pub async fn commit( self, expected: &SemanticEvaluationPublicationSnapshotV1, @@ -334,6 +335,7 @@ impl ProductionSemanticConfigurationOperationV1 { /// Validate and run the genuine checked-in direct evaluator without a /// publication capability. The returned qualification binds the opaque /// evaluator output to an unchanged mounted snapshot. + #[hotpath::measure(label = "usecases.semantic_config.qualify_profile", future = true)] pub async fn qualify_profile( snapshot_authority: &dyn SemanticEvaluationSnapshotPortV1, repo_root: &Path, @@ -377,6 +379,7 @@ impl ProductionSemanticConfigurationOperationV1 { /// Publish only evidence from the reviewed native-qualification package. /// Genuine evaluation is intentionally exclusive to [`Self::qualify_profile`]. + #[hotpath::measure(label = "usecases.semantic_config.evaluate_publish", future = true)] pub async fn evaluate_and_publish_profile( &self, snapshot_authority: &dyn SemanticEvaluationPublicationSnapshotPortV1, @@ -415,6 +418,7 @@ impl ProductionSemanticConfigurationOperationV1 { }) } + #[hotpath::measure(label = "usecases.semantic_config.activate", future = true)] pub async fn activate( &self, request: SemanticProtectedActivationOperationV1, @@ -548,6 +552,7 @@ impl ProductionSemanticConfigurationOperationV1 { }) } + #[hotpath::measure(label = "usecases.semantic_config.rollback", future = true)] pub async fn rollback( &self, request: SemanticProtectedRollbackOperationV1, @@ -722,6 +727,7 @@ fn map_packaged_qualification_error( } } +#[hotpath::measure(label = "usecases.semantic_config.prepare_activation")] fn prepare_semantic_activation_publication( snapshot: &SemanticEvaluationPublicationSnapshotV1, candidate: &SemanticEvaluationProfileCandidateV1, @@ -1153,6 +1159,7 @@ fn candidate_matches_evaluated_material( } } +#[hotpath::measure(label = "usecases.semantic_config.validate_snapshot")] fn validate_evaluation_snapshot( repo_root: &Path, snapshot: &SemanticEvaluationPublicationSnapshotV1, @@ -1257,6 +1264,7 @@ pub struct SemanticAppliedRollbackV1 { pub configuration_receipt: ConfigurationMutationReceipt, } +#[hotpath::measure(label = "usecases.semantic_config.read_state", future = true)] async fn current_configuration_state( runtime: &ProjectConfigurationRuntime, ) -> Result { diff --git a/crates/tracedecay-usecases/src/semantic_runtime/production.rs b/crates/tracedecay-usecases/src/semantic_runtime/production.rs index 68ec3257e8..7edc0efb74 100644 --- a/crates/tracedecay-usecases/src/semantic_runtime/production.rs +++ b/crates/tracedecay-usecases/src/semantic_runtime/production.rs @@ -428,6 +428,7 @@ impl ProductionSemanticRuntimeV1 { } /// Restore a compatible immutable generation after daemon restart. + #[hotpath::measure(label = "usecases.semantic.restore_current", future = true)] pub async fn restore_current( &self, generation: &CodeIndexPublishedGenerationV1, @@ -442,6 +443,7 @@ impl ProductionSemanticRuntimeV1 { Ok(prepared.commit()) } + #[hotpath::measure(label = "usecases.semantic.prepare_restore", future = true)] pub async fn prepare_restore_current( &self, generation: &CodeIndexPublishedGenerationV1, @@ -1435,6 +1437,7 @@ impl ProductionSemanticRuntimeV1 { /// Recheck the opaque pre-acceptance lifecycle observation immediately /// before publication. A changed vector/code/lifecycle target is a CAS /// conflict, while a malformed or foreign lease remains rejected. + #[hotpath::measure(label = "usecases.semantic.revalidate_target", future = true)] pub async fn revalidate_verified_evaluation_target( &self, verification: &SemanticEvaluationLifecycleVerificationV1, @@ -1544,6 +1547,7 @@ impl ProductionSemanticRuntimeV1 { /// Inspect only immutable vector/source identity before native evaluation. /// Resource evidence does not exist yet and is therefore not fabricated /// from the evaluator's configured ceilings. + #[hotpath::measure(label = "usecases.semantic.inspect_eval_snapshot", future = true)] pub async fn inspect_evaluation_current_generation_snapshot( &self, required: &crate::config::retrieval::SemanticCompatibilityPinsV1, @@ -1626,6 +1630,7 @@ impl ProductionSemanticRuntimeV1 { /// /// The installed runtime pointer is a cache observation only and cannot /// substitute another graph generation. + #[hotpath::measure(label = "usecases.semantic.active_generation", future = true)] pub async fn active_vector_generation( &self, pins: &crate::config::retrieval::SemanticCompatibilityPinsV1, @@ -2102,6 +2107,7 @@ impl ProductionSemanticRuntimeV1 { /// Real application consumer for the optional semantic lane. The exact /// configuration-pinned generation is loaded before composition; indexing/download never /// enters this request path. + #[hotpath::measure(label = "usecases.semantic.execute_search", future = true)] pub async fn execute_search( &self, code_generation: &CodeIndexPublishedGenerationV1, diff --git a/crates/tracedecay-usecases/src/store/vector_generations.rs b/crates/tracedecay-usecases/src/store/vector_generations.rs index 33edeb9f56..edfc60eab5 100644 --- a/crates/tracedecay-usecases/src/store/vector_generations.rs +++ b/crates/tracedecay-usecases/src/store/vector_generations.rs @@ -229,6 +229,7 @@ impl PhysicalVectorBytePoolV1 { /// Release every entry whose generation has been retired. Interning is /// unaffected: a swept key is re-interned on its next use. + #[hotpath::measure(label = "usecases.vector.sweep_retired")] pub fn sweep_retired(&self) -> Result<(), VectorGenerationStoreErrorV1> { self.lock()?.sweep(); Ok(()) @@ -1277,6 +1278,7 @@ impl VectorGenerationStateMachineV1 { } } + #[hotpath::measure(label = "usecases.vector.begin_generation")] pub fn begin_generation( &mut self, plan: VectorGenerationPlanV1, @@ -1326,6 +1328,7 @@ impl VectorGenerationStateMachineV1 { /// Discard any checkpointed execution for the same deterministic build /// identity and restart projection from its authoritative query inputs. /// Already-published generations are untouched. + #[hotpath::measure(label = "usecases.vector.rebuild_generation")] pub fn rebuild_generation( &mut self, plan: VectorGenerationPlanV1, @@ -1376,6 +1379,7 @@ impl VectorGenerationStateMachineV1 { /// Borrowing form of [`Self::commit_batch`]. The persistent adapter drives /// this one so a whole-corpus batch is never copied just to satisfy a /// retryable mutation closure. + #[hotpath::measure(label = "usecases.vector.commit_batch")] pub(crate) fn commit_batch_ref( &mut self, build_id: &VectorGenerationBuildIdV1, @@ -1393,6 +1397,7 @@ impl VectorGenerationStateMachineV1 { /// freshness, receipt verification, per-row validation against the /// admitted embedding key, base-generation lineage — happens here, while /// the batch's float payloads are still in hand. + #[hotpath::measure(label = "usecases.vector.validate_batch")] pub fn validate_batch( &self, build_id: &VectorGenerationBuildIdV1, @@ -1592,6 +1597,7 @@ impl VectorGenerationStateMachineV1 { /// that disappeared between decision and application and a census that /// contradicts the decision — both are foreign-mutation corruption, never /// a property of the batch itself. + #[hotpath::measure(label = "usecases.vector.apply_batch")] pub fn apply_batch( &mut self, build_id: &VectorGenerationBuildIdV1, @@ -1645,6 +1651,7 @@ impl VectorGenerationStateMachineV1 { /// after every batch) allocates nothing, a rejected publication leaves the /// machine byte-identical, and an accepted one moves the staged rows into /// the published generation instead of deep-copying the corpus. + #[hotpath::measure(label = "usecases.vector.publish_generation")] pub fn publish_generation( &mut self, build_id: &VectorGenerationBuildIdV1, @@ -1794,6 +1801,7 @@ impl VectorGenerationStateMachineV1 { /// vector bytes are persisted beside the document because the row map /// elides them, so the payload index is (re)derived here — publication /// itself never copies floats into the pool. + #[hotpath::measure(label = "usecases.vector.persist_sealed")] pub fn persist_sealed(&mut self) -> Result, VectorGenerationStoreErrorV1> { if self.staged_values == StagedVectorValueRetentionV1::Elided { return Err(VectorGenerationStoreErrorV1::Storage( @@ -1812,6 +1820,7 @@ impl VectorGenerationStateMachineV1 { } /// Reload a document persisted by [`Self::persist_sealed`]. + #[hotpath::measure(label = "usecases.vector.reopen_sealed")] pub fn reopen_sealed(bytes: &[u8]) -> Result { let persisted: PersistedSealedStateV1 = serde_json::from_slice(bytes).map_err(storage_error)?; @@ -1897,6 +1906,7 @@ fn physical_vector_reuse_key( Ok((physical_id, reuse_key)) } +#[hotpath::measure(label = "usecases.vector.intern_vectors")] fn intern_generation_vectors( physical_vector_pool: &PhysicalVectorBytePoolV1, published: &mut PublishedStateV1, @@ -2149,6 +2159,7 @@ struct PersistedSealedStateV1 { physical_vectors: BTreeMap, } +#[hotpath::measure(label = "usecases.vector.hydrate_values")] fn hydrate_elided_vector_values( state: &mut VectorGenerationStateMachineV1, ) -> Result<(), VectorGenerationStoreErrorV1> {