@shapeshift-labs/frontier-lang-compiler 0.2.65 → 0.2.67

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.
Files changed (67) hide show
  1. package/README.md +37 -8
  2. package/bench/smoke.mjs +15 -1
  3. package/bench/universal-fixture-suite.mjs +183 -0
  4. package/dist/declarations/import-adapter-core.d.ts +3 -0
  5. package/dist/declarations/native-project-admission.d.ts +133 -0
  6. package/dist/declarations/roundtrip-audit.d.ts +177 -0
  7. package/dist/declarations/roundtrip.d.ts +2 -53
  8. package/dist/declarations/semantic-history-records.d.ts +277 -0
  9. package/dist/declarations/semantic-history.d.ts +45 -92
  10. package/dist/declarations/semantic-merge-candidates.d.ts +200 -0
  11. package/dist/declarations/semantic-merge-conflicts.d.ts +12 -0
  12. package/dist/declarations/semantic-sidecar.d.ts +8 -3
  13. package/dist/declarations/semantic-slice-admission.d.ts +111 -0
  14. package/dist/declarations/semantic-slice.d.ts +36 -1
  15. package/dist/declarations/universal-conversion-plan.d.ts +59 -0
  16. package/dist/declarations/universal-runtime-capabilities.d.ts +171 -0
  17. package/dist/index.d.ts +2 -0
  18. package/dist/index.js +2 -0
  19. package/dist/internal/index-impl/attachExternalOwnership.js +18 -10
  20. package/dist/internal/index-impl/createNativeRoundtripEvidence.js +54 -49
  21. package/dist/internal/index-impl/createSemanticImportSidecar.js +6 -0
  22. package/dist/internal/index-impl/createSemanticSlice.js +4 -3
  23. package/dist/internal/index-impl/createSemanticSliceAdmissionRecord.js +10 -1
  24. package/dist/internal/index-impl/diffNativeSourceImports.js +3 -2
  25. package/dist/internal/index-impl/expandSemanticSliceSelection.js +0 -1
  26. package/dist/internal/index-impl/externalSemanticBase.js +1 -0
  27. package/dist/internal/index-impl/importExternalSemanticIndex.js +4 -0
  28. package/dist/internal/index-impl/nativeRoundtripAudit.js +217 -0
  29. package/dist/internal/index-impl/projectImportAdmissionImportEvidence.js +160 -0
  30. package/dist/internal/index-impl/projectImportAdmissionLanguageSummaries.js +247 -0
  31. package/dist/internal/index-impl/projectImportAdmissionRanks.js +52 -0
  32. package/dist/internal/index-impl/projectImportAdmissionSummaries.js +77 -117
  33. package/dist/internal/index-impl/projectImportAdmissionTasks.js +239 -0
  34. package/dist/internal/index-impl/semanticHistoryRecordNormalizers.js +151 -0
  35. package/dist/internal/index-impl/semanticHistoryRecordOverlaps.js +113 -0
  36. package/dist/internal/index-impl/semanticHistoryRecords.js +210 -149
  37. package/dist/internal/index-impl/semanticMergeCandidateRecordInternals.js +314 -0
  38. package/dist/internal/index-impl/semanticMergeCandidateRecords.js +241 -0
  39. package/dist/internal/index-impl/semanticSliceAdmissionSurface.js +142 -0
  40. package/dist/internal/index-impl/semanticSliceExpectationAssertions.js +100 -0
  41. package/dist/internal/index-impl/semanticSliceExpectationRecords.js +75 -0
  42. package/dist/internal/index-impl/semanticSliceExpectedAssertions.js +5 -2
  43. package/dist/internal/index-impl/testSemanticSlice.js +4 -1
  44. package/dist/internal/index-impl/withExternalEmptyLoss.js +1 -0
  45. package/dist/language-adapter-package-contracts.js +12 -57
  46. package/dist/language-adapter-package-rows.js +116 -0
  47. package/dist/lightweight-dependency-language.js +8 -0
  48. package/dist/native-region-scanner-core.js +42 -10
  49. package/dist/native-region-scanner-js-helpers.js +2 -0
  50. package/dist/native-region-scanner-js-imports.js +111 -0
  51. package/dist/native-region-scanner-js.js +111 -28
  52. package/dist/universal-conversion-plan-summary.js +42 -0
  53. package/dist/universal-conversion-plan.js +46 -40
  54. package/dist/universal-runtime-capabilities.js +92 -0
  55. package/dist/universal-runtime-host-selectors.js +192 -0
  56. package/dist/universal-runtime-profiles.js +109 -0
  57. package/dist/universal-runtime-route-records.js +162 -0
  58. package/examples/js-frontier-rust-workbench-adapters.mjs +89 -0
  59. package/examples/js-frontier-rust-workbench-bounds.mjs +4 -3
  60. package/examples/js-frontier-rust-workbench-client.mjs +135 -59
  61. package/examples/js-frontier-rust-workbench-convert.mjs +161 -0
  62. package/examples/js-frontier-rust-workbench-html.mjs +20 -13
  63. package/examples/js-frontier-rust-workbench-route-styles.mjs +126 -0
  64. package/examples/js-frontier-rust-workbench-route.mjs +190 -0
  65. package/examples/js-frontier-rust-workbench-styles.mjs +12 -54
  66. package/examples/js-frontier-rust-workbench.mjs +54 -214
  67. package/package.json +1 -1
