@shapeshift-labs/frontier-lang-compiler 0.2.52 → 0.2.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.
- package/README.md +2 -1
- package/bench/native-transform-suite.mjs +16 -0
- package/bench/smoke.mjs +17 -0
- package/bench/source-change-suite.mjs +3 -1
- package/dist/declarations/semantic-sidecar.d.ts +12 -10
- package/dist/declarations/universal-conversion-artifacts.d.ts +97 -1
- package/dist/internal/index-impl/createLightweightNativeImport.js +10 -3
- package/dist/internal/index-impl/createSemanticImportSidecar.js +5 -1
- package/dist/lightweight-dependency-relations.js +271 -0
- package/dist/semantic-import-dependencies.js +62 -0
- package/dist/semantic-import-sidecar-entry.js +4 -0
- package/dist/semantic-import-sidecar-types.d.ts +22 -0
- package/dist/universal-conversion-admission-record.js +122 -0
- package/dist/universal-conversion-artifact-query.js +6 -0
- package/dist/universal-conversion-artifact-summary.js +37 -0
- package/dist/universal-conversion-artifacts.js +21 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -183,6 +183,7 @@ console.log(pythonToRust.mergeScore.value); // sortable merge-review score, not
|
|
|
183
183
|
const conversionArtifacts = createUniversalConversionArtifacts(conversionPlan);
|
|
184
184
|
console.log(conversionArtifacts.historyRecords[0].kind); // "frontier.lang.semanticHistoryRecord"
|
|
185
185
|
console.log(conversionArtifacts.patchBundleRecords[0].admission.autoMergeClaim); // false
|
|
186
|
+
console.log(conversionArtifacts.admissionRecords[0].admissionBucket); // "blocked", "needs-evidence", "merge-ready", etc.
|
|
186
187
|
console.log(conversionArtifacts.index.semanticOperationKinds); // sourcePreservation/projection/merge
|
|
187
188
|
console.log(conversionArtifacts.routeArtifacts[0].semanticOperations.summary.conflictKeys);
|
|
188
189
|
```
|
|
@@ -199,7 +200,7 @@ The projection target matrix separates five runtime/API classes:
|
|
|
199
200
|
|
|
200
201
|
`createUniversalConversionPlan` turns that capability evidence into coordinator tasks: preserve exact source, run a target adapter, emit stubs, attach semantic-index evidence, or block the route until missing parser/adapter/proof evidence exists. Every route carries `autoMergeClaim: false`, `semanticEquivalenceClaim: false`, missing evidence, task hints, and a `frontier.lang.semanticMergeScore.v1` score for swarm merge admission.
|
|
201
202
|
|
|
202
|
-
`createUniversalConversionArtifacts` materializes those route refs into compact `SemanticHistoryRecord`, `SemanticPatchBundleRecord`,
|
|
203
|
+
`createUniversalConversionArtifacts` materializes those route refs into compact `SemanticHistoryRecord`, `SemanticPatchBundleRecord`, semantic operation sets, and `UniversalConversionAdmissionRecord` rows that swarm collectors can index by route, history ID, patch-bundle ID, admission-record ID, admission bucket, risk, operation kind, source path, ownership key, conflict key, evidence, proof, readiness, and admission status. It is still review evidence, not target-code proof: blocked and semantic-index-only routes stay blocked/needs-review, and every artifact keeps `autoMergeClaim: false` plus `semanticEquivalenceClaim: false`.
|
|
203
204
|
|
|
204
205
|
Preserve exact native source text, token/trivia hashes, comments, whitespace, and source directives as evidence. This does not claim full semantic understanding; it keeps round-trip material available while exact parser adapters catch up:
|
|
205
206
|
|
|
@@ -95,6 +95,22 @@ export function measureNativeTransformations(nativeImportResults) {
|
|
|
95
95
|
conversionArtifacts: conversionArtifacts.summary.routes,
|
|
96
96
|
conversionArtifactHistories: conversionArtifacts.summary.histories,
|
|
97
97
|
conversionArtifactPatchBundles: conversionArtifacts.summary.patchBundles,
|
|
98
|
+
conversionArtifactAdmissionRecords: conversionArtifacts.summary.admissionRecords,
|
|
99
|
+
conversionArtifactMergeReady: conversionArtifacts.summary.mergeReady,
|
|
100
|
+
conversionArtifactNeedsEvidence: conversionArtifacts.summary.needsEvidence,
|
|
101
|
+
conversionArtifactNeedsAdapter: conversionArtifacts.summary.needsAdapter,
|
|
102
|
+
conversionArtifactNeedsReview: conversionArtifacts.summary.needsReview,
|
|
103
|
+
conversionArtifactAdmissionBlocked: conversionArtifacts.summary.admissionBlocked,
|
|
104
|
+
conversionArtifactLowRisk: conversionArtifacts.summary.lowRisk,
|
|
105
|
+
conversionArtifactMediumRisk: conversionArtifacts.summary.mediumRisk,
|
|
106
|
+
conversionArtifactHighRisk: conversionArtifacts.summary.highRisk,
|
|
107
|
+
conversionArtifactQueued: conversionArtifacts.summary.queued,
|
|
108
|
+
conversionArtifactAdmissionReasonCodes: conversionArtifacts.summary.reasonCodes,
|
|
109
|
+
conversionArtifactAdmissionMissingEvidence: conversionArtifacts.summary.missingEvidence,
|
|
110
|
+
conversionArtifactAdmissionBlockers: conversionArtifacts.summary.blockers,
|
|
111
|
+
conversionArtifactAdmissionReviewReasons: conversionArtifacts.summary.reviewReasons,
|
|
112
|
+
conversionArtifactAdmissionEvidenceIds: conversionArtifacts.summary.evidenceIds,
|
|
113
|
+
conversionArtifactAdmissionProofIds: conversionArtifacts.summary.proofIds,
|
|
98
114
|
conversionArtifactsDurationMs,
|
|
99
115
|
featureEvidencePolicyMatches,
|
|
100
116
|
featureEvidenceDurationMs,
|
package/bench/smoke.mjs
CHANGED
|
@@ -63,6 +63,22 @@ console.log(JSON.stringify({
|
|
|
63
63
|
conversionArtifacts: transformMetrics.conversionArtifacts,
|
|
64
64
|
conversionArtifactHistories: transformMetrics.conversionArtifactHistories,
|
|
65
65
|
conversionArtifactPatchBundles: transformMetrics.conversionArtifactPatchBundles,
|
|
66
|
+
conversionArtifactAdmissionRecords: transformMetrics.conversionArtifactAdmissionRecords,
|
|
67
|
+
conversionArtifactMergeReady: transformMetrics.conversionArtifactMergeReady,
|
|
68
|
+
conversionArtifactNeedsEvidence: transformMetrics.conversionArtifactNeedsEvidence,
|
|
69
|
+
conversionArtifactNeedsAdapter: transformMetrics.conversionArtifactNeedsAdapter,
|
|
70
|
+
conversionArtifactNeedsReview: transformMetrics.conversionArtifactNeedsReview,
|
|
71
|
+
conversionArtifactAdmissionBlocked: transformMetrics.conversionArtifactAdmissionBlocked,
|
|
72
|
+
conversionArtifactLowRisk: transformMetrics.conversionArtifactLowRisk,
|
|
73
|
+
conversionArtifactMediumRisk: transformMetrics.conversionArtifactMediumRisk,
|
|
74
|
+
conversionArtifactHighRisk: transformMetrics.conversionArtifactHighRisk,
|
|
75
|
+
conversionArtifactQueued: transformMetrics.conversionArtifactQueued,
|
|
76
|
+
conversionArtifactAdmissionReasonCodes: transformMetrics.conversionArtifactAdmissionReasonCodes,
|
|
77
|
+
conversionArtifactAdmissionMissingEvidence: transformMetrics.conversionArtifactAdmissionMissingEvidence,
|
|
78
|
+
conversionArtifactAdmissionBlockers: transformMetrics.conversionArtifactAdmissionBlockers,
|
|
79
|
+
conversionArtifactAdmissionReviewReasons: transformMetrics.conversionArtifactAdmissionReviewReasons,
|
|
80
|
+
conversionArtifactAdmissionEvidenceIds: transformMetrics.conversionArtifactAdmissionEvidenceIds,
|
|
81
|
+
conversionArtifactAdmissionProofIds: transformMetrics.conversionArtifactAdmissionProofIds,
|
|
66
82
|
conversionArtifactsDurationMs: Number(transformMetrics.conversionArtifactsDurationMs.toFixed(2)),
|
|
67
83
|
featureEvidencePolicyMatches: transformMetrics.featureEvidencePolicyMatches,
|
|
68
84
|
featureEvidenceDurationMs: Number(transformMetrics.featureEvidenceDurationMs.toFixed(2)),
|
|
@@ -81,6 +97,7 @@ console.log(JSON.stringify({
|
|
|
81
97
|
nativeTargetAdapterDurationMs: Number(transformMetrics.nativeTargetAdapterDurationMs.toFixed(2)),
|
|
82
98
|
regionScanImports: sourceChangeMetrics.regionScanImports,
|
|
83
99
|
regionScanSymbols: sourceChangeMetrics.regionScanSymbols,
|
|
100
|
+
regionScanDependencyRelations: sourceChangeMetrics.regionScanDependencyRelations,
|
|
84
101
|
regionScanOwnershipRegions: sourceChangeMetrics.regionScanOwnershipRegions,
|
|
85
102
|
regionScanDurationMs: Number(sourceChangeMetrics.regionScanDurationMs.toFixed(2)),
|
|
86
103
|
changeProjectionSets: sourceChangeMetrics.changeProjectionSets,
|
|
@@ -22,6 +22,7 @@ function measureRegionScan() {
|
|
|
22
22
|
language: 'typescript',
|
|
23
23
|
sourcePath: `src/regions-${index}.ts`,
|
|
24
24
|
sourceText: `
|
|
25
|
+
export function normalizeCount${index}(value) { return value; }
|
|
25
26
|
export const appRoutes${index} = [
|
|
26
27
|
{ path: "/${index}", component: Screen${index} },
|
|
27
28
|
{ path: "/${index}/settings", component: Settings${index} }
|
|
@@ -31,7 +32,7 @@ function measureRegionScan() {
|
|
|
31
32
|
legal: { title: "Legal ${index}" }
|
|
32
33
|
};
|
|
33
34
|
export const runtimeConfig${index} = {
|
|
34
|
-
limits: { count: ${index} },
|
|
35
|
+
limits: { count: normalizeCount${index}(${index}) },
|
|
35
36
|
resolve(id) { return id; }
|
|
36
37
|
};
|
|
37
38
|
export const helpers${index} = {
|
|
@@ -45,6 +46,7 @@ function measureRegionScan() {
|
|
|
45
46
|
return {
|
|
46
47
|
regionScanImports: regionScanImports.length,
|
|
47
48
|
regionScanSymbols: regionScanImports.reduce((sum, entry) => sum + entry.imported.semanticIndex.symbols.length, 0),
|
|
49
|
+
regionScanDependencyRelations: regionScanImports.reduce((sum, entry) => sum + entry.sidecar.dependencies.total, 0),
|
|
48
50
|
regionScanOwnershipRegions: regionScanImports.reduce((sum, entry) => sum + entry.sidecar.ownershipRegions.length, 0),
|
|
49
51
|
regionScanDurationMs
|
|
50
52
|
};
|
|
@@ -132,6 +132,7 @@ export interface SemanticImportSidecarImportEntry {
|
|
|
132
132
|
readonly universalAstLayerIds: readonly string[];
|
|
133
133
|
readonly proofSpec: SemanticImportSidecarProofSpecSummary;
|
|
134
134
|
readonly paradigmSemantics: SemanticImportSidecarParadigmSemanticsSummary;
|
|
135
|
+
readonly dependencyRelationCount: number; readonly dependencyPredicates: readonly string[];
|
|
135
136
|
readonly readiness: SemanticMergeReadiness;
|
|
136
137
|
readonly emptySemanticIndex: boolean;
|
|
137
138
|
readonly regionTaxonomy?: SemanticImportRegionTaxonomySummary;
|
|
@@ -228,6 +229,13 @@ export interface SemanticImportSidecarParadigmSemanticsSummary {
|
|
|
228
229
|
readonly empty: boolean;
|
|
229
230
|
}
|
|
230
231
|
|
|
232
|
+
export interface SemanticImportDependencySummary {
|
|
233
|
+
readonly total: number; readonly calls: number; readonly uses: number; readonly references: number;
|
|
234
|
+
readonly imports: number; readonly extends: number; readonly implements: number; readonly includes: number; readonly requires: number;
|
|
235
|
+
readonly byPredicate: Readonly<Record<string, number>>; readonly predicates: readonly string[];
|
|
236
|
+
readonly ids: readonly string[]; readonly sourceSymbolIds: readonly string[]; readonly targetSymbolIds: readonly string[];
|
|
237
|
+
}
|
|
238
|
+
|
|
231
239
|
export interface SemanticImportSidecar {
|
|
232
240
|
readonly kind: 'frontier.lang.semanticImportSidecar';
|
|
233
241
|
readonly version: 1;
|
|
@@ -238,11 +246,7 @@ export interface SemanticImportSidecar {
|
|
|
238
246
|
readonly imports: readonly SemanticImportSidecarImportEntry[];
|
|
239
247
|
readonly symbols: readonly SemanticImportSidecarSymbol[];
|
|
240
248
|
readonly ownershipRegions: readonly SemanticImportOwnershipRegion[];
|
|
241
|
-
readonly sourceMaps: {
|
|
242
|
-
readonly total: number;
|
|
243
|
-
readonly mappings: number;
|
|
244
|
-
readonly ids: readonly string[];
|
|
245
|
-
};
|
|
249
|
+
readonly sourceMaps: { readonly total: number; readonly mappings: number; readonly ids: readonly string[] };
|
|
246
250
|
readonly sourcePreservation: {
|
|
247
251
|
readonly total: number;
|
|
248
252
|
readonly ids: readonly string[];
|
|
@@ -259,6 +263,7 @@ export interface SemanticImportSidecar {
|
|
|
259
263
|
readonly universalAstLayers: SemanticImportSidecarUniversalAstLayerSummary;
|
|
260
264
|
readonly proofSpec: SemanticImportSidecarProofSpecSummary;
|
|
261
265
|
readonly paradigmSemantics: SemanticImportSidecarParadigmSemanticsSummary;
|
|
266
|
+
readonly dependencies: SemanticImportDependencySummary;
|
|
262
267
|
readonly patchHints: readonly SemanticImportPatchHint[];
|
|
263
268
|
readonly quality: SemanticImportSidecarQuality;
|
|
264
269
|
readonly admission: SemanticImportSidecarAdmission;
|
|
@@ -280,11 +285,7 @@ export interface SemanticImportSidecar {
|
|
|
280
285
|
readonly reviewLossIds: readonly string[];
|
|
281
286
|
};
|
|
282
287
|
readonly regionTaxonomy: SemanticImportRegionTaxonomySummary;
|
|
283
|
-
readonly evidence: {
|
|
284
|
-
readonly total: number;
|
|
285
|
-
readonly failed: readonly string[];
|
|
286
|
-
readonly ids: readonly string[];
|
|
287
|
-
};
|
|
288
|
+
readonly evidence: { readonly total: number; readonly failed: readonly string[]; readonly ids: readonly string[] };
|
|
288
289
|
readonly summary: {
|
|
289
290
|
readonly imports: number;
|
|
290
291
|
readonly symbols: number;
|
|
@@ -300,6 +301,7 @@ export interface SemanticImportSidecar {
|
|
|
300
301
|
readonly paradigmSemanticsRecords: number;
|
|
301
302
|
readonly paradigmSemanticsGroups: number;
|
|
302
303
|
readonly paradigmSemanticsLoweringRecords: number;
|
|
304
|
+
readonly dependencyRelations: number; readonly dependencyPredicates: readonly string[];
|
|
303
305
|
readonly patchHints: number;
|
|
304
306
|
readonly evidenceWarnings: number;
|
|
305
307
|
readonly readiness: SemanticMergeReadiness;
|
|
@@ -14,10 +14,18 @@ import type {
|
|
|
14
14
|
UniversalConversionRoute,
|
|
15
15
|
UniversalConversionRouteAction,
|
|
16
16
|
UniversalConversionRouteMode,
|
|
17
|
-
UniversalConversionMergeScore
|
|
17
|
+
UniversalConversionMergeScore,
|
|
18
|
+
UniversalConversionRisk
|
|
18
19
|
} from './universal-conversion-plan.js';
|
|
19
20
|
|
|
20
21
|
export type UniversalConversionArtifactAdmissionStatus = 'queued' | 'needs-review' | 'blocked' | string;
|
|
22
|
+
export type UniversalConversionArtifactAdmissionBucket =
|
|
23
|
+
| 'merge-ready'
|
|
24
|
+
| 'needs-evidence'
|
|
25
|
+
| 'needs-adapter'
|
|
26
|
+
| 'needs-review'
|
|
27
|
+
| 'blocked'
|
|
28
|
+
| string;
|
|
21
29
|
export type UniversalConversionArtifactMaterializationStatus = 'materialized' | 'planned-only' | 'missing' | 'failed' | string;
|
|
22
30
|
|
|
23
31
|
export interface UniversalConversionArtifactMaterialization {
|
|
@@ -33,6 +41,69 @@ export interface UniversalConversionArtifactMaterialization {
|
|
|
33
41
|
readonly semanticEquivalenceClaim: false;
|
|
34
42
|
}
|
|
35
43
|
|
|
44
|
+
export interface UniversalConversionAdmissionRecord {
|
|
45
|
+
readonly kind: 'frontier.lang.universalConversionAdmissionRecord';
|
|
46
|
+
readonly version: 1;
|
|
47
|
+
readonly schema: 'frontier.lang.universalConversionAdmissionRecord.v1';
|
|
48
|
+
readonly id: string;
|
|
49
|
+
readonly routeId: string;
|
|
50
|
+
readonly planId?: string;
|
|
51
|
+
readonly sourceLanguage?: FrontierSourceLanguage | string;
|
|
52
|
+
readonly target?: FrontierCompileTarget | string;
|
|
53
|
+
readonly mode: UniversalConversionRouteMode;
|
|
54
|
+
readonly routeAction: UniversalConversionRouteAction;
|
|
55
|
+
readonly admissionStatus: UniversalConversionArtifactAdmissionStatus;
|
|
56
|
+
readonly admissionAction: UniversalConversionAdmissionAction;
|
|
57
|
+
readonly admissionBucket: UniversalConversionArtifactAdmissionBucket;
|
|
58
|
+
readonly reviewRequired: true;
|
|
59
|
+
readonly readiness: SemanticMergeReadiness | string;
|
|
60
|
+
readonly risk: UniversalConversionRisk | string;
|
|
61
|
+
readonly score: {
|
|
62
|
+
readonly value: number;
|
|
63
|
+
readonly uncappedValue: number;
|
|
64
|
+
readonly sortKey: number;
|
|
65
|
+
readonly higherIsBetter: true;
|
|
66
|
+
readonly componentStatuses: Record<string, string>;
|
|
67
|
+
readonly penalties: readonly string[];
|
|
68
|
+
};
|
|
69
|
+
readonly ids: {
|
|
70
|
+
readonly historyId?: string;
|
|
71
|
+
readonly patchBundleId?: string;
|
|
72
|
+
readonly semanticOperationIds: readonly string[];
|
|
73
|
+
readonly sourceMapLinkIds: readonly string[];
|
|
74
|
+
readonly evidenceIds: readonly string[];
|
|
75
|
+
readonly proofIds: readonly string[];
|
|
76
|
+
};
|
|
77
|
+
readonly semanticOperations: {
|
|
78
|
+
readonly total: number;
|
|
79
|
+
readonly byKind: Record<string, number>;
|
|
80
|
+
readonly kinds: readonly string[];
|
|
81
|
+
readonly dynamic: readonly string[];
|
|
82
|
+
readonly opaque: readonly string[];
|
|
83
|
+
};
|
|
84
|
+
readonly ownership: {
|
|
85
|
+
readonly keys: readonly string[];
|
|
86
|
+
readonly conflictKeys: readonly string[];
|
|
87
|
+
};
|
|
88
|
+
readonly source: {
|
|
89
|
+
readonly paths: readonly string[];
|
|
90
|
+
readonly hashes: readonly string[];
|
|
91
|
+
readonly baseHashes: readonly string[];
|
|
92
|
+
readonly targetHashes: readonly string[];
|
|
93
|
+
};
|
|
94
|
+
readonly evidence: {
|
|
95
|
+
readonly total: number;
|
|
96
|
+
readonly proofArtifacts: number;
|
|
97
|
+
readonly missing: readonly string[];
|
|
98
|
+
readonly blockers: readonly string[];
|
|
99
|
+
readonly review: readonly string[];
|
|
100
|
+
};
|
|
101
|
+
readonly reasons: readonly string[];
|
|
102
|
+
readonly autoMergeClaim: false;
|
|
103
|
+
readonly semanticEquivalenceClaim: false;
|
|
104
|
+
readonly metadata: Record<string, unknown>;
|
|
105
|
+
}
|
|
106
|
+
|
|
36
107
|
export interface UniversalConversionRouteArtifact {
|
|
37
108
|
readonly kind: 'frontier.lang.universalConversionRouteArtifact';
|
|
38
109
|
readonly version: 1;
|
|
@@ -50,9 +121,11 @@ export interface UniversalConversionRouteArtifact {
|
|
|
50
121
|
readonly reviewRequired: true;
|
|
51
122
|
readonly history: SemanticHistoryRecord;
|
|
52
123
|
readonly patchBundle: SemanticPatchBundleRecord;
|
|
124
|
+
readonly admissionRecord: UniversalConversionAdmissionRecord;
|
|
53
125
|
readonly semanticOperations: SemanticOperationSet;
|
|
54
126
|
readonly materialization: UniversalConversionArtifactMaterialization;
|
|
55
127
|
readonly mergeScore?: UniversalConversionMergeScore;
|
|
128
|
+
readonly admissionBucket: UniversalConversionArtifactAdmissionBucket;
|
|
56
129
|
readonly autoMergeClaim: false;
|
|
57
130
|
readonly semanticEquivalenceClaim: false;
|
|
58
131
|
readonly metadata: Record<string, unknown>;
|
|
@@ -62,11 +135,14 @@ export interface UniversalConversionArtifactIndex {
|
|
|
62
135
|
readonly routeIds: readonly string[];
|
|
63
136
|
readonly historyIds: readonly string[];
|
|
64
137
|
readonly patchBundleIds: readonly string[];
|
|
138
|
+
readonly admissionRecordIds: readonly string[];
|
|
65
139
|
readonly languages: readonly string[];
|
|
66
140
|
readonly targets: readonly string[];
|
|
67
141
|
readonly modes: readonly string[];
|
|
68
142
|
readonly readinesses: readonly string[];
|
|
69
143
|
readonly admissionStatuses: readonly string[];
|
|
144
|
+
readonly admissionBuckets: readonly string[];
|
|
145
|
+
readonly admissionRisks: readonly string[];
|
|
70
146
|
readonly sourcePaths: readonly string[];
|
|
71
147
|
readonly sourceHashes: readonly string[];
|
|
72
148
|
readonly ownershipKeys: readonly string[];
|
|
@@ -87,14 +163,31 @@ export interface UniversalConversionArtifacts {
|
|
|
87
163
|
readonly routeArtifacts: readonly UniversalConversionRouteArtifact[];
|
|
88
164
|
readonly historyRecords: readonly SemanticHistoryRecord[];
|
|
89
165
|
readonly patchBundleRecords: readonly SemanticPatchBundleRecord[];
|
|
166
|
+
readonly admissionRecords: readonly UniversalConversionAdmissionRecord[];
|
|
90
167
|
readonly index: UniversalConversionArtifactIndex;
|
|
91
168
|
readonly summary: {
|
|
92
169
|
readonly routes: number;
|
|
93
170
|
readonly histories: number;
|
|
94
171
|
readonly patchBundles: number;
|
|
172
|
+
readonly admissionRecords: number;
|
|
95
173
|
readonly semanticOperations: number;
|
|
174
|
+
readonly mergeReady: number;
|
|
175
|
+
readonly needsEvidence: number;
|
|
176
|
+
readonly needsAdapter: number;
|
|
177
|
+
readonly needsReview: number;
|
|
178
|
+
readonly admissionBlocked: number;
|
|
179
|
+
readonly lowRisk: number;
|
|
180
|
+
readonly mediumRisk: number;
|
|
181
|
+
readonly highRisk: number;
|
|
182
|
+
readonly queued: number;
|
|
96
183
|
readonly reviewRequired: number;
|
|
97
184
|
readonly blocked: number;
|
|
185
|
+
readonly reasonCodes: number;
|
|
186
|
+
readonly missingEvidence: number;
|
|
187
|
+
readonly blockers: number;
|
|
188
|
+
readonly reviewReasons: number;
|
|
189
|
+
readonly evidenceIds: number;
|
|
190
|
+
readonly proofIds: number;
|
|
98
191
|
readonly autoMergeClaims: 0;
|
|
99
192
|
readonly semanticEquivalenceClaims: 0;
|
|
100
193
|
};
|
|
@@ -128,12 +221,15 @@ export interface UniversalConversionArtifactQuery {
|
|
|
128
221
|
readonly routeId?: string | readonly string[];
|
|
129
222
|
readonly historyId?: string | readonly string[];
|
|
130
223
|
readonly patchBundleId?: string | readonly string[];
|
|
224
|
+
readonly admissionRecordId?: string | readonly string[];
|
|
131
225
|
readonly sourceLanguage?: FrontierSourceLanguage | string | readonly string[];
|
|
132
226
|
readonly target?: FrontierCompileTarget | string | readonly string[];
|
|
133
227
|
readonly mode?: UniversalConversionRouteMode | readonly string[];
|
|
134
228
|
readonly readiness?: SemanticMergeReadiness | string | readonly string[];
|
|
135
229
|
readonly admissionAction?: UniversalConversionAdmissionAction | readonly string[];
|
|
136
230
|
readonly admissionStatus?: UniversalConversionArtifactAdmissionStatus | readonly string[];
|
|
231
|
+
readonly admissionBucket?: UniversalConversionArtifactAdmissionBucket | readonly string[];
|
|
232
|
+
readonly risk?: UniversalConversionRisk | string | readonly string[];
|
|
137
233
|
readonly priority?: UniversalConversionPriority | readonly string[];
|
|
138
234
|
readonly routeAction?: UniversalConversionRouteAction | readonly string[];
|
|
139
235
|
readonly sourcePath?: string | readonly string[];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{idFragment}from'../../native-import-utils.js';import{lightweightCoverageLosses,scanNativeDeclarations}from'../../native-region-scanner.js';import{semanticOwnershipRegionForDeclaration}from'../../semantic-import-regions.js';import{createSemanticIndexRecord,hashSemanticValue}from'@shapeshift-labs/frontier-lang-kernel';
|
|
1
|
+
import{idFragment}from'../../native-import-utils.js';import{lightweightDependencyRelations}from'../../lightweight-dependency-relations.js';import{lightweightCoverageLosses,scanNativeDeclarations}from'../../native-region-scanner.js';import{semanticOwnershipRegionForDeclaration}from'../../semantic-import-regions.js';import{createSemanticIndexRecord,hashSemanticValue}from'@shapeshift-labs/frontier-lang-kernel';
|
|
2
2
|
export function createLightweightNativeImport(input) {
|
|
3
3
|
const parser = input.parser ?? `${input.language}.lightweight-declaration-scan`;
|
|
4
4
|
const rootId = 'native_root';
|
|
@@ -20,6 +20,7 @@ export function createLightweightNativeImport(input) {
|
|
|
20
20
|
const facts = [];
|
|
21
21
|
const mappings = [];
|
|
22
22
|
const evidenceId = `evidence_${idFragment(input.sourcePath ?? input.language)}_lightweight_scan`;
|
|
23
|
+
const dependencies = lightweightDependencyRelations(input, declarations, documentId);
|
|
23
24
|
|
|
24
25
|
for (const declaration of declarations) {
|
|
25
26
|
const ownershipRegion = semanticOwnershipRegionForDeclaration(input, declaration, documentId);
|
|
@@ -105,6 +106,9 @@ export function createLightweightNativeImport(input) {
|
|
|
105
106
|
}
|
|
106
107
|
if (declaration.loss) losses.push(declaration.loss);
|
|
107
108
|
}
|
|
109
|
+
occurrences.push(...dependencies.occurrences);
|
|
110
|
+
relations.push(...dependencies.relations);
|
|
111
|
+
facts.push(...dependencies.facts);
|
|
108
112
|
losses.push(...lightweightCoverageLosses(input, declarations, input.sourcePreservation));
|
|
109
113
|
|
|
110
114
|
const semanticIndex = createSemanticIndexRecord({
|
|
@@ -124,12 +128,13 @@ export function createLightweightNativeImport(input) {
|
|
|
124
128
|
kind: 'import',
|
|
125
129
|
status: 'passed',
|
|
126
130
|
path: input.sourcePath,
|
|
127
|
-
summary: `Lightweight declaration scan found ${symbols.length} symbol(s).`,
|
|
128
|
-
metadata: { parser }
|
|
131
|
+
summary: `Lightweight declaration scan found ${symbols.length} symbol(s) and ${dependencies.summary.total} dependency edge(s).`,
|
|
132
|
+
metadata: { parser, dependencyRelations: dependencies.summary.total }
|
|
129
133
|
}],
|
|
130
134
|
metadata: {
|
|
131
135
|
parser,
|
|
132
136
|
coverage: 'declarations-only',
|
|
137
|
+
dependencyRelations: dependencies.summary,
|
|
133
138
|
unsupported: ['full expression AST', 'type checking', 'control flow', 'comments and formatting preservation']
|
|
134
139
|
}
|
|
135
140
|
});
|
|
@@ -145,6 +150,8 @@ export function createLightweightNativeImport(input) {
|
|
|
145
150
|
parser,
|
|
146
151
|
scanKind: 'lightweight-declaration-scan',
|
|
147
152
|
declarationCount: declarations.length,
|
|
153
|
+
dependencyRelationCount: dependencies.summary.total,
|
|
154
|
+
dependencyOccurrenceCount: dependencies.occurrences.length,
|
|
148
155
|
...(input.sourcePreservation ? {
|
|
149
156
|
sourcePreservationId: input.sourcePreservation.id,
|
|
150
157
|
sourcePreservationSummary: input.sourcePreservation.summary
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{idFragment,maxSemanticMergeReadiness,uniqueRecordsById}from'../../native-import-utils.js';import{summarizeSemanticImportSidecarParadigmSemantics,summarizeSemanticImportSidecarProofSpec,summarizeSemanticImportSidecarUniversalAstLayers}from'../../semantic-import-layers.js';import{semanticPatchHintForRegion,summarizeSemanticImportRegionTaxonomy}from'../../semantic-import-regions.js';import{semanticImportSidecarEntry}from'../../semantic-import-sidecar-entry.js';import{summarizeKernelSourcePreservation}from'../../semantic-import-source-preservation.js';
|
|
1
|
+
import{idFragment,maxSemanticMergeReadiness,uniqueRecordsById}from'../../native-import-utils.js';import{summarizeSemanticImportDependencies}from'../../semantic-import-dependencies.js';import{summarizeSemanticImportSidecarParadigmSemantics,summarizeSemanticImportSidecarProofSpec,summarizeSemanticImportSidecarUniversalAstLayers}from'../../semantic-import-layers.js';import{semanticPatchHintForRegion,summarizeSemanticImportRegionTaxonomy}from'../../semantic-import-regions.js';import{semanticImportSidecarEntry}from'../../semantic-import-sidecar-entry.js';import{summarizeKernelSourcePreservation}from'../../semantic-import-source-preservation.js';
|
|
2
2
|
import{createSemanticImportSidecarAdmission,createSemanticImportSidecarQuality}from'./createSemanticImportSidecarAdmission.js';
|
|
3
3
|
import{summarizeNativeImportLosses}from'./summarizeNativeImportLosses.js';
|
|
4
4
|
export function createSemanticImportSidecar(importResult, options = {}) {
|
|
@@ -17,6 +17,7 @@ export function createSemanticImportSidecar(importResult, options = {}) {
|
|
|
17
17
|
const universalAstLayers = summarizeSemanticImportSidecarUniversalAstLayers(importEntries);
|
|
18
18
|
const proofSpec = summarizeSemanticImportSidecarProofSpec(importEntries);
|
|
19
19
|
const paradigmSemantics = summarizeSemanticImportSidecarParadigmSemantics(importEntries);
|
|
20
|
+
const dependencies = summarizeSemanticImportDependencies(imports);
|
|
20
21
|
const readiness = mergeCandidates.reduce(
|
|
21
22
|
(current, candidate) => maxSemanticMergeReadiness(current, candidate.readiness),
|
|
22
23
|
lossSummary.semanticMergeReadiness
|
|
@@ -51,6 +52,7 @@ export function createSemanticImportSidecar(importResult, options = {}) {
|
|
|
51
52
|
universalAstLayers,
|
|
52
53
|
proofSpec,
|
|
53
54
|
paradigmSemantics,
|
|
55
|
+
dependencies,
|
|
54
56
|
patchHints,
|
|
55
57
|
quality,
|
|
56
58
|
admission,
|
|
@@ -92,6 +94,8 @@ export function createSemanticImportSidecar(importResult, options = {}) {
|
|
|
92
94
|
paradigmSemanticsRecords: paradigmSemantics.total,
|
|
93
95
|
paradigmSemanticsGroups: paradigmSemantics.groups.length,
|
|
94
96
|
paradigmSemanticsLoweringRecords: paradigmSemantics.loweringRecords,
|
|
97
|
+
dependencyRelations: dependencies.total,
|
|
98
|
+
dependencyPredicates: dependencies.predicates,
|
|
95
99
|
patchHints: patchHints.length,
|
|
96
100
|
evidenceWarnings: quality.emptyEvidenceWarnings.length,
|
|
97
101
|
readiness,
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
import { idFragment } from './native-import-utils.js';
|
|
2
|
+
import { sourceLines } from './native-region-scanner-core.js';
|
|
3
|
+
|
|
4
|
+
const jsLikeLanguages = new Set(['javascript', 'typescript']);
|
|
5
|
+
const ignoredIdentifiers = new Set([
|
|
6
|
+
'async', 'await', 'break', 'case', 'catch', 'class', 'const', 'continue', 'default',
|
|
7
|
+
'delete', 'do', 'else', 'export', 'extends', 'false', 'finally', 'for', 'from',
|
|
8
|
+
'function', 'if', 'import', 'in', 'instanceof', 'let', 'new', 'null', 'of',
|
|
9
|
+
'return', 'static', 'super', 'switch', 'this', 'throw', 'true', 'try', 'typeof',
|
|
10
|
+
'undefined', 'var', 'void', 'while', 'with', 'yield'
|
|
11
|
+
]);
|
|
12
|
+
|
|
13
|
+
export function lightweightDependencyRelations(input, declarations, documentId) {
|
|
14
|
+
if (!jsLikeLanguages.has(String(input.language ?? '').toLowerCase())) {
|
|
15
|
+
return { relations: [], occurrences: [], facts: [], summary: emptySummary() };
|
|
16
|
+
}
|
|
17
|
+
const lines = sourceLines(input.sourceText);
|
|
18
|
+
const identifiers = declarationIdentifierMap(input, declarations, lines);
|
|
19
|
+
const records = { relations: [], occurrences: [], facts: [], seen: new Set() };
|
|
20
|
+
for (const scan of declarationScanRanges(declarations, lines)) {
|
|
21
|
+
scanDeclarationDependencies(input, documentId, scan, identifiers, lines, records);
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
relations: records.relations,
|
|
25
|
+
occurrences: records.occurrences,
|
|
26
|
+
facts: records.facts,
|
|
27
|
+
summary: {
|
|
28
|
+
total: records.relations.length,
|
|
29
|
+
calls: records.relations.filter((relation) => relation.predicate === 'calls').length,
|
|
30
|
+
uses: records.relations.filter((relation) => relation.predicate === 'uses').length
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function declarationIdentifierMap(input, declarations, lines) {
|
|
36
|
+
const identifiers = new Map();
|
|
37
|
+
for (const declaration of declarations ?? []) {
|
|
38
|
+
if (!declaration?.symbolId) continue;
|
|
39
|
+
const target = {
|
|
40
|
+
name: declaration.name,
|
|
41
|
+
symbolId: declaration.symbolId,
|
|
42
|
+
symbolKind: declaration.symbolKind,
|
|
43
|
+
nodeId: declaration.nodeId,
|
|
44
|
+
role: declaration.role
|
|
45
|
+
};
|
|
46
|
+
for (const identifier of identifiersForDeclaration(input, declaration, lines)) {
|
|
47
|
+
addIdentifierTarget(identifiers, identifier, target);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return identifiers;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function identifiersForDeclaration(input, declaration, lines) {
|
|
54
|
+
const identifiers = new Set();
|
|
55
|
+
addIdentifier(identifiers, declaration.name);
|
|
56
|
+
const parts = String(declaration.name ?? '').split('.');
|
|
57
|
+
addIdentifier(identifiers, parts[parts.length - 1]);
|
|
58
|
+
if (declaration.role === 'import') {
|
|
59
|
+
const line = lines[(declaration.span?.startLine ?? 1) - 1]?.line ?? '';
|
|
60
|
+
for (const identifier of importLocalIdentifiers(line)) addIdentifier(identifiers, identifier);
|
|
61
|
+
addIdentifier(identifiers, packageIdentifier(declaration.importPath ?? declaration.name));
|
|
62
|
+
}
|
|
63
|
+
return [...identifiers];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function importLocalIdentifiers(line) {
|
|
67
|
+
const source = String(line ?? '');
|
|
68
|
+
const identifiers = [];
|
|
69
|
+
let match = source.match(/^import\s+([A-Za-z_$][\w$]*)\s+from\b/);
|
|
70
|
+
if (match) identifiers.push(match[1]);
|
|
71
|
+
match = source.match(/^import\s+\*\s+as\s+([A-Za-z_$][\w$]*)\s+from\b/);
|
|
72
|
+
if (match) identifiers.push(match[1]);
|
|
73
|
+
match = source.match(/^import\s+[^,{]+,\s*\{([^}]+)\}\s+from\b/);
|
|
74
|
+
if (match) identifiers.push(...namedImportIdentifiers(match[1]));
|
|
75
|
+
match = source.match(/^import\s+\{([^}]+)\}\s+from\b/);
|
|
76
|
+
if (match) identifiers.push(...namedImportIdentifiers(match[1]));
|
|
77
|
+
return identifiers;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function namedImportIdentifiers(raw) {
|
|
81
|
+
return String(raw ?? '')
|
|
82
|
+
.split(',')
|
|
83
|
+
.map((part) => part.trim().split(/\s+as\s+/i).pop()?.trim())
|
|
84
|
+
.filter(Boolean);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function packageIdentifier(value) {
|
|
88
|
+
const parts = String(value ?? '').split('/').filter(Boolean);
|
|
89
|
+
const last = parts[parts.length - 1] ?? value;
|
|
90
|
+
return String(last).replace(/[^A-Za-z0-9_$]/g, '');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function addIdentifierTarget(map, identifier, target) {
|
|
94
|
+
if (!isIdentifier(identifier)) return;
|
|
95
|
+
const existing = map.get(identifier) ?? [];
|
|
96
|
+
if (!existing.some((entry) => entry.symbolId === target.symbolId)) existing.push(target);
|
|
97
|
+
map.set(identifier, existing);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function addIdentifier(set, value) {
|
|
101
|
+
if (isIdentifier(value)) set.add(value);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function isIdentifier(value) {
|
|
105
|
+
const text = String(value ?? '');
|
|
106
|
+
return /^[A-Za-z_$][\w$]*$/.test(text) && !ignoredIdentifiers.has(text);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function declarationScanRanges(declarations, lines) {
|
|
110
|
+
return (declarations ?? [])
|
|
111
|
+
.filter((declaration) => declaration?.symbolId && declaration.role !== 'import')
|
|
112
|
+
.map((declaration) => ({
|
|
113
|
+
declaration,
|
|
114
|
+
startLine: declaration.span?.startLine ?? 1,
|
|
115
|
+
endLine: declarationScanEndLine(declaration, lines)
|
|
116
|
+
}));
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function declarationScanEndLine(declaration, lines) {
|
|
120
|
+
const startLine = declaration.span?.startLine ?? 1;
|
|
121
|
+
if (!declaration.metadata?.hasBody || declaration.kind === 'ClassDeclaration') return startLine;
|
|
122
|
+
return balancedRegionEndLine(lines, startLine);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function balancedRegionEndLine(lines, startLine) {
|
|
126
|
+
const state = { inBlockComment: false, inTemplateString: false };
|
|
127
|
+
let depth = 0;
|
|
128
|
+
let opened = false;
|
|
129
|
+
for (let index = Math.max(0, startLine - 1); index < lines.length; index += 1) {
|
|
130
|
+
for (const char of maskReferenceLine(lines[index].line, state)) {
|
|
131
|
+
if (char === '{' || char === '[' || char === '(') {
|
|
132
|
+
depth += 1;
|
|
133
|
+
opened = true;
|
|
134
|
+
} else if (char === '}' || char === ']' || char === ')') {
|
|
135
|
+
depth -= 1;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (opened && depth <= 0) return lines[index].number;
|
|
139
|
+
}
|
|
140
|
+
return startLine;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function scanDeclarationDependencies(input, documentId, scan, identifiers, lines, records) {
|
|
144
|
+
const state = { inBlockComment: false, inTemplateString: false };
|
|
145
|
+
for (let lineNumber = scan.startLine; lineNumber <= scan.endLine; lineNumber += 1) {
|
|
146
|
+
const scanLine = maskReferenceLine(lines[lineNumber - 1]?.line ?? '', state);
|
|
147
|
+
for (const match of scanLine.matchAll(/[A-Za-z_$][\w$]*/g)) {
|
|
148
|
+
const name = match[0];
|
|
149
|
+
if (ignoredIdentifiers.has(name) || !identifiers.has(name)) continue;
|
|
150
|
+
const targets = identifiers.get(name).filter((target) => target.symbolId !== scan.declaration.symbolId);
|
|
151
|
+
for (const target of targets) {
|
|
152
|
+
addDependencyRecord(input, documentId, scan.declaration, target, {
|
|
153
|
+
line: scanLine,
|
|
154
|
+
lineNumber,
|
|
155
|
+
startColumn: match.index + 1,
|
|
156
|
+
name
|
|
157
|
+
}, records);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function addDependencyRecord(input, documentId, caller, target, occurrence, records) {
|
|
164
|
+
const predicate = isCallReference(occurrence.line, occurrence.startColumn + occurrence.name.length - 1) ? 'calls' : 'uses';
|
|
165
|
+
const key = `${caller.symbolId}|${predicate}|${target.symbolId}|${occurrence.lineNumber}|${occurrence.startColumn}`;
|
|
166
|
+
if (records.seen.has(key)) return;
|
|
167
|
+
records.seen.add(key);
|
|
168
|
+
const relationId = `rel_${idFragment(caller.symbolId)}_${predicate}_${idFragment(target.symbolId)}_${occurrence.lineNumber}_${occurrence.startColumn}`;
|
|
169
|
+
const occurrenceId = `occ_${idFragment(caller.nodeId)}_${predicate}_${idFragment(target.symbolId)}_${occurrence.lineNumber}_${occurrence.startColumn}`;
|
|
170
|
+
const span = {
|
|
171
|
+
sourceId: input.sourceHash,
|
|
172
|
+
path: input.sourcePath,
|
|
173
|
+
startLine: occurrence.lineNumber,
|
|
174
|
+
endLine: occurrence.lineNumber,
|
|
175
|
+
startColumn: occurrence.startColumn,
|
|
176
|
+
endColumn: occurrence.startColumn + occurrence.name.length
|
|
177
|
+
};
|
|
178
|
+
records.relations.push({
|
|
179
|
+
id: relationId,
|
|
180
|
+
sourceId: caller.symbolId,
|
|
181
|
+
predicate,
|
|
182
|
+
targetId: target.symbolId,
|
|
183
|
+
metadata: {
|
|
184
|
+
scan: 'lightweight-dependency',
|
|
185
|
+
confidence: 'lexical-reference',
|
|
186
|
+
sourceDocumentId: documentId,
|
|
187
|
+
sourceName: caller.name,
|
|
188
|
+
targetName: target.name
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
records.occurrences.push({
|
|
192
|
+
id: occurrenceId,
|
|
193
|
+
documentId,
|
|
194
|
+
symbolId: target.symbolId,
|
|
195
|
+
role: 'reference',
|
|
196
|
+
span,
|
|
197
|
+
nativeAstNodeId: caller.nodeId
|
|
198
|
+
});
|
|
199
|
+
records.facts.push({
|
|
200
|
+
id: `fact_${idFragment(relationId)}_lightweight_dependency`,
|
|
201
|
+
predicate: 'lightweightDependency',
|
|
202
|
+
subjectId: caller.symbolId,
|
|
203
|
+
value: {
|
|
204
|
+
relationId,
|
|
205
|
+
predicate,
|
|
206
|
+
targetId: target.symbolId,
|
|
207
|
+
line: occurrence.lineNumber,
|
|
208
|
+
confidence: 'lexical-reference'
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function isCallReference(line, afterIdentifierIndex) {
|
|
214
|
+
return /^\s*\(/.test(String(line ?? '').slice(afterIdentifierIndex));
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function maskReferenceLine(line, state) {
|
|
218
|
+
const text = String(line ?? '');
|
|
219
|
+
let output = '';
|
|
220
|
+
let quote;
|
|
221
|
+
let escaped = false;
|
|
222
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
223
|
+
const char = text[index];
|
|
224
|
+
const next = text[index + 1];
|
|
225
|
+
if (state.inBlockComment) {
|
|
226
|
+
output += ' ';
|
|
227
|
+
if (char === '*' && next === '/') {
|
|
228
|
+
output += ' ';
|
|
229
|
+
index += 1;
|
|
230
|
+
state.inBlockComment = false;
|
|
231
|
+
}
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
if (state.inTemplateString) {
|
|
235
|
+
output += ' ';
|
|
236
|
+
if (char === '`' && !escaped) state.inTemplateString = false;
|
|
237
|
+
escaped = char === '\\' && !escaped;
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
if (quote) {
|
|
241
|
+
output += ' ';
|
|
242
|
+
if (escaped) escaped = false;
|
|
243
|
+
else if (char === '\\') escaped = true;
|
|
244
|
+
else if (char === quote) quote = undefined;
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
if (char === '/' && next === '/') break;
|
|
248
|
+
if (char === '/' && next === '*') {
|
|
249
|
+
output += ' ';
|
|
250
|
+
index += 1;
|
|
251
|
+
state.inBlockComment = true;
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
if (char === '\'' || char === '"') {
|
|
255
|
+
output += ' ';
|
|
256
|
+
quote = char;
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
if (char === '`') {
|
|
260
|
+
output += ' ';
|
|
261
|
+
state.inTemplateString = true;
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
output += char;
|
|
265
|
+
}
|
|
266
|
+
return output;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
function emptySummary() {
|
|
270
|
+
return { total: 0, calls: 0, uses: 0 };
|
|
271
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { countBy, uniqueRecordsById, uniqueStrings } from './native-import-utils.js';
|
|
2
|
+
|
|
3
|
+
function summarizeSemanticImportDependencies(imports) {
|
|
4
|
+
return summarizeSemanticImportDependencyRelations((imports ?? [])
|
|
5
|
+
.flatMap((imported) => imported?.semanticIndex?.relations ?? imported?.universalAst?.semanticIndex?.relations ?? []));
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function summarizeSemanticImportDependencyRelations(relations) {
|
|
9
|
+
const dependencyRelations = uniqueRecordsById((relations ?? []).filter(isDependencyRelation));
|
|
10
|
+
const predicateKeys = dependencyRelations.map((relation) => semanticDependencyPredicateKey(relation.predicate));
|
|
11
|
+
const byPredicate = countBy(predicateKeys);
|
|
12
|
+
return {
|
|
13
|
+
total: dependencyRelations.length,
|
|
14
|
+
calls: byPredicate.calls ?? 0,
|
|
15
|
+
uses: byPredicate.uses ?? 0,
|
|
16
|
+
references: byPredicate.references ?? 0,
|
|
17
|
+
imports: byPredicate.imports ?? 0,
|
|
18
|
+
extends: byPredicate.extends ?? 0,
|
|
19
|
+
implements: byPredicate.implements ?? 0,
|
|
20
|
+
includes: byPredicate.includes ?? 0,
|
|
21
|
+
requires: byPredicate.requires ?? 0,
|
|
22
|
+
byPredicate,
|
|
23
|
+
predicates: uniqueStrings(predicateKeys),
|
|
24
|
+
ids: dependencyRelations.map((relation) => relation.id).filter(Boolean),
|
|
25
|
+
sourceSymbolIds: uniqueStrings(dependencyRelations.map((relation) => relation.sourceId).filter(Boolean)),
|
|
26
|
+
targetSymbolIds: uniqueStrings(dependencyRelations.map((relation) => relation.targetId).filter(Boolean))
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function isDependencyRelation(relation) {
|
|
31
|
+
const predicate = String(relation?.predicate ?? '').toLowerCase();
|
|
32
|
+
if (!predicate || predicate === 'defines' || predicate === 'definitionof') return false;
|
|
33
|
+
return predicate === 'imports'
|
|
34
|
+
|| predicate === 'calls'
|
|
35
|
+
|| predicate === 'uses'
|
|
36
|
+
|| predicate.includes('reference')
|
|
37
|
+
|| predicate.includes('depend')
|
|
38
|
+
|| predicate.includes('require')
|
|
39
|
+
|| predicate.includes('include')
|
|
40
|
+
|| predicate.includes('extend')
|
|
41
|
+
|| predicate.includes('implement');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function semanticDependencyPredicateKey(predicate) {
|
|
45
|
+
const value = String(predicate ?? 'unknown').toLowerCase();
|
|
46
|
+
if (value.includes('call')) return 'calls';
|
|
47
|
+
if (value.includes('reference')) return 'references';
|
|
48
|
+
if (value.includes('import')) return 'imports';
|
|
49
|
+
if (value.includes('depend')) return 'depends';
|
|
50
|
+
if (value.includes('require')) return 'requires';
|
|
51
|
+
if (value.includes('include')) return 'includes';
|
|
52
|
+
if (value.includes('extend')) return 'extends';
|
|
53
|
+
if (value.includes('implement')) return 'implements';
|
|
54
|
+
if (value === 'uses') return 'uses';
|
|
55
|
+
return value || 'unknown';
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export {
|
|
59
|
+
semanticDependencyPredicateKey,
|
|
60
|
+
summarizeSemanticImportDependencies,
|
|
61
|
+
summarizeSemanticImportDependencyRelations
|
|
62
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { uniqueRecordsById, uniqueStrings } from './native-import-utils.js';
|
|
2
|
+
import { summarizeSemanticImportDependencyRelations } from './semantic-import-dependencies.js';
|
|
2
3
|
import { semanticOwnershipRegionForSymbol, summarizeSemanticImportRegionTaxonomy } from './semantic-import-regions.js';
|
|
3
4
|
import { collectKernelSourcePreservationFromImport } from './semantic-import-source-preservation.js';
|
|
4
5
|
import {
|
|
@@ -16,6 +17,7 @@ function semanticImportSidecarEntry(imported, index, options) {
|
|
|
16
17
|
const universalAstLayers = summarizeUniversalAstLayers(imported?.universalAst);
|
|
17
18
|
const proofSpec = summarizeProofSpecLayer(imported?.universalAst?.proof ?? imported?.proof);
|
|
18
19
|
const paradigmSemantics = summarizeParadigmSemanticsLayer(imported?.universalAst?.paradigmSemantics ?? imported?.paradigmSemantics);
|
|
20
|
+
const dependencies = summarizeSemanticImportDependencyRelations(semanticIndex?.relations ?? []);
|
|
19
21
|
const mappingsBySymbolId = new Map();
|
|
20
22
|
for (const mapping of sourceMapMappings) {
|
|
21
23
|
if (mapping.semanticSymbolId && !mappingsBySymbolId.has(mapping.semanticSymbolId)) {
|
|
@@ -67,6 +69,8 @@ function semanticImportSidecarEntry(imported, index, options) {
|
|
|
67
69
|
universalAstLayerIds: universalAstLayers.ids,
|
|
68
70
|
proofSpec,
|
|
69
71
|
paradigmSemantics,
|
|
72
|
+
dependencyRelationCount: dependencies.total,
|
|
73
|
+
dependencyPredicates: dependencies.predicates,
|
|
70
74
|
readiness: imported?.metadata?.semanticMergeReadiness ?? imported?.mergeCandidates?.[0]?.readiness ?? 'needs-review',
|
|
71
75
|
emptySemanticIndex: symbols.length === 0,
|
|
72
76
|
regionTaxonomy,
|
|
@@ -90,6 +90,8 @@ export interface SemanticImportSidecarImportEntry {
|
|
|
90
90
|
readonly universalAstLayerIds: readonly string[];
|
|
91
91
|
readonly proofSpec: SemanticImportSidecarProofSpecSummary;
|
|
92
92
|
readonly paradigmSemantics: SemanticImportSidecarParadigmSemanticsSummary;
|
|
93
|
+
readonly dependencyRelationCount: number;
|
|
94
|
+
readonly dependencyPredicates: readonly string[];
|
|
93
95
|
readonly readiness: SemanticMergeReadiness;
|
|
94
96
|
readonly emptySemanticIndex: boolean;
|
|
95
97
|
readonly regionTaxonomy?: SemanticImportRegionTaxonomySummary;
|
|
@@ -186,6 +188,23 @@ export interface SemanticImportSidecarParadigmSemanticsSummary {
|
|
|
186
188
|
readonly empty: boolean;
|
|
187
189
|
}
|
|
188
190
|
|
|
191
|
+
export interface SemanticImportDependencySummary {
|
|
192
|
+
readonly total: number;
|
|
193
|
+
readonly calls: number;
|
|
194
|
+
readonly uses: number;
|
|
195
|
+
readonly references: number;
|
|
196
|
+
readonly imports: number;
|
|
197
|
+
readonly extends: number;
|
|
198
|
+
readonly implements: number;
|
|
199
|
+
readonly includes: number;
|
|
200
|
+
readonly requires: number;
|
|
201
|
+
readonly byPredicate: Readonly<Record<string, number>>;
|
|
202
|
+
readonly predicates: readonly string[];
|
|
203
|
+
readonly ids: readonly string[];
|
|
204
|
+
readonly sourceSymbolIds: readonly string[];
|
|
205
|
+
readonly targetSymbolIds: readonly string[];
|
|
206
|
+
}
|
|
207
|
+
|
|
189
208
|
export interface SemanticImportSidecar {
|
|
190
209
|
readonly kind: 'frontier.lang.semanticImportSidecar';
|
|
191
210
|
readonly version: 1;
|
|
@@ -217,6 +236,7 @@ export interface SemanticImportSidecar {
|
|
|
217
236
|
readonly universalAstLayers: SemanticImportSidecarUniversalAstLayerSummary;
|
|
218
237
|
readonly proofSpec: SemanticImportSidecarProofSpecSummary;
|
|
219
238
|
readonly paradigmSemantics: SemanticImportSidecarParadigmSemanticsSummary;
|
|
239
|
+
readonly dependencies: SemanticImportDependencySummary;
|
|
220
240
|
readonly patchHints: readonly SemanticImportPatchHint[];
|
|
221
241
|
readonly quality: SemanticImportSidecarQuality;
|
|
222
242
|
readonly admission: SemanticImportSidecarAdmission;
|
|
@@ -258,6 +278,8 @@ export interface SemanticImportSidecar {
|
|
|
258
278
|
readonly paradigmSemanticsRecords: number;
|
|
259
279
|
readonly paradigmSemanticsGroups: number;
|
|
260
280
|
readonly paradigmSemanticsLoweringRecords: number;
|
|
281
|
+
readonly dependencyRelations: number;
|
|
282
|
+
readonly dependencyPredicates: readonly string[];
|
|
261
283
|
readonly patchHints: number;
|
|
262
284
|
readonly evidenceWarnings: number;
|
|
263
285
|
readonly readiness: SemanticMergeReadiness;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { countBy, idFragment, uniqueStrings } from './native-import-utils.js';
|
|
2
|
+
|
|
3
|
+
export function createUniversalConversionAdmissionRecord(input) {
|
|
4
|
+
const route = input.route;
|
|
5
|
+
const operations = input.semanticOperations?.operations ?? [];
|
|
6
|
+
const operationKinds = uniqueStrings(operations.map((operation) => operation.operationKind));
|
|
7
|
+
const sourceRecords = input.patchBundle?.sources ?? input.history?.sources ?? [];
|
|
8
|
+
const evidenceIds = uniqueStrings([
|
|
9
|
+
...(input.history?.evidenceIds ?? []),
|
|
10
|
+
...(input.patchBundle?.evidenceIds ?? []),
|
|
11
|
+
...(input.materialization?.evidenceIds ?? [])
|
|
12
|
+
]);
|
|
13
|
+
const proofIds = uniqueStrings([
|
|
14
|
+
...(input.history?.proofIds ?? []),
|
|
15
|
+
...(input.patchBundle?.proofIds ?? []),
|
|
16
|
+
...(input.materialization?.proofIds ?? [])
|
|
17
|
+
]);
|
|
18
|
+
const score = route.mergeScore ?? {};
|
|
19
|
+
const missingEvidence = route.missingEvidence ?? [];
|
|
20
|
+
const blockers = route.blockers ?? [];
|
|
21
|
+
const bucket = admissionBucket({
|
|
22
|
+
action: score.action ?? route.admissionAction,
|
|
23
|
+
blockers,
|
|
24
|
+
missingEvidence,
|
|
25
|
+
mode: route.mode,
|
|
26
|
+
operationKinds,
|
|
27
|
+
opaqueOperations: operations.filter((operation) => operation.opaque).length,
|
|
28
|
+
scoreValue: score.value,
|
|
29
|
+
status: input.admissionStatus
|
|
30
|
+
});
|
|
31
|
+
return {
|
|
32
|
+
kind: 'frontier.lang.universalConversionAdmissionRecord',
|
|
33
|
+
version: 1,
|
|
34
|
+
schema: 'frontier.lang.universalConversionAdmissionRecord.v1',
|
|
35
|
+
id: `admission_${idFragment(route.id)}`,
|
|
36
|
+
routeId: route.id,
|
|
37
|
+
planId: input.planId,
|
|
38
|
+
sourceLanguage: route.sourceLanguage,
|
|
39
|
+
target: route.target,
|
|
40
|
+
mode: route.mode,
|
|
41
|
+
routeAction: route.routeAction,
|
|
42
|
+
admissionStatus: input.admissionStatus,
|
|
43
|
+
admissionAction: score.action ?? route.admissionAction,
|
|
44
|
+
admissionBucket: bucket,
|
|
45
|
+
reviewRequired: true,
|
|
46
|
+
readiness: route.readiness,
|
|
47
|
+
risk: score.risk ?? riskForRoute(route, input.admissionStatus),
|
|
48
|
+
score: {
|
|
49
|
+
value: Number(score.value ?? 0),
|
|
50
|
+
uncappedValue: Number(score.uncappedValue ?? score.value ?? 0),
|
|
51
|
+
sortKey: Number(score.sortKey ?? score.value ?? 0),
|
|
52
|
+
higherIsBetter: true,
|
|
53
|
+
componentStatuses: componentStatuses(score.components),
|
|
54
|
+
penalties: score.penalties ?? []
|
|
55
|
+
},
|
|
56
|
+
ids: {
|
|
57
|
+
historyId: input.history?.id,
|
|
58
|
+
patchBundleId: input.patchBundle?.id,
|
|
59
|
+
semanticOperationIds: operations.map((operation) => operation.id),
|
|
60
|
+
sourceMapLinkIds: input.materialization?.sourceMapLinkIds ?? [],
|
|
61
|
+
evidenceIds,
|
|
62
|
+
proofIds
|
|
63
|
+
},
|
|
64
|
+
semanticOperations: {
|
|
65
|
+
total: operations.length,
|
|
66
|
+
byKind: countBy(operations.map((operation) => operation.operationKind)),
|
|
67
|
+
kinds: operationKinds,
|
|
68
|
+
dynamic: operations.filter((operation) => operation.dynamic).map((operation) => operation.id),
|
|
69
|
+
opaque: operations.filter((operation) => operation.opaque).map((operation) => operation.id)
|
|
70
|
+
},
|
|
71
|
+
ownership: {
|
|
72
|
+
keys: uniqueStrings(input.history?.index?.ownershipKeys ?? input.patchBundle?.index?.ownershipKeys ?? []),
|
|
73
|
+
conflictKeys: uniqueStrings(input.history?.index?.conflictKeys ?? input.patchBundle?.index?.conflictKeys ?? [])
|
|
74
|
+
},
|
|
75
|
+
source: {
|
|
76
|
+
paths: uniqueStrings(sourceRecords.map((source) => source.sourcePath)),
|
|
77
|
+
hashes: uniqueStrings(sourceRecords.map((source) => source.sourceHash)),
|
|
78
|
+
baseHashes: uniqueStrings(sourceRecords.map((source) => source.baseHash)),
|
|
79
|
+
targetHashes: uniqueStrings(sourceRecords.map((source) => source.targetHash))
|
|
80
|
+
},
|
|
81
|
+
evidence: {
|
|
82
|
+
total: evidenceIds.length,
|
|
83
|
+
proofArtifacts: proofIds.length,
|
|
84
|
+
missing: missingEvidence,
|
|
85
|
+
blockers,
|
|
86
|
+
review: route.review ?? []
|
|
87
|
+
},
|
|
88
|
+
reasons: uniqueStrings([
|
|
89
|
+
...(input.reasonCodes ?? []),
|
|
90
|
+
...missingEvidence.map((reason) => `missing:${reason}`),
|
|
91
|
+
...blockers.map((reason) => `blocker:${reason}`),
|
|
92
|
+
...(route.review ?? []).map((reason) => `review:${reason}`),
|
|
93
|
+
...(score.penalties ?? [])
|
|
94
|
+
]),
|
|
95
|
+
autoMergeClaim: false,
|
|
96
|
+
semanticEquivalenceClaim: false,
|
|
97
|
+
metadata: {
|
|
98
|
+
routeId: route.id,
|
|
99
|
+
planId: input.planId,
|
|
100
|
+
mergeScoreSchema: score.schema,
|
|
101
|
+
note: 'Admission records are sortable merge-review evidence, not proof of target semantic equivalence.'
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function admissionBucket(input) {
|
|
107
|
+
if (input.status === 'blocked' || input.action === 'reject' || input.blockers.length) return 'blocked';
|
|
108
|
+
if (input.mode === 'semantic-index-only' || input.missingEvidence.includes('target-adapter')) return 'needs-adapter';
|
|
109
|
+
if (input.missingEvidence.length || input.opaqueOperations || input.operationKinds.includes('merge')) return 'needs-evidence';
|
|
110
|
+
if (Number(input.scoreValue ?? 0) >= 80) return 'merge-ready';
|
|
111
|
+
return 'needs-review';
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function riskForRoute(route, status) {
|
|
115
|
+
if (status === 'blocked' || route.readiness === 'blocked') return 'high';
|
|
116
|
+
if (route.readiness === 'needs-review' || route.mode === 'stub-only') return 'medium';
|
|
117
|
+
return 'low';
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function componentStatuses(components = {}) {
|
|
121
|
+
return Object.fromEntries(Object.entries(components).map(([key, component]) => [key, component.status]));
|
|
122
|
+
}
|
|
@@ -12,11 +12,14 @@ export function artifactIndex(routeArtifacts) {
|
|
|
12
12
|
routeIds: uniqueStrings(routeArtifacts.map((artifact) => artifact.routeId)),
|
|
13
13
|
historyIds: uniqueStrings(routeArtifacts.map((artifact) => artifact.history.id)),
|
|
14
14
|
patchBundleIds: uniqueStrings(routeArtifacts.map((artifact) => artifact.patchBundle.id)),
|
|
15
|
+
admissionRecordIds: uniqueStrings(routeArtifacts.map((artifact) => artifact.admissionRecord.id)),
|
|
15
16
|
languages: uniqueStrings(routeArtifacts.map((artifact) => artifact.sourceLanguage)),
|
|
16
17
|
targets: uniqueStrings(routeArtifacts.map((artifact) => artifact.target)),
|
|
17
18
|
modes: uniqueStrings(routeArtifacts.map((artifact) => artifact.mode)),
|
|
18
19
|
readinesses: uniqueStrings(routeArtifacts.map((artifact) => artifact.readiness)),
|
|
19
20
|
admissionStatuses: uniqueStrings(routeArtifacts.map((artifact) => artifact.admissionStatus)),
|
|
21
|
+
admissionBuckets: uniqueStrings(routeArtifacts.map((artifact) => artifact.admissionRecord.admissionBucket)),
|
|
22
|
+
admissionRisks: uniqueStrings(routeArtifacts.map((artifact) => artifact.admissionRecord.risk)),
|
|
20
23
|
sourcePaths: uniqueStrings(routeArtifacts.flatMap((artifact) => artifact.history.index.sourcePaths)),
|
|
21
24
|
sourceHashes: uniqueStrings(routeArtifacts.flatMap((artifact) => artifact.history.index.sourceHashes)),
|
|
22
25
|
ownershipKeys: uniqueStrings(routeArtifacts.flatMap((artifact) => artifact.history.index.ownershipKeys)),
|
|
@@ -39,6 +42,7 @@ function matchesArtifact(record, query) {
|
|
|
39
42
|
return match(query.routeId, [record.routeId])
|
|
40
43
|
&& match(query.historyId, [record.history.id])
|
|
41
44
|
&& match(query.patchBundleId, [record.patchBundle.id])
|
|
45
|
+
&& match(query.admissionRecordId, [record.admissionRecord.id])
|
|
42
46
|
&& match(query.sourceLanguage, [record.sourceLanguage])
|
|
43
47
|
&& match(query.target, [record.target])
|
|
44
48
|
&& match(query.mode, [record.mode])
|
|
@@ -46,6 +50,8 @@ function matchesArtifact(record, query) {
|
|
|
46
50
|
&& match(query.priority, [record.priority])
|
|
47
51
|
&& match(query.readiness, [record.readiness])
|
|
48
52
|
&& match(query.admissionStatus, [record.admissionStatus])
|
|
53
|
+
&& match(query.admissionBucket, [record.admissionRecord.admissionBucket])
|
|
54
|
+
&& match(query.risk, [record.admissionRecord.risk])
|
|
49
55
|
&& match(query.sourcePath, record.history.index.sourcePaths)
|
|
50
56
|
&& match(query.sourceHash, record.history.index.sourceHashes)
|
|
51
57
|
&& match(query.ownershipKey, record.history.index.ownershipKeys)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export function universalConversionArtifactSummary(routeArtifacts, records) {
|
|
2
|
+
const admissionRecords = records.admissionRecords;
|
|
3
|
+
return {
|
|
4
|
+
routes: routeArtifacts.length,
|
|
5
|
+
histories: records.historyRecords.length,
|
|
6
|
+
patchBundles: records.patchBundleRecords.length,
|
|
7
|
+
admissionRecords: admissionRecords.length,
|
|
8
|
+
semanticOperations: routeArtifacts.reduce((sum, artifact) => sum + artifact.semanticOperations.operations.length, 0),
|
|
9
|
+
mergeReady: countAdmissionBucket(admissionRecords, 'merge-ready'),
|
|
10
|
+
needsEvidence: countAdmissionBucket(admissionRecords, 'needs-evidence'),
|
|
11
|
+
needsAdapter: countAdmissionBucket(admissionRecords, 'needs-adapter'),
|
|
12
|
+
needsReview: countAdmissionBucket(admissionRecords, 'needs-review'),
|
|
13
|
+
admissionBlocked: countAdmissionBucket(admissionRecords, 'blocked'),
|
|
14
|
+
lowRisk: countAdmissionRisk(admissionRecords, 'low'),
|
|
15
|
+
mediumRisk: countAdmissionRisk(admissionRecords, 'medium'),
|
|
16
|
+
highRisk: countAdmissionRisk(admissionRecords, 'high'),
|
|
17
|
+
queued: routeArtifacts.filter((artifact) => artifact.admissionStatus === 'queued').length,
|
|
18
|
+
reviewRequired: routeArtifacts.filter((artifact) => artifact.reviewRequired).length,
|
|
19
|
+
blocked: routeArtifacts.filter((artifact) => artifact.admissionStatus === 'blocked').length,
|
|
20
|
+
reasonCodes: admissionRecords.reduce((sum, record) => sum + record.reasons.length, 0),
|
|
21
|
+
missingEvidence: admissionRecords.reduce((sum, record) => sum + record.evidence.missing.length, 0),
|
|
22
|
+
blockers: admissionRecords.reduce((sum, record) => sum + record.evidence.blockers.length, 0),
|
|
23
|
+
reviewReasons: admissionRecords.reduce((sum, record) => sum + record.evidence.review.length, 0),
|
|
24
|
+
evidenceIds: admissionRecords.reduce((sum, record) => sum + record.ids.evidenceIds.length, 0),
|
|
25
|
+
proofIds: admissionRecords.reduce((sum, record) => sum + record.ids.proofIds.length, 0),
|
|
26
|
+
autoMergeClaims: 0,
|
|
27
|
+
semanticEquivalenceClaims: 0
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function countAdmissionBucket(records, bucket) {
|
|
32
|
+
return records.filter((record) => record.admissionBucket === bucket).length;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function countAdmissionRisk(records, risk) {
|
|
36
|
+
return records.filter((record) => record.risk === risk).length;
|
|
37
|
+
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { idFragment, uniqueStrings } from './native-import-utils.js';
|
|
2
|
+
import { universalConversionArtifactSummary } from './universal-conversion-artifact-summary.js';
|
|
2
3
|
import { createUniversalConversionPlan } from './universal-conversion-plan.js';
|
|
3
4
|
import { artifactIndex } from './universal-conversion-artifact-query.js';
|
|
5
|
+
import { createUniversalConversionAdmissionRecord } from './universal-conversion-admission-record.js';
|
|
4
6
|
import { routeSemanticOperations } from './universal-conversion-route-operations.js';
|
|
5
7
|
import { createSemanticHistoryRecord } from './internal/index-impl/semanticHistoryRecords.js';
|
|
6
8
|
import { createSemanticPatchBundleRecord } from './internal/index-impl/semanticPatchBundleRecords.js';
|
|
@@ -23,6 +25,7 @@ export function createUniversalConversionArtifacts(input = {}, options = {}) {
|
|
|
23
25
|
}));
|
|
24
26
|
const historyRecords = routeArtifacts.map((artifact) => artifact.history);
|
|
25
27
|
const patchBundleRecords = routeArtifacts.map((artifact) => artifact.patchBundle);
|
|
28
|
+
const admissionRecords = routeArtifacts.map((artifact) => artifact.admissionRecord);
|
|
26
29
|
const index = artifactIndex(routeArtifacts);
|
|
27
30
|
return {
|
|
28
31
|
kind: 'frontier.lang.universalConversionArtifacts',
|
|
@@ -34,17 +37,13 @@ export function createUniversalConversionArtifacts(input = {}, options = {}) {
|
|
|
34
37
|
routeArtifacts,
|
|
35
38
|
historyRecords,
|
|
36
39
|
patchBundleRecords,
|
|
40
|
+
admissionRecords,
|
|
37
41
|
index,
|
|
38
|
-
summary: {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
reviewRequired: routeArtifacts.filter((artifact) => artifact.reviewRequired).length,
|
|
44
|
-
blocked: routeArtifacts.filter((artifact) => artifact.admissionStatus === 'blocked').length,
|
|
45
|
-
autoMergeClaims: 0,
|
|
46
|
-
semanticEquivalenceClaims: 0
|
|
47
|
-
},
|
|
42
|
+
summary: universalConversionArtifactSummary(routeArtifacts, {
|
|
43
|
+
historyRecords,
|
|
44
|
+
patchBundleRecords,
|
|
45
|
+
admissionRecords
|
|
46
|
+
}),
|
|
48
47
|
metadata: {
|
|
49
48
|
autoMergeClaim: false,
|
|
50
49
|
semanticEquivalenceClaim: false,
|
|
@@ -121,6 +120,16 @@ function createRouteArtifact(route, options) {
|
|
|
121
120
|
autoMergeClaim: false,
|
|
122
121
|
semanticEquivalenceClaim: false
|
|
123
122
|
};
|
|
123
|
+
const admissionRecord = createUniversalConversionAdmissionRecord({
|
|
124
|
+
route,
|
|
125
|
+
planId,
|
|
126
|
+
admissionStatus,
|
|
127
|
+
reasonCodes,
|
|
128
|
+
history,
|
|
129
|
+
patchBundle,
|
|
130
|
+
semanticOperations,
|
|
131
|
+
materialization
|
|
132
|
+
});
|
|
124
133
|
return {
|
|
125
134
|
kind: 'frontier.lang.universalConversionRouteArtifact',
|
|
126
135
|
version: 1,
|
|
@@ -138,9 +147,11 @@ function createRouteArtifact(route, options) {
|
|
|
138
147
|
reviewRequired: true,
|
|
139
148
|
history,
|
|
140
149
|
patchBundle,
|
|
150
|
+
admissionRecord,
|
|
141
151
|
semanticOperations,
|
|
142
152
|
materialization,
|
|
143
153
|
mergeScore: route.mergeScore,
|
|
154
|
+
admissionBucket: admissionRecord.admissionBucket,
|
|
144
155
|
autoMergeClaim: false,
|
|
145
156
|
semanticEquivalenceClaim: false,
|
|
146
157
|
metadata: { ...routeRecordMetadata(route, planId, options.metadata), materialization }
|
package/package.json
CHANGED