@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 +7 -0
- package/bench/native-transform-suite.mjs +8 -0
- package/bench/smoke.mjs +4 -0
- package/dist/declarations/runtime.d.ts +6 -0
- package/dist/declarations/universal-conversion-artifacts.d.ts +148 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/universal-conversion-artifact-query.js +60 -0
- package/dist/universal-conversion-artifacts.js +287 -0
- package/package.json +1 -1
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