@shapeshift-labs/frontier-lang-compiler 0.2.49 → 0.2.50

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 CHANGED
@@ -129,6 +129,7 @@ import {
129
129
  createNativeParserAstFormatMatrix,
130
130
  createProjectionTargetLossMatrix,
131
131
  createUniversalCapabilityMatrix,
132
+ createUniversalConversionArtifacts,
132
133
  createUniversalConversionPlan,
133
134
  queryUniversalConversionPlan,
134
135
  importNativeSource
@@ -178,6 +179,10 @@ const pythonToRust = queryUniversalConversionPlan(conversionPlan, {
178
179
  console.log(pythonToRust.mode); // "semantic-index-only", "target-adapter", "stub-only", etc.
179
180
  console.log(pythonToRust.missingEvidence); // adapter/proof/source-map gaps for swarm workers
180
181
  console.log(pythonToRust.mergeScore.value); // sortable merge-review score, not a proof
182
+
183
+ const conversionArtifacts = createUniversalConversionArtifacts(conversionPlan);
184
+ console.log(conversionArtifacts.historyRecords[0].kind); // "frontier.lang.semanticHistoryRecord"
185
+ console.log(conversionArtifacts.patchBundleRecords[0].admission.autoMergeClaim); // false
181
186
  ```
182
187
 
183
188
  The projection target matrix separates five runtime/API classes:
@@ -192,6 +197,8 @@ The projection target matrix separates five runtime/API classes:
192
197
 
193
198
  `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.
194
199
 
200
+ `createUniversalConversionArtifacts` materializes those route refs into compact `SemanticHistoryRecord` and `SemanticPatchBundleRecord` artifacts that swarm collectors can index by route, history ID, patch-bundle ID, 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`.
201
+
195
202
  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:
196
203
 
197
204
  ```js
@@ -5,6 +5,7 @@ import {
5
5
  createSemanticImportSidecar,
6
6
  createSemanticSlice,
7
7
  createSemanticSliceAdmissionRecord,
8
+ createUniversalConversionArtifacts,
8
9
  createUniversalConversionPlan,
9
10
  projectNativeImportToSource,
10
11
  summarizeNativeImportFeatureEvidence,
@@ -54,6 +55,9 @@ export function measureNativeTransformations(nativeImportResults) {
54
55
  targets: ['javascript', 'rust', 'python']
55
56
  });
56
57
  const conversionPlanDurationMs = performance.now() - conversionPlanStart;
58
+ const conversionArtifactsStart = performance.now();
59
+ const conversionArtifacts = createUniversalConversionArtifacts(conversionPlan);
60
+ const conversionArtifactsDurationMs = performance.now() - conversionArtifactsStart;
57
61
 
58
62
  const featureEvidenceStart = performance.now();
59
63
  const featureEvidenceSummaries = nativeImportResults.map((imported) => summarizeNativeImportFeatureEvidence(imported.losses, {
@@ -88,6 +92,10 @@ export function measureNativeTransformations(nativeImportResults) {
88
92
  conversionPlanRoutes: conversionPlan.routes.length,
89
93
  conversionPlanBlocked: conversionPlan.summary.blockedRoutes,
90
94
  conversionPlanDurationMs,
95
+ conversionArtifacts: conversionArtifacts.summary.routes,
96
+ conversionArtifactHistories: conversionArtifacts.summary.histories,
97
+ conversionArtifactPatchBundles: conversionArtifacts.summary.patchBundles,
98
+ conversionArtifactsDurationMs,
91
99
  featureEvidencePolicyMatches,
92
100
  featureEvidenceDurationMs,
93
101
  nativeProjections: nativeProjections.length,
package/bench/smoke.mjs CHANGED
@@ -60,6 +60,10 @@ console.log(JSON.stringify({
60
60
  conversionPlanRoutes: transformMetrics.conversionPlanRoutes,
61
61
  conversionPlanBlocked: transformMetrics.conversionPlanBlocked,
62
62
  conversionPlanDurationMs: Number(transformMetrics.conversionPlanDurationMs.toFixed(2)),
63
+ conversionArtifacts: transformMetrics.conversionArtifacts,
64
+ conversionArtifactHistories: transformMetrics.conversionArtifactHistories,
65
+ conversionArtifactPatchBundles: transformMetrics.conversionArtifactPatchBundles,
66
+ conversionArtifactsDurationMs: Number(transformMetrics.conversionArtifactsDurationMs.toFixed(2)),
63
67
  featureEvidencePolicyMatches: transformMetrics.featureEvidencePolicyMatches,
64
68
  featureEvidenceDurationMs: Number(transformMetrics.featureEvidenceDurationMs.toFixed(2)),
65
69
  nativeProjections: transformMetrics.nativeProjections,
@@ -37,6 +37,7 @@ import type { NativeParserFeatureCategory, NativeParserFeatureCoverageStatus, Na
37
37
  import type { NativeImportCoverageLanguage, NativeImportCoverageMatrix, NativeImportCoverageMatrixOptions } from './native-import-coverage.js';
38
38
  import type { ProjectionTargetLossClass, ProjectionSourceProjectionCoverage, ProjectionTargetCoverageEntry, ProjectionTargetLanguageCoverage, ProjectionTargetLossMatrix, ProjectionTargetLossMatrixOptions } from './projection-coverage.js';
39
39
  import type { UniversalCapabilityLanguageRow, UniversalCapabilityMatrix, UniversalCapabilityMatrixOptions } from './universal-capability.js';
40
+ import type { CreateUniversalConversionArtifactsInput, CreateUniversalConversionArtifactsOptions, UniversalConversionArtifactQuery, UniversalConversionArtifacts, UniversalConversionRouteArtifact } from './universal-conversion-artifacts.js';
40
41
  import type { UniversalConversionPlan, UniversalConversionPlanOptions, UniversalConversionPlanQuery, UniversalConversionPlanQueryResult } from './universal-conversion-plan.js';
41
42
  import type { UniversalDialectRegistry, UniversalDialectRegistryInput, UniversalDialectRecordInput, UniversalExternRecordInput } from './universal-dialects.js';
42
43
  import type { NativeImportContractSource, NativeImportSourcePreservationRecordSummary, NativeImportSourcePreservationContract, NativeImportAdapterCoverageRecordSummary, NativeImportAdapterCoverageContract, NativeImportRegionSummary, NativeImportSourceMapSummary, NativeImportReadinessContract, NativeImportResultContract, NativeImportResultContractOptions } from './native-import-contracts.js';
@@ -88,7 +89,12 @@ export declare function createNativeParserFeatureMatrix(options?: NativeParserFe
88
89
  export declare function queryNativeParserFeatureMatrix(matrixOrOptions?: NativeParserFeatureMatrix | NativeParserFeatureMatrixOptions, query?: NativeParserFeatureMatrixQuery): NativeParserFeatureMatrixQueryResult;
89
90
  export declare function createProjectionTargetLossMatrix(options?: ProjectionTargetLossMatrixOptions): ProjectionTargetLossMatrix;
90
91
  export declare function createUniversalCapabilityMatrix(options?: UniversalCapabilityMatrixOptions): UniversalCapabilityMatrix;
92
+ export declare function createUniversalConversionArtifacts(input?: CreateUniversalConversionArtifactsInput, options?: CreateUniversalConversionArtifactsOptions): UniversalConversionArtifacts;
91
93
  export declare function createUniversalConversionPlan(options?: UniversalConversionPlanOptions): UniversalConversionPlan;
94
+ export declare function queryUniversalConversionArtifacts(
95
+ records: UniversalConversionArtifacts | UniversalConversionRouteArtifact | readonly (UniversalConversionArtifacts | UniversalConversionRouteArtifact)[],
96
+ query?: UniversalConversionArtifactQuery
97
+ ): readonly UniversalConversionRouteArtifact[];
92
98
  export declare function queryUniversalConversionPlan(
93
99
  planOrOptions?: UniversalConversionPlan | UniversalConversionPlanOptions,
94
100
  query?: UniversalConversionPlanQuery
@@ -0,0 +1,148 @@
1
+ import type {
2
+ FrontierSourceLanguage,
3
+ SemanticMergeReadiness
4
+ } from '@shapeshift-labs/frontier-lang-kernel';
5
+ import type { FrontierCompileTarget } from './compile.js';
6
+ import type { SemanticHistoryRecord } from './semantic-history.js';
7
+ import type { SemanticPatchBundleRecord } from './semantic-patch-bundle.js';
8
+ import type {
9
+ UniversalConversionAdmissionAction,
10
+ UniversalConversionPlan,
11
+ UniversalConversionPlanOptions,
12
+ UniversalConversionPriority,
13
+ UniversalConversionRoute,
14
+ UniversalConversionRouteAction,
15
+ UniversalConversionRouteMode,
16
+ UniversalConversionMergeScore
17
+ } from './universal-conversion-plan.js';
18
+
19
+ export type UniversalConversionArtifactAdmissionStatus = 'queued' | 'needs-review' | 'blocked' | string;
20
+ export type UniversalConversionArtifactMaterializationStatus = 'materialized' | 'planned-only' | 'missing' | 'failed' | string;
21
+
22
+ export interface UniversalConversionArtifactMaterialization {
23
+ readonly status: UniversalConversionArtifactMaterializationStatus;
24
+ readonly plannedHistoryIds: readonly string[];
25
+ readonly materializedHistoryIds: readonly string[];
26
+ readonly patchBundleIds: readonly string[];
27
+ readonly sourceMapLinkIds: readonly string[];
28
+ readonly evidenceIds: readonly string[];
29
+ readonly proofIds: readonly string[];
30
+ readonly autoMergeClaim: false;
31
+ readonly semanticEquivalenceClaim: false;
32
+ }
33
+
34
+ export interface UniversalConversionRouteArtifact {
35
+ readonly kind: 'frontier.lang.universalConversionRouteArtifact';
36
+ readonly version: 1;
37
+ readonly schema: 'frontier.lang.universalConversionRouteArtifact.v1';
38
+ readonly routeId: string;
39
+ readonly planId?: string;
40
+ readonly sourceLanguage?: FrontierSourceLanguage | string;
41
+ readonly target?: FrontierCompileTarget | string;
42
+ readonly mode: UniversalConversionRouteMode;
43
+ readonly routeAction: UniversalConversionRouteAction;
44
+ readonly priority: UniversalConversionPriority;
45
+ readonly readiness: SemanticMergeReadiness | string;
46
+ readonly admissionAction: UniversalConversionAdmissionAction;
47
+ readonly admissionStatus: UniversalConversionArtifactAdmissionStatus;
48
+ readonly reviewRequired: true;
49
+ readonly history: SemanticHistoryRecord;
50
+ readonly patchBundle: SemanticPatchBundleRecord;
51
+ readonly materialization: UniversalConversionArtifactMaterialization;
52
+ readonly mergeScore?: UniversalConversionMergeScore;
53
+ readonly autoMergeClaim: false;
54
+ readonly semanticEquivalenceClaim: false;
55
+ readonly metadata: Record<string, unknown>;
56
+ }
57
+
58
+ export interface UniversalConversionArtifactIndex {
59
+ readonly routeIds: readonly string[];
60
+ readonly historyIds: readonly string[];
61
+ readonly patchBundleIds: readonly string[];
62
+ readonly languages: readonly string[];
63
+ readonly targets: readonly string[];
64
+ readonly modes: readonly string[];
65
+ readonly readinesses: readonly string[];
66
+ readonly admissionStatuses: readonly string[];
67
+ readonly sourcePaths: readonly string[];
68
+ readonly sourceHashes: readonly string[];
69
+ readonly ownershipKeys: readonly string[];
70
+ readonly conflictKeys: readonly string[];
71
+ readonly evidenceIds: readonly string[];
72
+ readonly proofIds: readonly string[];
73
+ }
74
+
75
+ export interface UniversalConversionArtifacts {
76
+ readonly kind: 'frontier.lang.universalConversionArtifacts';
77
+ readonly version: 1;
78
+ readonly schema: 'frontier.lang.universalConversionArtifacts.v1';
79
+ readonly id: string;
80
+ readonly planId?: string;
81
+ readonly generatedAt: number | string;
82
+ readonly routeArtifacts: readonly UniversalConversionRouteArtifact[];
83
+ readonly historyRecords: readonly SemanticHistoryRecord[];
84
+ readonly patchBundleRecords: readonly SemanticPatchBundleRecord[];
85
+ readonly index: UniversalConversionArtifactIndex;
86
+ readonly summary: {
87
+ readonly routes: number;
88
+ readonly histories: number;
89
+ readonly patchBundles: number;
90
+ readonly reviewRequired: number;
91
+ readonly blocked: number;
92
+ readonly autoMergeClaims: 0;
93
+ readonly semanticEquivalenceClaims: 0;
94
+ };
95
+ readonly metadata: {
96
+ readonly autoMergeClaim: false;
97
+ readonly semanticEquivalenceClaim: false;
98
+ readonly note: string;
99
+ } & Record<string, unknown>;
100
+ }
101
+
102
+ export interface CreateUniversalConversionArtifactsOptions {
103
+ readonly id?: string;
104
+ readonly planId?: string;
105
+ readonly generatedAt?: number | string;
106
+ readonly routeId?: string;
107
+ readonly sourceLanguage?: FrontierSourceLanguage | string;
108
+ readonly target?: FrontierCompileTarget | string;
109
+ readonly mode?: UniversalConversionRouteMode;
110
+ readonly readiness?: SemanticMergeReadiness | string;
111
+ readonly admissionAction?: UniversalConversionAdmissionAction;
112
+ readonly maxRoutes?: number;
113
+ readonly metadata?: Record<string, unknown>;
114
+ }
115
+
116
+ export type CreateUniversalConversionArtifactsInput =
117
+ | UniversalConversionPlan
118
+ | UniversalConversionRoute
119
+ | UniversalConversionPlanOptions;
120
+
121
+ export interface UniversalConversionArtifactQuery {
122
+ readonly routeId?: string | readonly string[];
123
+ readonly historyId?: string | readonly string[];
124
+ readonly patchBundleId?: string | readonly string[];
125
+ readonly sourceLanguage?: FrontierSourceLanguage | string | readonly string[];
126
+ readonly target?: FrontierCompileTarget | string | readonly string[];
127
+ readonly mode?: UniversalConversionRouteMode | readonly string[];
128
+ readonly readiness?: SemanticMergeReadiness | string | readonly string[];
129
+ readonly admissionAction?: UniversalConversionAdmissionAction | readonly string[];
130
+ readonly admissionStatus?: UniversalConversionArtifactAdmissionStatus | readonly string[];
131
+ readonly priority?: UniversalConversionPriority | readonly string[];
132
+ readonly routeAction?: UniversalConversionRouteAction | readonly string[];
133
+ readonly sourcePath?: string | readonly string[];
134
+ readonly sourceHash?: string | readonly string[];
135
+ readonly ownershipKey?: string | readonly string[];
136
+ readonly conflictKey?: string | readonly string[];
137
+ readonly evidenceId?: string | readonly string[];
138
+ readonly proofId?: string | readonly string[];
139
+ }
140
+
141
+ export declare function createUniversalConversionArtifacts(
142
+ input?: CreateUniversalConversionArtifactsInput,
143
+ options?: CreateUniversalConversionArtifactsOptions
144
+ ): UniversalConversionArtifacts;
145
+ export declare function queryUniversalConversionArtifacts(
146
+ records: UniversalConversionArtifacts | UniversalConversionRouteArtifact | readonly (UniversalConversionArtifacts | UniversalConversionRouteArtifact)[],
147
+ query?: UniversalConversionArtifactQuery
148
+ ): readonly UniversalConversionRouteArtifact[];
package/dist/index.d.ts CHANGED
@@ -6,6 +6,7 @@ export * from './declarations/native-import-coverage.js';
6
6
  export * from './declarations/projection-coverage.js';
7
7
  export * from './declarations/projection-readiness.js';
8
8
  export * from './declarations/universal-capability.js';
9
+ export * from './declarations/universal-conversion-artifacts.js';
9
10
  export * from './declarations/universal-conversion-plan.js';
10
11
  export * from './declarations/universal-dialects.js';
11
12
  export * from './declarations/language-adapter-package-contracts.js';
package/dist/index.js CHANGED
@@ -29,6 +29,7 @@ export { createTreeSitterNativeImporterAdapter } from './internal/index-impl/cre
29
29
  export { createTypeScriptCompilerNativeImporterAdapter } from './internal/index-impl/createTypeScriptCompilerNativeImporterAdapter.js';
30
30
  export { createUniversalAstFromDocument } from './internal/index-impl/createUniversalAstFromDocument.js';
31
31
  export { createUniversalCapabilityMatrix } from './internal/index-impl/createUniversalCapabilityMatrix.js';
32
+ export { createUniversalConversionArtifacts, queryUniversalConversionArtifacts } from './universal-conversion-artifacts.js';
32
33
  export { createUniversalConversionPlan } from './internal/index-impl/createUniversalConversionPlan.js';
33
34
  export { attachUniversalDialectRegistry, createUniversalDialectRecord, createUniversalDialectRegistry, createUniversalExternRecord, summarizeUniversalDialectRegistry, UniversalDialectConstructKinds, UniversalDialectProjectionDispositions } from './universal-dialect-registry.js';
34
35
  export { diffNativeSourceImports } from './internal/index-impl/diffNativeSourceImports.js';
@@ -0,0 +1,60 @@
1
+ import { uniqueStrings } from './native-import-utils.js';
2
+
3
+ export function queryUniversalConversionArtifacts(records, query = {}) {
4
+ return artifactRecords(records)
5
+ .filter((record) => matchesArtifact(record, query))
6
+ .sort((left, right) => Number(right.mergeScore?.sortKey ?? 0) - Number(left.mergeScore?.sortKey ?? 0)
7
+ || String(left.routeId).localeCompare(String(right.routeId)));
8
+ }
9
+
10
+ export function artifactIndex(routeArtifacts) {
11
+ return {
12
+ routeIds: uniqueStrings(routeArtifacts.map((artifact) => artifact.routeId)),
13
+ historyIds: uniqueStrings(routeArtifacts.map((artifact) => artifact.history.id)),
14
+ patchBundleIds: uniqueStrings(routeArtifacts.map((artifact) => artifact.patchBundle.id)),
15
+ languages: uniqueStrings(routeArtifacts.map((artifact) => artifact.sourceLanguage)),
16
+ targets: uniqueStrings(routeArtifacts.map((artifact) => artifact.target)),
17
+ modes: uniqueStrings(routeArtifacts.map((artifact) => artifact.mode)),
18
+ readinesses: uniqueStrings(routeArtifacts.map((artifact) => artifact.readiness)),
19
+ admissionStatuses: uniqueStrings(routeArtifacts.map((artifact) => artifact.admissionStatus)),
20
+ sourcePaths: uniqueStrings(routeArtifacts.flatMap((artifact) => artifact.history.index.sourcePaths)),
21
+ sourceHashes: uniqueStrings(routeArtifacts.flatMap((artifact) => artifact.history.index.sourceHashes)),
22
+ ownershipKeys: uniqueStrings(routeArtifacts.flatMap((artifact) => artifact.history.index.ownershipKeys)),
23
+ conflictKeys: uniqueStrings(routeArtifacts.flatMap((artifact) => artifact.history.index.conflictKeys)),
24
+ evidenceIds: uniqueStrings(routeArtifacts.flatMap((artifact) => artifact.history.evidenceIds)),
25
+ proofIds: uniqueStrings(routeArtifacts.flatMap((artifact) => artifact.history.proofIds))
26
+ };
27
+ }
28
+
29
+ function artifactRecords(records) {
30
+ if (Array.isArray(records)) return records.flatMap(artifactRecords);
31
+ if (records?.kind === 'frontier.lang.universalConversionArtifacts') return records.routeArtifacts ?? [];
32
+ if (records?.kind === 'frontier.lang.universalConversionRouteArtifact') return [records];
33
+ return [];
34
+ }
35
+
36
+ function matchesArtifact(record, query) {
37
+ return match(query.routeId, [record.routeId])
38
+ && match(query.historyId, [record.history.id])
39
+ && match(query.patchBundleId, [record.patchBundle.id])
40
+ && match(query.sourceLanguage, [record.sourceLanguage])
41
+ && match(query.target, [record.target])
42
+ && match(query.mode, [record.mode])
43
+ && match(query.routeAction, [record.routeAction])
44
+ && match(query.priority, [record.priority])
45
+ && match(query.readiness, [record.readiness])
46
+ && match(query.admissionStatus, [record.admissionStatus])
47
+ && match(query.sourcePath, record.history.index.sourcePaths)
48
+ && match(query.sourceHash, record.history.index.sourceHashes)
49
+ && match(query.ownershipKey, record.history.index.ownershipKeys)
50
+ && match(query.conflictKey, record.history.index.conflictKeys)
51
+ && match(query.evidenceId, record.history.evidenceIds)
52
+ && match(query.proofId, record.history.proofIds);
53
+ }
54
+
55
+ function match(filter, values) {
56
+ const filters = Array.isArray(filter) ? filter : filter === undefined ? [] : [filter];
57
+ if (filters.length === 0) return true;
58
+ const valueSet = new Set((values ?? []).map(String));
59
+ return filters.some((item) => valueSet.has(String(item)));
60
+ }
@@ -0,0 +1,287 @@
1
+ import { idFragment, uniqueStrings } from './native-import-utils.js';
2
+ import { createUniversalConversionPlan } from './universal-conversion-plan.js';
3
+ import { artifactIndex } from './universal-conversion-artifact-query.js';
4
+ import { createSemanticHistoryRecord } from './internal/index-impl/semanticHistoryRecords.js';
5
+ import { createSemanticPatchBundleRecord } from './internal/index-impl/semanticPatchBundleRecords.js';
6
+
7
+ export { queryUniversalConversionArtifacts } from './universal-conversion-artifact-query.js';
8
+
9
+ export function createUniversalConversionArtifacts(input = {}, options = {}) {
10
+ const generatedAt = options.generatedAt ?? input.generatedAt ?? Date.now();
11
+ const plan = input?.kind === 'frontier.lang.universalConversionPlan'
12
+ ? input
13
+ : input?.target && input?.sourceLanguage
14
+ ? undefined
15
+ : createUniversalConversionPlan(input);
16
+ const routes = selectRoutes(plan?.routes ?? (input?.target && input?.sourceLanguage ? [input] : []), options);
17
+ const routeArtifacts = routes.map((route) => createRouteArtifact(route, {
18
+ generatedAt,
19
+ planId: options.planId ?? plan?.id ?? route.mergeRefs?.planId,
20
+ metadata: options.metadata
21
+ }));
22
+ const historyRecords = routeArtifacts.map((artifact) => artifact.history);
23
+ const patchBundleRecords = routeArtifacts.map((artifact) => artifact.patchBundle);
24
+ const index = artifactIndex(routeArtifacts);
25
+ return {
26
+ kind: 'frontier.lang.universalConversionArtifacts',
27
+ version: 1,
28
+ schema: 'frontier.lang.universalConversionArtifacts.v1',
29
+ id: options.id ?? `universal_conversion_artifacts_${idFragment(index.routeIds.join('_') || plan?.id || 'routes')}`,
30
+ planId: plan?.id ?? options.planId,
31
+ generatedAt,
32
+ routeArtifacts,
33
+ historyRecords,
34
+ patchBundleRecords,
35
+ index,
36
+ summary: {
37
+ routes: routeArtifacts.length,
38
+ histories: historyRecords.length,
39
+ patchBundles: patchBundleRecords.length,
40
+ reviewRequired: routeArtifacts.filter((artifact) => artifact.reviewRequired).length,
41
+ blocked: routeArtifacts.filter((artifact) => artifact.admissionStatus === 'blocked').length,
42
+ autoMergeClaims: 0,
43
+ semanticEquivalenceClaims: 0
44
+ },
45
+ metadata: {
46
+ autoMergeClaim: false,
47
+ semanticEquivalenceClaim: false,
48
+ note: 'Materialized conversion artifacts are merge-review records. They preserve provenance and admission state but do not prove target semantic equivalence.',
49
+ ...options.metadata
50
+ }
51
+ };
52
+ }
53
+
54
+ function createRouteArtifact(route, options) {
55
+ const refs = route.mergeRefs ?? {};
56
+ const planId = options.planId ?? refs.planId;
57
+ const sources = normalizeSources(refs.sources, route);
58
+ const regions = routeRegions(route, refs, sources);
59
+ const sourceMapLinks = routeSourceMapLinks(route, refs, sources, regions);
60
+ const admissionStatus = routeAdmissionStatus(route);
61
+ const reasonCodes = routeReasonCodes(route);
62
+ const historyId = refs.historyIds?.[0] ?? `history_${route.id}`;
63
+ const patchBundleId = refs.patchBundleIds?.[0] ?? `semantic_patch_bundle_${route.id}`;
64
+ const history = createSemanticHistoryRecord({
65
+ id: historyId,
66
+ createdAt: options.generatedAt,
67
+ language: route.sourceLanguage,
68
+ sourcePath: sources[0]?.sourcePath,
69
+ sources,
70
+ ownershipRegions: regions,
71
+ semanticCandidates: routeSemanticCandidates(route, refs),
72
+ evidenceIds: refs.evidenceIds,
73
+ proofIds: refs.proofIds,
74
+ replayLinks: refs.replayLinks,
75
+ admission: {
76
+ status: admissionStatus,
77
+ readiness: route.readiness,
78
+ reasonCodes,
79
+ evidenceIds: refs.evidenceIds,
80
+ metadata: routeAdmissionMetadata(route, planId)
81
+ },
82
+ metadata: routeRecordMetadata(route, planId, options.metadata)
83
+ }, { id: historyId, createdAt: options.generatedAt });
84
+ const patchBundle = createSemanticPatchBundleRecord({
85
+ id: patchBundleId,
86
+ language: route.sourceLanguage,
87
+ sourcePath: sources[0]?.sourcePath,
88
+ sources,
89
+ changedRegions: regions,
90
+ sourceMapLinks,
91
+ evidenceIds: refs.evidenceIds,
92
+ proofIds: refs.proofIds,
93
+ historyIds: [history.id],
94
+ readiness: route.readiness,
95
+ conflictKeys: refs.conflictKeys,
96
+ admission: {
97
+ status: admissionStatus,
98
+ readiness: route.readiness,
99
+ reviewRequired: true,
100
+ reasonCodes,
101
+ conflictKeys: refs.conflictKeys,
102
+ evidenceIds: refs.evidenceIds,
103
+ metadata: routeAdmissionMetadata(route, planId)
104
+ },
105
+ metadata: routeRecordMetadata(route, planId, options.metadata)
106
+ }, { id: patchBundleId, createdAt: options.generatedAt });
107
+ const materialization = {
108
+ status: 'materialized',
109
+ plannedHistoryIds: refs.historyIds ?? [],
110
+ materializedHistoryIds: [history.id],
111
+ patchBundleIds: [patchBundle.id],
112
+ sourceMapLinkIds: patchBundle.index.sourceMapLinkIds,
113
+ evidenceIds: history.evidenceIds,
114
+ proofIds: history.proofIds,
115
+ autoMergeClaim: false,
116
+ semanticEquivalenceClaim: false
117
+ };
118
+ return {
119
+ kind: 'frontier.lang.universalConversionRouteArtifact',
120
+ version: 1,
121
+ schema: 'frontier.lang.universalConversionRouteArtifact.v1',
122
+ routeId: route.id,
123
+ planId,
124
+ sourceLanguage: route.sourceLanguage,
125
+ target: route.target,
126
+ mode: route.mode,
127
+ routeAction: route.routeAction,
128
+ priority: route.priority,
129
+ readiness: route.readiness,
130
+ admissionAction: route.admissionAction,
131
+ admissionStatus,
132
+ reviewRequired: true,
133
+ history,
134
+ patchBundle,
135
+ materialization,
136
+ mergeScore: route.mergeScore,
137
+ autoMergeClaim: false,
138
+ semanticEquivalenceClaim: false,
139
+ metadata: { ...routeRecordMetadata(route, planId, options.metadata), materialization }
140
+ };
141
+ }
142
+
143
+ function selectRoutes(routes, options) {
144
+ const selected = (routes ?? []).filter((route) => {
145
+ if (options.routeId && route.id !== options.routeId) return false;
146
+ if (options.sourceLanguage && route.sourceLanguage !== options.sourceLanguage) return false;
147
+ if (options.target && route.target !== options.target) return false;
148
+ if (options.mode && route.mode !== options.mode) return false;
149
+ if (options.readiness && route.readiness !== options.readiness) return false;
150
+ if (options.admissionAction && route.admissionAction !== options.admissionAction) return false;
151
+ return true;
152
+ });
153
+ return Number.isFinite(options.maxRoutes) ? selected.slice(0, Math.max(0, Number(options.maxRoutes))) : selected;
154
+ }
155
+
156
+ function normalizeSources(sources, route) {
157
+ return (sources?.length ? sources : [{}]).map((source, index) => ({
158
+ id: source.sourceId ?? source.id ?? `route_source_${idFragment(route.id)}_${index + 1}`,
159
+ importId: source.importId,
160
+ language: route.sourceLanguage,
161
+ sourcePath: source.sourcePath,
162
+ sourceHash: source.sourceHash,
163
+ baseHash: source.baseHash,
164
+ targetHash: source.targetHash,
165
+ metadata: {
166
+ routeId: route.id,
167
+ target: route.target,
168
+ mode: route.mode
169
+ }
170
+ }));
171
+ }
172
+
173
+ function routeRegions(route, refs, sources) {
174
+ const source = sources[0] ?? {};
175
+ const keys = refs.semanticOwnershipKeys?.length
176
+ ? refs.semanticOwnershipKeys
177
+ : [`conversion#${route.sourceLanguage ?? 'source'}#${route.target ?? 'target'}#${route.id}`];
178
+ return uniqueStrings(keys).map((key, index) => ({
179
+ id: `route_region_${idFragment(route.id)}_${index + 1}`,
180
+ key,
181
+ conflictKey: refs.conflictKeys?.[index] ?? refs.conflictKeys?.[0] ?? key,
182
+ changeKind: 'conversion-route',
183
+ regionKind: route.mode,
184
+ granularity: 'conversion-route',
185
+ precision: route.mode === 'preserve-source' ? 'exact-source' : 'semantic-route',
186
+ language: route.sourceLanguage,
187
+ sourcePath: source.sourcePath,
188
+ sourceHash: source.sourceHash,
189
+ sourceMapIds: refs.sourceMapIds,
190
+ sourceMapMappingIds: refs.sourceMapMappingIds,
191
+ admission: {
192
+ readiness: route.readiness,
193
+ action: route.admissionAction,
194
+ conflictKeys: refs.conflictKeys
195
+ },
196
+ metadata: {
197
+ routeId: route.id,
198
+ target: route.target,
199
+ mode: route.mode,
200
+ autoMergeClaim: false,
201
+ semanticEquivalenceClaim: false
202
+ }
203
+ }));
204
+ }
205
+
206
+ function routeSourceMapLinks(route, refs, sources, regions) {
207
+ const source = sources[0] ?? {};
208
+ const max = Math.max(refs.sourceMapIds?.length ?? 0, refs.sourceMapMappingIds?.length ?? 0);
209
+ return Array.from({ length: max }, (_, index) => ({
210
+ id: refs.sourceMapLinkIds?.[index] ?? `route_source_map_link_${idFragment(route.id)}_${index + 1}`,
211
+ sourceMapId: refs.sourceMapIds?.[index] ?? refs.sourceMapIds?.[0],
212
+ sourceMapMappingId: refs.sourceMapMappingIds?.[index],
213
+ sourcePath: source.sourcePath,
214
+ sourceHash: source.sourceHash,
215
+ targetPath: `${route.target}:${source.sourcePath ?? route.id}`,
216
+ precision: route.mode === 'preserve-source' ? 'exact-source' : 'semantic-route',
217
+ regionKey: regions[index % Math.max(1, regions.length)]?.key,
218
+ regionKind: route.mode
219
+ }));
220
+ }
221
+
222
+ function routeSemanticCandidates(route, refs) {
223
+ const ids = refs.mergeCandidateIds?.length ? refs.mergeCandidateIds : [`candidate_${route.id}`];
224
+ return uniqueStrings(ids).map((id) => ({
225
+ id,
226
+ sourcePath: refs.sources?.[0]?.sourcePath,
227
+ baseHash: refs.sources?.[0]?.baseHash,
228
+ targetHash: refs.sources?.[0]?.targetHash,
229
+ readiness: route.readiness,
230
+ conflictKeys: refs.conflictKeys ?? [],
231
+ ownershipKeys: refs.semanticOwnershipKeys ?? [],
232
+ evidenceIds: refs.evidenceIds ?? [],
233
+ proofIds: refs.proofIds ?? [],
234
+ replayIds: (refs.replayLinks ?? []).map((link) => link?.id).filter(Boolean),
235
+ metadata: {
236
+ routeId: route.id,
237
+ target: route.target,
238
+ mode: route.mode,
239
+ risk: route.mergeScore?.risk
240
+ }
241
+ }));
242
+ }
243
+
244
+ function routeAdmissionStatus(route) {
245
+ if (route.readiness === 'blocked' || route.admissionAction === 'reject') return 'blocked';
246
+ if (route.readiness === 'ready' && route.missingEvidence?.length === 0) return 'queued';
247
+ return 'needs-review';
248
+ }
249
+
250
+ function routeReasonCodes(route) {
251
+ return uniqueStrings([
252
+ `mode:${route.mode}`,
253
+ `action:${route.routeAction}`,
254
+ ...(route.missingEvidence ?? []).map((item) => `missing:${item}`),
255
+ ...(route.blockers ?? []).map((item) => `blocker:${item}`),
256
+ ...(route.review ?? []).map((item) => `review:${item}`)
257
+ ]);
258
+ }
259
+
260
+ function routeAdmissionMetadata(route, planId) {
261
+ return {
262
+ planId,
263
+ routeId: route.id,
264
+ routeAction: route.routeAction,
265
+ admissionAction: route.admissionAction,
266
+ priority: route.priority,
267
+ mergeScore: route.mergeScore,
268
+ autoMergeClaim: false,
269
+ semanticEquivalenceClaim: false
270
+ };
271
+ }
272
+
273
+ function routeRecordMetadata(route, planId, metadata) {
274
+ return {
275
+ planId,
276
+ routeId: route.id,
277
+ target: route.target,
278
+ mode: route.mode,
279
+ routeAction: route.routeAction,
280
+ missingEvidence: route.missingEvidence ?? [],
281
+ blockers: route.blockers ?? [],
282
+ review: route.review ?? [],
283
+ autoMergeClaim: false,
284
+ semanticEquivalenceClaim: false,
285
+ ...metadata
286
+ };
287
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shapeshift-labs/frontier-lang-compiler",
3
- "version": "0.2.49",
3
+ "version": "0.2.50",
4
4
  "description": "Compiler facade for Frontier Lang source documents and language projection adapters.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",