@saptools/service-flow 0.1.53 → 0.1.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13,6 +13,16 @@ function projectBounded(values, compare, limit = DEFAULT_EVIDENCE_CANDIDATE_LIMI
13
13
  items
14
14
  };
15
15
  }
16
+ function projectBoundedInOrder(values, limit = DEFAULT_EVIDENCE_CANDIDATE_LIMIT) {
17
+ const normalizedLimit = positiveLimit(limit);
18
+ const items = values.slice(0, normalizedLimit);
19
+ return {
20
+ totalCount: values.length,
21
+ shownCount: items.length,
22
+ omittedCount: Math.max(0, values.length - items.length),
23
+ items
24
+ };
25
+ }
16
26
  function positiveLimit(value) {
17
27
  return Number.isFinite(value) && Number(value) > 0 ? Math.floor(Number(value)) : DEFAULT_EVIDENCE_CANDIDATE_LIMIT;
18
28
  }
@@ -51,7 +61,7 @@ function boundCandidateLikeEvidence(evidence, limit = DEFAULT_EVIDENCE_CANDIDATE
51
61
  output[key] = boundNestedEvidence(value, limit);
52
62
  continue;
53
63
  }
54
- const projection = projectBounded(value, compareEvidenceValue, limit);
64
+ const projection = projectBoundedInOrder(value, limit);
55
65
  output[key] = projection.items.map((item) => boundNestedEvidence(item, limit));
56
66
  addCollectionCounts(output, evidence, key, projection);
57
67
  }
@@ -106,17 +116,6 @@ function collectionStem(key) {
106
116
  };
107
117
  return stems[key] ?? "candidate";
108
118
  }
109
- function compareEvidenceValue(left, right) {
110
- return stableProjectionValue(left).localeCompare(stableProjectionValue(right));
111
- }
112
- function stableProjectionValue(value) {
113
- if (Array.isArray(value))
114
- return `[${value.map(stableProjectionValue).join(",")}]`;
115
- if (isEvidenceRecord(value)) {
116
- return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${stableProjectionValue(value[key])}`).join(",")}}`;
117
- }
118
- return JSON.stringify(value) ?? "";
119
- }
120
119
  function numericValue(value) {
121
120
  return typeof value === "number" && Number.isFinite(value) ? value : 0;
122
121
  }
@@ -3931,9 +3930,41 @@ function buildRemoteQueryTarget(input) {
3931
3930
  }
3932
3931
 
3933
3932
  // src/linker/001-implementation-evidence-projection.ts
