@shapeshift-labs/frontier-lang-compiler 0.2.103 → 0.2.105

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 (125) hide show
  1. package/README.md +14 -0
  2. package/dist/declarations/bidirectional-target-change-source-edit.d.ts +30 -0
  3. package/dist/declarations/bidirectional-target-change.d.ts +10 -0
  4. package/dist/declarations/js-ts-safe-member-merge.d.ts +86 -0
  5. package/dist/declarations/js-ts-safe-merge.d.ts +131 -0
  6. package/dist/declarations/js-ts-semantic-conflict-sidecars.d.ts +235 -0
  7. package/dist/declarations/js-ts-semantic-merge-contracts.d.ts +287 -0
  8. package/dist/declarations/js-ts-semantic-merge.d.ts +4 -0
  9. package/dist/declarations/native-import-losses.d.ts +3 -0
  10. package/dist/declarations/semantic-edit-replay-diagnostics.d.ts +12 -0
  11. package/dist/declarations/semantic-edit-script.d.ts +7 -4
  12. package/dist/declarations/semantic-patch-bundle-index.d.ts +45 -0
  13. package/dist/declarations/semantic-patch-bundle.d.ts +6 -4
  14. package/dist/declarations/semantic-sidecar-example.d.ts +18 -0
  15. package/dist/declarations/semantic-transform-identity.d.ts +3 -0
  16. package/dist/declarations/source-preservation.d.ts +72 -0
  17. package/dist/declarations/universal-capability.d.ts +4 -0
  18. package/dist/declarations/universal-conversion-artifacts.d.ts +61 -1
  19. package/dist/declarations/universal-conversion-compact-counts.d.ts +51 -0
  20. package/dist/declarations/universal-conversion-plan.d.ts +6 -1
  21. package/dist/declarations/universal-representation-coverage.d.ts +90 -0
  22. package/dist/index.d.ts +4 -0
  23. package/dist/index.js +3 -0
  24. package/dist/internal/index-impl/bidirectionalExactSourceBackprojection.js +199 -0
  25. package/dist/internal/index-impl/bidirectionalSameLanguageSourceProjection.js +112 -0
  26. package/dist/internal/index-impl/bidirectionalSourceEditProjection.js +319 -0
  27. package/dist/internal/index-impl/bidirectionalSourceEditProjectionArtifacts.js +67 -0
  28. package/dist/internal/index-impl/bidirectionalTargetChangeRecordInternals.js +17 -5
  29. package/dist/internal/index-impl/bidirectionalTargetRoundtripEvidence.js +58 -20
  30. package/dist/internal/index-impl/createBidirectionalTargetChangeRecord.js +60 -7
  31. package/dist/internal/index-impl/createLightweightNativeImport.js +1 -0
  32. package/dist/internal/index-impl/createNativeSourcePreservation.js +28 -2
  33. package/dist/internal/index-impl/diffNativeSymbols.js +3 -3
  34. package/dist/internal/index-impl/nativeChangeProjectionSourceMapLinks.js +2 -0
  35. package/dist/internal/index-impl/projectSemanticEditScriptToSource.js +43 -8
  36. package/dist/internal/index-impl/replaySemanticEditLineEndings.js +34 -0
  37. package/dist/internal/index-impl/replaySemanticEditProjection.js +39 -19
  38. package/dist/internal/index-impl/semanticEditBundleAdmission.js +7 -3
  39. package/dist/internal/index-impl/semanticEditBundleIndex.js +47 -1
  40. package/dist/internal/index-impl/semanticEditExplicitSourceReplacement.js +40 -0
  41. package/dist/internal/index-impl/semanticEditOperationCoverage.js +33 -3
  42. package/dist/internal/index-impl/semanticEditProjectionRecord.js +29 -0
  43. package/dist/internal/index-impl/semanticEditReplayDiagnostics.js +39 -0
  44. package/dist/internal/index-impl/semanticEditReplaySourceReplacement.js +85 -0
  45. package/dist/internal/index-impl/semanticEditScripts.js +4 -0
  46. package/dist/internal/index-impl/semanticEditSourceRanges.js +27 -0
  47. package/dist/internal/index-impl/semanticIndexFromNativeDeclarations.js +1 -0
  48. package/dist/internal/index-impl/semanticPatchBundleAdmission.js +41 -7
  49. package/dist/internal/index-impl/semanticPatchBundleRecords.js +16 -0
  50. package/dist/internal/index-impl/semanticPatchBundleSourceRecords.js +2 -0
  51. package/dist/internal/index-impl/semanticSidecarQuality.js +111 -0
  52. package/dist/internal/index-impl/semanticSourceEditDedupe.js +69 -9
  53. package/dist/internal/index-impl/semanticTransformIdentityRecords.js +85 -9
  54. package/dist/js-ts-safe-member-merge-result.js +158 -0
  55. package/dist/js-ts-safe-member-merge.js +265 -0
  56. package/dist/js-ts-safe-merge-analyze.js +279 -0
  57. package/dist/js-ts-safe-merge-composed.js +170 -0
  58. package/dist/js-ts-safe-merge-constants.js +50 -0
  59. package/dist/js-ts-safe-merge-context.js +118 -0
  60. package/dist/js-ts-safe-merge-ledger-validation.js +92 -0
  61. package/dist/js-ts-safe-merge-ledger.js +85 -0
  62. package/dist/js-ts-safe-merge-parse-declarations.js +210 -0
  63. package/dist/js-ts-safe-merge-parse-statements.js +155 -0
  64. package/dist/js-ts-safe-merge-plan.js +190 -0
  65. package/dist/js-ts-safe-merge.js +175 -0
  66. package/dist/js-ts-semantic-conflict-sidecar-constants.js +77 -0
  67. package/dist/js-ts-semantic-conflict-sidecar-detectors.js +195 -0
  68. package/dist/js-ts-semantic-conflict-sidecar-normalize.js +203 -0
  69. package/dist/js-ts-semantic-conflict-sidecar-utils.js +190 -0
  70. package/dist/js-ts-semantic-conflict-sidecars.js +81 -0
  71. package/dist/js-ts-semantic-merge-contract-helpers.js +128 -0
  72. package/dist/js-ts-semantic-merge-contracts.js +217 -0
  73. package/dist/js-ts-semantic-merge-member-containers.js +100 -0
  74. package/dist/js-ts-semantic-merge-member-keys.js +142 -0
  75. package/dist/js-ts-semantic-merge-member-segments.js +185 -0
  76. package/dist/js-ts-semantic-merge-member-source.js +82 -0
  77. package/dist/js-ts-semantic-merge-member-utils.js +18 -0
  78. package/dist/js-ts-semantic-merge-parse.js +16 -0
  79. package/dist/js-ts-semantic-merge.js +24 -0
  80. package/dist/lightweight-dependency-effects.js +51 -0
  81. package/dist/lightweight-dependency-language.js +12 -1
  82. package/dist/lightweight-dependency-relations.js +14 -27
  83. package/dist/native-region-scanner-core.js +33 -1
  84. package/dist/native-region-scanner-csharp.js +151 -0
  85. package/dist/native-region-scanner-dart.js +91 -0
  86. package/dist/native-region-scanner-dynamic.js +21 -151
  87. package/dist/native-region-scanner-functional.js +40 -13
  88. package/dist/native-region-scanner-java.js +97 -0
  89. package/dist/native-region-scanner-js-class.js +100 -0
  90. package/dist/native-region-scanner-js-helpers.js +28 -86
  91. package/dist/native-region-scanner-js-imports.js +121 -1
  92. package/dist/native-region-scanner-js-nested.js +96 -8
  93. package/dist/native-region-scanner-js-structure.js +27 -0
  94. package/dist/native-region-scanner-js-types.js +99 -0
  95. package/dist/native-region-scanner-js.js +70 -118
  96. package/dist/native-region-scanner-kotlin.js +94 -0
  97. package/dist/native-region-scanner-main.js +15 -181
  98. package/dist/native-region-scanner-php.js +80 -0
  99. package/dist/native-region-scanner-python.js +62 -0
  100. package/dist/native-region-scanner-ruby.js +72 -0
  101. package/dist/native-region-scanner-scala.js +91 -0
  102. package/dist/native-region-scanner-spans.js +74 -0
  103. package/dist/native-region-scanner-swift.js +155 -0
  104. package/dist/native-region-scanner.js +14 -10
  105. package/dist/native-source-ledger-helpers.js +195 -0
  106. package/dist/native-source-ledger.js +306 -0
  107. package/dist/native-source-preservation-scanner.js +4 -0
  108. package/dist/semantic-import-callsite-regions.js +136 -0
  109. package/dist/semantic-import-effect-regions.js +283 -0
  110. package/dist/semantic-import-regions.js +11 -2
  111. package/dist/semantic-import-sidecar-entry.js +16 -2
  112. package/dist/semantic-import-sidecar-types.d.ts +2 -0
  113. package/dist/semantic-sidecar-example.js +68 -0
  114. package/dist/universal-capability-matrix.js +23 -0
  115. package/dist/universal-conversion-artifact-query.js +79 -2
  116. package/dist/universal-conversion-artifact-semantic-edit.js +103 -0
  117. package/dist/universal-conversion-artifact-summary.js +33 -1
  118. package/dist/universal-conversion-artifacts.js +13 -48
  119. package/dist/universal-conversion-plan-scoring.js +21 -1
  120. package/dist/universal-conversion-plan-summary.js +30 -0
  121. package/dist/universal-conversion-plan.js +25 -9
  122. package/dist/universal-conversion-route-metadata.js +96 -0
  123. package/dist/universal-conversion-route-operations.js +7 -0
  124. package/dist/universal-representation-coverage.js +193 -0
  125. package/package.json +1 -1
