@shapeshift-labs/frontier-lang-compiler 0.2.51 → 0.2.53
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 +16 -0
- package/dist/declarations/universal-conversion-artifacts.d.ts +97 -1
- package/dist/index.js +2 -1
- package/dist/internal/index-impl/createUniversalConversionArtifacts.js +6 -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 +23 -11
- 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)),
|
|
@@ -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[];
|
package/dist/index.js
CHANGED
|
@@ -29,7 +29,8 @@ 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
|
|
32
|
+
export { createUniversalConversionArtifacts } from './internal/index-impl/createUniversalConversionArtifacts.js';
|
|
33
|
+
export { queryUniversalConversionArtifacts } from './universal-conversion-artifacts.js';
|
|
33
34
|
export { createUniversalConversionPlan } from './internal/index-impl/createUniversalConversionPlan.js';
|
|
34
35
|
export { attachUniversalDialectRegistry, createUniversalDialectRecord, createUniversalDialectRegistry, createUniversalExternRecord, summarizeUniversalDialectRegistry, UniversalDialectConstructKinds, UniversalDialectProjectionDispositions } from './universal-dialect-registry.js';
|
|
35
36
|
export { diffNativeSourceImports } from './internal/index-impl/diffNativeSourceImports.js';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { createUniversalConversionArtifacts as createUniversalConversionArtifactsImpl } from '../../universal-conversion-artifacts.js';
|
|
2
|
+
import { coverageMatrixContext } from './coverageMatrixContext.js';
|
|
3
|
+
|
|
4
|
+
export function createUniversalConversionArtifacts(input = {}, options = {}) {
|
|
5
|
+
return createUniversalConversionArtifactsImpl(input, { ...options, context: coverageMatrixContext() });
|
|
6
|
+
}
|
|
@@ -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';
|
|
@@ -9,11 +11,12 @@ export { queryUniversalConversionArtifacts } from './universal-conversion-artifa
|
|
|
9
11
|
|
|
10
12
|
export function createUniversalConversionArtifacts(input = {}, options = {}) {
|
|
11
13
|
const generatedAt = options.generatedAt ?? input.generatedAt ?? Date.now();
|
|
14
|
+
const context = options.context ?? {};
|
|
12
15
|
const plan = input?.kind === 'frontier.lang.universalConversionPlan'
|
|
13
16
|
? input
|
|
14
17
|
: input?.target && input?.sourceLanguage
|
|
15
18
|
? undefined
|
|
16
|
-
: createUniversalConversionPlan(input);
|
|
19
|
+
: createUniversalConversionPlan(input, context);
|
|
17
20
|
const routes = selectRoutes(plan?.routes ?? (input?.target && input?.sourceLanguage ? [input] : []), options);
|
|
18
21
|
const routeArtifacts = routes.map((route) => createRouteArtifact(route, {
|
|
19
22
|
generatedAt,
|
|
@@ -22,6 +25,7 @@ export function createUniversalConversionArtifacts(input = {}, options = {}) {
|
|
|
22
25
|
}));
|
|
23
26
|
const historyRecords = routeArtifacts.map((artifact) => artifact.history);
|
|
24
27
|
const patchBundleRecords = routeArtifacts.map((artifact) => artifact.patchBundle);
|
|
28
|
+
const admissionRecords = routeArtifacts.map((artifact) => artifact.admissionRecord);
|
|
25
29
|
const index = artifactIndex(routeArtifacts);
|
|
26
30
|
return {
|
|
27
31
|
kind: 'frontier.lang.universalConversionArtifacts',
|
|
@@ -33,17 +37,13 @@ export function createUniversalConversionArtifacts(input = {}, options = {}) {
|
|
|
33
37
|
routeArtifacts,
|
|
34
38
|
historyRecords,
|
|
35
39
|
patchBundleRecords,
|
|
40
|
+
admissionRecords,
|
|
36
41
|
index,
|
|
37
|
-
summary: {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
reviewRequired: routeArtifacts.filter((artifact) => artifact.reviewRequired).length,
|
|
43
|
-
blocked: routeArtifacts.filter((artifact) => artifact.admissionStatus === 'blocked').length,
|
|
44
|
-
autoMergeClaims: 0,
|
|
45
|
-
semanticEquivalenceClaims: 0
|
|
46
|
-
},
|
|
42
|
+
summary: universalConversionArtifactSummary(routeArtifacts, {
|
|
43
|
+
historyRecords,
|
|
44
|
+
patchBundleRecords,
|
|
45
|
+
admissionRecords
|
|
46
|
+
}),
|
|
47
47
|
metadata: {
|
|
48
48
|
autoMergeClaim: false,
|
|
49
49
|
semanticEquivalenceClaim: false,
|
|
@@ -120,6 +120,16 @@ function createRouteArtifact(route, options) {
|
|
|
120
120
|
autoMergeClaim: false,
|
|
121
121
|
semanticEquivalenceClaim: false
|
|
122
122
|
};
|
|
123
|
+
const admissionRecord = createUniversalConversionAdmissionRecord({
|
|
124
|
+
route,
|
|
125
|
+
planId,
|
|
126
|
+
admissionStatus,
|
|
127
|
+
reasonCodes,
|
|
128
|
+
history,
|
|
129
|
+
patchBundle,
|
|
130
|
+
semanticOperations,
|
|
131
|
+
materialization
|
|
132
|
+
});
|
|
123
133
|
return {
|
|
124
134
|
kind: 'frontier.lang.universalConversionRouteArtifact',
|
|
125
135
|
version: 1,
|
|
@@ -137,9 +147,11 @@ function createRouteArtifact(route, options) {
|
|
|
137
147
|
reviewRequired: true,
|
|
138
148
|
history,
|
|
139
149
|
patchBundle,
|
|
150
|
+
admissionRecord,
|
|
140
151
|
semanticOperations,
|
|
141
152
|
materialization,
|
|
142
153
|
mergeScore: route.mergeScore,
|
|
154
|
+
admissionBucket: admissionRecord.admissionBucket,
|
|
143
155
|
autoMergeClaim: false,
|
|
144
156
|
semanticEquivalenceClaim: false,
|
|
145
157
|
metadata: { ...routeRecordMetadata(route, planId, options.metadata), materialization }
|
package/package.json
CHANGED