@@ -0,0 +1,171 @@
1
+ import type {
2
+ FrontierSourceLanguage,
3
+ SemanticMergeReadiness
4
+ } from '@shapeshift-labs/frontier-lang-kernel';
5
+ import type { FrontierCompileTarget } from './compile.js';
6
+ import type { NativeImportLanguageProfile } from './native-import-losses.js';
7
+ import type { NativeSourceImportResult } from './import-adapter-core.js';
8
+
9
+ export type UniversalRuntimeCapabilityKind =
10
+ | 'fetch'
11
+ | 'timers'
12
+ | 'storage'
13
+ | 'filesystem'
14
+ | 'threading'
15
+ | 'dom'
16
+ | 'async'
17
+ | 'ffi'
18
+ | string;
19
+
20
+ export type UniversalRuntimeCapabilitySupport = 'native' | 'adapter' | 'unavailable' | string;
21
+
22
+ export interface UniversalRuntimeCapabilitySupportRecord {
23
+ readonly kind: UniversalRuntimeCapabilityKind;
24
+ readonly support: UniversalRuntimeCapabilitySupport;
25
+ readonly binding: string;
26
+ readonly notes: readonly string[];
27
+ }
28
+
29
+ export interface UniversalRuntimeHostProfile {
30
+ readonly id: string;
31
+ readonly language: FrontierSourceLanguage | string;
32
+ readonly aliases?: readonly string[];
33
+ readonly languageIds?: readonly string[];
34
+ readonly runtime: string;
35
+ readonly host: string;
36
+ readonly target: FrontierCompileTarget | string;
37
+ readonly capabilities: Readonly<Record<UniversalRuntimeCapabilityKind, UniversalRuntimeCapabilitySupportRecord>>;
38
+ readonly notes?: readonly string[];
39
+ }
40
+
41
+ export interface UniversalRuntimeHostSummary extends UniversalRuntimeHostProfile {
42
+ readonly aliases: readonly string[];
43
+ readonly languageIds: readonly string[];
44
+ readonly notes?: readonly string[];
45
+ }
46
+
47
+ export interface UniversalRuntimeRequirementInput {
48
+ readonly capability?: UniversalRuntimeCapabilityKind;
49
+ readonly kind?: UniversalRuntimeCapabilityKind;
50
+ readonly capabilities?: readonly UniversalRuntimeCapabilityKind[];
51
+ readonly requiredCapabilities?: readonly UniversalRuntimeCapabilityKind[];
52
+ readonly sourceLanguage?: FrontierSourceLanguage | string;
53
+ readonly language?: FrontierSourceLanguage | string;
54
+ readonly sourceRuntime?: string;
55
+ readonly runtime?: string;
56
+ readonly sourceHost?: string | UniversalRuntimeHostProfile;
57
+ readonly sourceRuntimeHost?: string | UniversalRuntimeHostProfile;
58
+ readonly target?: FrontierCompileTarget | string;
59
+ readonly targetRuntime?: string;
60
+ readonly targetHost?: string | UniversalRuntimeHostProfile;
61
+ readonly targetRuntimeHost?: string | UniversalRuntimeHostProfile;
62
+ readonly reason?: string;
63
+ readonly evidenceIds?: readonly string[];
64
+ }
65
+
66
+ export interface UniversalRuntimeAdapterRequirement {
67
+ readonly id: string;
68
+ readonly capability: UniversalRuntimeCapabilityKind;
69
+ readonly adapterKind: string;
70
+ readonly sourceHost: string;
71
+ readonly targetHost: string;
72
+ readonly sourceBinding: string;
73
+ readonly targetBinding: string;
74
+ readonly required: true;
75
+ readonly reason: string;
76
+ readonly evidenceIds: readonly string[];
77
+ }
78
+
79
+ export interface UniversalRuntimeCapabilityRoute {
80
+ readonly id: string;
81
+ readonly source: UniversalRuntimeHostSummary;
82
+ readonly target: UniversalRuntimeHostSummary;
83
+ readonly requiredCapabilities: readonly UniversalRuntimeCapabilityKind[];
84
+ readonly satisfiedCapabilities: readonly UniversalRuntimeCapabilityKind[];
85
+ readonly adapterRequirements: readonly UniversalRuntimeAdapterRequirement[];
86
+ readonly missingCapabilities: readonly UniversalRuntimeCapabilityKind[];
87
+ readonly readiness: SemanticMergeReadiness;
88
+ readonly blockers: readonly string[];
89
+ readonly review: readonly string[];
90
+ readonly metadata: Record<string, unknown>;
91
+ }
92
+
93
+ export interface UniversalRuntimeCapabilityMatrix {
94
+ readonly kind: 'frontier.lang.universalRuntimeCapabilityMatrix';
95
+ readonly version: 1;
96
+ readonly generatedAt: number;
97
+ readonly hostProfiles: readonly UniversalRuntimeHostProfile[];
98
+ readonly routes: readonly UniversalRuntimeCapabilityRoute[];
99
+ readonly summary: {
100
+ readonly routes: number;
101
+ readonly routesWithAdapters: number;
102
+ readonly adapterRequirements: number;
103
+ readonly missingCapabilities: number;
104
+ readonly byReadiness: Readonly<Record<SemanticMergeReadiness, number>>;
105
+ readonly byCapability: Readonly<Record<UniversalRuntimeCapabilityKind, number>>;
106
+ readonly byAdapterKind: Readonly<Record<string, number>>;
107
+ };
108
+ readonly metadata: {
109
+ readonly capabilityKinds: readonly UniversalRuntimeCapabilityKind[];
110
+ readonly sourceHosts: readonly string[];
111
+ readonly targetHosts: readonly string[];
112
+ readonly note: string;
113
+ };
114
+ }
115
+
116
+ export interface UniversalRuntimeCapabilityMatrixOptions {
117
+ readonly generatedAt?: number;
118
+ readonly imports?: readonly NativeSourceImportResult[];
119
+ readonly languages?: readonly (NativeImportLanguageProfile | FrontierSourceLanguage | string)[];
120
+ readonly sourceLanguages?: readonly (NativeImportLanguageProfile | FrontierSourceLanguage | string)[];
121
+ readonly targets?: readonly (FrontierCompileTarget | string)[];
122
+ readonly hostProfiles?: readonly UniversalRuntimeHostProfile[];
123
+ readonly runtimeHosts?: readonly UniversalRuntimeHostProfile[];
124
+ readonly sourceHosts?: readonly (string | UniversalRuntimeHostProfile)[] | Readonly<Record<string, string | UniversalRuntimeHostProfile>>;
125
+ readonly sourceRuntimeHosts?: readonly (string | UniversalRuntimeHostProfile)[] | Readonly<Record<string, string | UniversalRuntimeHostProfile>>;
126
+ readonly targetHosts?: readonly (string | UniversalRuntimeHostProfile)[] | Readonly<Record<string, string | UniversalRuntimeHostProfile>>;
127
+ readonly targetRuntimeHosts?: readonly (string | UniversalRuntimeHostProfile)[] | Readonly<Record<string, string | UniversalRuntimeHostProfile>>;
128
+ readonly sourceRuntime?: string;
129
+ readonly targetRuntime?: string;
130
+ readonly sourceRuntimes?: Readonly<Record<string, string>>;
131
+ readonly targetRuntimes?: Readonly<Record<string, string>>;
132
+ readonly runtimeRequirements?:
133
+ | readonly (UniversalRuntimeCapabilityKind | UniversalRuntimeRequirementInput)[]
134
+ | Readonly<Record<string, readonly UniversalRuntimeCapabilityKind[]>>;
135
+ readonly requiredRuntimeCapabilities?:
136
+ | readonly (UniversalRuntimeCapabilityKind | UniversalRuntimeRequirementInput)[]
137
+ | Readonly<Record<string, readonly UniversalRuntimeCapabilityKind[]>>;
138
+ readonly effects?:
139
+ | readonly (UniversalRuntimeCapabilityKind | UniversalRuntimeRequirementInput)[]
140
+ | Readonly<Record<string, readonly UniversalRuntimeCapabilityKind[]>>;
141
+ }
142
+
143
+ export interface UniversalRuntimeCapabilityMatrixQuery {
144
+ readonly sourceLanguage?: FrontierSourceLanguage | string;
145
+ readonly language?: FrontierSourceLanguage | string;
146
+ readonly target?: FrontierCompileTarget | string;
147
+ readonly sourceRuntime?: string;
148
+ readonly targetRuntime?: string;
149
+ readonly runtime?: string;
150
+ readonly capability?: UniversalRuntimeCapabilityKind;
151
+ readonly requiresAdapter?: boolean;
152
+ }
153
+
154
+ export interface UniversalRuntimeCapabilityMatrixQueryResult {
155
+ readonly kind: 'frontier.lang.universalRuntimeCapabilityMatrixQuery';
156
+ readonly version: 1;
157
+ readonly found: boolean;
158
+ readonly routes: readonly UniversalRuntimeCapabilityRoute[];
159
+ readonly bestRoute?: UniversalRuntimeCapabilityRoute;
160
+ readonly reasons: readonly string[];
161
+ }
162
+
163
+ export declare const UniversalRuntimeCapabilityKinds: readonly UniversalRuntimeCapabilityKind[];
164
+ export declare const UniversalRuntimeHostProfiles: readonly UniversalRuntimeHostProfile[];
165
+ export declare function createUniversalRuntimeCapabilityMatrix(
166
+ options?: UniversalRuntimeCapabilityMatrixOptions
167
+ ): UniversalRuntimeCapabilityMatrix;
168
+ export declare function queryUniversalRuntimeCapabilityMatrix(
169
+ matrixOrOptions?: UniversalRuntimeCapabilityMatrix | UniversalRuntimeCapabilityMatrixOptions,
170
+ query?: UniversalRuntimeCapabilityMatrixQuery
171
+ ): UniversalRuntimeCapabilityMatrixQueryResult;
package/dist/index.d.ts CHANGED
@@ -8,11 +8,13 @@ export * from './declarations/projection-readiness.js';
8
8
  export * from './declarations/universal-capability.js';