@@ -0,0 +1,103 @@
1
+ import { uniqueStrings } from './native-import-utils.js';
2
+ import { semanticEditRecordIndex } from './internal/index-impl/semanticEditBundleIndex.js';
3
+
4
+ export function artifactSemanticEditIndex(record) {
5
+ const patchIndex = record.patchBundle?.index ?? {};
6
+ const scripts = semanticEditRecords(record, 'semanticEditScript', 'semanticEditScripts', 'script', 'scripts');
7
+ const projections = semanticEditRecords(record, 'semanticEditProjection', 'semanticEditProjections', 'projection', 'projections');
8
+ const replays = semanticEditRecords(record, 'semanticEditReplay', 'semanticEditReplays', 'replay', 'replays');
9
+ const editIndex = semanticEditRecordIndex(scripts, projections, replays, {
10
+ index: patchIndex,
11
+ metadata: { semanticEditSummary: record.patchBundle?.metadata?.semanticEditSummary ?? record.metadata?.semanticEditSummary }
12
+ });
13
+ const admissions = semanticEditAdmissions(record);
14
+ const admissionStatuses = uniqueStrings([...strings(patchIndex.semanticEditAdmissionStatuses), ...admissions.map((admission) => admission.status)]);
15
+ const admissionActions = uniqueStrings([...strings(patchIndex.semanticEditAdmissionActions), ...admissions.map((admission) => admission.action)]);
16
+ const admissionReadinesses = uniqueStrings([...strings(patchIndex.semanticEditAdmissionReadinesses), ...admissions.map((admission) => admission.readiness)]);
17
+ return {
18
+ semanticEditStatuses: uniqueStrings([
19
+ ...editIndex.semanticEditReplayStatuses,
20
+ ...admissionStatuses,
21
+ ...scripts.flatMap((script) => array(script.operations).map((operation) => operation.status)),
22
+ ...projections.flatMap((projection) => [projection.status, projection.admission?.status]),
23
+ ...replays.flatMap((replay) => [replay.status, replay.admission?.status])
24
+ ]),
25
+ semanticEditScriptIds: editIndex.semanticEditScriptIds,
26
+ semanticEditProjectionIds: editIndex.semanticEditProjectionIds,
27
+ semanticEditReplayIds: editIndex.semanticEditReplayIds,
28
+ semanticEditReplayStatuses: editIndex.semanticEditReplayStatuses,
29
+ semanticEditReplayActions: editIndex.semanticEditReplayActions,
30
+ semanticEditAdmissionStatuses: admissionStatuses,
31
+ semanticEditAdmissionActions: admissionActions,
32
+ semanticEditAdmissionReadinesses: admissionReadinesses,
33
+ semanticEditReplayCurrentHashes: editIndex.semanticEditReplayCurrentHashes,
34
+ semanticEditReplayOutputHashes: editIndex.semanticEditReplayOutputHashes,
35
+ semanticEditKeys: editIndex.semanticEditKeys,
36
+ semanticEditHashes: uniqueStrings([
37
+ ...editIndex.semanticEditReplayCurrentHashes,
38
+ ...editIndex.semanticEditReplayOutputHashes,
39
+ ...editIndex.semanticIdentityHashes,
40
+ ...editIndex.sourceIdentityHashes,
41
+ ...editIndex.operationContentHashes,
42
+ ...editIndex.editContentHashes,
43
+ ...semanticEditRecordHashes(scripts),
44
+ ...semanticEditRecordHashes(projections),
45
+ ...semanticEditRecordHashes(replays)
46
+ ]),
47
+ semanticIdentityHashes: editIndex.semanticIdentityHashes,
48
+ sourceIdentityHashes: editIndex.sourceIdentityHashes,
49
+ operationContentHashes: editIndex.operationContentHashes,
50
+ editContentHashes: editIndex.editContentHashes
51
+ };
52
+ }
53
+
54
+ function semanticEditAdmissions(record) {
55
+ return [
56
+ record.patchBundle?.admission?.semanticEditAdmission,
57
+ record.patchBundle?.metadata?.semanticEditAdmission,
58
+ record.metadata?.semanticEditAdmission,
59
+ record.metadata?.semanticEdit?.admission
60
+ ].filter(Boolean);
61
+ }
62
+
63
+ function semanticEditRecords(record, singularKey, pluralKey, nestedSingularKey, nestedPluralKey) {
64
+ const metadata = record.metadata ?? {};
65
+ const semanticEdit = metadata.semanticEdit ?? {};
66
+ const patchMetadata = record.patchBundle?.metadata ?? {};
67
+ const patchSemanticEdit = patchMetadata.semanticEdit ?? {};
68
+ return [
69
+ ...array(record[pluralKey] ?? record[singularKey]),
70
+ ...array(metadata[pluralKey] ?? metadata[singularKey]),
71
+ ...array(semanticEdit[nestedPluralKey] ?? semanticEdit[nestedSingularKey]),
72
+ ...array(record.patchBundle?.[pluralKey] ?? record.patchBundle?.[singularKey]),
73
+ ...array(patchMetadata[pluralKey] ?? patchMetadata[singularKey]),
74
+ ...array(patchSemanticEdit[nestedPluralKey] ?? patchSemanticEdit[nestedSingularKey])
75
+ ].filter(Boolean);
76
+ }
77
+
78
+ function semanticEditRecordHashes(records) {
79
+ return records.flatMap((record) => {
80
+ const hashes = record?.hashes;
81
+ return [
82
+ record?.hash,
83
+ record?.stableHash,
84
+ record?.semanticIdentityHash,
85
+ record?.sourceIdentityHash,
86
+ record?.operationContentHash,
87
+ record?.editContentHash,
88
+ record?.currentHash,
89
+ record?.projectedHash,
90
+ record?.outputHash,
91
+ ...(hashes && typeof hashes === 'object' ? Object.values(hashes) : [])
92
+ ];
93
+ });
94
+ }
95
+
96
+ function array(value) {
97
+ if (value === undefined || value === null) return [];
98
+ return Array.isArray(value) ? value : [value];
99
+ }
100
+
101
+ function strings(value) {
102
+ return array(value).map((entry) => String(entry ?? '')).filter(Boolean);
103
+ }
@@ -1,11 +1,16 @@
1
+ import { countBy } from './native-import-utils.js';
2
+
1
3
  export function universalConversionArtifactSummary(routeArtifacts, records) {
2
4
  const admissionRecords = records.admissionRecords;
5
+ const semanticOperations = routeArtifacts.flatMap((artifact) => artifact.semanticOperations?.operations ?? []);
6
+ const compactCounts = compactArtifactCounts(routeArtifacts, admissionRecords, semanticOperations);
3
7
  return {
4
8
  routes: routeArtifacts.length,
5
9
  histories: records.historyRecords.length,
6
10
  patchBundles: records.patchBundleRecords.length,
7
11
  admissionRecords: admissionRecords.length,
8
- semanticOperations: routeArtifacts.reduce((sum, artifact) => sum + artifact.semanticOperations.operations.length, 0),
12
+ semanticOperations: semanticOperations.length,
13
+ compactCounts,
9
14
  mergeReady: countAdmissionBucket(admissionRecords, 'merge-ready'),
10
15
  needsEvidence: countAdmissionBucket(admissionRecords, 'needs-evidence'),
11
16
  needsAdapter: countAdmissionBucket(admissionRecords, 'needs-adapter'),
@@ -35,3 +40,30 @@ function countAdmissionBucket(records, bucket) {
35
40
  function countAdmissionRisk(records, risk) {
36
41
  return records.filter((record) => record.risk === risk).length;
37
42
  }
43
+
44
+ function compactArtifactCounts(routeArtifacts, admissionRecords, semanticOperations) {
45
+ const constructKinds = routeArtifacts.flatMap((artifact) => artifact.metadata?.representation?.constructKinds ?? []);
46
+ const missingConstructs = routeArtifacts.flatMap((artifact) => artifact.metadata?.representation?.missing ?? []);
47
+ return {
48
+ representationConstructs: {
49
+ total: constructKinds.length,
50
+ routeArtifacts: routeArtifacts.filter((artifact) => artifact.metadata?.representation?.constructKinds?.length).length,
51
+ byKind: countBy(constructKinds)
52
+ },
53
+ missingConstructs: {
54
+ total: missingConstructs.length,
55
+ routeArtifacts: routeArtifacts.filter((artifact) => artifact.metadata?.representation?.missing?.length).length,
56
+ byKind: countBy(missingConstructs)
57
+ },
58
+ semanticEditReadiness: {
59
+ routeArtifacts: countBy(routeArtifacts.map((artifact) => artifact.readiness)),
60
+ semanticOperations: countBy(semanticOperations.map((operation) => operation.readiness))
61
+ },
62
+ admissionStatuses: {
63
+ byStatus: countBy(routeArtifacts.map((artifact) => artifact.admissionStatus)),
64
+ byBucket: countBy(admissionRecords.map((record) => record.admissionBucket)),
65
+ byAction: countBy(admissionRecords.map((record) => record.admissionAction)),
66
+ byRisk: countBy(admissionRecords.map((record) => record.risk))
67
+ }
68
+ };
69
+ }
@@ -3,6 +3,13 @@ import { universalConversionArtifactSummary } from './universal-conversion-artif
3
3
  import { createUniversalConversionPlan } from './universal-conversion-plan.js';
4
4
  import { artifactIndex } from './universal-conversion-artifact-query.js';
5
5
  import { createUniversalConversionAdmissionRecord } from './universal-conversion-admission-record.js';
6
+ import {
7
+ routeAdmissionMetadata,
8
+ routeAdmissionStatus,
9
+ routeReasonCodes,
10
+ routeRecordMetadata,
11
+ routeSemanticEditBundle
12
+ } from './universal-conversion-route-metadata.js';
6
13
  import { routeSemanticOperations } from './universal-conversion-route-operations.js';
7
14
  import { createSemanticHistoryRecord } from './internal/index-impl/semanticHistoryRecords.js';
8
15
  import { createSemanticPatchBundleRecord } from './internal/index-impl/semanticPatchBundleRecords.js';
@@ -60,6 +67,8 @@ function createRouteArtifact(route, options) {
60
67
  const regions = routeRegions(route, refs, sources);
61
68
  const sourceMapLinks = routeSourceMapLinks(route, refs, sources, regions);
62
69
  const semanticOperations = routeSemanticOperations(route, refs, sources, regions, sourceMapLinks);
70
+ const semanticEditBundle = routeSemanticEditBundle(route);
71
+ const recordMetadata = routeRecordMetadata(route, planId, options.metadata);
63
72
  const admissionStatus = routeAdmissionStatus(route);
64
73
  const reasonCodes = routeReasonCodes(route);
65
74
  const historyId = refs.historyIds?.[0] ?? `history_${route.id}`;
@@ -82,7 +91,7 @@ function createRouteArtifact(route, options) {
82
91
  evidenceIds: refs.evidenceIds,
83
92
  metadata: routeAdmissionMetadata(route, planId)
84
93
  },
85
- metadata: routeRecordMetadata(route, planId, options.metadata)
94
+ metadata: recordMetadata
86
95
  }, { id: historyId, createdAt: options.generatedAt });
87
96
  const patchBundle = createSemanticPatchBundleRecord({
88
97
  id: patchBundleId,
@@ -97,6 +106,7 @@ function createRouteArtifact(route, options) {
97
106
  historyIds: [history.id],
98
107
  readiness: route.readiness,
99
108
  conflictKeys: refs.conflictKeys,
109
+ ...semanticEditBundle,
100
110
  admission: {
101
111
  status: admissionStatus,
102
112
  readiness: route.readiness,
@@ -106,7 +116,7 @@ function createRouteArtifact(route, options) {
106
116
  evidenceIds: refs.evidenceIds,
107
117
  metadata: routeAdmissionMetadata(route, planId)
108
118
  },
109
- metadata: routeRecordMetadata(route, planId, options.metadata)
119
+ metadata: recordMetadata
110
120
  }, { id: patchBundleId, createdAt: options.generatedAt });
111
121
  const materialization = {
112
122
  status: 'materialized',
@@ -154,7 +164,7 @@ function createRouteArtifact(route, options) {
154
164
  admissionBucket: admissionRecord.admissionBucket,
155
165
  autoMergeClaim: false,
156
166
  semanticEquivalenceClaim: false,
157
- metadata: { ...routeRecordMetadata(route, planId, options.metadata), materialization }
167
+ metadata: { ...recordMetadata, materialization }
158
168
  };
159
169
  }
160
170
 
@@ -258,48 +268,3 @@ function routeSemanticCandidates(route, refs) {
258
268
  }
259
269
  }));
260
270
  }
