@shapeshift-labs/frontier-lang-compiler 0.2.60 → 0.2.62

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
@@ -272,6 +272,7 @@ const sidecar = createSemanticImportSidecar(imported);
272
272
  console.log(sidecar.summary.emptySemanticIndex); // false when symbols were found
273
273
  console.log(sidecar.ownershipRegions[0].key); // source#src/runtime.ts#type#Runtime
274
274
  console.log(sidecar.patchHints[0].supportedOperations); // source-region patch operations
275
+ console.log(sidecar.semanticImpact.records[0].verificationPlan); // dependency/source-map/proof checks for a region
275
276
  console.log(sidecar.proofSpec.obligations); // proof/spec obligations when the import carries a universal AST proof layer
276
277
  console.log(sidecar.paradigmSemantics.hasLowering); // true when source import preserved lowering/paradigm records
277
278
  ```
@@ -0,0 +1,55 @@
1
+ import type { SemanticMergeReadiness, SourceSpan } from '@shapeshift-labs/frontier-lang-kernel';
2
+ import type { NativeImportRegionTaxonomyKind } from './native-import-losses.js';
3
+
4
+ export type SemanticImportImpactRisk = 'low' | 'medium' | 'high' | string;
5
+ export type SemanticImportImpactConfidence = 'source-exact' | 'source-addressed' | 'estimated-source-region' | 'review-required' | string;
6
+
7
+ export interface SemanticImportImpactVerificationStep {
8
+ readonly kind: 'dependency-review' | 'source-map-review' | 'reject-or-reprove' | 'proof-review' | 'patch-admission' | 'evidence-review' | string;
9
+ readonly reason: string;
10
+ readonly required: boolean;
11
+ }
12
+
13
+ export interface SemanticImportImpactRecord {
14
+ readonly id: string;
15
+ readonly kind: 'ownership-region-impact' | string;
16
+ readonly ownershipRegionId: string;
17
+ readonly ownershipKey: string;
18
+ readonly regionKind?: NativeImportRegionTaxonomyKind;
19
+ readonly sourcePath?: string;
20
+ readonly sourceHash?: string;
21
+ readonly sourceSpan?: SourceSpan;
22
+ readonly symbolIds: readonly string[];
23
+ readonly symbolNames: readonly string[];
24
+ readonly dependencyRelationIds: readonly string[];
25
+ readonly dependencyPredicates: readonly string[];
26
+ readonly affectedSymbolIds: readonly string[];
27
+ readonly sourceMapMappingIds: readonly string[];
28
+ readonly sourcePreservationRecordIds: readonly string[];
29
+ readonly patchHintIds: readonly string[];
30
+ readonly proofSpecIds: readonly string[];
31
+ readonly proofObligationIds: readonly string[];
32
+ readonly failedProofObligationIds: readonly string[];
33
+ readonly openProofObligationIds: readonly string[];
34
+ readonly paradigmSemanticIds: readonly string[];
35
+ readonly loweringRecordIds: readonly string[];
36
+ readonly evidenceIds: readonly string[];
37
+ readonly verificationPlan: readonly SemanticImportImpactVerificationStep[];
38
+ readonly conflictKeys: readonly string[];
39
+ readonly readiness: SemanticMergeReadiness;
40
+ readonly risk: SemanticImportImpactRisk;
41
+ readonly confidence: SemanticImportImpactConfidence;
42
+ }
43
+
44
+ export interface SemanticImportImpactSummary {
45
+ readonly kind: 'frontier.lang.semanticImpact';
46
+ readonly version: 1;
47
+ readonly records: readonly SemanticImportImpactRecord[];
48
+ readonly summary: {
49
+ readonly total: number; readonly byRisk: Readonly<Record<string, number>>; readonly byReadiness: Readonly<Record<string, number>>;
50
+ readonly conflictKeys: readonly string[]; readonly dependencyRelations: number; readonly affectedSymbols: number;
51
+ readonly sourceMapMappings: number; readonly sourcePreservationRecords: number; readonly patchHints: number;
52
+ readonly proofObligations: number; readonly openProofObligations: number; readonly failedProofObligations: number; readonly paradigmSemantics: number; readonly loweringRecords: number;
53
+ readonly evidenceIds: number; readonly verificationPlans: readonly string[]; readonly requiredVerificationSteps: number;
54
+ };
55
+ }
@@ -14,6 +14,7 @@ export interface SemanticImportSidecarProofAdmissionSummary {
14
14
  readonly discharged: number;
15
15
  readonly pending?: number;
16
16
  readonly failed: number;
17
+ readonly stale?: number;
17
18
  readonly assumed?: number;
18
19
  readonly externalToolRequired?: number;
19
20
  readonly open: number;
@@ -26,6 +26,7 @@ import type {
26
26
  } from '@shapeshift-labs/frontier-lang-kernel';
27
27
  import type { SemanticImportSidecarAdmission, SemanticImportSidecarQuality } from './semantic-sidecar-admission.js';
28
28
  import type { SemanticMergeConflictClass, SemanticMergeConflictSummary } from './semantic-merge-conflicts.js';
29
+ import type { SemanticImportImpactSummary } from './semantic-impact.js';
29
30
  import type { Diagnostic } from '@shapeshift-labs/frontier-lang-checker';
30
31
  import type { EmitTypeScriptOptions, TypeScriptAstModule, TypeScriptDocumentSourceMapResult, TypeScriptGeneratedSourceMapResult } from '@shapeshift-labs/frontier-lang-typescript';
31
32
  import type { EmitJavaScriptOptions, EmitJavaScriptWithSourceMapResult, JavaScriptAstModule, JavaScriptSourceMapResult } from '@shapeshift-labs/frontier-lang-javascript';
@@ -263,7 +264,7 @@ export interface SemanticImportSidecar {
263
264
  readonly universalAstLayers: SemanticImportSidecarUniversalAstLayerSummary;
264
265
  readonly proofSpec: SemanticImportSidecarProofSpecSummary;
265
266
  readonly paradigmSemantics: SemanticImportSidecarParadigmSemanticsSummary;
266
- readonly dependencies: SemanticImportDependencySummary;
267
+ readonly dependencies: SemanticImportDependencySummary; readonly semanticImpact: SemanticImportImpactSummary;
267
268
  readonly patchHints: readonly SemanticImportPatchHint[];
268
269
  readonly quality: SemanticImportSidecarQuality;
269
270
  readonly admission: SemanticImportSidecarAdmission;
@@ -302,6 +303,7 @@ export interface SemanticImportSidecar {
302
303
  readonly paradigmSemanticsGroups: number;
303
304
  readonly paradigmSemanticsLoweringRecords: number;
304
305
  readonly dependencyRelations: number; readonly dependencyPredicates: readonly string[];
306
+ readonly semanticImpactRecords: number; readonly semanticImpactHighRiskRecords: number; readonly semanticImpactRequiredVerificationSteps: number;
305
307
  readonly patchHints: number;
306
308
  readonly evidenceWarnings: number;
307
309
  readonly semanticImportExpected: boolean; readonly semanticImportExpectedSatisfied: boolean; readonly semanticImportExpectedMissingReasonCodes: readonly string[];
@@ -310,10 +312,4 @@ export interface SemanticImportSidecar {
310
312
  readonly metadata?: Record<string, unknown>;
311
313
  }
312
314
 
313
- export interface SemanticImportSidecarOptions {
314
- readonly id?: string;
315
- readonly generatedAt?: number;
316
- readonly regionPrefix?: string;
317
- readonly targetPath?: string; readonly expected?: boolean; readonly semanticImportExpected?: boolean;
318
- readonly metadata?: Record<string, unknown>;
319
- }
315
+ export interface SemanticImportSidecarOptions { readonly id?: string; readonly generatedAt?: number; readonly regionPrefix?: string; readonly targetPath?: string; readonly expected?: boolean; readonly semanticImportExpected?: boolean; readonly metadata?: Record<string, unknown>; }
package/dist/index.d.ts CHANGED
@@ -16,6 +16,7 @@ export * from './declarations/semantic-sidecar-admission.js';
16
16
  export * from './declarations/semantic-merge-conflicts.js';
17
17
  export * from './declarations/semantic-history.js';
18
18
  export * from './declarations/semantic-patch-bundle.js';
19
+ export * from './declarations/semantic-impact.js';
19
20
  export * from './declarations/semantic-sidecar.js';
20
21
  export * from './declarations/native-diff.js';
21
22
  export * from './declarations/semantic-slice.js';
@@ -1,4 +1,4 @@
1
- import{idFragment,maxSemanticMergeReadiness,uniqueRecordsById}from'../../native-import-utils.js';import{summarizeSemanticImportDependencies}from'../../semantic-import-dependencies.js';import{summarizeSemanticImportSidecarParadigmSemantics,summarizeSemanticImportSidecarProofSpec,summarizeSemanticImportSidecarUniversalAstLayers}from'../../semantic-import-layers.js';import{semanticPatchHintForRegion,summarizeSemanticImportRegionTaxonomy}from'../../semantic-import-regions.js';import{semanticImportSidecarEntry}from'../../semantic-import-sidecar-entry.js';import{summarizeKernelSourcePreservation}from'../../semantic-import-source-preservation.js';
1
+ import{idFragment,maxSemanticMergeReadiness,uniqueRecordsById}from'../../native-import-utils.js';import{summarizeSemanticImportDependencies}from'../../semantic-import-dependencies.js';import{createSemanticImportImpact}from'../../semantic-import-impact.js';import{summarizeSemanticImportSidecarParadigmSemantics,summarizeSemanticImportSidecarProofSpec,summarizeSemanticImportSidecarUniversalAstLayers}from'../../semantic-import-layers.js';import{semanticPatchHintForRegion,summarizeSemanticImportRegionTaxonomy}from'../../semantic-import-regions.js';import{semanticImportSidecarEntry}from'../../semantic-import-sidecar-entry.js';import{summarizeKernelSourcePreservation}from'../../semantic-import-source-preservation.js';
2
2
  import{createSemanticImportSidecarAdmission,createSemanticImportSidecarQuality}from'./createSemanticImportSidecarAdmission.js';
3
3
  import{summarizeNativeImportLosses}from'./summarizeNativeImportLosses.js';
4
4
  export function createSemanticImportSidecar(importResult, options = {}) {
@@ -38,6 +38,22 @@ export function createSemanticImportSidecar(importResult, options = {}) {
38
38
  readiness
39
39
  });
40
40
  const admission = createSemanticImportSidecarAdmission(quality, readiness);
41
+ const semanticImpact = createSemanticImportImpact({
42
+ imports,
43
+ symbols,
44
+ ownershipRegions,
45
+ sourceMapMappings,
46
+ sourcePreservation,
47
+ dependencies,
48
+ patchHints,
49
+ proofSpec,
50
+ evidence: {
51
+ total: evidence.length,
52
+ failed: evidence.filter((record) => record.status === 'failed').map((record) => record.id),
53
+ ids: evidence.map((record) => record.id)
54
+ },
55
+ readiness
56
+ });
41
57
  return {
42
58
  kind: 'frontier.lang.semanticImportSidecar',
43
59
  version: 1,
@@ -58,6 +74,7 @@ export function createSemanticImportSidecar(importResult, options = {}) {
58
74
  proofSpec,
59
75
  paradigmSemantics,
60
76
  dependencies,
77
+ semanticImpact,
61
78
  patchHints,
62
79
  quality,
63
80
  admission,
@@ -101,6 +118,9 @@ export function createSemanticImportSidecar(importResult, options = {}) {
101
118
  paradigmSemanticsLoweringRecords: paradigmSemantics.loweringRecords,
102
119
  dependencyRelations: dependencies.total,
103
120
  dependencyPredicates: dependencies.predicates,
121
+ semanticImpactRecords: semanticImpact.summary.total,
122
+ semanticImpactHighRiskRecords: semanticImpact.summary.byRisk.high ?? 0,
123
+ semanticImpactRequiredVerificationSteps: semanticImpact.summary.requiredVerificationSteps,
104
124
  patchHints: patchHints.length,
105
125
  evidenceWarnings: quality.emptyEvidenceWarnings.length,
106
126
  semanticImportExpected: quality.expected,
@@ -72,6 +72,18 @@ export function createSemanticImportSidecarQuality(input) {
72
72
  'review-pending-proof-obligations',
73
73
  sourcePaths
74
74
  ));
75
+ if ((proofSpec.byReadinessStatus?.open ?? 0) > 0) warnings.push(sidecarQualityWarning(
76
+ 'open-proof-obligations',
77
+ 'Semantic sidecar has open proof obligations.',
78
+ 'review-open-proof-obligations',
79
+ sourcePaths
80
+ ));
81
+ if (proofSpec.stale > 0) warnings.push(sidecarQualityWarning(
82
+ 'stale-proof-obligations',
83
+ 'Semantic sidecar has stale proof obligations.',
84
+ 'rerun-stale-proof-obligations',
85
+ sourcePaths
86
+ ));
75
87
  if (proofSpec.assumed > 0) warnings.push(sidecarQualityWarning(
76
88
  'assumed-proof-obligations',
77
89
  'Semantic sidecar has assumed proof obligations.',
@@ -120,6 +132,7 @@ export function createSemanticImportSidecarQuality(input) {
120
132
  discharged: proofSpec.discharged,
121
133
  pending: proofSpec.pending,
122
134
  failed: proofSpec.failed,
135
+ stale: proofSpec.stale,
123
136
  assumed: proofSpec.assumed,
124
137
  externalToolRequired: proofSpec.externalToolRequired,
125
138
  open: proofSpec.open,
@@ -186,6 +199,6 @@ function sidecarAdmissionAction(quality, readiness) {
186
199
  }
187
200
 
188
201
  function sidecarProofReviewObligations(proofSummary) {
189
- return (proofSummary.pending ?? 0) + (proofSummary.assumed ?? 0) +
202
+ return (proofSummary.open ?? 0) + (proofSummary.stale ?? 0) + (proofSummary.assumed ?? 0) +
190
203
  (proofSummary.externalToolRequired ?? 0) + (proofSummary.unknown ?? 0);
191
204
  }
@@ -38,8 +38,8 @@ function scanJavaScriptLike(input) {
38
38
  declarations.push(nativeDeclaration(input, number, 'FunctionDeclaration', 'function', match[1], { parameters: splitParameters(match[2]) }, declarationLine.includes('{')));
39
39
  } else if ((match = trimmed.match(/^export\s+default\s+(?:async\s+)?function\*?\s*([A-Za-z_$][\w$]*)?\s*\(([^)]*)\)/))) {
40
40
  declarations.push(nativeDeclaration(input, number, 'ExportDefaultFunctionDeclaration', 'function', match[1] ?? 'default', { parameters: splitParameters(match[2]), exportDefault: true }, trimmed.includes('{')));
41
- } else if ((match = declarationLine.match(/^(?:abstract\s+)?class\s+([A-Za-z_$][\w$]*)/))) {
42
- declarations.push(nativeDeclaration(input, number, 'ClassDeclaration', 'class', match[1], {}, declarationLine.includes('{')));
41
+ } else if ((match = declarationLine.match(/^(?:default\s+)?(?:abstract\s+)?class\s+([A-Za-z_$][\w$]*)/))) {
42
+ declarations.push(nativeDeclaration(input, number, declarationLine.startsWith('default ') ? 'ExportDefaultClassDeclaration' : 'ClassDeclaration', 'class', match[1], { exportDefault: declarationLine.startsWith('default ') || undefined }, declarationLine.includes('{')));
43
43
  if (declarationLine.includes('{') && !declarationLine.includes('}')) {
44
44
  currentClass = match[1];
45
45
  classDepth = 0;
@@ -196,6 +196,7 @@ function jsInitializerKind(line) {
196
196
  const initializer = String(line ?? '').split('=').slice(1).join('=').trim();
197
197
  if (!initializer) return 'unknown';
198
198
  if (/^(?:async\s+)?function\b/.test(initializer) || /=>/.test(initializer)) return 'function';
199
+ if (/^(?:React\.)?(?:forwardRef|memo|lazy|observer)\s*(?:<[^>]+>)?\s*\(/.test(initializer)) return 'function';
199
200
  if (initializer.startsWith('{')) return 'object';
200
201
  if (initializer.startsWith('[')) return 'array';
201
202
  if (/^new\s+/.test(initializer)) return 'instance';
@@ -0,0 +1,67 @@
1
+ import type { SemanticMergeReadiness, SourceSpan } from '@shapeshift-labs/frontier-lang-kernel';
2
+ import type { NativeImportRegionTaxonomyKind } from './index.js';
3
+
4
+ export type SemanticImportImpactRisk = 'low' | 'medium' | 'high' | string;
5
+ export type SemanticImportImpactConfidence = 'source-exact' | 'source-addressed' | 'estimated-source-region' | 'review-required' | string;
6
+
7
+ export interface SemanticImportImpactVerificationStep {
8
+ readonly kind: 'dependency-review' | 'source-map-review' | 'reject-or-reprove' | 'proof-review' | 'patch-admission' | 'evidence-review' | string;
9
+ readonly reason: string;
10
+ readonly required: boolean;
11
+ }
12
+
13
+ export interface SemanticImportImpactRecord {
14
+ readonly id: string;
15
+ readonly kind: 'ownership-region-impact' | string;
16
+ readonly ownershipRegionId: string;
17
+ readonly ownershipKey: string;
18
+ readonly regionKind?: NativeImportRegionTaxonomyKind;
19
+ readonly sourcePath?: string;
20
+ readonly sourceHash?: string;
21
+ readonly sourceSpan?: SourceSpan;
22
+ readonly symbolIds: readonly string[];
23
+ readonly symbolNames: readonly string[];
24
+ readonly dependencyRelationIds: readonly string[];
25
+ readonly dependencyPredicates: readonly string[];
26
+ readonly affectedSymbolIds: readonly string[];
27
+ readonly sourceMapMappingIds: readonly string[];
28
+ readonly sourcePreservationRecordIds: readonly string[];
29
+ readonly patchHintIds: readonly string[];
30
+ readonly proofSpecIds: readonly string[];
31
+ readonly proofObligationIds: readonly string[];
32
+ readonly failedProofObligationIds: readonly string[];
33
+ readonly openProofObligationIds: readonly string[];
34
+ readonly paradigmSemanticIds: readonly string[];
35
+ readonly loweringRecordIds: readonly string[];
36
+ readonly evidenceIds: readonly string[];
37
+ readonly verificationPlan: readonly SemanticImportImpactVerificationStep[];
38
+ readonly conflictKeys: readonly string[];
39
+ readonly readiness: SemanticMergeReadiness;
40
+ readonly risk: SemanticImportImpactRisk;
41
+ readonly confidence: SemanticImportImpactConfidence;
42
+ }
43
+
44
+ export interface SemanticImportImpactSummary {
45
+ readonly kind: 'frontier.lang.semanticImpact';
46
+ readonly version: 1;
47
+ readonly records: readonly SemanticImportImpactRecord[];
48
+ readonly summary: {
49
+ readonly total: number;
50
+ readonly byRisk: Readonly<Record<string, number>>;
51
+ readonly byReadiness: Readonly<Record<string, number>>;
52
+ readonly conflictKeys: readonly string[];
53
+ readonly dependencyRelations: number;
54
+ readonly affectedSymbols: number;
55
+ readonly sourceMapMappings: number;
56
+ readonly sourcePreservationRecords: number;
57
+ readonly patchHints: number;
58
+ readonly proofObligations: number;
59
+ readonly openProofObligations: number;
60
+ readonly failedProofObligations: number;
61
+ readonly paradigmSemantics: number;
62
+ readonly loweringRecords: number;
63
+ readonly evidenceIds: number;
64
+ readonly verificationPlans: readonly string[];
65
+ readonly requiredVerificationSteps: number;
66
+ };
67
+ }
@@ -0,0 +1,317 @@
1
+ import { countBy, idFragment, maxSemanticMergeReadiness, uniqueRecordsById, uniqueStrings } from './native-import-utils.js';
2
+ import { semanticDependencyPredicateKey } from './semantic-import-dependencies.js';
3
+
4
+ function createSemanticImportImpact(input) {
5
+ const relations = collectDependencyRelations(input.imports, input.dependencies);
6
+ const proofRecords = collectProofRecords(input.imports);
7
+ const paradigmRecords = collectParadigmRecords(input.imports);
8
+ const symbolsByRegion = groupBy(input.symbols, (symbol) => symbol.ownershipRegionId);
9
+ const symbolIds = new Set((input.symbols ?? []).map((symbol) => symbol.id).filter(Boolean));
10
+ const records = [];
11
+ for (const region of input.ownershipRegions ?? []) {
12
+ const regionSymbols = symbolsForRegion(region, symbolsByRegion);
13
+ const record = semanticImpactRecord({
14
+ region,
15
+ regionSymbols,
16
+ relations: relations.filter((relation) => relationTouchesSymbols(relation, regionSymbols, symbolIds)),
17
+ sourceMapMappings: sourceMapMappingsForSymbols(input.sourceMapMappings, regionSymbols),
18
+ sourcePreservationRecords: preservationRecordsForSymbols(input.sourcePreservation?.records, regionSymbols),
19
+ proofRecords: proofRecordsForSymbols(proofRecords, regionSymbols, region),
20
+ paradigmRecords: paradigmRecordsForSymbols(paradigmRecords, regionSymbols, region),
21
+ patchHints: (input.patchHints ?? []).filter((hint) => hint.ownershipRegionId === region.id || hint.ownershipKey === region.key),
22
+ allSymbolIds: symbolIds,
23
+ evidence: input.evidence ?? { failed: [], ids: [] },
24
+ readiness: input.readiness
25
+ });
26
+ records.push(record);
27
+ }
28
+ return {
29
+ kind: 'frontier.lang.semanticImpact',
30
+ version: 1,
31
+ records,
32
+ summary: summarizeSemanticImpactRecords(records)
33
+ };
34
+ }
35
+
36
+ function semanticImpactRecord(input) {
37
+ const symbolIds = uniqueStrings(input.regionSymbols.map((symbol) => symbol.id).filter(Boolean));
38
+ const dependencyPredicates = uniqueStrings(input.relations.map((relation) => semanticDependencyPredicateKey(relation.predicate)));
39
+ const proof = summarizeProofImpact(input.proofRecords);
40
+ const paradigm = summarizeParadigmImpact(input.paradigmRecords);
41
+ const evidenceIds = relatedEvidenceIds(input);
42
+ const readiness = input.regionSymbols.reduce(
43
+ (current, symbol) => maxSemanticMergeReadiness(current, symbol.readiness),
44
+ input.readiness
45
+ );
46
+ const verificationPlan = semanticImpactVerificationPlan({
47
+ dependencyPredicates,
48
+ proof,
49
+ paradigm,
50
+ evidenceIds,
51
+ sourcePreservationRecords: input.sourcePreservationRecords,
52
+ patchHints: input.patchHints,
53
+ readiness
54
+ });
55
+ const risk = semanticImpactRisk({
56
+ readiness,
57
+ proof,
58
+ failedEvidenceIds: input.evidence.failed ?? [],
59
+ sourcePreservationRecords: input.sourcePreservationRecords,
60
+ relationCount: input.relations.length,
61
+ verificationPlan
62
+ });
63
+ return {
64
+ id: `impact_${idFragment(input.region.id ?? input.region.key)}`,
65
+ kind: 'ownership-region-impact',
66
+ ownershipRegionId: input.region.id,
67
+ ownershipKey: input.region.key,
68
+ regionKind: input.region.regionKind,
69
+ sourcePath: input.region.sourcePath,
70
+ sourceHash: input.region.sourceHash,
71
+ sourceSpan: input.region.sourceSpan,
72
+ symbolIds,
73
+ symbolNames: uniqueStrings(input.regionSymbols.map((symbol) => symbol.name).filter(Boolean)),
74
+ dependencyRelationIds: input.relations.map((relation) => relation.id).filter(Boolean),
75
+ dependencyPredicates,
76
+ affectedSymbolIds: affectedSymbolIds(input.relations, symbolIds, input.allSymbolIds),
77
+ sourceMapMappingIds: uniqueStrings([
78
+ ...input.sourceMapMappings.map((mapping) => mapping.id),
79
+ ...input.sourcePreservationRecords.map((record) => record.sourceMapMappingId)
80
+ ].filter(Boolean)),
81
+ sourcePreservationRecordIds: input.sourcePreservationRecords.map((record) => record.id).filter(Boolean),
82
+ patchHintIds: input.patchHints.map((hint) => hint.id).filter(Boolean),
83
+ proofSpecIds: proof.specIds,
84
+ proofObligationIds: proof.obligationIds,
85
+ failedProofObligationIds: proof.failedObligationIds,
86
+ openProofObligationIds: proof.openObligationIds,
87
+ paradigmSemanticIds: paradigm.semanticIds,
88
+ loweringRecordIds: paradigm.loweringIds,
89
+ evidenceIds,
90
+ verificationPlan,
91
+ conflictKeys: semanticImpactConflictKeys(input.region, symbolIds, input.relations, dependencyPredicates),
92
+ readiness,
93
+ risk,
94
+ confidence: semanticImpactConfidence(input.region, input.sourceMapMappings, input.sourcePreservationRecords)
95
+ };
96
+ }
97
+
98
+ function collectDependencyRelations(imports, dependencies) {
99
+ const dependencyIds = new Set(dependencies?.ids ?? []);
100
+ return uniqueRecordsById((imports ?? [])
101
+ .flatMap((imported) => imported?.semanticIndex?.relations ?? imported?.universalAst?.semanticIndex?.relations ?? [])
102
+ .filter((relation) => dependencyIds.has(relation?.id)));
103
+ }
104
+
105
+ function collectProofRecords(imports) {
106
+ const records = [];
107
+ for (const imported of imports ?? []) {
108
+ const proof = imported?.universalAst?.proof ?? imported?.proof;
109
+ if (!proof) continue;
110
+ const proofGroups = [
111
+ ['proof-record', proof.contracts, proof.refinements, proof.invariants, proof.termination, proof.temporal],
112
+ ['obligation', proof.obligations],
113
+ ['proof-record', proof.artifacts, proof.assumptions]
114
+ ];
115
+ for (const [proofRecordKind, ...groups] of proofGroups) for (const record of groups.flatMap((group) => group ?? [])) records.push({ ...record, proofSpecId: proof.id, proofRecordKind });
116
+ }
117
+ return records.filter(Boolean);
118
+ }
119
+
120
+ const ParadigmImpactGroups = Object.freeze([
121
+ 'bindingScopes', 'bindings', 'patterns', 'typeConstraints', 'evaluationModels',
122
+ 'memoryLocations', 'effectRegions', 'controlRegions', 'logicPrograms',
123
+ 'actorSystems', 'stackEffects', 'arrayShapes', 'numericKernels',
124
+ 'dataflowNetworks', 'clockModels', 'objectModels', 'macroExpansions',
125
+ 'reflectionBoundaries', 'loweringRecords'
126
+ ]);
127
+
128
+ function collectParadigmRecords(imports) {
129
+ const records = [];
130
+ for (const imported of imports ?? []) {
131
+ const semantics = imported?.universalAst?.paradigmSemantics ?? imported?.paradigmSemantics;
132
+ if (!semantics) continue;
133
+ for (const group of ParadigmImpactGroups) {
134
+ for (const record of semantics[group] ?? []) records.push({ ...record, paradigmGroup: group, paradigmSpecId: semantics.id });
135
+ }
136
+ }
137
+ return records.filter(Boolean);
138
+ }
139
+
140
+ function proofRecordsForSymbols(proofRecords, symbols, region) {
141
+ const ids = new Set(symbols.map((symbol) => symbol.id).filter(Boolean));
142
+ const mappingIds = new Set(symbols.map((symbol) => symbol.sourceMapMappingId).filter(Boolean));
143
+ const nativeNodeIds = new Set(symbols.map((symbol) => symbol.nativeAstNodeId).filter(Boolean));
144
+ const regionIds = new Set([region.id, region.key].filter(Boolean));
145
+ return proofRecords.filter((record) => isImportWideProofRecord(record) || ids.has(record.subjectId) || ids.has(record.semanticSymbolId) || mappingIds.has(record.sourceMapMappingId) || nativeNodeIds.has(record.nativeAstNodeId) || regionIds.has(record.subjectId) || regionIds.has(record.ownershipRegionId));
146
+ }
147
+
148
+ function isImportWideProofRecord(record) {
149
+ const kind = String(record?.subjectKind ?? '').toLowerCase();
150
+ return (!record?.subjectId && !record?.semanticSymbolId && !record?.sourceMapMappingId && !record?.nativeAstNodeId && !record?.ownershipRegionId) || ['import', 'source', 'nativesource', 'document', 'proofspec'].includes(kind);
151
+ }
152
+
153
+ function paradigmRecordsForSymbols(records, symbols, region) {
154
+ const symbolIds = new Set(symbols.map((symbol) => symbol.id).filter(Boolean));
155
+ const mappingIds = new Set(symbols.map((symbol) => symbol.sourceMapMappingId).filter(Boolean));
156
+ const nativeNodeIds = new Set(symbols.map((symbol) => symbol.nativeAstNodeId).filter(Boolean));
157
+ const regionIds = new Set([region.id, region.key].filter(Boolean));
158
+ return records.filter((record) => symbolIds.has(record.semanticSymbolId)
159
+ || symbolIds.has(record.symbolId)
160
+ || symbolIds.has(record.subjectId)
161
+ || mappingIds.has(record.sourceMapMappingId)
162
+ || nativeNodeIds.has(record.nativeAstNodeId)
163
+ || regionIds.has(record.ownershipRegionId)
164
+ || regionIds.has(record.subjectId));
165
+ }
166
+
167
+ function summarizeProofImpact(records) {
168
+ const obligationRecords = records.filter((record) => record.proofRecordKind === 'obligation');
169
+ const failed = obligationRecords.filter((record) => proofReadinessStatus(record.status) === 'failed');
170
+ const open = obligationRecords.filter((record) => ['open', 'pending', 'unknown', 'stale', 'assumed', 'external-tool-required'].includes(proofReadinessStatus(record.status)));
171
+ return {
172
+ specIds: uniqueStrings(records.map((record) => record.proofSpecId).filter(Boolean)),
173
+ obligationIds: uniqueStrings(obligationRecords.map((record) => record.id).filter(Boolean)),
174
+ failedObligationIds: uniqueStrings(failed.map((record) => record.id).filter(Boolean)),
175
+ openObligationIds: uniqueStrings(open.map((record) => record.id).filter(Boolean)),
176
+ evidenceIds: uniqueStrings(records.flatMap((record) => record.evidenceIds ?? []).filter(Boolean))
177
+ };
178
+ }
179
+
180
+ function summarizeParadigmImpact(records) {
181
+ const lowering = records.filter((record) => record.paradigmGroup === 'loweringRecords');
182
+ const semantic = records.filter((record) => record.paradigmGroup !== 'loweringRecords');
183
+ return {
184
+ semanticIds: uniqueStrings(semantic.map((record) => record.id).filter(Boolean)),
185
+ loweringIds: uniqueStrings(lowering.map((record) => record.id).filter(Boolean)),
186
+ evidenceIds: uniqueStrings(records.flatMap((record) => record.evidenceIds ?? []).filter(Boolean)),
187
+ lossIds: uniqueStrings(records.flatMap((record) => record.lossIds ?? []).filter(Boolean))
188
+ };
189
+ }
190
+
191
+ function proofReadinessStatus(status) {
192
+ const value = String(status ?? 'unknown').trim().toLowerCase().replace(/[\s_]+/g, '-');
193
+ if (['accepted', 'checked', 'ok', 'passed', 'proved', 'qed', 'success', 'succeeded', 'valid', 'verified', 'discharged'].includes(value)) return 'discharged';
194
+ if (['counterexample', 'cex', 'error', 'failed', 'falsified', 'invalid', 'rejected', 'violated'].includes(value)) return 'failed';
195
+ if (['obsolete', 'outdated', 'stale'].includes(value)) return 'stale';
196
+ if (['admit', 'admitted', 'assume', 'assumed', 'axiom', 'trusted', 'unchecked'].includes(value)) return 'assumed';
197
+ if (['solver-required', 'prover-required', 'tool-required', 'external-tool-required'].includes(value)) return 'external-tool-required';
198
+ if (['pending', 'todo', 'unproved', 'unverified'].includes(value)) return 'pending';
199
+ if (value === 'open') return 'open';
200
+ return 'unknown';
201
+ }
202
+
203
+ function symbolsForRegion(region, symbolsByRegion) {
204
+ const symbols = [...(symbolsByRegion.get(region.id) ?? [])];
205
+ if (symbols.length === 0 && region.symbolId) {
206
+ symbols.push({ id: region.symbolId, name: region.symbolName, ownershipRegionId: region.id, readiness: 'needs-review' });
207
+ }
208
+ return symbols;
209
+ }
210
+
211
+ function relationTouchesSymbols(relation, symbols, allSymbolIds) {
212
+ const ids = new Set(symbols.map((symbol) => symbol.id).filter(Boolean));
213
+ if (ids.has(relation.sourceId) || ids.has(relation.targetId)) return true;
214
+ return allSymbolIds.has(relation.sourceId) && allSymbolIds.has(relation.targetId) && ids.size === 0;
215
+ }
216
+
217
+ function sourceMapMappingsForSymbols(mappings, symbols) {
218
+ const ids = new Set(symbols.map((symbol) => symbol.id).filter(Boolean));
219
+ const mappingIds = new Set(symbols.map((symbol) => symbol.sourceMapMappingId).filter(Boolean));
220
+ return uniqueRecordsById((mappings ?? []).filter((mapping) => ids.has(mapping.semanticSymbolId) || mappingIds.has(mapping.id)));
221
+ }
222
+
223
+ function preservationRecordsForSymbols(records, symbols) {
224
+ const ids = new Set(symbols.map((symbol) => symbol.id).filter(Boolean));
225
+ const mappingIds = new Set(symbols.map((symbol) => symbol.sourceMapMappingId).filter(Boolean));
226
+ return uniqueRecordsById((records ?? []).filter((record) => ids.has(record.semanticSymbolId) || mappingIds.has(record.sourceMapMappingId)));
227
+ }
228
+
229
+ function relatedEvidenceIds(input) {
230
+ return uniqueStrings([
231
+ ...input.proofRecords.flatMap((record) => record.evidenceIds ?? []),
232
+ ...input.paradigmRecords.flatMap((record) => record.evidenceIds ?? []),
233
+ ...input.sourcePreservationRecords.flatMap((record) => record.evidenceIds ?? []),
234
+ ...(input.evidence.failed ?? [])
235
+ ].filter(Boolean));
236
+ }
237
+
238
+ function semanticImpactVerificationPlan(input) {
239
+ const plan = [];
240
+ if (input.dependencyPredicates.length > 0) plan.push({ kind: 'dependency-review', reason: 'region touches semantic dependency relations', required: true });
241
+ if (input.sourcePreservationRecords.some((record) => record.level === 'estimated' || record.level === 'blocked')) plan.push({ kind: 'source-map-review', reason: 'source preservation is not exact', required: true });
242
+ if (input.proof.failedObligationIds.length > 0) plan.push({ kind: 'reject-or-reprove', reason: 'failed proof obligations are linked', required: true });
243
+ else if (input.proof.openObligationIds.length > 0) plan.push({ kind: 'proof-review', reason: 'open proof obligations are linked', required: true });
244
+ if (input.paradigm.loweringIds.length > 0) plan.push({ kind: 'semantic-lowering-review', reason: 'lowering records are linked to this region', required: input.readiness !== 'ready' });
245
+ if (input.patchHints.length > 0) plan.push({ kind: 'patch-admission', reason: 'patch hints exist for this region', required: input.readiness !== 'ready' });
246
+ if (input.evidenceIds.length === 0) plan.push({ kind: 'evidence-review', reason: 'no region-specific evidence ids were linked', required: input.readiness !== 'ready' });
247
+ return plan;
248
+ }
249
+
250
+ function semanticImpactRisk(input) {
251
+ if (input.readiness === 'blocked' || input.proof.failedObligationIds.length > 0 || input.sourcePreservationRecords.some((record) => record.level === 'blocked')) return 'high';
252
+ if (input.failedEvidenceIds.length > 0 || input.proof.openObligationIds.length > 0) return 'high';
253
+ if (input.relationCount > 0 || input.verificationPlan.some((step) => step.required)) return 'medium';
254
+ if (input.sourcePreservationRecords.some((record) => record.level === 'estimated')) return 'medium';
255
+ return 'low';
256
+ }
257
+
258
+ function semanticImpactConflictKeys(region, symbolIds, relations, predicates) {
259
+ return uniqueStrings([
260
+ region.id ? `region:${region.id}` : undefined,
261
+ region.key ? `ownership:${region.key}` : undefined,
262
+ region.sourcePath ? `source:${region.sourcePath}` : undefined,
263
+ ...symbolIds.map((id) => `symbol:${id}`),
264
+ ...relations.map((relation) => `dependency:${relation.sourceId}:${semanticDependencyPredicateKey(relation.predicate)}:${relation.targetId}`),
265
+ ...predicates.map((predicate) => `predicate:${predicate}`)
266
+ ].filter(Boolean));
267
+ }
268
+
269
+ function semanticImpactConfidence(region, mappings, sourcePreservationRecords) {
270
+ if (sourcePreservationRecords.some((record) => record.level === 'exact')) return 'source-exact';
271
+ if ((mappings ?? []).length > 0 || region.precision === 'declaration') return 'source-addressed';
272
+ if (region.precision === 'line' || region.precision === 'estimated') return 'estimated-source-region';
273
+ return 'review-required';
274
+ }
275
+
276
+ function affectedSymbolIds(relations, ownSymbolIds, allSymbolIds) {
277
+ const own = new Set(ownSymbolIds);
278
+ return uniqueStrings(relations
279
+ .flatMap((relation) => [relation.sourceId, relation.targetId])
280
+ .filter((id) => id && allSymbolIds.has(id) && !own.has(id)));
281
+ }
282
+
283
+ function summarizeSemanticImpactRecords(records) {
284
+ const verificationPlans = records.flatMap((record) => record.verificationPlan.map((step) => step.kind));
285
+ return {
286
+ total: records.length,
287
+ byRisk: countBy(records.map((record) => record.risk)),
288
+ byReadiness: countBy(records.map((record) => record.readiness)),
289
+ conflictKeys: uniqueStrings(records.flatMap((record) => record.conflictKeys)),
290
+ dependencyRelations: uniqueStrings(records.flatMap((record) => record.dependencyRelationIds)).length,
291
+ affectedSymbols: uniqueStrings(records.flatMap((record) => record.affectedSymbolIds)).length,
292
+ sourceMapMappings: uniqueStrings(records.flatMap((record) => record.sourceMapMappingIds)).length,
293
+ sourcePreservationRecords: uniqueStrings(records.flatMap((record) => record.sourcePreservationRecordIds)).length,
294
+ patchHints: uniqueStrings(records.flatMap((record) => record.patchHintIds)).length,
295
+ proofObligations: uniqueStrings(records.flatMap((record) => record.proofObligationIds)).length,
296
+ openProofObligations: uniqueStrings(records.flatMap((record) => record.openProofObligationIds)).length,
297
+ failedProofObligations: uniqueStrings(records.flatMap((record) => record.failedProofObligationIds)).length,
298
+ paradigmSemantics: uniqueStrings(records.flatMap((record) => record.paradigmSemanticIds)).length,
299
+ loweringRecords: uniqueStrings(records.flatMap((record) => record.loweringRecordIds)).length,
300
+ evidenceIds: uniqueStrings(records.flatMap((record) => record.evidenceIds)).length,
301
+ verificationPlans: uniqueStrings(verificationPlans),
302
+ requiredVerificationSteps: records.flatMap((record) => record.verificationPlan).filter((step) => step.required).length
303
+ };
304
+ }
305
+
306
+ function groupBy(values, keyFn) {
307
+ const grouped = new Map();
308
+ for (const value of values ?? []) {
309
+ const key = keyFn(value);
310
+ if (!key) continue;
311
+ if (!grouped.has(key)) grouped.set(key, []);
312
+ grouped.get(key).push(value);
313
+ }
314
+ return grouped;
315
+ }
316
+
317
+ export { createSemanticImportImpact, summarizeSemanticImpactRecords };
@@ -14,6 +14,7 @@ export interface SemanticImportSidecarProofAdmissionSummary {
14
14
  readonly discharged: number;
15
15
  readonly pending?: number;
16
16
  readonly failed: number;
17
+ readonly stale?: number;
17
18
  readonly assumed?: number;
18
19
  readonly externalToolRequired?: number;
19
20
  readonly open: number;
@@ -24,6 +25,9 @@ export interface SemanticImportSidecarProofAdmissionSummary {
24
25
 
25
26
  export interface SemanticImportSidecarQuality {
26
27
  readonly schema: 'frontier.lang.semanticSidecarQuality.v1';
28
+ readonly expected: boolean;
29
+ readonly expectedSatisfied: boolean;
30
+ readonly expectedMissingReasonCodes: readonly string[];
27
31
  readonly selected: boolean;
28
32
  readonly eligible: boolean;
29
33
  readonly imported: boolean;
@@ -40,6 +44,9 @@ export interface SemanticImportSidecarQuality {
40
44
 
41
45
  export interface SemanticImportSidecarAdmission {
42
46
  readonly schema: 'frontier.lang.semanticSidecarAdmission.v1';
47
+ readonly expected: boolean;
48
+ readonly expectedSatisfied: boolean;
49
+ readonly expectedMissingReasonCodes: readonly string[];
43
50
  readonly selected: boolean;
44
51
  readonly eligible: boolean;
45
52
  readonly imported: boolean;
@@ -6,6 +6,7 @@ import type {
6
6
  SourceSpan
7
7
  } from '@shapeshift-labs/frontier-lang-kernel';
8
8
  import type { NativeImportRegionTaxonomyKind, NativeImportTaxonomyKind } from './index.js';
9
+ import type { SemanticImportImpactSummary } from './semantic-import-impact-types.js';
9
10
  import type { SemanticImportSidecarAdmission, SemanticImportSidecarQuality } from './semantic-import-sidecar-admission-types.js';
10
11
  import type { SemanticMergeConflictClass, SemanticMergeConflictSummary } from './declarations/semantic-merge-conflicts.js';
11
12
 
@@ -237,6 +238,7 @@ export interface SemanticImportSidecar {
237
238
  readonly proofSpec: SemanticImportSidecarProofSpecSummary;
238
239
  readonly paradigmSemantics: SemanticImportSidecarParadigmSemanticsSummary;
239
240
  readonly dependencies: SemanticImportDependencySummary;
241
+ readonly semanticImpact: SemanticImportImpactSummary;
240
242
  readonly patchHints: readonly SemanticImportPatchHint[];
241
243
  readonly quality: SemanticImportSidecarQuality;
242
244
  readonly admission: SemanticImportSidecarAdmission;
@@ -280,6 +282,9 @@ export interface SemanticImportSidecar {
280
282
  readonly paradigmSemanticsLoweringRecords: number;
281
283
  readonly dependencyRelations: number;
282
284
  readonly dependencyPredicates: readonly string[];
285
+ readonly semanticImpactRecords: number;
286
+ readonly semanticImpactHighRiskRecords: number;
287
+ readonly semanticImpactRequiredVerificationSteps: number;
283
288
  readonly patchHints: number;
284
289
  readonly evidenceWarnings: number;
285
290
  readonly readiness: SemanticMergeReadiness;
@@ -293,5 +298,7 @@ export interface SemanticImportSidecarOptions {
293
298
  readonly generatedAt?: number;
294
299
  readonly regionPrefix?: string;
295
300
  readonly targetPath?: string;
301
+ readonly expected?: boolean;
302
+ readonly semanticImportExpected?: boolean;
296
303
  readonly metadata?: Record<string, unknown>;
297
304
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shapeshift-labs/frontier-lang-compiler",
3
- "version": "0.2.60",
3
+ "version": "0.2.62",
4
4
  "description": "Compiler facade for Frontier Lang source documents and language projection adapters.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",