9
9
  export * from './declarations/universal-conversion-artifacts.js';
10
10
  export * from './declarations/universal-conversion-plan.js';
11
+ export * from './declarations/universal-runtime-capabilities.js';
11
12
  export * from './declarations/universal-dialects.js';
12
13
  export * from './declarations/language-adapter-package-contracts.js';
13
14
  export * from './declarations/native-import-contracts.js';
14
15
  export * from './declarations/source-preservation.js';
15
16
  export * from './declarations/semantic-sidecar-admission.js';
17
+ export * from './declarations/semantic-merge-candidates.js';
16
18
  export * from './declarations/semantic-merge-conflicts.js';
17
19
  export * from './declarations/semantic-history.js';
18
20
  export * from './declarations/semantic-patch-bundle.js';
package/dist/index.js CHANGED
@@ -32,6 +32,7 @@ export { createUniversalCapabilityMatrix } from './internal/index-impl/createUni
32
32
  export { createUniversalConversionArtifacts } from './internal/index-impl/createUniversalConversionArtifacts.js';
33
33
  export { queryUniversalConversionArtifacts } from './universal-conversion-artifacts.js';
34
34
  export { createUniversalConversionPlan } from './internal/index-impl/createUniversalConversionPlan.js';
35
+ export { createUniversalRuntimeCapabilityMatrix, queryUniversalRuntimeCapabilityMatrix, UniversalRuntimeCapabilityKinds, UniversalRuntimeHostProfiles } from './universal-runtime-capabilities.js';
35
36
  export { attachUniversalDialectRegistry, createUniversalDialectRecord, createUniversalDialectRegistry, createUniversalExternRecord, summarizeUniversalDialectRegistry, UniversalDialectConstructKinds, UniversalDialectProjectionDispositions } from './universal-dialect-registry.js';