261
-
262
- function routeAdmissionStatus(route) {
263
- if (route.readiness === 'blocked' || route.admissionAction === 'reject') return 'blocked';
264
- if (route.readiness === 'ready' && route.missingEvidence?.length === 0) return 'queued';
265
- return 'needs-review';
266
- }
267
-
268
- function routeReasonCodes(route) {
269
- return uniqueStrings([
270
- `mode:${route.mode}`,
271
- `action:${route.routeAction}`,
272
- ...(route.missingEvidence ?? []).map((item) => `missing:${item}`),
273
- ...(route.blockers ?? []).map((item) => `blocker:${item}`),
274
- ...(route.review ?? []).map((item) => `review:${item}`)
275
- ]);
276
- }
277
-
278
- function routeAdmissionMetadata(route, planId) {
279
- return {
280
- planId,
281
- routeId: route.id,
282
- routeAction: route.routeAction,
283
- admissionAction: route.admissionAction,
284
- priority: route.priority,
285
- mergeScore: route.mergeScore,
286
- autoMergeClaim: false,
287
- semanticEquivalenceClaim: false
288
- };
289
- }
290
-
291
- function routeRecordMetadata(route, planId, metadata) {
292
- return {
293
- planId,
294
- routeId: route.id,
295
- target: route.target,
296
- mode: route.mode,
297
- routeAction: route.routeAction,
298
- missingEvidence: route.missingEvidence ?? [],
299
- blockers: route.blockers ?? [],
300
- review: route.review ?? [],
301
- autoMergeClaim: false,
302
- semanticEquivalenceClaim: false,
303
- ...metadata
304
- };
305
- }
@@ -14,11 +14,12 @@ const componentWeights = Object.freeze({
14
14
  importEvidence: 22,
15
15
  parserEvidence: 18,
16
16
  semanticIndex: 18,
17
+ representationCoverage: 18,
17
18
  projectionPath: 24,
18
19
  proofEvidence: 18
19
20
  });