3933
+ function selectedHandlerProvenance(source) {
3934
+ return {
3935
+ status: "selected",
3936
+ accepted: true,
3937
+ graphTargetId: String(source.methodId),
3938
+ methodId: source.methodId,
3939
+ className: source.className,
3940
+ methodName: source.methodName,
3941
+ repository: {
3942
+ id: source.repositoryId,
3943
+ name: source.repositoryName,
3944
+ packageName: source.repositoryPackageName
3945
+ },
3946
+ sourceFile: source.sourceFile,
3947
+ sourceLine: source.sourceLine
3948
+ };
3949
+ }
3950
+ function displayImplementationCandidates(candidates2, selectedMethodId) {
3951
+ return [...candidates2].sort((left, right) => compareDisplayCandidate(
3952
+ left,
3953
+ right,
3954
+ selectedMethodId
3955
+ )).map((candidate, index) => ({
3956
+ ...candidate,
3957
+ discoveryRank: candidate.rank,
3958
+ displayRank: index + 1,
3959
+ selected: selectedMethodId !== void 0 && Number(candidate.methodId) === selectedMethodId
3960
+ }));
3961
+ }
3962
+ function compareDisplayCandidate(left, right, selectedMethodId) {
3963
+ return Number(Number(right.methodId) === selectedMethodId) - Number(Number(left.methodId) === selectedMethodId) || Number(right.accepted === true) - Number(left.accepted === true) || numberValue(left.rank) - numberValue(right.rank) || compareTargetCandidates(left, right);
3964
+ }
3934
3965
  function boundedImplementationEvidence(evidence, targetCandidateCount) {
3935
3966
  const candidates2 = recordArray(evidence.candidates);
3936
- const candidateProjection = projectBounded(candidates2, compareCandidateEvidence);
3967
+ const candidateProjection = projectBoundedInOrder(candidates2);
3937
3968
  const families = recordArray(evidence.candidateFamilies);
3938
3969
  const familyProjection = projectBounded(families, compareFamilies);
3939
3970
  const hints = recordArray(evidence.implementationHintSuggestions);
@@ -3996,9 +4027,6 @@ function boundedFamilyEvidence(family) {
3996
4027
  function compareTargetCandidates(left, right) {
3997
4028
  return Number(right.score ?? 0) - Number(left.score ?? 0) || String(left.className ?? "").localeCompare(String(right.className ?? "")) || Number(left.methodId ?? 0) - Number(right.methodId ?? 0);
3998
4029
  }
3999
- function compareCandidateEvidence(left, right) {
4000
- return Number(left.rank ?? 0) - Number(right.rank ?? 0) || compareTargetCandidates(left, right);
4001
- }
4002
4030
  function compareFamilies(left, right) {
4003
4031
  return String(left.packageName ?? "").localeCompare(String(right.packageName ?? "")) || String(left.reason ?? "").localeCompare(String(right.reason ?? ""));
4004
4032
  }
@@ -4082,7 +4110,8 @@ function implementationDecision(db, workspaceId, operation, recordDiagnostics) {
4082
4110
  implementationContext,
4083
4111
  candidates2,
4084
4112
  duplicateFamilies,
4085
- ambiguityReasons
4113
+ ambiguityReasons,
4114
+ unique3
4086
4115
  );
4087
4116
  const hintProjection = implementationHintSuggestionProjection(evidence);
4088
4117
  return {
@@ -4126,7 +4155,7 @@ function insertImplementationEdge(db, workspaceId, generation, operation, decisi
4126
4155
  generation
4127
4156
  );
4128
4157
  }
4129
- function implementationEvidence(operation, context, candidates2, duplicateFamilies, ambiguityReasons) {
4158
+ function implementationEvidence(operation, context, candidates2, duplicateFamilies, ambiguityReasons, selected) {
4130
4159
  return {
4131
4160
  servicePath: operation.servicePath,
4132
4161
  operationPath: operation.operationPath,
@@ -4141,7 +4170,11 @@ function implementationEvidence(operation, context, candidates2, duplicateFamili
4141
4170
  implementationOperationId: context.operationId,
4142
4171
  ambiguityReasons,
4143
4172
  candidateFamilies: duplicateFamilies,
4144
- candidates: candidates2.map((candidate, index) => candidateEvidence(candidate, index + 1))
4173
+ selectedHandler: selected ? selectedHandlerProvenance(selectedHandlerSource(selected)) : void 0,
4174
+ candidates: displayImplementationCandidates(
4175
+ candidates2.map((candidate, index) => candidateEvidence(candidate, index + 1)),
4176
+ selected?.methodId
4177
+ )
4145
4178
  };
4146
4179
  }
4147
4180
  function implementationContextForOperation(db, operation) {
@@ -4271,7 +4304,7 @@ function implementationCandidates(db, workspaceId, operation) {
4271
4304
  hm.id methodId,hm.method_name methodName,hm.decorator_value decoratorValue,
4272
4305
  hm.decorator_raw_expression decoratorRawExpression,
4273
4306
  hm.decorator_resolution_json decoratorResolutionJson,hc.id classId,
4274
- hc.class_name className,hc.source_file sourceFile,hc.source_line sourceLine,
4307
+ hc.class_name className,hc.source_file sourceFile,hm.source_line sourceLine,
4275
4308
  hr.id registrationId,hr.handler_class_id registrationHandlerClassId,
4276
4309
  hr.class_name registrationClassName,hr.repo_id applicationRepoId,
4277
4310
  hr.registration_file registrationFile,hr.registration_line registrationLine,
@@ -4440,6 +4473,7 @@ function ownershipScore(signals, acceptedReasons) {
4440
4473
  function candidateEvidence(candidate, rank) {
4441
4474
  return {
4442
4475
  rank,
4476
+ rankKind: "discovery_score",
4443
4477
  score: candidate.score,
4444
4478
  accepted: candidate.accepted,
4445
4479
  acceptedReasons: candidate.acceptedReasons,
@@ -4492,6 +4526,18 @@ function candidateEvidence(candidate, rank) {
4492
4526
  }
4493
4527
  };
4494
4528
  }
4529
+ function selectedHandlerSource(candidate) {
4530
+ return {
4531
+ methodId: candidate.methodId,
4532
+ className: stringValue4(candidate.className),
4533
+ methodName: stringValue4(candidate.methodName),
4534
+ repositoryId: numberValue2(candidate.handlerRepoId),
4535
+ repositoryName: stringValue4(candidate.handlerRepo),
4536
+ repositoryPackageName: stringValue4(candidate.handlerPackage),
4537
+ sourceFile: stringValue4(candidate.sourceFile),
4538
+ sourceLine: numberValue2(candidate.sourceLine)
4539
+ };
4540
+ }
4495
4541
  function implementationMethodSignal(row, operation) {
4496
4542
  const resolution = objectJson(row.decoratorResolutionJson) ?? {};
4497
4543
  if (resolution.handlerKind && resolution.handlerKind !== "operation")
@@ -6550,9 +6596,198 @@ function isConcrete(value) {
6550
6596
  return typeof value === "string" && value.length > 0 && extractPlaceholders(value).length === 0;
6551
6597
  }
6552
6598
 
6599
+ // src/trace/006-contextual-projection.ts
6600
+ function boundedContextCandidates(values) {
6601
+ const candidates2 = values.flatMap((value) => {
6602
+ return isRecord5(value) ? [value] : [];
6603
+ });
6604
+ const projection = projectBounded(candidates2, (left, right) => Number(right.score ?? 0) - Number(left.score ?? 0) || String(left.repoName ?? "").localeCompare(String(right.repoName ?? "")) || String(left.servicePath ?? "").localeCompare(String(right.servicePath ?? "")) || String(left.sourceFile ?? "").localeCompare(String(right.sourceFile ?? "")) || Number(left.sourceLine ?? 0) - Number(right.sourceLine ?? 0) || Number(left.bindingId ?? left.operationId ?? 0) - Number(right.bindingId ?? right.operationId ?? 0));
6605
+ return {
6606
+ candidates: projection.items,
6607
+ candidateCount: projection.totalCount,
6608
+ shownCandidateCount: projection.shownCount,
6609
+ omittedCandidateCount: projection.omittedCount
6610
+ };
6611
+ }
6612
+ function isRecord5(value) {
6613
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
6614
+ }
6615
+
6616
+ // src/trace/008-contextual-runtime-state.ts
6617
+ function dynamicMissingReason(keys) {
6618
+ const missing = normalizedKeys(keys);
6619
+ return missing.length > 0 ? `Dynamic target is missing runtime variables: ${missing.join(", ")}` : "Dynamic target still requires runtime variables";
6620
+ }
6621
+ function isStructuralContextualBlocker(state) {
6622
+ return state?.category === "ambiguous_binding" || state?.category === "ambiguous_operation" || state?.category === "no_matching_operation" || state?.category === "other_blocker";
6623
+ }
6624
+ function contextualRuntimeResolution(db, call, binding, workspaceId, persistedRows = []) {
6625
+ if (!binding || call.call_type !== "remote_action" || call.operation_path_expr === void 0 || call.operation_path_expr === null)
6626
+ return { state: { category: "none" } };
6627
+ if (binding.resolutionStatus === "ambiguous")
6628
+ return ambiguousBindingResolution(binding);
6629
+ return selectedBindingResolution(db, call, binding, workspaceId, persistedRows);
6630
+ }
6631
+ function ambiguousBindingResolution(binding) {
6632
+ const candidates2 = boundedContextCandidates(binding.bindingCandidates ?? []);
6633
+ const state = {
6634
+ category: "ambiguous_binding",
6635
+ message: "Ambiguous contextual service binding candidates",
6636
+ resolutionStatus: "ambiguous"
6637
+ };
6638
+ return {
6639
+ evidence: {
6640
+ contextualServiceBindingAttempted: true,
6641
+ contextualBinding: {
6642
+ source: binding.source,
6643
+ status: "tied",
6644
+ candidates: candidates2.candidates,
6645
+ candidateCount: candidates2.candidateCount,
6646
+ shownCandidateCount: candidates2.shownCandidateCount,
6647
+ omittedCandidateCount: candidates2.omittedCandidateCount
6648
+ },
6649
+ contextualResolutionStatus: "ambiguous",
6650
+ contextualCandidateCount: candidates2.candidateCount,
6651
+ contextualPreSubstitutionState: historicalState(state)
6652
+ },
6653
+ state
6654
+ };
6655
+ }
6656
+ function selectedBindingResolution(db, call, binding, workspaceId, persistedRows) {
6657
+ const normalized = normalizeODataOperationInvocationPath(
6658
+ String(call.operation_path_expr)
6659
+ );
6660
+ const operationPath = normalized?.normalizedOperationPath ?? withLeadingSlash(String(call.operation_path_expr));
6661
+ const servicePath = binding.effectiveServicePath ?? binding.servicePathExpr ?? binding.requireServicePath;
6662
+ const destination = binding.effectiveDestination ?? binding.destinationExpr ?? binding.requireDestination;
6663
+ const resolution = resolveOperation(db, {
6664
+ servicePath,
6665
+ operationPath,
6666
+ alias: binding.aliasExpr ?? binding.alias,
6667
+ destination,
6668
+ hasExplicitOverride: true,
6669
+ isDynamic: false
6670
+ }, workspaceId);
6671
+ const state = stateForResolution(resolution);
6672
+ const evidence = contextualEvidence(
6673
+ binding,
6674
+ normalized,
6675
+ operationPath,
6676
+ servicePath,
6677
+ destination,
6678
+ resolution,
6679
+ state
6680
+ );
6681
+ if (!resolution.target) return { evidence, state };
6682
+ const resolvedEvidence = {
6683
+ ...evidence,
6684
+ contextualServiceBindingSelected: true,
6685
+ targetRepo: resolution.target.repoName,
6686
+ targetServicePath: resolution.target.servicePath,
6687
+ targetOperationPath: resolution.target.operationPath,
6688
+ targetOperation: resolution.target.operationName
6689
+ };
6690
+ if (persistedRows.some((row) => row.status === "resolved"))
6691
+ return { evidence: { ...resolvedEvidence, contextualPreservedPersistedResolvedEdge: true }, state };
6692
+ return {
6693
+ row: {
6694
+ id: -call.id,
6695
+ edge_type: "REMOTE_CALL_RESOLVES_TO_OPERATION",
6696
+ from_id: String(call.id),
6697
+ to_kind: "operation",
6698
+ to_id: String(resolution.target.operationId),
6699
+ confidence: resolution.target.score,
6700
+ evidence_json: JSON.stringify(resolvedEvidence),
6701
+ status: "resolved"
6702
+ },
6703
+ evidence: resolvedEvidence,
6704
+ state
6705
+ };
6706
+ }
6707
+ function contextualEvidence(binding, normalized, operationPath, servicePath, destination, resolution, state) {
6708
+ const candidates2 = boundedContextCandidates(resolution.candidates);
6709
+ return {
6710
+ contextualServiceBindingAttempted: true,
6711
+ contextualBinding: bindingEvidence2(binding),
6712
+ operationPath,
6713
+ rawOperationPath: normalized?.rawOperationPath,
6714
+ normalizedOperationPath: normalized?.wasInvocation ? normalized.normalizedOperationPath : void 0,
6715
+ invocationArgumentPlaceholderKeys: normalized?.invocationArgumentPlaceholderKeys.length ? normalized.invocationArgumentPlaceholderKeys : void 0,
6716
+ servicePath,
6717
+ serviceAlias: binding.alias,
6718
+ serviceAliasExpr: binding.aliasExpr,
6719
+ destination,
6720
+ requireServicePath: binding.requireServicePath,
6721
+ requireDestination: binding.requireDestination,
6722
+ effectiveServicePath: binding.effectiveServicePath,
6723
+ effectiveDestination: binding.effectiveDestination,
6724
+ contextualResolutionStatus: resolution.status,
6725
+ contextualCandidateCount: candidates2.candidateCount,
6726
+ shownContextualCandidateCount: candidates2.shownCandidateCount,
6727
+ omittedContextualCandidateCount: candidates2.omittedCandidateCount,
6728
+ candidates: candidates2.candidates,
6729
+ contextualResolutionReasons: resolution.reasons,
6730
+ resolutionReasons: resolution.reasons,
6731
+ contextualPreSubstitutionState: historicalState(state)
6732
+ };
6733
+ }
6734
+ function bindingEvidence2(binding) {
6735
+ return {
6736
+ source: binding.source,
6737
+ callerArgument: binding.callerArgument,
6738
+ callerProperty: binding.callerProperty,
6739
+ calleeParameter: binding.calleeParameter,
6740
+ calleeReceiver: binding.calleeReceiver,
6741
+ callerSite: binding.callerSite,
6742
+ calleeSite: binding.calleeSite,
6743
+ bindingSourceFile: binding.sourceFile,
6744
+ bindingSourceLine: binding.sourceLine,
6745
+ alias: binding.alias,
6746
+ aliasExpr: binding.aliasExpr,
6747
+ requireServicePath: binding.requireServicePath,
6748
+ requireDestination: binding.requireDestination,
6749
+ effectiveServicePath: binding.effectiveServicePath,
6750
+ effectiveDestination: binding.effectiveDestination
6751
+ };
6752
+ }
6753
+ function stateForResolution(resolution) {
6754
+ if (resolution.status === "resolved") return { category: "none" };
6755
+ if (resolution.status === "dynamic") {
6756
+ const missingVariables = missingVariableKeys(resolution.reasons);
6757
+ return {
6758
+ category: "dynamic_missing",
6759
+ message: dynamicMissingReason(missingVariables),
6760
+ missingVariables,
6761
+ resolutionStatus: resolution.status
6762
+ };
6763
+ }
6764
+ if (resolution.status === "ambiguous") return {
6765
+ category: "ambiguous_operation",
6766
+ message: "Ambiguous contextual operation candidates",
6767
+ resolutionStatus: resolution.status
6768
+ };
6769
+ return {
6770
+ category: resolution.status === "unresolved" ? "no_matching_operation" : "other_blocker",
6771
+ message: resolution.status === "unresolved" ? "No contextual operation candidate matched" : "Contextual operation resolution is blocked",
6772
+ resolutionStatus: resolution.status
6773
+ };
6774
+ }
6775
+ function historicalState(state) {
6776
+ return { ...state, phase: "before_runtime_substitution" };
6777
+ }
6778
+ function missingVariableKeys(reasons) {
6779
+ return normalizedKeys(reasons.flatMap((reason) => reason.startsWith("missing_variable:") ? [reason.slice("missing_variable:".length)] : []));
6780
+ }
6781
+ function normalizedKeys(keys) {
6782
+ return [...new Set(keys.filter((key) => key.length > 0))].sort();
6783
+ }
6784
+ function withLeadingSlash(value) {
6785
+ return value.startsWith("/") ? value : `/${value}`;
6786
+ }
6787
+
6553
6788
  // src/trace/evidence.ts
6554
- function baseTraceEvidence(row, call, persistedEvidence, contextualEvidence) {
6555
- const evidence = { ...persistedEvidence, ...contextualEvidence ?? {} };
6789
+ function baseTraceEvidence(row, call, persistedEvidence, contextualEvidence2) {
6790
+ const evidence = { ...persistedEvidence, ...contextualEvidence2 ?? {} };
6556
6791
  return {
6557
6792
  ...evidence,
6558
6793
  graphEdgeId: row.id,
@@ -6566,11 +6801,11 @@ function baseTraceEvidence(row, call, persistedEvidence, contextualEvidence) {
6566
6801
  file: call.source_file,
6567
6802
  line: call.source_line,
6568
6803
  persistedTarget: { kind: row.to_kind, id: row.to_id },
6569
- contextualResolutionParticipated: Boolean(contextualEvidence?.contextualServiceBindingAttempted),
6804
+ contextualResolutionParticipated: Boolean(contextualEvidence2?.contextualServiceBindingAttempted),
6570
6805
  persistedResolution: persistedResolution(row)
6571
6806
  };
6572
6807
  }
6573
- function runtimeResolution(db, row, evidence, options, workspaceId, contextualUnresolvedReason) {
6808
+ function runtimeResolution(db, row, evidence, options, workspaceId, contextualState) {
6574
6809
  const dynamicMode = options.dynamicMode ?? "strict";
6575
6810
  const candidateCap = positiveCandidateCap(options.maxDynamicCandidates);
6576
6811
  const boundedEvidence = boundCandidateLikeEvidence(evidence, candidateCap);
@@ -6578,7 +6813,7 @@ function runtimeResolution(db, row, evidence, options, workspaceId, contextualUn
6578
6813
  return unchangedRuntimeResolution(
6579
6814
  row,
6580
6815
  boundDynamicEvidence(boundedEvidence, candidateCap),
6581
- contextualUnresolvedReason
6816
+ contextualState
6582
6817
  );
6583
6818
  const substituted = evidenceWithRuntimeVariables(boundedEvidence, options.vars);
6584
6819
  const analysis = analyzeDynamicTargetCandidates(
@@ -6592,50 +6827,98 @@ function runtimeResolution(db, row, evidence, options, workspaceId, contextualUn
6592
6827
  analysis ? evidenceWithDynamicAnalysis(substituted, analysis) : substituted,
6593
6828
  candidateCap
6594
6829
  );
6830
+ const appliedRuntimeValues = hasApplicableRuntimeVariables(evidence, options.vars);
6831
+ const analyzed = analyzedRuntimeResolution(
6832
+ row,
6833
+ enriched,
6834
+ analysis,
6835
+ dynamicMode,
6836
+ appliedRuntimeValues,
6837
+ contextualState
6838
+ );
6839
+ if (analyzed) return analyzed;
6840
+ if (!appliedRuntimeValues) {
6841
+ const unresolvedReason = contextualReason(contextualState) ?? row.unresolved_reason;
6842
+ const withSections = withEffectiveResolution(
6843
+ enriched,
6844
+ row,
6845
+ unresolvedReason,
6846
+ void 0,
6847
+ contextualState
6848
+ );
6849
+ return { row, evidence: withSections, unresolvedReason };
6850
+ }
6851
+ return resolveSuppliedRuntimeOperation(db, row, enriched, workspaceId, contextualState);
6852
+ }
6853
+ function analyzedRuntimeResolution(row, evidence, analysis, dynamicMode, appliedRuntimeValues, contextualState) {
6595
6854
  if (analysis && analysis.viableCandidateCount === 0 && Object.keys(analysis.appliedSuppliedVariables).length > 0)
6596
- return noCandidateRuntimeResolution(row, enriched);
6597
- if (dynamicMode === "infer") {
6598
- const inferred = inferredTarget(analysis);
6599
- if (inferred)
6600
- return resolvedRuntimeResolution(row, enriched, inferred, inferred.reasons);
6601
- }
6602
- if (analysis && analysis.missingVariables.length > 0) {
6603
- const unresolvedReason2 = contextualUnresolvedReason ?? row.unresolved_reason ?? "Dynamic target still requires runtime variables";
6855
+ return noCandidateRuntimeResolution(row, evidence, contextualState);
6856
+ const inferred = dynamicMode === "infer" ? inferredTarget(analysis) : void 0;
6857
+ if (inferred && !isStructuralContextualBlocker(contextualState))
6858
+ return resolvedRuntimeResolution(row, evidence, inferred, inferred.reasons);
6859
+ if (analysis && analysis.missingVariables.length > 0 && appliedRuntimeValues) {
6860
+ const unresolvedReason = dynamicMissingReason(analysis.missingVariables);
6604
6861
  return {
6605
6862
  row,
6606
- evidence: withEffectiveResolution(enriched, row, unresolvedReason2),
6607
- unresolvedReason: unresolvedReason2
6863
+ evidence: withEffectiveResolution(
6864
+ evidence,
6865
+ row,
6866
+ unresolvedReason,
6867
+ void 0,
6868
+ contextualState
6869
+ ),
6870
+ unresolvedReason
6608
6871
  };
6609
6872
  }
6610
- if (!hasApplicableRuntimeVariables(evidence, options.vars)) {
6611
- const unresolvedReason2 = contextualUnresolvedReason ?? row.unresolved_reason;
6612
- const withSections = withEffectiveResolution(enriched, row, unresolvedReason2);
6613
- return { row, evidence: withSections, unresolvedReason: unresolvedReason2 };
6614
- }
6615
- const resolution = resolveRuntimeOperation(db, enriched, workspaceId);
6873
+ return isStructuralContextualBlocker(contextualState) ? unchangedRuntimeResolution(row, evidence, contextualState) : void 0;
6874
+ }
6875
+ function resolveSuppliedRuntimeOperation(db, row, evidence, workspaceId, contextualState) {
6876
+ const resolution = resolveRuntimeOperation(db, evidence, workspaceId);
6616
6877
  if (resolution.target)
6617
6878
  return resolvedRuntimeResolution(
6618
6879
  row,
6619
- enriched,
6880
+ evidence,
6620
6881
  resolution.target,
6621
6882
  resolution.reasons
6622
6883
  );
6623
6884
  const unresolvedReason = runtimeUnresolvedReason(resolution);
6624
- return { row, evidence: withEffectiveResolution(enriched, row, unresolvedReason, resolution), unresolvedReason };
6885
+ return {
6886
+ row,
6887
+ evidence: withEffectiveResolution(
6888
+ evidence,
6889
+ row,
6890
+ unresolvedReason,
6891
+ resolution,
6892
+ contextualState
6893
+ ),
6894
+ unresolvedReason
6895
+ };
6625
6896
  }
6626
- function unchangedRuntimeResolution(row, evidence, contextualUnresolvedReason) {
6627
- const unresolvedReason = contextualUnresolvedReason ?? row.unresolved_reason;
6897
+ function unchangedRuntimeResolution(row, evidence, contextualState) {
6898
+ const unresolvedReason = contextualReason(contextualState) ?? row.unresolved_reason;
6628
6899
  return {
6629
6900
  row,
6630
- evidence: withEffectiveResolution(evidence, row, unresolvedReason),
6901
+ evidence: withEffectiveResolution(
6902
+ evidence,
6903
+ row,
6904
+ unresolvedReason,
6905
+ void 0,
6906
+ contextualState
6907
+ ),
6631
6908
  unresolvedReason
6632
6909
  };
6633
6910
  }
6634
- function noCandidateRuntimeResolution(row, evidence) {
6911
+ function noCandidateRuntimeResolution(row, evidence, contextualState) {
6635
6912
  const unresolvedReason = "No candidate remained after runtime substitution";
6636
6913
  return {
6637
6914
  row,
6638
- evidence: withEffectiveResolution(evidence, row, unresolvedReason),
6915
+ evidence: withEffectiveResolution(
6916
+ evidence,
6917
+ row,
6918
+ unresolvedReason,
6919
+ void 0,
6920
+ contextualState
6921
+ ),
6639
6922
  unresolvedReason
6640
6923
  };
6641
6924
  }
@@ -6804,7 +7087,7 @@ function persistedResolution(row) {
6804
7087
  edgeType: row.edge_type
6805
7088
  };
6806
7089
  }
6807
- function effectiveResolution(row, evidence, unresolvedReason, resolution) {
7090
+ function effectiveResolution(row, evidence, unresolvedReason, resolution, contextualState) {
6808
7091
  const target = resolution?.target;
6809
7092
  return {
6810
7093
  status: target ? "resolved" : row.status,
@@ -6817,14 +7100,34 @@ function effectiveResolution(row, evidence, unresolvedReason, resolution) {
6817
7100
  confidence: target?.score ?? row.confidence,
6818
7101
  reasons: resolution?.reasons ?? evidence.resolutionReasons,
6819
7102
  unresolvedReason,
6820
- edgeType: target ? "REMOTE_CALL_RESOLVES_TO_OPERATION" : row.edge_type
7103
+ edgeType: target ? "REMOTE_CALL_RESOLVES_TO_OPERATION" : row.edge_type,
7104
+ contextualBlocker: isStructuralContextualBlocker(contextualState) ? contextualState : void 0
6821
7105
  };
6822
7106
  }
6823
- function withEffectiveResolution(evidence, row, unresolvedReason, resolution) {
6824
- const current = effectiveResolution(row, evidence, unresolvedReason, resolution);
7107
+ function withEffectiveResolution(evidence, row, unresolvedReason, resolution, contextualState) {
7108
+ const current = effectiveResolution(
7109
+ row,
7110
+ evidence,
7111
+ unresolvedReason,
7112
+ resolution,
7113
+ contextualState
7114
+ );
6825
7115
  const rest = { ...evidence };
6826
7116
  delete rest.runtimeResolvedCandidate;
6827
- return { ...rest, effectiveResolution: current, linker: { status: current.status, confidence: current.confidence, reason: unresolvedReason, edgeType: current.edgeType } };
7117
+ return {
7118
+ ...rest,
7119
+ effectiveResolution: current,
7120
+ linker: {
7121
+ status: current.status,
7122
+ confidence: current.confidence,
7123
+ reason: unresolvedReason,
7124
+ edgeType: current.edgeType,
7125
+ contextualBlocker: current.contextualBlocker
7126
+ }
7127
+ };
7128
+ }
7129
+ function contextualReason(state) {
7130
+ return state?.category === "none" ? void 0 : state?.message;
6828
7131
  }
6829
7132
  function resolveRuntimeOperation(db, evidence, workspaceId) {
6830
7133
  const servicePath = stringValue10(evidence.servicePath);
@@ -7197,32 +7500,15 @@ function parsedEvidence(value) {
7197
7500
  }
7198
7501
  }
7199
7502
  function record4(value) {
7200
- return isRecord5(value) ? value : {};
7503
+ return isRecord6(value) ? value : {};
7201
7504
  }
7202
- function isRecord5(value) {
7505
+ function isRecord6(value) {
7203
7506
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
7204
7507
  }
7205
7508
  function numberValue8(value) {
7206
7509
  return typeof value === "number" && Number.isFinite(value) ? value : void 0;
7207
7510
  }
7208
7511
 
7209
- // src/trace/006-contextual-projection.ts
7210
- function boundedContextCandidates(values) {
7211
- const candidates2 = values.flatMap((value) => {
7212
- return isRecord6(value) ? [value] : [];
7213
- });
7214
- const projection = projectBounded(candidates2, (left, right) => Number(right.score ?? 0) - Number(left.score ?? 0) || String(left.repoName ?? "").localeCompare(String(right.repoName ?? "")) || String(left.servicePath ?? "").localeCompare(String(right.servicePath ?? "")) || String(left.sourceFile ?? "").localeCompare(String(right.sourceFile ?? "")) || Number(left.sourceLine ?? 0) - Number(right.sourceLine ?? 0) || Number(left.bindingId ?? left.operationId ?? 0) - Number(right.bindingId ?? right.operationId ?? 0));
7215
- return {
7216
- candidates: projection.items,
7217
- candidateCount: projection.totalCount,
7218
- shownCandidateCount: projection.shownCount,
7219
- omittedCandidateCount: projection.omittedCount
7220
- };
7221
- }
7222
- function isRecord6(value) {
7223
- return Boolean(value && typeof value === "object" && !Array.isArray(value));
7224
- }
7225
-
7226
7512
  // src/trace/007-implementation-start-diagnostic.ts
7227
7513
  function implementationStartDiagnostic(edge, evidence) {
7228
7514
  return {
@@ -7262,6 +7548,137 @@ function isRecord7(value) {
7262
7548
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
7263
7549
  }
7264
7550
 
7551
+ // src/trace/009-selected-handler-provenance.ts
7552
+ function handlerMethodNode(db, methodId) {
7553
+ const row = db.prepare(`SELECT hm.id methodId,hm.method_name methodName,
7554
+ hm.source_line sourceLine,hc.class_name className,hc.source_file sourceFile,
7555
+ r.name repoName,r.id repoId,r.package_name packageName
7556
+ FROM handler_methods hm JOIN handler_classes hc ON hc.id=hm.handler_class_id
7557
+ JOIN repositories r ON r.id=hc.repo_id WHERE hm.id=?`).get(methodId);
7558
+ return handlerNodeFromRow(row);
7559
+ }
7560
+ function withSelectedHandlerProvenance(evidence, targetId, handler) {
7561
+ if (!handler) return unavailableHandlerEvidence(evidence, targetId);
7562
+ const selected = selectedHandlerProvenance(handlerSource(handler));
7563
+ const stored = record5(evidence.selectedHandler);
7564
+ const mismatchedFields = storedSelectedHandlerMismatches(
7565
+ stored,
7566
+ selected,
7567
+ targetId
7568
+ );
7569
+ if (mismatchedFields.length === 0)
7570
+ return { handler, evidence: { ...evidence, selectedHandler: selected } };
7571
+ return {
7572
+ handler,
7573
+ evidence: {
7574
+ ...evidence,
7575
+ selectedHandler: selected,
7576
+ selectedHandlerProvenanceAudit: {
7577
+ status: "mismatch",
7578
+ graphTargetId: targetId,
7579
+ mismatchedFields,
7580
+ persistedSelectedHandler: stored
7581
+ }
7582
+ },
7583
+ diagnostic: {
7584
+ severity: "warning",
7585
+ code: "selected_handler_provenance_mismatch",
7586
+ message: "Persisted selected handler provenance did not match the resolved graph target",
7587
+ graphTargetId: targetId,
7588
+ mismatchedFields,
7589
+ sourceFile: handler.sourceFile,
7590
+ sourceLine: handler.sourceLine
7591
+ }
7592
+ };
7593
+ }
7594
+ function unavailableHandlerEvidence(evidence, targetId) {
7595
+ return {
7596
+ evidence: {
7597
+ ...evidence,
7598
+ selectedHandlerProvenanceAudit: {
7599
+ status: "unavailable",
7600
+ graphTargetId: targetId,
7601
+ reason: "handler_target_not_indexed"
7602
+ }
7603
+ },
7604
+ diagnostic: {
7605
+ severity: "warning",
7606
+ code: "selected_handler_target_not_found",
7607
+ message: "Resolved implementation target is not an indexed handler method",
7608
+ graphTargetId: targetId
7609
+ },
7610
+ unresolvedReason: "Resolved implementation target is not an indexed handler method"
7611
+ };
7612
+ }
7613
+ function handlerNodeFromRow(row) {
7614
+ const methodId = numberValue9(row?.methodId);
7615
+ const methodName2 = stringValue12(row?.methodName);
7616
+ const className = stringValue12(row?.className);
7617
+ const sourceFile = stringValue12(row?.sourceFile);
7618
+ const sourceLine2 = numberValue9(row?.sourceLine);
7619
+ const repoId = numberValue9(row?.repoId);
7620
+ const repoName = stringValue12(row?.repoName);
7621
+ if (methodId === void 0 || !methodName2 || !className || !sourceFile || sourceLine2 === void 0 || repoId === void 0 || !repoName)
7622
+ return void 0;
7623
+ return {
7624
+ id: `handler_method:${methodId}`,
7625
+ kind: "handler_method",
7626
+ label: `${repoName}:${className}.${methodName2}`,
7627
+ methodId,
7628
+ methodName: methodName2,
7629
+ className,
7630
+ sourceFile,
7631
+ sourceLine: sourceLine2,
7632
+ repoId,
7633
+ repoName,
7634
+ packageName: stringValue12(row?.packageName)
7635
+ };
7636
+ }
7637
+ function handlerSource(node) {
7638
+ return {
7639
+ methodId: node.methodId,
7640
+ methodName: node.methodName,
7641
+ className: node.className,
7642
+ repositoryId: node.repoId,
7643
+ repositoryName: node.repoName,
7644
+ repositoryPackageName: node.packageName,
7645
+ sourceFile: node.sourceFile,
7646
+ sourceLine: node.sourceLine
7647
+ };
7648
+ }
7649
+ function storedSelectedHandlerMismatches(stored, selected, targetId) {
7650
+ if (Object.keys(stored).length === 0) return [];
7651
+ const expectedRepository = record5(stored.repository);
7652
+ const selectedRepository = selected.repository ?? {};
7653
+ return [
7654
+ mismatch("graphTargetId", stored.graphTargetId, targetId),
7655
+ mismatch("methodId", stored.methodId, selected.methodId),
7656
+ mismatch("className", stored.className, selected.className),
7657
+ mismatch("methodName", stored.methodName, selected.methodName),
7658
+ mismatch("sourceFile", stored.sourceFile, selected.sourceFile),
7659
+ mismatch("sourceLine", stored.sourceLine, selected.sourceLine),
7660
+ mismatch("repository.id", expectedRepository.id, selectedRepository.id),
7661
+ mismatch("repository.name", expectedRepository.name, selectedRepository.name),
7662
+ mismatch(
7663
+ "repository.packageName",
7664
+ expectedRepository.packageName,
7665
+ selectedRepository.packageName
7666
+ )
7667
+ ].flatMap((field) => field ? [field] : []);
7668
+ }
7669
+ function mismatch(field, stored, actual) {
7670
+ return stored === void 0 || stored === actual ? void 0 : field;
7671
+ }
7672
+ function record5(value) {
7673
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
7674
+ }
7675
+ function stringValue12(value) {
7676
+ return typeof value === "string" ? value : void 0;
7677
+ }
7678
+ function numberValue9(value) {
7679
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
7680
+ }
7681
+
7265
7682
  // src/trace/trace-engine.ts
7266
7683
  function normalizeOperation2(value) {
7267
7684
  if (!value) return void 0;
@@ -7381,11 +7798,6 @@ function handlerFilesForOperation(db, operationId) {
7381
7798
  function implementationEdge(db, operationId) {
7382
7799
  return db.prepare("SELECT * FROM graph_edges WHERE edge_type='OPERATION_IMPLEMENTED_BY_HANDLER' AND from_kind='operation' AND from_id=? ORDER BY CASE status WHEN 'resolved' THEN 0 WHEN 'ambiguous' THEN 1 ELSE 2 END,id LIMIT 1").get(operationId);
7383
7800
  }
7384
- function handlerMethodNode(db, methodId) {
7385
- const row = db.prepare(`SELECT hm.id methodId,hm.method_name methodName,hm.decorator_value decoratorValue,hm.source_line sourceLine,hc.class_name className,hc.source_file sourceFile,r.name repoName,r.id repoId FROM handler_methods hm JOIN handler_classes hc ON hc.id=hm.handler_class_id JOIN repositories r ON r.id=hc.repo_id WHERE hm.id=?`).get(methodId);
7386
- if (!row) return void 0;
7387
- return { id: `handler_method:${methodId}`, kind: "handler_method", label: `${String(row.repoName)}:${String(row.className)}.${String(row.methodName)}`, ...row };
7388
- }
7389
7801
  function implementationScope(db, operationId) {
7390
7802
  const edge = implementationEdge(db, operationId);
7391
7803
  if (!edge || edge.status !== "resolved") return { files: /* @__PURE__ */ new Set(), edge };
@@ -7575,40 +7987,6 @@ function contextForSymbolCall(db, symbolCall, callerBindings) {
7575
7987
  });
7576
7988
  return next;
7577
7989
  }
7578
- function contextualRuntimeResolution(db, call, binding, workspaceId, persistedRows = []) {
7579
- if (!binding || String(call.call_type) !== "remote_action" || call.operation_path_expr === void 0 || call.operation_path_expr === null) return {};
7580
- if (binding.resolutionStatus === "ambiguous") {
7581
- const candidates3 = boundedContextCandidates(binding.bindingCandidates ?? []);
7582
- return {
7583
- evidence: {
7584
- contextualServiceBindingAttempted: true,
7585
- contextualBinding: {
7586
- source: binding.source,
7587
- status: "tied",
7588
- candidates: candidates3.candidates,
7589
- candidateCount: candidates3.candidateCount,
7590
- shownCandidateCount: candidates3.shownCandidateCount,
7591
- omittedCandidateCount: candidates3.omittedCandidateCount
7592
- },
7593
- contextualResolutionStatus: "ambiguous",
7594
- contextualCandidateCount: candidates3.candidateCount
7595
- },
7596
- unresolvedReason: "Ambiguous contextual service binding candidates"
7597
- };
7598
- }
7599
- const normalized = normalizeODataOperationInvocationPath(String(call.operation_path_expr));
7600
- const op = normalized?.normalizedOperationPath ?? (String(call.operation_path_expr).startsWith("/") ? String(call.operation_path_expr) : `/${String(call.operation_path_expr)}`);
7601
- const servicePath = binding.effectiveServicePath ?? binding.servicePathExpr ?? binding.requireServicePath;
7602
- const destination = binding.effectiveDestination ?? binding.destinationExpr ?? binding.requireDestination;
7603
- const resolution = resolveOperation(db, { servicePath, operationPath: op, alias: binding.aliasExpr ?? binding.alias, destination, hasExplicitOverride: true, isDynamic: false }, workspaceId);
7604
- const candidates2 = boundedContextCandidates(resolution.candidates);
7605
- const evidence = { contextualServiceBindingAttempted: true, contextualBinding: { source: binding.source, callerArgument: binding.callerArgument, callerProperty: binding.callerProperty, calleeParameter: binding.calleeParameter, calleeReceiver: binding.calleeReceiver, callerSite: binding.callerSite, calleeSite: binding.calleeSite, bindingSourceFile: binding.sourceFile, bindingSourceLine: binding.sourceLine, alias: binding.alias, aliasExpr: binding.aliasExpr, requireServicePath: binding.requireServicePath, requireDestination: binding.requireDestination, effectiveServicePath: binding.effectiveServicePath, effectiveDestination: binding.effectiveDestination }, operationPath: op, rawOperationPath: normalized?.rawOperationPath, normalizedOperationPath: normalized?.wasInvocation ? normalized.normalizedOperationPath : void 0, invocationArgumentPlaceholderKeys: normalized?.invocationArgumentPlaceholderKeys.length ? normalized.invocationArgumentPlaceholderKeys : void 0, servicePath, serviceAlias: binding.alias, serviceAliasExpr: binding.aliasExpr, destination, requireServicePath: binding.requireServicePath, requireDestination: binding.requireDestination, effectiveServicePath: binding.effectiveServicePath, effectiveDestination: binding.effectiveDestination, contextualResolutionStatus: resolution.status, contextualCandidateCount: candidates2.candidateCount, shownContextualCandidateCount: candidates2.shownCandidateCount, omittedContextualCandidateCount: candidates2.omittedCandidateCount, candidates: candidates2.candidates, contextualResolutionReasons: resolution.reasons, resolutionReasons: resolution.reasons };
7606
- if (!resolution.target) return { evidence, unresolvedReason: resolution.status === "ambiguous" ? "Ambiguous contextual operation candidates" : resolution.status === "dynamic" ? `Dynamic contextual target is missing runtime variables: ${resolution.reasons.join(", ")}` : "No contextual operation candidate matched" };
7607
- const resolvedEvidence = { ...evidence, contextualServiceBindingSelected: true, targetRepo: resolution.target.repoName, targetServicePath: resolution.target.servicePath, targetOperationPath: resolution.target.operationPath, targetOperation: resolution.target.operationName };
7608
- const persistedResolved = persistedRows.find((item) => item.status === "resolved");
7609
- if (persistedResolved) return { row: void 0, evidence: { ...resolvedEvidence, contextualPreservedPersistedResolvedEdge: true }, unresolvedReason: void 0 };
7610
- return { row: { id: -Number(call.id), edge_type: "REMOTE_CALL_RESOLVES_TO_OPERATION", from_id: String(call.id), to_kind: "operation", to_id: String(resolution.target.operationId), confidence: resolution.target.score, evidence_json: JSON.stringify(resolvedEvidence), status: "resolved" }, evidence: resolvedEvidence, unresolvedReason: void 0 };
7611
- }
7612
7990
  function trace(db, start, options) {
7613
7991
  const hintOptions = { implementationRepo: options.implementationRepo, implementationHints: options.implementationHints };
7614
7992
  const scope = startScope(db, start, hintOptions, options.workspaceId);
@@ -7644,11 +8022,26 @@ function trace(db, start, options) {
7644
8022
  );
7645
8023
  if (impl.edge && (impl.edge.status === "resolved" || startSelection.methodId)) {
7646
8024
  const selectedMethodId = impl.edge.status === "resolved" ? impl.edge.to_id : startSelection.methodId;
7647
- const implEvidence = { ...parseEvidence(impl.edge.evidence_json), startResolution: { strategy: "indexed_operation_graph", matchedOperationId: scope.startOperationId, implementationEdgeId: impl.edge.id, implementationStatus: impl.edge.status, selectedHandlerMethodId: selectedMethodId }, implementationSelection: startSelection.methodId ? startSelection.evidence : void 0 };
7648
- const handlerNode = selectedMethodId ? handlerMethodNode(db, selectedMethodId) : void 0;
7649
- if (handlerNode) nodes.set(String(handlerNode.id), handlerNode);
8025
+ const implEvidence = {
8026
+ ...parseEvidence(impl.edge.evidence_json),
8027
+ startResolution: {
8028
+ strategy: "indexed_operation_graph",
8029
+ matchedOperationId: scope.startOperationId,
8030
+ implementationEdgeId: impl.edge.id,
8031
+ implementationStatus: impl.edge.status,
8032
+ selectedHandlerMethodId: selectedMethodId
8033
+ },
8034
+ implementationSelection: startSelection.methodId ? startSelection.evidence : void 0
8035
+ };
8036
+ const selected = selectedMethodId ? withSelectedHandlerProvenance(
8037
+ implEvidence,
8038
+ selectedMethodId,
8039
+ handlerMethodNode(db, selectedMethodId)
8040
+ ) : { evidence: implEvidence };
8041
+ if (selected.diagnostic) prependTraceDiagnostic(diagnostics, selected.diagnostic);
8042
+ if (selected.handler) nodes.set(String(selected.handler.id), selected.handler);
7650
8043
  seenEdges.add(Number(impl.edge.id));
7651
- edges.push({ step: 1, type: "operation_implemented_by_handler", from: op?.label ? String(op.label) : `operation:${scope.startOperationId}`, to: handlerNode?.label ? String(handlerNode.label) : `${impl.edge.to_kind}:${impl.edge.to_id}`, evidence: implEvidence, confidence: Number(impl.edge.confidence ?? 0), unresolvedReason: impl.edge.status === "resolved" || startSelection.methodId ? void 0 : String(impl.edge.unresolved_reason ?? impl.edge.status) });
8044
+ edges.push({ step: 1, type: "operation_implemented_by_handler", from: op?.label ? String(op.label) : `operation:${scope.startOperationId}`, to: selected.handler?.label ? String(selected.handler.label) : `${impl.edge.to_kind}:${impl.edge.to_id}`, evidence: selected.evidence, confidence: Number(impl.edge.confidence ?? 0), unresolvedReason: selected.unresolvedReason ?? (impl.edge.status === "resolved" || startSelection.methodId ? void 0 : String(impl.edge.unresolved_reason ?? impl.edge.status)) });
7652
8045
  }
7653
8046
  }
7654
8047
  const seenScopes = /* @__PURE__ */ new Set();
@@ -7708,7 +8101,7 @@ function trace(db, start, options) {
7708
8101
  vars: options.vars,
7709
8102
  dynamicMode: options.dynamicMode ?? "strict",
7710
8103
  maxDynamicCandidates: options.maxDynamicCandidates
7711
- }, workspaceIdForCall(db, String(call.id)), contextual.unresolvedReason);
8104
+ }, workspaceIdForCall(db, String(call.id)), contextual.state);
7712
8105
  const evidence = effective.evidence;
7713
8106
  const effectiveRow = effective.row;
7714
8107
  const targetNode = `${effectiveRow.to_kind}:${effectiveRow.to_id}`;
@@ -7741,29 +8134,46 @@ function trace(db, start, options) {
7741
8134
  hintOptions
7742
8135
  );
7743
8136
  const contextMethodId = contextSelection.methodId;
7744
- const contextNode = contextMethodId ? handlerMethodNode(db, contextMethodId) : void 0;
8137
+ let selectedHandlerAvailable = true;
7745
8138
  if (implementation.edge) {
7746
8139
  const implEvidence = parseEvidence(implementation.edge.evidence_json);
7747
8140
  const hintDiagnostic = implementationHintDiagnostic(contextSelection, implEvidence);
7748
8141
  if (hintDiagnostic) prependTraceDiagnostic(diagnostics, hintDiagnostic);
7749
- const handlerNode = implementation.edge.status === "resolved" ? handlerMethodNode(db, implementation.edge.to_id) : contextNode;
7750
- const implTo = handlerNode?.label ? String(handlerNode.label) : `${implementation.edge.to_kind}:${implementation.edge.to_id}`;
7751
- if (handlerNode) nodes.set(String(handlerNode.id), handlerNode);
8142
+ const selectedMethodId = implementation.edge.status === "resolved" ? implementation.edge.to_id : contextMethodId;
8143
+ const selectionEvidence = contextMethodId ? {
8144
+ ...implEvidence,
8145
+ contextualImplementationSelected: contextSelection.evidence.strategy !== "implementation_repo_hint",
8146
+ contextualImplementation: contextSelection.evidence,
8147
+ implementationSelection: contextSelection.evidence
8148
+ } : {
8149
+ ...implEvidence,
8150
+ contextualImplementation: contextSelection.evidence,
8151
+ implementationSelection: contextSelection.evidence
8152
+ };
8153
+ const selected = selectedMethodId ? withSelectedHandlerProvenance(
8154
+ selectionEvidence,
8155
+ selectedMethodId,
8156
+ handlerMethodNode(db, selectedMethodId)
8157
+ ) : { evidence: selectionEvidence };
8158
+ selectedHandlerAvailable = !selected.unresolvedReason;
8159
+ if (selected.diagnostic) prependTraceDiagnostic(diagnostics, selected.diagnostic);
8160
+ const implTo = selected.handler?.label ? String(selected.handler.label) : `${implementation.edge.to_kind}:${implementation.edge.to_id}`;
8161
+ if (selected.handler) nodes.set(String(selected.handler.id), selected.handler);
7752
8162
  edges.push({
7753
8163
  step: current.depth,
7754
8164
  type: "operation_implemented_by_handler",
7755
8165
  from: to,
7756
8166
  to: implTo,
7757
- evidence: contextMethodId ? { ...implEvidence, contextualImplementationSelected: contextSelection.evidence.strategy !== "implementation_repo_hint", contextualImplementation: contextSelection.evidence, implementationSelection: contextSelection.evidence } : { ...implEvidence, contextualImplementation: contextSelection.evidence, implementationSelection: contextSelection.evidence },
8167
+ evidence: selected.evidence,
7758
8168
  confidence: Number(implementation.edge.confidence ?? 0),
7759
- unresolvedReason: implementation.edge.status === "resolved" || contextMethodId ? void 0 : String(implementation.edge.unresolved_reason ?? implementation.edge.status)
8169
+ unresolvedReason: selected.unresolvedReason ?? (implementation.edge.status === "resolved" || contextMethodId ? void 0 : String(implementation.edge.unresolved_reason ?? implementation.edge.status))
7760
8170
  });
7761
8171
  }
7762
8172
  if (current.depth >= maxDepth) continue;
7763
8173
  const contextScope = contextMethodId ? handlerScope(db, contextMethodId) : void 0;
7764
8174
  const files = contextScope?.files ?? (implementation.files.size > 0 ? implementation.files : handlerFilesForOperation(db, effectiveRow.to_id));
7765
8175
  const symbolIds = contextScope?.symbolId ? /* @__PURE__ */ new Set([contextScope.symbolId]) : implementation.symbolId ? /* @__PURE__ */ new Set([implementation.symbolId]) : void 0;
7766
- if ((implementation.edge?.status === "resolved" || contextScope) && files.size > 0) {
8176
+ if (selectedHandlerAvailable && (implementation.edge?.status === "resolved" || contextScope) && files.size > 0) {
7767
8177
  const targetRepoId = contextScope?.repoId ?? implementation.repoId ?? db.prepare(
7768
8178
  "SELECT s.repo_id repoId FROM cds_operations o JOIN cds_services s ON s.id=o.service_id WHERE o.id=?"
7769
8179
  ).get(effectiveRow.to_id)?.repoId;
@@ -7798,8 +8208,7 @@ function trace(db, start, options) {
7798
8208
  }
7799
8209
 
7800
8210
  export {
7801
- projectBounded,
7802
- stableProjectionValue,
8211
+ projectBoundedInOrder,
7803
8212
  upsertWorkspace,
7804
8213
  getWorkspace,
7805
8214
  upsertRepository,
@@ -7841,4 +8250,4 @@ export {
7841
8250
  selectorRepoAmbiguousDiagnostic,
7842
8251
  trace
7843
8252
  };
7844
- //# sourceMappingURL=chunk-LFH7C46B.js.map
8253
+ //# sourceMappingURL=chunk-ERIZHM5C.js.map