36
37
  export { diffNativeSourceImports } from './internal/index-impl/diffNativeSourceImports.js';
37
38
  export { diffNativeSources } from './internal/index-impl/diffNativeSources.js';
@@ -64,6 +65,7 @@ export { projectNativeImportToSource } from './internal/index-impl/projectNative
64
65
  export { queryNativeParserFeatureMatrix } from './internal/index-impl/queryNativeParserFeatureMatrix.js';
65
66
  export { queryProjectionReadinessMatrix } from './internal/index-impl/queryProjectionReadinessMatrix.js';
66
67
  export { createSemanticPatchBundleRecord, querySemanticPatchBundleRecords, SemanticPatchBundleAdmissionStatuses } from './internal/index-impl/semanticPatchBundleRecords.js';
68
+ export { createSemanticMergeCandidateAdmissionRecord, decorateSemanticMergeCandidateForAdmission, querySemanticMergeCandidateAdmissionOverlaps, SemanticMergeCandidateProjectionRisks, semanticMergeCandidateReadinessSortKey, sortSemanticMergeCandidateAdmissionRecords } from './internal/index-impl/semanticMergeCandidateRecords.js';
67
69
  export { querySemanticMergeConflictClasses, SemanticMergeConflictClasses, semanticMergeConflictRiskScore, sortSemanticMergeCandidatesByConflictRisk, summarizeSemanticMergeConflicts } from './internal/index-impl/semanticMergeConflicts.js';
68
70
  export { queryUniversalConversionPlan } from './internal/index-impl/queryUniversalConversionPlan.js';
69
71
  export { createSemanticHistoryRecord, querySemanticHistoryRecordOverlaps, SemanticHistoryAdmissionStatuses, SemanticHistoryConflictReasons, SemanticHistoryOverlapKinds, SemanticHistoryReviewerStatuses, semanticHistoryRecordsConflict, semanticHistoryRecordsOverlap } from './internal/index-impl/semanticHistoryRecords.js';
@@ -1,7 +1,9 @@
1
- import{idFragment}from'../../native-import-utils.js';import{semanticRegionKindForSymbol,semanticRegionMergePolicy}from'../../semantic-import-regions.js';
1
+ import{idFragment,uniqueRecordsById}from'../../native-import-utils.js';import{semanticRegionKindForSymbol,semanticRegionMergePolicy}from'../../semantic-import-regions.js';
2
2
  import{externalRelationPredicateForOccurrence}from'./externalRelationPredicateForOccurrence.js';
