@shapeshift-labs/frontier-swarm-codex 0.5.35 → 0.5.37
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 +3 -3
- package/dist/index.d.ts +48 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +325 -10
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -336,6 +336,7 @@ export async function runCodexJob(job, options, outDir, lease) {
|
|
|
336
336
|
evidenceDir: paths.evidenceDir,
|
|
337
337
|
options: options.semanticImport
|
|
338
338
|
});
|
|
339
|
+
const semanticImportSummary = semanticImport?.sidecar.summary;
|
|
339
340
|
const handoffArtifacts = await discoverCodexHandoffArtifacts({ root: paths.jobDir });
|
|
340
341
|
const evidenceSummaryPath = path.join(paths.evidenceDir, 'evidence.json');
|
|
341
342
|
const evidencePaths = uniqueStrings([
|
|
@@ -364,14 +365,14 @@ export async function runCodexJob(job, options, outDir, lease) {
|
|
|
364
365
|
...(patchPath ? { patchPath } : {}),
|
|
365
366
|
queueItemIds: [job.taskId],
|
|
366
367
|
verification,
|
|
367
|
-
...(
|
|
368
|
+
...(semanticImportSummary ? { semanticImport: semanticImportSummary } : {}),
|
|
368
369
|
lastMessage: execution.lastMessage,
|
|
369
370
|
error: execution.error,
|
|
370
371
|
metadata: {
|
|
371
372
|
...(lease ? { leaseId: lease.id, leaseToken: lease.token, fencingToken: lease.fencingToken } : {}),
|
|
372
373
|
resourceAllocation,
|
|
373
374
|
logSummary,
|
|
374
|
-
...(
|
|
375
|
+
...(semanticImportSummary ? { semanticImport: semanticImportSummary } : {}),
|
|
375
376
|
codexHandoffArtifacts: handoffArtifacts
|
|
376
377
|
}
|
|
377
378
|
};
|
|
@@ -391,9 +392,16 @@ export async function runCodexJob(job, options, outDir, lease) {
|
|
|
391
392
|
...handoffArtifacts.map((artifact) => artifact.path)
|
|
392
393
|
]),
|
|
393
394
|
queueItemIds: [job.taskId],
|
|
394
|
-
...(
|
|
395
|
-
...(
|
|
395
|
+
...(semanticImportSummary ? { semanticImport: semanticImportSummary } : {}),
|
|
396
|
+
...(semanticImportSummary ? { metadata: { semanticImport: semanticImportSummary } } : {})
|
|
396
397
|
});
|
|
398
|
+
if (semanticImportSummary) {
|
|
399
|
+
mergeBundle.semanticImport = semanticImportSummary;
|
|
400
|
+
mergeBundle.metadata = {
|
|
401
|
+
...(isObject(mergeBundle.metadata) ? mergeBundle.metadata : {}),
|
|
402
|
+
semanticImport: semanticImportSummary
|
|
403
|
+
};
|
|
404
|
+
}
|
|
397
405
|
await fs.writeFile(paths.mergeBundlePath, JSON.stringify(mergeBundle, null, 2) + '\n');
|
|
398
406
|
await writeCodexPatchIntent({
|
|
399
407
|
file: paths.patchIntentPath,
|
|
@@ -650,6 +658,8 @@ async function createCodexSemanticImportSidecar(input) {
|
|
|
650
658
|
losses: summarizeSemanticLosses(importResult?.losses),
|
|
651
659
|
semanticIndex: summarizeSemanticIndex(importResult?.semanticIndex),
|
|
652
660
|
semanticSidecar: summarizeLangSemanticImportSidecar(semanticSidecar),
|
|
661
|
+
universalAstLayers: summarizeUniversalAstLayers(importResult?.universalAst, semanticSidecar),
|
|
662
|
+
proofSpec: summarizeProofSpec(importResult?.universalAst?.proof, semanticSidecar),
|
|
653
663
|
sourceProjection: summarizeNativeSourceProjection(sourceProjection),
|
|
654
664
|
nativeCompile: summarizeNativeSourceCompile(nativeCompile),
|
|
655
665
|
mergeCandidate: summarizeSemanticMergeCandidate(mergeCandidate)
|
|
@@ -1472,6 +1482,7 @@ async function copyOrWriteCollectedEvidenceSummary(input) {
|
|
|
1472
1482
|
}
|
|
1473
1483
|
function createCollectedEvidenceEntries(bundle, collectedEvidencePath, bucket) {
|
|
1474
1484
|
const confidence = bucket === 'ready-to-apply' ? 0.95 : bucket === 'needs-human-port' ? 0.7 : bucket === 'failed-evidence' ? 0.25 : 0.2;
|
|
1485
|
+
const universalAstLayers = semanticImportUniversalAstLayerSummary(bundle.semanticImport);
|
|
1475
1486
|
const entries = [{
|
|
1476
1487
|
jobId: bundle.jobId,
|
|
1477
1488
|
queueItemId: bundle.queueItemIds[0],
|
|
@@ -1489,7 +1500,11 @@ function createCollectedEvidenceEntries(bundle, collectedEvidencePath, bucket) {
|
|
|
1489
1500
|
autoMergeable: bundle.autoMergeable,
|
|
1490
1501
|
staleAgainstHead: bundle.staleAgainstHead,
|
|
1491
1502
|
semanticSymbols: bundle.semanticImport?.semanticIndex.symbols ?? 0,
|
|
1492
|
-
semanticRegions: bundle.semanticImport?.semanticSidecars.ownershipRegions ?? 0
|
|
1503
|
+
semanticRegions: bundle.semanticImport?.semanticSidecars.ownershipRegions ?? 0,
|
|
1504
|
+
universalAstLayers: universalAstLayers.total,
|
|
1505
|
+
universalAstLayerNames: universalAstLayers.names.join(','),
|
|
1506
|
+
proofSpecObligations: semanticImportProofSpecSummary(bundle.semanticImport).obligations,
|
|
1507
|
+
proofSpecFailedObligations: semanticImportProofSpecSummary(bundle.semanticImport).failed
|
|
1493
1508
|
}
|
|
1494
1509
|
}];
|
|
1495
1510
|
for (const file of bundle.evidencePaths) {
|
|
@@ -1551,7 +1566,11 @@ function createCodexCompactDashboard(input) {
|
|
|
1551
1566
|
weakCount: semanticQualities.filter((entry) => entry.present && entry.warnings.length > 0).length,
|
|
1552
1567
|
symbolCount: semanticQualities.reduce((sum, entry) => sum + entry.symbols, 0),
|
|
1553
1568
|
ownershipRegionCount: semanticQualities.reduce((sum, entry) => sum + entry.ownershipRegions, 0),
|
|
1554
|
-
patchHintCount: semanticQualities.reduce((sum, entry) => sum + entry.patchHints, 0)
|
|
1569
|
+
patchHintCount: semanticQualities.reduce((sum, entry) => sum + entry.patchHints, 0),
|
|
1570
|
+
universalAstLayerCount: semanticQualities.reduce((sum, entry) => sum + entry.universalAstLayers, 0),
|
|
1571
|
+
universalAstLayerNames: uniqueStrings(semanticQualities.flatMap((entry) => entry.universalAstLayerNames)),
|
|
1572
|
+
proofSpecObligations: semanticQualities.reduce((sum, entry) => sum + entry.proofSpecObligations, 0),
|
|
1573
|
+
proofSpecFailedObligations: semanticQualities.reduce((sum, entry) => sum + entry.proofSpecFailedObligations, 0)
|
|
1555
1574
|
},
|
|
1556
1575
|
evidence: {
|
|
1557
1576
|
readyToApply: input.dashboard.summary.readyToApplyCount,
|
|
@@ -1800,6 +1819,10 @@ function summarizePatchScoreSemanticEvidence(bundle) {
|
|
|
1800
1819
|
semanticSymbols: 0,
|
|
1801
1820
|
ownershipRegions: 0,
|
|
1802
1821
|
patchHints: 0,
|
|
1822
|
+
universalAstLayers: 0,
|
|
1823
|
+
universalAstLayerNames: [],
|
|
1824
|
+
proofSpecObligations: 0,
|
|
1825
|
+
proofSpecFailedObligations: 0,
|
|
1803
1826
|
readiness: {},
|
|
1804
1827
|
lossesBySeverity: {},
|
|
1805
1828
|
scoreAdjustment,
|
|
@@ -1817,6 +1840,10 @@ function summarizePatchScoreSemanticEvidence(bundle) {
|
|
|
1817
1840
|
const semanticSymbols = nonNegativeNumber(summary.semanticIndex?.symbols);
|
|
1818
1841
|
const ownershipRegions = nonNegativeNumber(summary.semanticSidecars?.ownershipRegions);
|
|
1819
1842
|
const patchHints = nonNegativeNumber(summary.semanticSidecars?.patchHints);
|
|
1843
|
+
const universalAstLayerSummary = semanticImportUniversalAstLayerSummary(summary);
|
|
1844
|
+
const universalAstLayers = universalAstLayerSummary.total;
|
|
1845
|
+
const universalAstLayerNames = universalAstLayerSummary.names;
|
|
1846
|
+
const proofSpec = semanticImportProofSpecSummary(summary);
|
|
1820
1847
|
const errorLosses = nonNegativeNumber(lossesBySeverity.error);
|
|
1821
1848
|
const warningLosses = nonNegativeNumber(lossesBySeverity.warning);
|
|
1822
1849
|
const blocked = nonNegativeNumber(readiness.blocked);
|
|
@@ -1856,16 +1883,39 @@ function summarizePatchScoreSemanticEvidence(bundle) {
|
|
|
1856
1883
|
scoreAdjustment -= 5;
|
|
1857
1884
|
cleanEligible = false;
|
|
1858
1885
|
}
|
|
1886
|
+
if (selected > 0 && universalAstLayers === 0) {
|
|
1887
|
+
reasons.push('semantic sidecar has no universal AST layers');
|
|
1888
|
+
scoreAdjustment -= 5;
|
|
1889
|
+
cleanEligible = false;
|
|
1890
|
+
}
|
|
1859
1891
|
if (warningLosses > 0 || needsReview > 0) {
|
|
1860
1892
|
reasons.push('semantic evidence needs review');
|
|
1861
1893
|
scoreAdjustment -= Math.min(10, warningLosses + needsReview);
|
|
1862
1894
|
cleanEligible = false;
|
|
1863
1895
|
}
|
|
1864
|
-
if (
|
|
1896
|
+
if (proofSpec.failed > 0) {
|
|
1897
|
+
reasons.push(`failed proof obligations: ${proofSpec.failed}`);
|
|
1898
|
+
scoreAdjustment -= 30;
|
|
1899
|
+
cleanEligible = false;
|
|
1900
|
+
}
|
|
1901
|
+
if (proofSpec.stale > 0) {
|
|
1902
|
+
reasons.push(`stale proof obligations: ${proofSpec.stale}`);
|
|
1903
|
+
scoreAdjustment -= 20;
|
|
1904
|
+
cleanEligible = false;
|
|
1905
|
+
}
|
|
1906
|
+
if (proofSpec.open > 0 || proofSpec.unknown > 0) {
|
|
1907
|
+
reasons.push('proof evidence needs review');
|
|
1908
|
+
scoreAdjustment -= Math.min(10, proofSpec.open + proofSpec.unknown);
|
|
1909
|
+
cleanEligible = false;
|
|
1910
|
+
}
|
|
1911
|
+
if (sourceMapMappings > 0 && semanticSymbols > 0 && ownershipRegions > 0 && universalAstLayers > 0) {
|
|
1865
1912
|
scoreAdjustment += 10;
|
|
1866
1913
|
}
|
|
1867
1914
|
if (patchHints > 0)
|
|
1868
1915
|
scoreAdjustment += 5;
|
|
1916
|
+
if (proofSpec.discharged > 0 && proofSpec.failed === 0 && proofSpec.stale === 0 && proofSpec.open === 0 && proofSpec.unknown === 0) {
|
|
1917
|
+
scoreAdjustment += 5;
|
|
1918
|
+
}
|
|
1869
1919
|
return {
|
|
1870
1920
|
present: true,
|
|
1871
1921
|
total,
|
|
@@ -1875,6 +1925,10 @@ function summarizePatchScoreSemanticEvidence(bundle) {
|
|
|
1875
1925
|
semanticSymbols,
|
|
1876
1926
|
ownershipRegions,
|
|
1877
1927
|
patchHints,
|
|
1928
|
+
universalAstLayers,
|
|
1929
|
+
universalAstLayerNames,
|
|
1930
|
+
proofSpecObligations: proofSpec.obligations,
|
|
1931
|
+
proofSpecFailedObligations: proofSpec.failed,
|
|
1878
1932
|
readiness,
|
|
1879
1933
|
lossesBySeverity,
|
|
1880
1934
|
scoreAdjustment: Math.max(-60, Math.min(15, scoreAdjustment)),
|
|
@@ -1890,6 +1944,10 @@ function summarizeCodexSemanticImportQuality(summary, expected = false) {
|
|
|
1890
1944
|
const ownershipRegions = nonNegativeNumber(summary?.semanticSidecars?.ownershipRegions);
|
|
1891
1945
|
const patchHints = nonNegativeNumber(summary?.semanticSidecars?.patchHints);
|
|
1892
1946
|
const sourceMapMappings = nonNegativeNumber(summary?.sourceMapMappingCount);
|
|
1947
|
+
const universalAstLayerSummary = semanticImportUniversalAstLayerSummary(summary);
|
|
1948
|
+
const universalAstLayers = universalAstLayerSummary.total;
|
|
1949
|
+
const universalAstLayerNames = universalAstLayerSummary.names;
|
|
1950
|
+
const proofSpec = semanticImportProofSpecSummary(summary);
|
|
1893
1951
|
const present = !!summary;
|
|
1894
1952
|
const empty = present && (nonNegativeNumber(summary?.total) === 0 || selected === 0 && eligible === 0 && imported === 0 && symbols === 0);
|
|
1895
1953
|
const warnings = [];
|
|
@@ -1905,6 +1963,12 @@ function summarizeCodexSemanticImportQuality(summary, expected = false) {
|
|
|
1905
1963
|
warnings.push('semantic import has no ownership regions');
|
|
1906
1964
|
if (present && selected > 0 && sourceMapMappings === 0)
|
|
1907
1965
|
warnings.push('semantic import has no source-map mappings');
|
|
1966
|
+
if (present && selected > 0 && universalAstLayers === 0)
|
|
1967
|
+
warnings.push('semantic import has no universal AST layers');
|
|
1968
|
+
if (present && proofSpec.failed > 0)
|
|
1969
|
+
warnings.push('semantic import has failed proof obligations');
|
|
1970
|
+
if (present && proofSpec.stale > 0)
|
|
1971
|
+
warnings.push('semantic import has stale proof obligations');
|
|
1908
1972
|
return {
|
|
1909
1973
|
expected,
|
|
1910
1974
|
present,
|
|
@@ -1916,14 +1980,60 @@ function summarizeCodexSemanticImportQuality(summary, expected = false) {
|
|
|
1916
1980
|
ownershipRegions,
|
|
1917
1981
|
patchHints,
|
|
1918
1982
|
sourceMapMappings,
|
|
1983
|
+
universalAstLayers,
|
|
1984
|
+
universalAstLayerNames,
|
|
1985
|
+
proofSpecObligations: proofSpec.obligations,
|
|
1986
|
+
proofSpecFailedObligations: proofSpec.failed,
|
|
1919
1987
|
warnings: uniqueStrings(warnings)
|
|
1920
1988
|
};
|
|
1921
1989
|
}
|
|
1990
|
+
function semanticImportProofSpecSummary(summary) {
|
|
1991
|
+
const input = isObject(summary) && isObject(summary.proofSpec) ? summary.proofSpec : undefined;
|
|
1992
|
+
return input ? normalizeProofSpecSummary(input) : emptyProofSpecSummary();
|
|
1993
|
+
}
|
|
1994
|
+
function semanticImportUniversalAstLayerSummary(summary) {
|
|
1995
|
+
const input = isObject(summary) && isObject(summary.universalAstLayers) ? summary.universalAstLayers : undefined;
|
|
1996
|
+
const names = Array.isArray(input?.names)
|
|
1997
|
+
? uniqueStrings(input.names.map((entry) => String(entry)).filter(Boolean))
|
|
1998
|
+
: [];
|
|
1999
|
+
const ids = Array.isArray(input?.ids)
|
|
2000
|
+
? uniqueStrings(input.ids.map((entry) => String(entry)).filter(Boolean))
|
|
2001
|
+
: [];
|
|
2002
|
+
const byName = isObject(input?.byName) ? numberRecord(input.byName) : {};
|
|
2003
|
+
const total = nonNegativeNumber(input?.total ?? ids.length);
|
|
2004
|
+
return {
|
|
2005
|
+
total,
|
|
2006
|
+
names,
|
|
2007
|
+
ids,
|
|
2008
|
+
byName,
|
|
2009
|
+
empty: input?.empty === true || total === 0
|
|
2010
|
+
};
|
|
2011
|
+
}
|
|
1922
2012
|
function semanticImportSummaryFromBundle(bundle) {
|
|
1923
|
-
if (bundle.semanticImport)
|
|
1924
|
-
return bundle.semanticImport;
|
|
1925
2013
|
const metadata = bundle.metadata;
|
|
1926
|
-
return metadata?.semanticImport;
|
|
2014
|
+
return richerSemanticImportSummary(bundle.semanticImport, metadata?.semanticImport);
|
|
2015
|
+
}
|
|
2016
|
+
function richerSemanticImportSummary(first, second) {
|
|
2017
|
+
if (!first)
|
|
2018
|
+
return second;
|
|
2019
|
+
if (!second)
|
|
2020
|
+
return first;
|
|
2021
|
+
return semanticImportSummaryRichness(second) > semanticImportSummaryRichness(first) ? second : first;
|
|
2022
|
+
}
|
|
2023
|
+
function semanticImportSummaryRichness(summary) {
|
|
2024
|
+
if (!summary)
|
|
2025
|
+
return 0;
|
|
2026
|
+
return [
|
|
2027
|
+
summary.total,
|
|
2028
|
+
summary.selected,
|
|
2029
|
+
summary.imported,
|
|
2030
|
+
summary.sourceMapMappingCount,
|
|
2031
|
+
summary.semanticIndex?.symbols,
|
|
2032
|
+
summary.semanticSidecars?.ownershipRegions,
|
|
2033
|
+
summary.semanticSidecars?.patchHints,
|
|
2034
|
+
semanticImportUniversalAstLayerSummary(summary).total,
|
|
2035
|
+
semanticImportProofSpecSummary(summary).total
|
|
2036
|
+
].reduce((sum, value) => sum + nonNegativeNumber(value), 0);
|
|
1927
2037
|
}
|
|
1928
2038
|
function semanticImportEnabled(input) {
|
|
1929
2039
|
if (input === true)
|
|
@@ -2618,6 +2728,7 @@ function createSemanticImportSidecar(job, records, selection) {
|
|
|
2618
2728
|
totals.empty += 1;
|
|
2619
2729
|
return totals;
|
|
2620
2730
|
}, { total: 0, symbols: 0, ownershipRegions: 0, patchHints: 0, empty: 0 });
|
|
2731
|
+
const universalAstLayers = summarizeSemanticImportUniversalAstLayers(records);
|
|
2621
2732
|
const sourceProjections = records.reduce((totals, record) => {
|
|
2622
2733
|
const summary = record.sourceProjection;
|
|
2623
2734
|
if (!summary)
|
|
@@ -2654,6 +2765,7 @@ function createSemanticImportSidecar(job, records, selection) {
|
|
|
2654
2765
|
totals.needsReview += 1;
|
|
2655
2766
|
return totals;
|
|
2656
2767
|
}, { total: 0, emitted: 0, preserved: 0, targetStubs: 0, ready: 0, needsReview: 0, blocked: 0 });
|
|
2768
|
+
const proofSpec = summarizeSemanticImportProofSpec(records);
|
|
2657
2769
|
const lossesBySeverity = {};
|
|
2658
2770
|
const readiness = {};
|
|
2659
2771
|
for (const record of records) {
|
|
@@ -2689,6 +2801,8 @@ function createSemanticImportSidecar(job, records, selection) {
|
|
|
2689
2801
|
lossesBySeverity,
|
|
2690
2802
|
semanticIndex,
|
|
2691
2803
|
semanticSidecars,
|
|
2804
|
+
universalAstLayers,
|
|
2805
|
+
proofSpec,
|
|
2692
2806
|
sourceProjections,
|
|
2693
2807
|
nativeCompiles,
|
|
2694
2808
|
readiness
|
|
@@ -2716,6 +2830,13 @@ function summarizeLangSemanticImportSidecar(value) {
|
|
|
2716
2830
|
symbols: value.summary?.symbols,
|
|
2717
2831
|
ownershipRegions: value.summary?.ownershipRegions,
|
|
2718
2832
|
sourceMapMappings: value.summary?.sourceMapMappings,
|
|
2833
|
+
universalAstLayers: value.summary?.universalAstLayers ?? value.universalAstLayers?.total,
|
|
2834
|
+
universalAstLayerNames: Array.isArray(value.summary?.universalAstLayerNames)
|
|
2835
|
+
? value.summary.universalAstLayerNames
|
|
2836
|
+
: Array.isArray(value.universalAstLayers?.names)
|
|
2837
|
+
? value.universalAstLayers.names
|
|
2838
|
+
: [],
|
|
2839
|
+
proofSpec: summarizeProofSpec(undefined, value),
|
|
2719
2840
|
readiness: value.summary?.readiness,
|
|
2720
2841
|
emptySemanticIndex: value.summary?.emptySemanticIndex,
|
|
2721
2842
|
patchHints: Array.isArray(value.patchHints) ? value.patchHints.length : 0,
|
|
@@ -2732,6 +2853,200 @@ function summarizeLangSemanticImportSidecar(value) {
|
|
|
2732
2853
|
: []
|
|
2733
2854
|
};
|
|
2734
2855
|
}
|
|
2856
|
+
function summarizeSemanticImportProofSpec(records) {
|
|
2857
|
+
const summary = emptyProofSpecSummary();
|
|
2858
|
+
for (const record of records) {
|
|
2859
|
+
mergeProofSpecSummary(summary, record.proofSpec);
|
|
2860
|
+
}
|
|
2861
|
+
summary.empty = summary.total === 0;
|
|
2862
|
+
return summary;
|
|
2863
|
+
}
|
|
2864
|
+
function summarizeProofSpec(proof, semanticSidecar) {
|
|
2865
|
+
const sidecarProof = semanticSidecar?.proofSpec ?? semanticSidecar?.summary?.proofSpec;
|
|
2866
|
+
if (sidecarProof && typeof sidecarProof === 'object' && hasProofSpecSummaryShape(sidecarProof)) {
|
|
2867
|
+
return normalizeProofSpecSummary(sidecarProof);
|
|
2868
|
+
}
|
|
2869
|
+
const raw = proof && typeof proof === 'object' ? proof : {};
|
|
2870
|
+
const contracts = Array.isArray(raw.contracts) ? raw.contracts : [];
|
|
2871
|
+
const refinements = Array.isArray(raw.refinements) ? raw.refinements : [];
|
|
2872
|
+
const invariants = Array.isArray(raw.invariants) ? raw.invariants : [];
|
|
2873
|
+
const termination = Array.isArray(raw.termination) ? raw.termination : [];
|
|
2874
|
+
const temporal = Array.isArray(raw.temporal) ? raw.temporal : [];
|
|
2875
|
+
const obligations = Array.isArray(raw.obligations) ? raw.obligations : [];
|
|
2876
|
+
const artifacts = Array.isArray(raw.artifacts) ? raw.artifacts : [];
|
|
2877
|
+
const assumptions = Array.isArray(raw.assumptions) ? raw.assumptions : [];
|
|
2878
|
+
const evidence = Array.isArray(raw.evidence) ? raw.evidence : [];
|
|
2879
|
+
const allContracts = [...contracts, ...refinements, ...invariants, ...termination, ...temporal];
|
|
2880
|
+
const byStatus = {};
|
|
2881
|
+
const byContractKind = {};
|
|
2882
|
+
const byArtifactKind = {};
|
|
2883
|
+
for (const obligation of obligations) {
|
|
2884
|
+
const status = String(obligation?.status ?? 'unknown');
|
|
2885
|
+
byStatus[status] = (byStatus[status] ?? 0) + 1;
|
|
2886
|
+
}
|
|
2887
|
+
for (const contract of allContracts) {
|
|
2888
|
+
const kind = String(contract?.kind ?? 'unknown');
|
|
2889
|
+
byContractKind[kind] = (byContractKind[kind] ?? 0) + 1;
|
|
2890
|
+
}
|
|
2891
|
+
for (const artifact of artifacts) {
|
|
2892
|
+
const kind = String(artifact?.kind ?? 'unknown');
|
|
2893
|
+
byArtifactKind[kind] = (byArtifactKind[kind] ?? 0) + 1;
|
|
2894
|
+
}
|
|
2895
|
+
const total = allContracts.length + obligations.length + artifacts.length + assumptions.length;
|
|
2896
|
+
return {
|
|
2897
|
+
total,
|
|
2898
|
+
ids: uniqueStrings([
|
|
2899
|
+
raw.id,
|
|
2900
|
+
...allContracts.map((record) => record?.id),
|
|
2901
|
+
...obligations.map((record) => record?.id),
|
|
2902
|
+
...artifacts.map((record) => record?.id),
|
|
2903
|
+
...assumptions.map((record) => record?.id),
|
|
2904
|
+
...evidence.map((record) => record?.id)
|
|
2905
|
+
].filter(Boolean).map(String)),
|
|
2906
|
+
contracts: contracts.length,
|
|
2907
|
+
refinements: refinements.length,
|
|
2908
|
+
invariants: invariants.length,
|
|
2909
|
+
termination: termination.length,
|
|
2910
|
+
temporal: temporal.length,
|
|
2911
|
+
obligations: obligations.length,
|
|
2912
|
+
artifacts: artifacts.length,
|
|
2913
|
+
assumptions: assumptions.length,
|
|
2914
|
+
evidence: evidence.length,
|
|
2915
|
+
discharged: byStatus.discharged ?? 0,
|
|
2916
|
+
failed: byStatus.failed ?? 0,
|
|
2917
|
+
open: byStatus.open ?? 0,
|
|
2918
|
+
unknown: byStatus.unknown ?? 0,
|
|
2919
|
+
stale: byStatus.stale ?? 0,
|
|
2920
|
+
assumed: byStatus.assumed ?? 0,
|
|
2921
|
+
contractKinds: uniqueStrings(Object.keys(byContractKind)),
|
|
2922
|
+
artifactKinds: uniqueStrings(Object.keys(byArtifactKind)),
|
|
2923
|
+
byStatus,
|
|
2924
|
+
byContractKind,
|
|
2925
|
+
byArtifactKind,
|
|
2926
|
+
empty: total === 0
|
|
2927
|
+
};
|
|
2928
|
+
}
|
|
2929
|
+
function hasProofSpecSummaryShape(value) {
|
|
2930
|
+
return typeof value.total === 'number' ||
|
|
2931
|
+
typeof value.obligations === 'number' ||
|
|
2932
|
+
typeof value.contracts === 'number' ||
|
|
2933
|
+
typeof value.failed === 'number';
|
|
2934
|
+
}
|
|
2935
|
+
function normalizeProofSpecSummary(value) {
|
|
2936
|
+
const summary = emptyProofSpecSummary();
|
|
2937
|
+
mergeProofSpecSummary(summary, value);
|
|
2938
|
+
summary.empty = summary.total === 0;
|
|
2939
|
+
return summary;
|
|
2940
|
+
}
|
|
2941
|
+
function emptyProofSpecSummary() {
|
|
2942
|
+
return {
|
|
2943
|
+
total: 0,
|
|
2944
|
+
ids: [],
|
|
2945
|
+
contracts: 0,
|
|
2946
|
+
refinements: 0,
|
|
2947
|
+
invariants: 0,
|
|
2948
|
+
termination: 0,
|
|
2949
|
+
temporal: 0,
|
|
2950
|
+
obligations: 0,
|
|
2951
|
+
artifacts: 0,
|
|
2952
|
+
assumptions: 0,
|
|
2953
|
+
evidence: 0,
|
|
2954
|
+
discharged: 0,
|
|
2955
|
+
failed: 0,
|
|
2956
|
+
open: 0,
|
|
2957
|
+
unknown: 0,
|
|
2958
|
+
stale: 0,
|
|
2959
|
+
assumed: 0,
|
|
2960
|
+
contractKinds: [],
|
|
2961
|
+
artifactKinds: [],
|
|
2962
|
+
byStatus: {},
|
|
2963
|
+
byContractKind: {},
|
|
2964
|
+
byArtifactKind: {},
|
|
2965
|
+
empty: true
|
|
2966
|
+
};
|
|
2967
|
+
}
|
|
2968
|
+
function mergeProofSpecSummary(target, input) {
|
|
2969
|
+
if (!input || typeof input !== 'object')
|
|
2970
|
+
return;
|
|
2971
|
+
for (const key of ['total', 'contracts', 'refinements', 'invariants', 'termination', 'temporal', 'obligations', 'artifacts', 'assumptions', 'evidence', 'discharged', 'failed', 'open', 'unknown', 'stale', 'assumed']) {
|
|
2972
|
+
target[key] += nonNegativeNumber(input[key]);
|
|
2973
|
+
}
|
|
2974
|
+
target.ids = uniqueStrings([...target.ids, ...proofStringList(input.ids)]);
|
|
2975
|
+
target.contractKinds = uniqueStrings([...target.contractKinds, ...proofStringList(input.contractKinds)]);
|
|
2976
|
+
target.artifactKinds = uniqueStrings([...target.artifactKinds, ...proofStringList(input.artifactKinds)]);
|
|
2977
|
+
for (const [status, count] of Object.entries(numberRecord(input.byStatus))) {
|
|
2978
|
+
target.byStatus[status] = (target.byStatus[status] ?? 0) + count;
|
|
2979
|
+
}
|
|
2980
|
+
for (const [kind, count] of Object.entries(numberRecord(input.byContractKind))) {
|
|
2981
|
+
target.byContractKind[kind] = (target.byContractKind[kind] ?? 0) + count;
|
|
2982
|
+
}
|
|
2983
|
+
for (const [kind, count] of Object.entries(numberRecord(input.byArtifactKind))) {
|
|
2984
|
+
target.byArtifactKind[kind] = (target.byArtifactKind[kind] ?? 0) + count;
|
|
2985
|
+
}
|
|
2986
|
+
}
|
|
2987
|
+
function proofStringList(value) {
|
|
2988
|
+
if (!Array.isArray(value))
|
|
2989
|
+
return [];
|
|
2990
|
+
return value.map((entry) => String(entry)).filter(Boolean);
|
|
2991
|
+
}
|
|
2992
|
+
function summarizeSemanticImportUniversalAstLayers(records) {
|
|
2993
|
+
const byName = {};
|
|
2994
|
+
const names = [];
|
|
2995
|
+
const ids = [];
|
|
2996
|
+
for (const record of records) {
|
|
2997
|
+
for (const name of record.universalAstLayers?.names ?? []) {
|
|
2998
|
+
names.push(name);
|
|
2999
|
+
byName[name] = (byName[name] ?? 0) + 1;
|
|
3000
|
+
}
|
|
3001
|
+
ids.push(...(record.universalAstLayers?.ids ?? []));
|
|
3002
|
+
}
|
|
3003
|
+
const uniqueNames = uniqueStrings(names);
|
|
3004
|
+
const uniqueIds = uniqueStrings(ids);
|
|
3005
|
+
return {
|
|
3006
|
+
total: records.reduce((sum, record) => sum + (record.universalAstLayers?.total ?? 0), 0),
|
|
3007
|
+
names: uniqueNames,
|
|
3008
|
+
ids: uniqueIds,
|
|
3009
|
+
byName,
|
|
3010
|
+
empty: uniqueIds.length === 0
|
|
3011
|
+
};
|
|
3012
|
+
}
|
|
3013
|
+
function summarizeUniversalAstLayers(universalAst, semanticSidecar) {
|
|
3014
|
+
const layers = collectUniversalAstLayerRecords(universalAst?.layers);
|
|
3015
|
+
const sidecarNames = Array.isArray(semanticSidecar?.summary?.universalAstLayerNames)
|
|
3016
|
+
? semanticSidecar.summary.universalAstLayerNames
|
|
3017
|
+
: Array.isArray(semanticSidecar?.universalAstLayers?.names)
|
|
3018
|
+
? semanticSidecar.universalAstLayers.names
|
|
3019
|
+
: [];
|
|
3020
|
+
const sidecarIds = Array.isArray(semanticSidecar?.universalAstLayers?.ids) ? semanticSidecar.universalAstLayers.ids : [];
|
|
3021
|
+
const byName = {};
|
|
3022
|
+
for (const layer of layers) {
|
|
3023
|
+
if (!layer?.layer)
|
|
3024
|
+
continue;
|
|
3025
|
+
byName[String(layer.layer)] = (byName[String(layer.layer)] ?? 0) + 1;
|
|
3026
|
+
}
|
|
3027
|
+
for (const [name, count] of Object.entries(semanticSidecar?.universalAstLayers?.byName ?? {})) {
|
|
3028
|
+
byName[name] = Math.max(byName[name] ?? 0, Number(count) || 0);
|
|
3029
|
+
}
|
|
3030
|
+
const names = uniqueStrings([
|
|
3031
|
+
...layers.map((layer) => String(layer?.layer ?? '')).filter(Boolean),
|
|
3032
|
+
...sidecarNames.map((name) => String(name)).filter(Boolean)
|
|
3033
|
+
]);
|
|
3034
|
+
const ids = uniqueStrings([
|
|
3035
|
+
...layers.map((layer) => String(layer?.id ?? '')).filter(Boolean),
|
|
3036
|
+
...sidecarIds.map((id) => String(id)).filter(Boolean)
|
|
3037
|
+
]);
|
|
3038
|
+
const total = Math.max(layers.length, Number(semanticSidecar?.universalAstLayers?.total ?? 0) || 0, ids.length);
|
|
3039
|
+
return { total, names, ids, byName, empty: total === 0 };
|
|
3040
|
+
}
|
|
3041
|
+
function collectUniversalAstLayerRecords(layers) {
|
|
3042
|
+
if (!layers)
|
|
3043
|
+
return [];
|
|
3044
|
+
if (Array.isArray(layers))
|
|
3045
|
+
return layers.filter(Boolean);
|
|
3046
|
+
if (typeof layers !== 'object')
|
|
3047
|
+
return [];
|
|
3048
|
+
return Object.values(layers).flatMap((value) => Array.isArray(value) ? value : [value]).filter(Boolean);
|
|
3049
|
+
}
|
|
2735
3050
|
function summarizeNativeSourceProjection(value) {
|
|
2736
3051
|
if (!value || typeof value !== 'object')
|
|
2737
3052
|
return undefined;
|