20
21
 
21
- export function conversionScoreComponents(language, targetCell, readiness, mode, evidence) {
22
+ export function conversionScoreComponents(language, targetCell, readiness, mode, evidence, representation) {
22
23
  return {
23
24
  importEvidence: scoreComponent('importEvidence', readinessScore[language.imports.readiness] ?? 48, [
24
25
  ...(language.imports.total ? [] : ['No source import evidence.']),
@@ -32,6 +33,16 @@ export function conversionScoreComponents(language, targetCell, readiness, mode,
32
33
  ...(language.imports.symbols ? [] : ['No semantic symbols were imported.']),
33
34
  ...(language.imports.sourceMapMappings ? [] : ['No source-map mappings were imported.'])
34
35
  ], { symbols: language.imports.symbols, sourceMapMappings: language.imports.sourceMapMappings }),
36
+ representationCoverage: scoreComponent('representationCoverage', representationScore(representation), [
37
+ ...(representation?.missing ?? []).map((item) => `Missing representation evidence: ${item}.`),
38
+ ...(representation?.blockers ?? [])
39
+ ], {
40
+ constructKinds: representation?.constructKinds ?? [],
41
+ representedConstructs: representation?.summary?.representedConstructs ?? 0,
42
+ missing: representation?.summary?.missing ?? 0,
43
+ runtimeCapabilities: representation?.surfaces?.runtime?.requiredCapabilities ?? [],
44
+ sourceMapPrecisions: representation?.surfaces?.sourceMaps?.precisions ?? []
45
+ }),
35
46
  projectionPath: scoreComponent('projectionPath', projectionPathScore(targetCell, mode, readiness), projectionPathReasons(targetCell, mode), {
36
47
  mode,
37
48
  lossClass: targetCell?.lossClass,
@@ -84,6 +95,15 @@ function semanticIndexScore(language) {
84
95
  return Math.min(100, 62 + Math.min(22, symbols * 3) + Math.min(16, mappings * 2));
85
96
  }
86
97
 
98
+ function representationScore(representation) {
99
+ if (!representation) return 0;
100
+ const summary = representation.summary ?? {};
101
+ const represented = Number(summary.representedConstructs ?? 0);
102
+ const missing = Number(summary.missing ?? 0);
103
+ const blockers = Number(summary.blockers ?? 0);
104
+ return Math.max(0, Math.min(100, 44 + represented * 8 - missing * 5 - blockers * 18));
105
+ }
106
+
87
107
  function projectionPathScore(targetCell, mode, readiness) {
88
108
  if (mode === 'blocked') return 0;
89
109
  if (mode === 'preserve-source') return 92;
@@ -1,9 +1,13 @@
1
+ import { countBy } from './native-import-utils.js';
2
+
1
3
  export function conversionPlanSummary(routes) {
4
+ const compactCounts = compactRouteCounts(routes);
2
5
  const summary = {
3
6
  routes: routes.length,
4
7
  byMode: {},
5
8
  byReadiness: {},
6
9
  byAdmissionAction: {},
10
+ compactCounts,
7
11
  readyRoutes: 0,
8
12
  reviewRoutes: 0,
9
13
  blockedRoutes: 0,
@@ -40,3 +44,29 @@ export function conversionPlanSummary(routes) {
40
44
  }
41
45
  return summary;
42
46
  }
47
+
48
+ function compactRouteCounts(routes) {
49
+ const constructs = routes.flatMap((route) => route.representation?.constructs ?? []);
50
+ const missingConstructs = routes.flatMap((route) => route.representation?.missing ?? []);
51
+ return {
52
+ representationConstructs: {
53
+ total: constructs.length,
54
+ represented: constructs.filter((construct) => construct.status === 'represented').length,
55
+ missing: constructs.filter((construct) => construct.status === 'missing').length,
56
+ review: constructs.filter((construct) => construct.status === 'review').length,
57
+ blocked: constructs.filter((construct) => construct.status === 'blocked').length,
58
+ byKind: countBy(constructs.map((construct) => construct.kind)),
59
+ byStatus: countBy(constructs.map((construct) => construct.status))
60
+ },
61
+ missingConstructs: {
62
+ total: missingConstructs.length,
63
+ byKind: countBy(missingConstructs)
64
+ },
65
+ semanticEditReadiness: { routes: countBy(routes.map((route) => route.readiness)) },
66
+ admissionStatuses: {
67
+ byAction: countBy(routes.map((route) => route.admissionAction)),
68
+ byRouteStatus: countBy(routes.map((route) => route.mergeRefs?.admissionStatus ?? route.admissionAction)),
69
+ byRisk: countBy(routes.map((route) => route.mergeScore?.risk))
70
+ }
71
+ };
72
+ }
@@ -22,6 +22,10 @@ import {
22
22
  conversionScoreComponents
23
23
  } from './universal-conversion-plan-scoring.js';
24
24
  import { conversionPlanSummary } from './universal-conversion-plan-summary.js';
25
+ import {
26
+ createUniversalRepresentationCoverage,
27
+ representationCoverageMatches
28
+ } from './universal-representation-coverage.js';
25
29
 
26
30
  export function createUniversalConversionPlan(input = {}, context = {}) {
27
31
  const generatedAt = input.generatedAt ?? Date.now();
@@ -81,6 +85,7 @@ export function queryUniversalConversionPlan(planOrInput = {}, query = {}, conte
81
85
  if (query.mode && route.mode !== query.mode) return false;
82
86
  if (query.readiness && route.readiness !== query.readiness) return false;
83
87
  if (query.admissionAction && route.admissionAction !== query.admissionAction) return false;
88
+ if (!representationCoverageMatches(route.representation, query)) return false;
84
89
  return true;
85
90
  });
86
91
  return {
@@ -113,10 +118,26 @@ function conversionRoute(language, target, input, planId) {
113
118
  const readiness = blockers.length
114
119
  ? 'blocked'
115
120
  : maxSemanticMergeReadiness(language.readiness, targetCell?.readiness ?? readinessCell?.readiness ?? 'needs-review');
116
- const components = conversionScoreComponents(language, targetCell, readiness, mode, input.evidence);
117
- const mergeScore = conversionMergeScore({ readiness, mode, components, blockers, review });
118
121
  const id = `conversion_${idFragment(language.language)}_to_${idFragment(target)}`;
119
122
  const routeImports = importsForConversionLanguage(input.imports, language);
123
+ const mergeRefs = conversionMergeRefs({
124
+ planId,
125
+ routeId: id,
126
+ imports: routeImports,
127
+ readiness,
128
+ admissionStatus: 'pending'
129
+ });
130
+ const representation = createUniversalRepresentationCoverage({
131
+ language,
132
+ target,
133
+ targetCell,
134
+ runtime,
135
+ mergeRefs,
136
+ evidence: input.evidence
137
+ });
138
+ const components = conversionScoreComponents(language, targetCell, readiness, mode, input.evidence, representation);
139
+ const mergeScore = conversionMergeScore({ readiness, mode, components, blockers, review });
140
+ const admissionStatus = mergeScore.action;
120
141
  return {
121
142
  id,
122
143
  sourceLanguage: language.language,
@@ -135,18 +156,13 @@ function conversionRoute(language, target, input, planId) {
135
156
  runtime,
136
157
  runtimeAdapterRequirements: runtime.adapterRequirements,
137
158
  evidence: conversionEvidence(language, targetCell),
159
+ representation,
138
160
  missingEvidence: conversionMissingEvidence(language, targetCell, mode),
139
161
  blockers,
140
162
  review,
141
163
  tasks: conversionTasks(language, target, mode, blockers, review),
142
164
  mergeScore,
143
- mergeRefs: conversionMergeRefs({
144
- planId,
145
- routeId: id,
146
- imports: routeImports,
147
- readiness,
148
- admissionStatus: mergeScore.action
149
- }),
165
+ mergeRefs: { ...mergeRefs, admissionStatus },
150
166
  autoMergeClaim: false,
151
167
  semanticEquivalenceClaim: false,
152
168
  metadata: {
@@ -0,0 +1,96 @@
1
+ import { uniqueStrings } from './native-import-utils.js';
2
+
3
+ export function routeAdmissionStatus(route) {
4
+ if (route.readiness === 'blocked' || route.admissionAction === 'reject') return 'blocked';
5
+ if (route.readiness === 'ready' && route.missingEvidence?.length === 0) return 'queued';
6
+ return 'needs-review';
7
+ }
8
+
9
+ export function routeReasonCodes(route) {
10
+ return uniqueStrings([
11
+ `mode:${route.mode}`,
12
+ `action:${route.routeAction}`,
13
+ ...(route.missingEvidence ?? []).map((item) => `missing:${item}`),
14
+ ...(route.blockers ?? []).map((item) => `blocker:${item}`),
15
+ ...(route.review ?? []).map((item) => `review:${item}`)
16
+ ]);
17
+ }
18
+
19
+ export function routeAdmissionMetadata(route, planId) {
20
+ return {
21
+ planId,
22
+ routeId: route.id,
23
+ routeAction: route.routeAction,
24
+ admissionAction: route.admissionAction,
25
+ priority: route.priority,
26
+ mergeScore: route.mergeScore,
27
+ representation: routeRepresentationMetadata(route),
28
+ ...routeSemanticEditRecordMetadata(route),
29
+ autoMergeClaim: false,
30
+ semanticEquivalenceClaim: false
31
+ };
32
+ }
33
+
34
+ export function routeRecordMetadata(route, planId, metadata) {
35
+ return {
36
+ planId,
37
+ routeId: route.id,
38
+ target: route.target,
39
+ mode: route.mode,
40
+ routeAction: route.routeAction,
41
+ representation: routeRepresentationMetadata(route),
42
+ ...routeSemanticEditRecordMetadata(route),
43
+ missingEvidence: route.missingEvidence ?? [],
44
+ blockers: route.blockers ?? [],
45
+ review: route.review ?? [],
46
+ autoMergeClaim: false,
47
+ semanticEquivalenceClaim: false,
48
+ ...metadata
49
+ };
50
+ }
51
+
52
+ export function routeSemanticEditBundle(route) {
53
+ const metadata = route.metadata ?? {};
54
+ const semanticEdit = metadata.semanticEdit ?? {};
55
+ return compactRecord({
56
+ semanticEditScript: firstDefined(route.semanticEditScript, metadata.semanticEditScript, semanticEdit.script),
57
+ semanticEditScripts: firstDefined(route.semanticEditScripts, metadata.semanticEditScripts, semanticEdit.scripts),
58
+ semanticEditProjection: firstDefined(route.semanticEditProjection, metadata.semanticEditProjection, semanticEdit.projection),
59
+ semanticEditProjections: firstDefined(route.semanticEditProjections, metadata.semanticEditProjections, semanticEdit.projections),
60
+ semanticEditReplay: firstDefined(route.semanticEditReplay, metadata.semanticEditReplay, semanticEdit.replay),
61
+ semanticEditReplays: firstDefined(route.semanticEditReplays, metadata.semanticEditReplays, semanticEdit.replays),
62
+ semanticEditAdmission: firstDefined(route.semanticEditAdmission, metadata.semanticEditAdmission, semanticEdit.admission),
63
+ evidence: firstDefined(route.semanticEditEvidence, metadata.semanticEditEvidence, semanticEdit.evidence),
64
+ testEvidence: firstDefined(route.semanticEditTestEvidence, metadata.semanticEditTestEvidence, semanticEdit.testEvidence),
65
+ gateEvidence: firstDefined(route.semanticEditGateEvidence, metadata.semanticEditGateEvidence, semanticEdit.gateEvidence),
66
+ proofEvidence: firstDefined(route.semanticEditProofEvidence, metadata.semanticEditProofEvidence, semanticEdit.proofEvidence)
67
+ });
68
+ }
69
+
70
+ function routeRepresentationMetadata(route) {
71
+ return {
72
+ constructKinds: route.representation?.constructKinds ?? [],
73
+ runtimeCapabilities: route.representation?.surfaces?.runtime?.requiredCapabilities ?? [],
74
+ sourceMapPrecisions: route.representation?.surfaces?.sourceMaps?.precisions ?? [],
75
+ transformIdentityHashes: route.representation?.surfaces?.mergeRefs?.transformIdentityHashes ?? [],
76
+ missing: route.representation?.missing ?? [],
77
+ blockers: route.representation?.blockers ?? []
78
+ };
79
+ }
80
+
81
+ function routeSemanticEditRecordMetadata(route) {
82
+ const metadata = route.metadata ?? {};
83
+ const semanticEdit = metadata.semanticEdit ?? {};
84
+ return compactRecord({
85
+ semanticEditSummary: firstDefined(metadata.semanticEditSummary, semanticEdit.summary),
86
+ semanticEditAdmission: firstDefined(route.semanticEditAdmission, metadata.semanticEditAdmission, semanticEdit.admission)
87
+ });
88
+ }
89
+
90
+ function firstDefined(...values) {
91
+ return values.find((value) => value !== undefined);
92
+ }
93
+
94
+ function compactRecord(value) {
95
+ return Object.fromEntries(Object.entries(value ?? {}).filter(([, entry]) => entry !== undefined && (!Array.isArray(entry) || entry.length > 0)));
96
+ }
@@ -47,6 +47,13 @@ function routeOperationMetadata(route, source, sourceMapLinks) {
47
47
  sourcePath: source.sourcePath,
48
48
  sourceHash: source.sourceHash,
49
49
  sourceMapLinkIds: sourceMapLinks.map((link) => link.id),
50
+ representation: {
51
+ constructKinds: route.representation?.constructKinds ?? [],
52
+ runtimeCapabilities: route.representation?.surfaces?.runtime?.requiredCapabilities ?? [],
53
+ sourceMapPrecisions: route.representation?.surfaces?.sourceMaps?.precisions ?? [],
54
+ missing: route.representation?.missing ?? [],
55
+ blockers: route.representation?.blockers ?? []
56
+ },
50
57
  targetLossKinds: route.evidence?.targetLossKinds ?? [],
51
58
  missingEvidence: route.missingEvidence ?? [],
52
59
  blockers: route.blockers ?? [],