3
3
  export function attachExternalOwnership(result, context) {
4
4
  const occurrencesBySymbol = new Map();
5
+ const documentsById = new Map((result.documents ?? []).map((document) => [document.id, document]));
6
+ const ownershipRegions = [];
5
7
  for (const occurrence of result.occurrences) {
6
8
  if (!occurrencesBySymbol.has(occurrence.symbolId)) occurrencesBySymbol.set(occurrence.symbolId, []);
7
9
  occurrencesBySymbol.get(occurrence.symbolId).push(occurrence);
@@ -21,24 +23,28 @@ export function attachExternalOwnership(result, context) {
21
23
  result.symbols = result.symbols.map((symbol) => {
22
24
  const occurrences = occurrencesBySymbol.get(symbol.id) ?? [];
23
25
  const definition = occurrences.find((occurrence) => occurrence.role === 'definition') ?? occurrences[0];
26
+ const document = documentsById.get(definition?.documentId);
24
27
  const sourceSpan = symbol.definitionSpan ?? definition?.span;
25
28
  const regionKind = semanticRegionKindForSymbol(symbol, undefined, undefined);
29
+ const sourcePath = sourceSpan?.path ?? document?.path ?? context.sourcePath;
30
+ const language = symbol.language ?? document?.language ?? context.language;
31
+ const normalizedRegionKind = symbol.metadata?.ownershipRegionKind ?? regionKind;
26
32
  const key = [
27
33
  'external',
28
- symbol.language ?? context.language ?? 'unknown',
29
- sourceSpan?.path ?? context.sourcePath ?? 'memory',
30
- regionKind,
34
+ language ?? 'unknown',
35
+ sourcePath ?? 'memory',
36
+ normalizedRegionKind,
31
37
  symbol.name ?? symbol.id
32
38
  ].join('#');
33
39
  const region = {
34
- id: `region_${idFragment(key)}`,
35
- key,
36
- regionKind,
40
+ id: symbol.metadata?.ownershipRegionId ?? `region_${idFragment(key)}`,
41
+ key: symbol.metadata?.ownershipRegionKey ?? key,
42
+ regionKind: normalizedRegionKind,
37
43
  granularity: 'symbol',
38
- language: symbol.language ?? context.language,
44
+ language,
39
45
  documentId: definition?.documentId,
40
- sourcePath: sourceSpan?.path ?? context.sourcePath,
41
- sourceHash: context.sourceHash,
46
+ sourcePath,
47
+ sourceHash: sourceSpan?.sourceId ?? document?.sourceHash ?? context.sourceHash,
42
48
  symbolId: symbol.id,
43
49
  symbolName: symbol.name,
44
50
  symbolKind: symbol.kind,
@@ -50,6 +56,7 @@ export function attachExternalOwnership(result, context) {
50
56
  source: 'external-semantic-index'
51
57
  }
52
58
  };
59
+ ownershipRegions.push(region);
53
60
  result.facts.push({
54
61
  id: `fact_${idFragment(symbol.id)}_ownership_region`,
55
62
  predicate: 'semanticOwnershipRegion',
@@ -76,4 +83,5 @@ export function attachExternalOwnership(result, context) {
76
83
  }
77
84
  };
78
85
  });
86
+ result.ownershipRegions = uniqueRecordsById([...(result.ownershipRegions ?? []), ...ownershipRegions]);
79
87
  }
@@ -1,6 +1,7 @@
1
1
  import{validateUniversalAstEnvelope}from'@shapeshift-labs/frontier-lang-kernel';
2
2
  import{countBy,idFragment,maxSemanticMergeReadiness,uniqueStrings}from'../../native-import-utils.js';
3
3
  import{nativeImportEntries}from'./nativeImportEntries.js';import{nativeImportHasExactAstCoverage}from'./nativeImportHasExactAstCoverage.js';
4
+ import{createRoundtripAudit}from'./nativeRoundtripAudit.js';
4
5
  const precisionRank=Object.freeze({exact:0,line:1,declaration:2,estimated:3,unknown:4,none:5});
5
6
  export function createNativeRoundtripEvidence(importResult,options={}) {
6
7
  if(!importResult||typeof importResult!=='object') throw new Error('createNativeRoundtripEvidence requires a native import result');
@@ -28,6 +29,8 @@ export function createNativeRoundtripEvidence(importResult,options={}) {
28
29
  const sourceMapEvidence=summarizeSourceMaps(hasOutputSourceMaps?outputSourceMaps:universalSourceMaps);
29
30
  const sourceLanguage=projection?.language??importResult.language;
30
31
  const target=options.target??options.targetCoverage?.target??options.targetProjection?.target;
32
+ const sourcePreservation=summarizeSourcePreservation(importResult,universalSourceMaps);
33
+ const hashChecks=summarizeHashChecks({importResult,projection,targetProjection:options.targetProjection,sourceHashVerified});
31
34
  const audit=createRoundtripAudit({
32
35
  status,
33
36
  semanticMerge,
@@ -35,6 +38,7 @@ export function createNativeRoundtripEvidence(importResult,options={}) {
35
38
  target,
36
39
  sameLanguage:Boolean(sourceLanguage&&target&&String(sourceLanguage)===String(target)),
37
40
  outputMode,
41
+ projection,
38
42
  projectionMode:projection?.mode,
39
43
  sourceHashVerified,
40
44
  hasOutputSourceMaps,
@@ -42,7 +46,9 @@ export function createNativeRoundtripEvidence(importResult,options={}) {
42
46
  universalSourceMapEvidence,
43
47
  targetProjection:options.targetProjection,
44
48
  targetCoverage:options.targetCoverage,
45
- lossSummary
49
+ lossSummary,
50
+ sourcePreservation,
51
+ hashChecks
46
52
  });
47
53
  const metadata={
48
54
  schema:'frontier.lang.nativeRoundtripEvidence',
@@ -135,55 +141,54 @@ function summarizeSourceMaps(sourceMaps){
135
141
  }
136
142
  function normalizePrecision(value){const precision=String(value??'unknown');return Object.prototype.hasOwnProperty.call(precisionRank,precision)?precision:'unknown';}
137
143
  function worstPrecision(precisions){if(!precisions.length)return'none';return precisions.reduce((worst,next)=>precisionRank[next]>precisionRank[worst]?next:worst,'exact');}
138
- function createRoundtripAudit(input){
139
- const disposition=roundtripAuditDisposition(input);
144
+ function summarizeSourcePreservation(importResult,sourceMaps){
145
+ const preservation=importResult.metadata?.sourcePreservation??importResult.nativeSource?.metadata?.sourcePreservation??importResult.nativeAst?.metadata?.sourcePreservation??importResult.universalAst?.metadata?.sourcePreservation;
146
+ const summary=preservation?.summary??importResult.metadata?.sourcePreservationSummary??importResult.nativeSource?.metadata?.sourcePreservationSummary??importResult.nativeAst?.metadata?.sourcePreservationSummary??importResult.universalAst?.metadata?.sourcePreservationSummary??{};
147
+ const kernelSummary=importResult.metadata?.kernelSourcePreservationSummary??importResult.universalAst?.metadata?.kernelSourcePreservationSummary??{};
148
+ const records=asArray(importResult.metadata?.kernelSourcePreservationRecords??importResult.metadata?.sourcePreservationRecords??importResult.universalAst?.metadata?.kernelSourcePreservationRecords??importResult.universalAst?.metadata?.sourcePreservationRecords);
149
+ const mappings=(sourceMaps??[]).flatMap((sourceMap)=>sourceMap?.mappings??[]);
140
150
  return{
141
- schema:'frontier.lang.nativeRoundtripAuditSignal',
142
- version:1,
143
- disposition,
144
- claim:roundtripAuditClaim(disposition),
145
- sourceLanguage:input.sourceLanguage,
146
- target:input.target,
147
- sameLanguage:input.sameLanguage,
148
- outputMode:input.outputMode,
149
- projectionMode:input.projectionMode,
150
- sourceHashVerified:input.sourceHashVerified,
151
- outputSourceMapPrecision:input.sourceMapEvidence.precision,
152
- universalSourceMapPrecision:input.universalSourceMapEvidence.precision,
153
- targetProjectionAdapterId:input.targetProjection?.adapter?.id,
154
- targetCoverageLossClass:input.targetCoverage?.lossClass,
155
- reviewRequired:input.semanticMerge!=='ready',
156
- semanticMergeReadiness:input.semanticMerge,
157
- semanticEquivalenceClaim:false,
158
- autoMergeClaim:false,
159
- blockingLossCount:input.lossSummary.blockingLossIds.length,
160
- reviewLossCount:input.lossSummary.reviewLossIds.length,
161
- reasonCodes:uniqueStrings([
162
- `status:${input.status}`,
163
- `semantic:${input.semanticMerge}`,
164
- `output:${input.outputMode??'unknown'}`,
165
- `projection:${input.projectionMode??'unknown'}`,
166
- input.sourceHashVerified?'source-hash:verified':'source-hash:unverified',
167
- `output-source-map:${input.sourceMapEvidence.precision}`,
168
- `universal-source-map:${input.universalSourceMapEvidence.precision}`,
169
- input.targetCoverage?.lossClass?`target-loss:${input.targetCoverage.lossClass}`:undefined,
170
- input.targetProjection?.adapter?.id?`target-adapter:${input.targetProjection.adapter.id}`:undefined,
171
- input.lossSummary.blockingLossIds.length?'losses:blocking':undefined,
172
- input.lossSummary.reviewLossIds.length?'losses:review':undefined
173
- ])
151
+ id:preservation?.id??importResult.metadata?.sourcePreservationId??importResult.nativeSource?.metadata?.sourcePreservationId??importResult.universalAst?.metadata?.sourcePreservationId,
152
+ exactSourceAvailable:Boolean(summary.exactSourceAvailable??preservation?.summary?.exactSourceAvailable??preservation?.sourceText),
153
+ sourceTextAvailable:typeof preservation?.sourceText==='string',
154
+ recordCount:numeric(kernelSummary.total,records.length||(preservation?1:0)),
155
+ byLevel:kernelSummary.byLevel??countBy(records.map((record)=>record?.level??'unknown')),
156
+ exactRecords:numeric(kernelSummary.exact),
157
+ declarationRecords:numeric(kernelSummary.declaration),
158
+ estimatedRecords:numeric(kernelSummary.estimated),
159
+ blockedRecords:numeric(kernelSummary.blocked),
160
+ sourcePaths:uniqueStrings([...(asArray(kernelSummary.sourcePaths)),preservation?.sourcePath,importResult.sourcePath]),
161
+ sourceMapIds:uniqueStrings([...(asArray(kernelSummary.sourceMapIds)),...(sourceMaps??[]).map((sourceMap)=>sourceMap?.id)]),
162
+ mappingPreservation:countBy(mappings.map((mapping)=>mapping?.preservation??'unknown')),
163
+ comments:numeric(summary.comments),
164
+ trivia:numeric(summary.trivia),
165
+ directives:numeric(summary.directives),
166
+ tokens:numeric(summary.tokens),
167
+ whitespace:numeric(summary.whitespace),
168
+ truncated:Boolean(summary.truncated)
174
169
  };
175
170
  }
176
- function roundtripAuditDisposition(input){
177
- if(input.outputMode==='target-adapter')return'adapter-projected';
178
- if(input.projectionMode==='native-source-stubs'||input.outputMode==='target-stubs')return'stub-only';
179
- if(input.sourceHashVerified&&input.outputMode==='preserved-source'&&input.hasOutputSourceMaps&&input.sourceMapEvidence.precision==='exact')return'reversible';
180
- if(input.sourceHashVerified||input.projectionMode==='preserved-source')return'preserved-source';
181
- return'review-required';
182
- }
183
- function roundtripAuditClaim(disposition){
184
- if(disposition==='reversible')return'source-text-reversible';
185
- if(disposition==='preserved-source')return'source-preserved';
186
- if(disposition==='stub-only')return'declaration-stubs-only';
187
- if(disposition==='adapter-projected')return'host-adapter-projected';
188
- return'review-required';
171
+ function summarizeHashChecks(input){
172
+ const importResult=input.importResult;
173
+ const sourceHash=importResult.nativeSource?.sourceHash??importResult.nativeAst?.sourceHash??importResult.sourceHash;
174
+ const declaredSourceHash=importResult.metadata?.declaredSourceHash??importResult.nativeSource?.metadata?.declaredSourceHash??importResult.nativeAst?.metadata?.declaredSourceHash;
175
+ const expectedSourceHash=input.projection?.sourceHash??sourceHash;
176
+ const projectionOutputHash=input.projection?.outputHash;
177
+ const targetOutputHash=input.targetProjection?.outputHash;
178
+ const outputHash=targetOutputHash??projectionOutputHash;
179
+ return{
180
+ sourceHashPresent:Boolean(sourceHash),
181
+ declaredSourceHashPresent:Boolean(declaredSourceHash),
182
+ declaredSourceHashVerified:declaredSourceHash?declaredSourceHash===sourceHash&&importResult.metadata?.sourceHashVerified!==false:undefined,
183
+ expectedSourceHashPresent:Boolean(expectedSourceHash),
184
+ outputHashPresent:Boolean(outputHash),
185
+ projectionOutputHashPresent:Boolean(projectionOutputHash),
186
+ targetOutputHashPresent:Boolean(targetOutputHash),
187
+ sourceHashVerified:input.sourceHashVerified,
188
+ projectionOutputMatchesSourceHash:Boolean(projectionOutputHash&&expectedSourceHash&&projectionOutputHash===expectedSourceHash),
189
+ targetOutputMatchesSourceHash:Boolean(targetOutputHash&&expectedSourceHash&&targetOutputHash===expectedSourceHash),
190
+ outputMatchesSourceHash:Boolean(outputHash&&expectedSourceHash&&outputHash===expectedSourceHash)
191
+ };
189
192
  }
193
+ function asArray(value){return Array.isArray(value)?value:[];}
194
+ function numeric(value,fallback=0){const number=Number(value);return Number.isFinite(number)?number:fallback;}
@@ -84,6 +84,12 @@ export function createSemanticImportSidecar(importResult, options = {}) {
84
84
  reasons: candidate.reasons ?? [],
85
85
  conflictClasses: (candidate.conflictClasses ?? candidate.metadata?.conflictClasses ?? []).map((record) => record.class).filter(Boolean),
86
86
  conflictSummary: candidate.conflictSummary ?? candidate.metadata?.conflictSummary,
87
+ changedSemanticRegions: candidate.changedSemanticRegions?.length ?? candidate.mergeAdmission?.changedSemanticRegions?.length ?? 0,
88
+ sourceHashes: candidate.sourceHashes ?? candidate.mergeAdmission?.sourceHashes,
89
+ evidenceIds: candidate.evidenceIds ?? candidate.mergeAdmission?.evidenceIds ?? [],
90
+ projectionRisk: candidate.projectionRisk ?? candidate.mergeAdmission?.projectionRisk,
91
+ readinessSortKey: candidate.readinessSortKey ?? candidate.mergeAdmission?.readinessSortKey,
92
+ overlapSummary: candidate.mergeAdmission?.overlapSummary,
87
93
  risk: candidate.risk,
88
94
  operationCount: candidate.operations?.length ?? candidate.patch?.operations?.length ?? 0
89
95
  })),
@@ -1,5 +1,6 @@
1
1
  import{idFragment,uniqueStrings}from'../../native-import-utils.js';import{createSemanticMergeCandidateRecord}from'@shapeshift-labs/frontier-lang-kernel';
2
2
  import{createSemanticImportSidecar}from'./createSemanticImportSidecar.js';import{nativeNodeId}from'./nativeNodeId.js';import{readStringArray}from'./readStringArray.js';import{selectSemanticSliceRecords}from'./selectSemanticSliceRecords.js';import{semanticSliceContext}from'./semanticSliceContext.js';import{semanticSliceExpectedAssertions}from'./semanticSliceExpectedAssertions.js';import{semanticSliceReadiness}from'./semanticSliceReadiness.js';import{semanticSliceReasons}from'./semanticSliceReasons.js';import{semanticSliceRecords}from'./semanticSliceRecords.js';import{semanticSliceSourceFiles}from'./semanticSliceSourceFiles.js';import{semanticSliceSourceMapLinks}from'./semanticSliceSourceMapLinks.js';import{semanticSliceSourceSpans}from'./semanticSliceSourceSpans.js';import{semanticSliceTouchedSymbol}from'./semanticSliceTouchedSymbol.js';
3
+ import{decorateSemanticMergeCandidateForAdmission}from'./semanticMergeCandidateRecords.js';
3
4
  export function createSemanticSlice(input, options = {}) {
4
5
  const context = semanticSliceContext(input, options);
5
6
  const sidecar = context.sidecar ?? (context.importResult ? createSemanticImportSidecar(context.importResult, {
@@ -50,7 +51,7 @@ export function createSemanticSlice(input, options = {}) {
50
51
  sidecarId: sidecar?.id
51
52
  }
52
53
  }];
53
- const mergeCandidate = createSemanticMergeCandidateRecord({
54
+ const mergeCandidate = decorateSemanticMergeCandidateForAdmission(createSemanticMergeCandidateRecord({
54
55
  id: options.mergeCandidateId ?? `merge_candidate_${idPart}_semantic_slice`,
55
56
  importResultId: context.importResult?.id,
56
57
  language: context.language,
@@ -70,7 +71,7 @@ export function createSemanticSlice(input, options = {}) {
70
71
  dependencyRelationIds: selection.relations.map((relation) => relation.id).filter(Boolean),
71
72
  autoMergeClaim: false
72
73
  }
73
- });
74
+ }),{evidence,sourceHash:sourceFiles[0]?.sourceHash,metadata:{source:'createSemanticSlice'}});
74
75
  return {
75
76
  kind: 'frontier.lang.semanticSlice',
76
77
  version: 1,
@@ -99,7 +100,7 @@ export function createSemanticSlice(input, options = {}) {
99
100
  verification: {
100
101
  focusedCommands: readStringArray(options.focusedCommands),
101
102
  fixtureHints: readStringArray(options.fixtureHints),
102
- expectedAssertions: semanticSliceExpectedAssertions(selection, unresolvedEntryRefs)
103
+ expectedAssertions: semanticSliceExpectedAssertions(selection, unresolvedEntryRefs, options)
103
104
  },
104
105
  summary: {
105
106
  symbols: selection.symbols.length,
@@ -1,5 +1,6 @@
1
- import{idFragment,maxSemanticMergeReadiness,uniqueStrings}from'../../native-import-utils.js';
1
+ import{idFragment,maxSemanticMergeReadiness,uniqueByEvidenceId,uniqueStrings}from'../../native-import-utils.js';
2
2
  import{testSemanticSlice}from'./testSemanticSlice.js';
3
+ import{semanticSliceAdmissionSelectedSurface,semanticSliceSelectedSurfaceEvidence}from'./semanticSliceAdmissionSurface.js';
3
4
 
4
5
  const readinessScore=Object.freeze({ready:100,'ready-with-losses':78,'needs-review':48,blocked:0});
5
6
  const readinessRank=Object.freeze({ready:3,'ready-with-losses':2,'needs-review':1,blocked:0});
@@ -19,6 +20,12 @@ export function createSemanticSliceAdmissionRecord(slice,options={}){
19
20
  const value=mergeScoreValue(components,readiness);
20
21
  const action=admissionAction(slice,readiness,components,testResult);
21
22
  const risk=admissionRisk(readiness,components,testResult);
23
+ const selectedSurface=semanticSliceAdmissionSelectedSurface(slice);
24
+ const evidence=uniqueByEvidenceId([
25
+ ...(slice?.evidence??[]),
26
+ ...(options.evidence??[]),
27
+ semanticSliceSelectedSurfaceEvidence(slice,selectedSurface,testResult,readiness,action)
28
+ ]);
22
29
  return{
23
30
  kind:'frontier.lang.semanticSliceAdmission',
24
31
  version:1,
@@ -61,6 +68,8 @@ export function createSemanticSliceAdmissionRecord(slice,options={}){
61
68
  conflictKeys:uniqueStrings(slice?.mergeAdmission?.conflictKeys??[]),
62
69
  ownershipKeys:uniqueStrings(slice?.mergeAdmission?.ownershipKeys??[]),
63
70
  sourceHashes:slice?.mergeAdmission?.sourceHashes??[],
71
+ selectedSurface,
72
+ evidence,
64
73
  testResult,
65
74
  reasons:uniqueStrings([
66
75
  ...(slice?.mergeAdmission?.reasons??[]),
@@ -1,5 +1,6 @@
1
1
  import{idFragment,maxSemanticMergeReadiness,uniqueByLossId,uniqueRecordsById,uniqueStrings}from'../../native-import-utils.js';import{createPatch,createSemanticMergeCandidateRecord}from'@shapeshift-labs/frontier-lang-kernel';
2
2
  import{attachNativeChangeRegionProjectionMetadata}from'./attachNativeChangeRegionProjectionMetadata.js';import{classifyNativeSourceMergeConflicts}from'./semanticMergeConflicts.js';import{createSemanticImportSidecar}from'./createSemanticImportSidecar.js';import{diffNativeOwnershipRegions}from'./diffNativeOwnershipRegions.js';import{diffNativeSymbols}from'./diffNativeSymbols.js';import{fileLevelNativeChangeRegion}from'./fileLevelNativeChangeRegion.js';import{mapDiffSymbols}from'./mapDiffSymbols.js';import{nativeChangeSpans}from'./nativeChangeSpans.js';import{nativeChangeTouchedSymbol}from'./nativeChangeTouchedSymbol.js';import{nativeImportReadiness}from'./nativeImportReadiness.js';import{nativeSourceChangeReasons}from'./nativeSourceChangeReasons.js';import{nativeSourceChangeSummary}from'./nativeSourceChangeSummary.js';import{normalizeNativeDiffImport}from'./normalizeNativeDiffImport.js';import{summarizeNativeChangedRegionProjections}from'./summarizeNativeChangedRegionProjections.js';
3
+ import{decorateSemanticMergeCandidateForAdmission}from'./semanticMergeCandidateRecords.js';
3
4
  export function diffNativeSourceImports(input) {
4
5
  const before = normalizeNativeDiffImport(input.before, input, 'before');
5
6
  const after = normalizeNativeDiffImport(input.after, input, 'after');
@@ -104,7 +105,7 @@ export function diffNativeSourceImports(input) {
104
105
  semanticMergeConflictSummary: mergeConflictProfile.conflictSummary
105
106
  }
106
107
  });
107
- const mergeCandidate = createSemanticMergeCandidateRecord({
108
+ const mergeCandidate = decorateSemanticMergeCandidateForAdmission(createSemanticMergeCandidateRecord({
108
109
  id: input.mergeCandidateId ?? `merge_candidate_${idPart}_native_source_diff`,
109
110
  importResultId: after?.id ?? before?.id,
110
111
  patchId: patch.id,
@@ -131,7 +132,7 @@ export function diffNativeSourceImports(input) {
131
132
  conflictClasses: mergeConflictProfile.conflictClasses,
132
133
  conflictSummary: mergeConflictProfile.conflictSummary
133
134
  }
134
- });
135
+ }),{changedRegions,evidence,patch,baseHash:beforeHash,targetHash:afterHash,metadata:{source:'diffNativeSourceImports'}});
135
136
  return {
136
137
  kind: 'frontier.lang.nativeSourceChangeSet',
137
138
  version: 1,
@@ -41,7 +41,6 @@ export function expandSemanticSliceSelection(records, selection) {
41
41
  }
42
42
  for (const node of records.nativeNodes) {
43
43
  if (!selection.selectedNativeNodes.has(node.id)) continue;
44
- for (const child of node.children ?? []) changed = addSet(selection.selectedNativeNodes, child) || changed;
45
44
  const parent = childToParent.get(node.id);
46
45
  if (parent) changed = addSet(selection.selectedNativeNodes, parent) || changed;
47
46
  }
@@ -7,6 +7,7 @@ export function externalSemanticBase(context, metadata = {}) {
7
7
  occurrences: [],
8
8
  relations: [],
9
9
  facts: [],
10
+ ownershipRegions: [],
10
11
  evidence: [externalSemanticEvidence(context, 'passed', `Imported ${context.format} semantic index payload.`)],
11
12
  losses: [externalSemanticCoverageLoss(context)],
12
13
  semanticStatus: 'external-semantic-index',
@@ -18,6 +18,7 @@ export function importExternalSemanticIndex(input) {
18
18
  metadata: input?.metadata ?? {}
19
19
  };
20
20
  const normalized = normalizeExternalSemanticIndexPayload(payload, context);
21
+ const ownershipRegions = normalized.ownershipRegions ?? [];
21
22
  const evidence = attachNativeImportLossSummary(
22
23
  uniqueByEvidenceId([...(normalized.evidence ?? []), ...(input?.evidence ?? [])]),
23
24
  summarizeNativeImportLosses(normalized.losses ?? [], {
@@ -116,6 +117,7 @@ export function importExternalSemanticIndex(input) {
116
117
  semanticIndex,
117
118
  universalAst,
118
119
  sourceMaps,
120
+ ownershipRegions,
119
121
  losses,
120
122
  evidence,
121
123
  readiness,
@@ -125,6 +127,8 @@ export function importExternalSemanticIndex(input) {
125
127
  occurrences: semanticIndex.occurrences.length,
126
128
  relations: semanticIndex.relations.length,
127
129
  facts: semanticIndex.facts.length,
130
+ ownershipRegions: ownershipRegions.length,
131
+ ownershipRegionKinds: [...new Set(ownershipRegions.map((region) => region.regionKind).filter(Boolean))],
128
132
  sourceMapMappings: sourceMaps.reduce((sum, sourceMap) => sum + (sourceMap.mappings?.length ?? 0), 0),
129
133
  losses: losses.length,
130
134
  readiness: readiness.readiness