@shapeshift-labs/frontier-swarm 0.5.8 → 0.5.10

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/dist/index.js CHANGED
@@ -52,6 +52,10 @@ export const FRONTIER_SWARM_PARITY_ORACLE_KIND = 'frontier.swarm.parity-oracle';
52
52
  export const FRONTIER_SWARM_PARITY_ORACLE_VERSION = 1;
53
53
  export const FRONTIER_SWARM_DIVERGENCE_REPORT_KIND = 'frontier.swarm.divergence-report';
54
54
  export const FRONTIER_SWARM_DIVERGENCE_REPORT_VERSION = 1;
55
+ export const FRONTIER_SWARM_TRACE_SHARD_KIND = 'frontier.swarm.trace-shard';
56
+ export const FRONTIER_SWARM_TRACE_SHARD_VERSION = 1;
57
+ export const FRONTIER_SWARM_TRACE_INDEX_KIND = 'frontier.swarm.trace-index';
58
+ export const FRONTIER_SWARM_TRACE_INDEX_VERSION = 1;
55
59
  export const FRONTIER_SWARM_OBSERVABILITY_POINT_KIND = 'frontier.swarm.observability-point';
56
60
  export const FRONTIER_SWARM_OBSERVABILITY_POINT_VERSION = 1;
57
61
  export const FRONTIER_SWARM_WATCHPOINT_PLAN_KIND = 'frontier.swarm.watchpoint-plan';
@@ -457,6 +461,11 @@ export function createSwarmMergeBundle(input) {
457
461
  const commandsPassed = result.verification.filter((entry) => entry.status === 0 || entry.required === false && entry.status === undefined);
458
462
  const commandsFailed = result.verification.filter((entry) => entry.status !== undefined && entry.status !== 0 && entry.required !== false);
459
463
  const ownedFilesTouched = job ? changedPaths.filter((file) => job.allowedWrites.some((glob) => matchesGlob(file, glob))) : changedPaths;
464
+ const traceShards = [
465
+ ...(input.traceShards ?? []),
466
+ ...traceShardInputsFromUnknown(result.metadata?.traceShards),
467
+ ...traceShardInputsFromUnknown(inputMetadata?.traceShards)
468
+ ].map((shard) => normalizeTraceShardForBundle(shard, result, job, generatedAt));
460
469
  const reasons = mergeBundleReasons(result, disposition, input.staleAgainstHead ?? false);
461
470
  return {
462
471
  kind: FRONTIER_SWARM_MERGE_BUNDLE_KIND,
@@ -488,6 +497,7 @@ export function createSwarmMergeBundle(input) {
488
497
  staleAgainstHead: input.staleAgainstHead ?? false,
489
498
  reasons,
490
499
  ...(semanticImport ? { semanticImport } : {}),
500
+ traceShards,
491
501
  ...(inputMetadata ? { metadata: inputMetadata } : {})
492
502
  };
493
503
  }
@@ -1106,6 +1116,97 @@ export function createSwarmDivergenceReport(input = {}) {
1106
1116
  ...(toJsonObject(input.metadata) ? { metadata: toJsonObject(input.metadata) } : {})
1107
1117
  };
1108
1118
  }
1119
+ export function createSwarmTraceShard(input = {}) {
1120
+ const generatedAt = input.generatedAt ?? Date.now();
1121
+ const divergence = input.divergence
1122
+ ? isSwarmDivergenceReport(input.divergence)
1123
+ ? cloneJsonValue(input.divergence)
1124
+ : createSwarmDivergenceReport(input.divergence)
1125
+ : undefined;
1126
+ const rowWindows = (input.rowWindows ?? []).map((window) => normalizeTraceRowWindow(window, generatedAt));
1127
+ const hypotheses = (input.hypotheses ?? []).map((hypothesis) => normalizeTraceHypothesis(hypothesis, generatedAt));
1128
+ const executableOwnershipRegions = (input.executableOwnershipRegions ?? []).map(normalizeExecutableOwnershipRegion);
1129
+ const focusedTests = normalizeCommands(input.focusedTests ?? []);
1130
+ const referenceEvidence = normalizeNamedRefs(input.referenceEvidence ?? [], 'reference-evidence');
1131
+ const traceRefs = normalizeNamedRefs(input.traceRefs ?? [], 'trace');
1132
+ const status = input.status ?? (divergence && divergence.status === 'failed' ? 'failed' : focusedTests.length || rowWindows.length || hypotheses.length ? 'passed' : 'unknown');
1133
+ const id = input.id ?? 'swarm-trace-shard:' + stableHash([
1134
+ input.jobId,
1135
+ input.lane,
1136
+ input.subject ?? divergence?.subject,
1137
+ status,
1138
+ divergence?.id,
1139
+ rowWindows,
1140
+ hypotheses,
1141
+ executableOwnershipRegions,
1142
+ generatedAt
1143
+ ]);
1144
+ return {
1145
+ kind: FRONTIER_SWARM_TRACE_SHARD_KIND,
1146
+ version: FRONTIER_SWARM_TRACE_SHARD_VERSION,
1147
+ id,
1148
+ ...(input.jobId ? { jobId: input.jobId } : {}),
1149
+ ...(input.lane ? { lane: input.lane } : {}),
1150
+ ...(input.subject ?? divergence?.subject ? { subject: input.subject ?? divergence?.subject } : {}),
1151
+ status,
1152
+ traceRefs,
1153
+ ...(divergence ? { divergence } : {}),
1154
+ rowWindows,
1155
+ hypotheses,
1156
+ executableOwnershipRegions,
1157
+ focusedTests,
1158
+ referenceEvidence,
1159
+ generatedAt,
1160
+ summary: summarizeTraceShards([{ rowWindows, hypotheses, executableOwnershipRegions, focusedTests, referenceEvidence, divergence }]),
1161
+ ...(toJsonObject(input.metadata) ? { metadata: toJsonObject(input.metadata) } : {})
1162
+ };
1163
+ }
1164
+ export function createSwarmTraceIndex(input = {}) {
1165
+ const generatedAt = input.generatedAt ?? Date.now();
1166
+ const shards = [
1167
+ ...(input.shards ?? []).map((shard) => isSwarmTraceShard(shard) ? cloneJsonValue(shard) : createSwarmTraceShard({ ...shard, generatedAt: shard.generatedAt ?? generatedAt })),
1168
+ ...(input.bundles ?? []).flatMap((bundle) => bundle.traceShards)
1169
+ ];
1170
+ const uniqueById = new Map();
1171
+ for (const shard of shards)
1172
+ uniqueById.set(shard.id, shard);
1173
+ const indexed = Array.from(uniqueById.values()).sort((left, right) => left.id.localeCompare(right.id));
1174
+ return {
1175
+ kind: FRONTIER_SWARM_TRACE_INDEX_KIND,
1176
+ version: FRONTIER_SWARM_TRACE_INDEX_VERSION,
1177
+ id: input.id ?? 'swarm-trace-index:' + stableHash([indexed.map((shard) => shard.id), generatedAt]),
1178
+ generatedAt,
1179
+ shards: indexed,
1180
+ byJobId: groupObjects(indexed.filter((shard) => shard.jobId), (shard) => shard.jobId),
1181
+ bySubject: groupObjects(indexed.filter((shard) => shard.subject), (shard) => shard.subject),
1182
+ byRegion: groupTraceShardsByMany(indexed, traceShardRegions),
1183
+ bySourcePath: groupTraceShardsByMany(indexed, traceShardSourcePaths),
1184
+ summary: summarizeTraceShards(indexed),
1185
+ ...(toJsonObject(input.metadata) ? { metadata: toJsonObject(input.metadata) } : {})
1186
+ };
1187
+ }
1188
+ export function querySwarmTraceIndex(index, query = {}) {
1189
+ const needles = query.textIncludes ? [query.textIncludes.toLowerCase()] : [];
1190
+ const minConfidence = query.minConfidence ?? 0;
1191
+ const shards = index.shards.filter((shard) => ((query.jobId === undefined || shard.jobId === query.jobId)
1192
+ && (query.lane === undefined || shard.lane === query.lane)
1193
+ && (query.subject === undefined || shard.subject === query.subject)
1194
+ && (query.status === undefined || shard.status === query.status)
1195
+ && (query.region === undefined || traceShardRegions(shard).includes(query.region))
1196
+ && (query.sourcePath === undefined || traceShardSourcePaths(shard).some((path) => path.includes(query.sourcePath)))
1197
+ && (query.hasDivergence === undefined || Boolean(shard.divergence) === query.hasDivergence)
1198
+ && (query.minConfidence === undefined || traceShardMaxConfidence(shard) >= minConfidence)
1199
+ && (needles.length === 0 || needles.some((needle) => traceShardSearchText(shard).includes(needle)))));
1200
+ return {
1201
+ shards,
1202
+ summary: {
1203
+ shardCount: shards.length,
1204
+ rowWindowCount: shards.reduce((total, shard) => total + shard.rowWindows.length, 0),
1205
+ hypothesisCount: shards.reduce((total, shard) => total + shard.hypotheses.length, 0),
1206
+ executableOwnershipRegionCount: shards.reduce((total, shard) => total + shard.executableOwnershipRegions.length, 0)
1207
+ }
1208
+ };
1209
+ }
1109
1210
  export function createSwarmWatchpointPlan(input = {}) {
1110
1211
  const generatedAt = input.generatedAt ?? Date.now();
1111
1212
  const watchpoints = (input.watchpoints ?? []).map(normalizeWatchpoint);
@@ -1624,6 +1725,7 @@ export function createSwarmCoordinatorDashboard(input = {}) {
1624
1725
  const mergeIndex = input.mergeIndex ?? (bundles.length ? createSwarmMergeIndex({ runId, planId, bundles, generatedAt }) : undefined);
1625
1726
  const queueOverlay = input.queueOverlay ?? (bundles.length ? createSwarmQueueOverlay({ runId, bundles, generatedAt }) : undefined);
1626
1727
  const evidenceIndex = input.evidenceIndex ?? (input.run ? createSwarmEvidenceIndex({ run: input.run, generatedAt }) : undefined);
1728
+ const traceIndex = input.traceIndex ?? (bundles.some((bundle) => bundle.traceShards.length > 0) ? createSwarmTraceIndex({ bundles, generatedAt }) : undefined);
1627
1729
  const admission = input.admission;
1628
1730
  const jobsById = new Map((input.plan?.jobs ?? []).map((job) => [job.id, job]));
1629
1731
  const resultsById = new Map((input.run?.results ?? []).map((result) => [result.jobId, result]));
@@ -1650,6 +1752,7 @@ export function createSwarmCoordinatorDashboard(input = {}) {
1650
1752
  const result = resultsById.get(jobId);
1651
1753
  const entry = entriesById.get(jobId);
1652
1754
  const bundle = bundlesById.get(jobId);
1755
+ const traceShards = traceIndex?.byJobId[jobId] ?? bundle?.traceShards ?? [];
1653
1756
  const processList = processesByJob[jobId] ?? [];
1654
1757
  const duplicateGroup = duplicateByJob.get(jobId);
1655
1758
  const admissionReasons = admissionDeferred.get(jobId) ?? [];
@@ -1660,7 +1763,7 @@ export function createSwarmCoordinatorDashboard(input = {}) {
1660
1763
  : entry?.autoMergeable
1661
1764
  ? 'not-admissible'
1662
1765
  : 'unknown';
1663
- const score = scoreCoordinatorMergeJob(entry, bundle, evidenceIndex?.byJobId[jobId]?.length ?? 0, duplicateGroup, admissionStatus, admissionReasons);
1766
+ const score = scoreCoordinatorMergeJob(entry, bundle, evidenceIndex?.byJobId[jobId]?.length ?? 0, duplicateGroup, admissionStatus, admissionReasons, traceShards);
1664
1767
  const evidencePaths = uniqueStrings([
1665
1768
  ...(entry?.evidencePaths ?? []),
1666
1769
  ...(result?.evidencePaths ?? []),
@@ -1699,6 +1802,7 @@ export function createSwarmCoordinatorDashboard(input = {}) {
1699
1802
  ...(entry?.semanticImport ?? result?.semanticImport ?? bundle?.semanticImport ? {
1700
1803
  semanticImport: cloneJsonValue(entry?.semanticImport ?? result?.semanticImport ?? bundle?.semanticImport)
1701
1804
  } : {}),
1805
+ ...(traceShards.length ? { traceSummary: createCoordinatorTraceSummary(traceShards) } : {}),
1702
1806
  generatedAt
1703
1807
  };
1704
1808
  }).sort((left, right) => right.mergeScore - left.mergeScore || left.jobId.localeCompare(right.jobId));
@@ -1721,6 +1825,7 @@ export function createSwarmCoordinatorDashboard(input = {}) {
1721
1825
  ...(mergeIndex ? { mergeIndex } : {}),
1722
1826
  ...(queueOverlay ? { queueOverlay } : {}),
1723
1827
  ...(evidenceIndex ? { evidenceIndex } : {}),
1828
+ ...(traceIndex ? { traceIndex } : {}),
1724
1829
  ...(admission ? { admission } : {}),
1725
1830
  summary: {
1726
1831
  jobCount: jobs.length,
@@ -1731,6 +1836,9 @@ export function createSwarmCoordinatorDashboard(input = {}) {
1731
1836
  duplicateGroupCount: duplicateGroups.length,
1732
1837
  semanticSidecarCount: jobs.filter((job) => job.semanticImport && job.semanticImport.total > 0).length,
1733
1838
  semanticRegionCount: jobs.reduce((total, job) => total + job.semanticRegions.length, 0),
1839
+ traceShardCount: traceIndex?.summary.shardCount ?? 0,
1840
+ traceDivergenceCount: traceIndex?.summary.divergenceCount ?? 0,
1841
+ executableOwnershipRegionCount: traceIndex?.summary.executableOwnershipRegionCount ?? 0,
1734
1842
  averageMergeScore: averageScore(jobs.map((job) => job.mergeScore))
1735
1843
  },
1736
1844
  ...(toJsonObject(input.metadata) ? { metadata: toJsonObject(input.metadata) } : {})
@@ -1746,6 +1854,9 @@ export function querySwarmCoordinatorDashboard(dashboard, query = {}) {
1746
1854
  && (query.region === undefined || job.changedRegions.includes(query.region) || job.semanticRegions.includes(query.region))
1747
1855
  && (query.hasSemanticImport === undefined || Boolean(job.semanticImport && job.semanticImport.total > 0) === query.hasSemanticImport)
1748
1856
  && (query.hasSemanticRegions === undefined || (job.semanticRegions.length > 0) === query.hasSemanticRegions)
1857
+ && (query.hasTraceShards === undefined || Boolean(job.traceSummary && job.traceSummary.shardCount > 0) === query.hasTraceShards)
1858
+ && (query.traceSubject === undefined || (dashboard.traceIndex?.bySubject[query.traceSubject] ?? []).some((shard) => shard.jobId === job.jobId))
1859
+ && (query.traceRegion === undefined || (dashboard.traceIndex?.byRegion[query.traceRegion] ?? []).some((shard) => shard.jobId === job.jobId))
1749
1860
  && (query.staleAgainstHead === undefined || job.staleAgainstHead === query.staleAgainstHead)
1750
1861
  && (query.duplicateOnly !== true || Boolean(job.duplicateGroupId))
1751
1862
  && (query.minMergeScore === undefined || job.mergeScore >= query.minMergeScore)
@@ -3424,6 +3535,12 @@ function normalizeAutoReviewFinding(input, generatedAt) {
3424
3535
  function isSwarmObservabilityPoint(value) {
3425
3536
  return !!value && typeof value === 'object' && value.kind === FRONTIER_SWARM_OBSERVABILITY_POINT_KIND;
3426
3537
  }
3538
+ function isSwarmDivergenceReport(value) {
3539
+ return !!value && typeof value === 'object' && value.kind === FRONTIER_SWARM_DIVERGENCE_REPORT_KIND;
3540
+ }
3541
+ function isSwarmTraceShard(value) {
3542
+ return !!value && typeof value === 'object' && value.kind === FRONTIER_SWARM_TRACE_SHARD_KIND;
3543
+ }
3427
3544
  function isSwarmInstrumentationBudget(value) {
3428
3545
  return !!value && typeof value === 'object' && value.kind === FRONTIER_SWARM_INSTRUMENTATION_BUDGET_KIND;
3429
3546
  }
@@ -3441,6 +3558,158 @@ function groupObjects(items, key) {
3441
3558
  }
3442
3559
  return out;
3443
3560
  }
3561
+ function normalizeTraceRowWindow(input, generatedAt) {
3562
+ const start = Number.isFinite(input.start) ? Math.floor(input.start) : undefined;
3563
+ const end = Number.isFinite(input.end) ? Math.floor(input.end) : undefined;
3564
+ const rowCount = Number.isFinite(input.rowCount) ? Math.max(0, Math.floor(input.rowCount)) : undefined;
3565
+ const firstDivergenceAt = Number.isFinite(input.firstDivergenceAt) ? Math.floor(input.firstDivergenceAt) : undefined;
3566
+ const deltaFields = uniqueStrings(input.deltaFields ?? []);
3567
+ const id = input.id ?? 'swarm-trace-window:' + stableHash([start, end, rowCount, firstDivergenceAt, deltaFields, generatedAt]);
3568
+ return {
3569
+ id,
3570
+ title: input.title ?? titleFromId(id),
3571
+ ...(start !== undefined ? { start } : {}),
3572
+ ...(end !== undefined ? { end } : {}),
3573
+ ...(rowCount !== undefined ? { rowCount } : {}),
3574
+ ...(firstDivergenceAt !== undefined ? { firstDivergenceAt } : {}),
3575
+ deltaFields,
3576
+ evidenceRefs: normalizeNamedRefs(input.evidenceRefs ?? [], 'trace-window-evidence'),
3577
+ ...(toJsonObject(input.metadata) ? { metadata: toJsonObject(input.metadata) } : {})
3578
+ };
3579
+ }
3580
+ function normalizeTraceHypothesis(input, generatedAt) {
3581
+ const line = Number.isFinite(input.line) ? Math.max(1, Math.floor(input.line)) : undefined;
3582
+ const id = input.id ?? 'swarm-trace-hypothesis:' + stableHash([
3583
+ input.sourcePath,
3584
+ line,
3585
+ input.symbol,
3586
+ input.region,
3587
+ input.reason,
3588
+ generatedAt
3589
+ ]);
3590
+ return {
3591
+ id,
3592
+ title: input.title ?? titleFromId(input.symbol ?? input.region ?? id),
3593
+ ...(input.sourcePath ? { sourcePath: input.sourcePath } : {}),
3594
+ ...(line !== undefined ? { line } : {}),
3595
+ ...(input.symbol ? { symbol: input.symbol } : {}),
3596
+ ...(input.region ? { region: input.region } : {}),
3597
+ confidence: input.confidence ?? 'medium',
3598
+ ...(input.reason ? { reason: input.reason } : {}),
3599
+ evidenceRefs: normalizeNamedRefs(input.evidenceRefs ?? [], 'trace-hypothesis-evidence'),
3600
+ ...(toJsonObject(input.metadata) ? { metadata: toJsonObject(input.metadata) } : {})
3601
+ };
3602
+ }
3603
+ function normalizeExecutableOwnershipRegion(input) {
3604
+ return {
3605
+ id: normalizeId(input.id, 'executable ownership region id'),
3606
+ kind: input.kind ?? 'semantic-region',
3607
+ ...(input.sourcePath ? { sourcePath: input.sourcePath } : {}),
3608
+ ...(input.symbol ? { symbol: input.symbol } : {}),
3609
+ selectors: uniqueStrings(input.selectors ?? []),
3610
+ affectedTests: normalizeCommands(input.affectedTests ?? []),
3611
+ conflictingAssumptions: uniqueStrings(input.conflictingAssumptions ?? []),
3612
+ traceRefs: normalizeNamedRefs(input.traceRefs ?? [], 'trace'),
3613
+ riskLevel: input.riskLevel ?? 'unknown',
3614
+ ...(toJsonObject(input.metadata) ? { metadata: toJsonObject(input.metadata) } : {})
3615
+ };
3616
+ }
3617
+ function traceShardInputsFromUnknown(value) {
3618
+ if (!Array.isArray(value))
3619
+ return [];
3620
+ return value.filter((entry) => !!entry && typeof entry === 'object');
3621
+ }
3622
+ function normalizeTraceShardForBundle(shard, result, job, generatedAt) {
3623
+ return createSwarmTraceShard({
3624
+ ...cloneJsonValue(shard),
3625
+ jobId: shard.jobId ?? result.jobId,
3626
+ lane: shard.lane ?? job?.lane,
3627
+ generatedAt: shard.generatedAt ?? generatedAt
3628
+ });
3629
+ }
3630
+ function summarizeTraceShards(shards) {
3631
+ const rowWindowCount = shards.reduce((total, shard) => total + shard.rowWindows.length, 0);
3632
+ const hypothesisCount = shards.reduce((total, shard) => total + shard.hypotheses.length, 0);
3633
+ const executableOwnershipRegionCount = shards.reduce((total, shard) => total + shard.executableOwnershipRegions.length, 0);
3634
+ const focusedTestCount = shards.reduce((total, shard) => total + shard.focusedTests.length, 0);
3635
+ const referenceEvidenceCount = shards.reduce((total, shard) => total + shard.referenceEvidence.length, 0);
3636
+ const divergenceCount = shards.filter((shard) => Boolean(shard.divergence)).length;
3637
+ return {
3638
+ shardCount: shards.length,
3639
+ rowWindowCount,
3640
+ hypothesisCount,
3641
+ executableOwnershipRegionCount,
3642
+ focusedTestCount,
3643
+ referenceEvidenceCount,
3644
+ divergenceCount,
3645
+ hasDivergence: divergenceCount > 0
3646
+ };
3647
+ }
3648
+ function groupTraceShardsByMany(shards, key) {
3649
+ const out = {};
3650
+ for (const shard of shards) {
3651
+ for (const value of key(shard))
3652
+ out[value] = [...(out[value] ?? []), shard];
3653
+ }
3654
+ return out;
3655
+ }
3656
+ function traceShardRegions(shard) {
3657
+ return uniqueStrings([
3658
+ ...shard.hypotheses.map((hypothesis) => hypothesis.region),
3659
+ ...shard.executableOwnershipRegions.flatMap((region) => [region.id, ...region.selectors])
3660
+ ]);
3661
+ }
3662
+ function traceShardSourcePaths(shard) {
3663
+ return uniqueStrings([
3664
+ ...shard.hypotheses.map((hypothesis) => hypothesis.sourcePath),
3665
+ ...shard.executableOwnershipRegions.map((region) => region.sourcePath)
3666
+ ]);
3667
+ }
3668
+ function traceShardMaxConfidence(shard) {
3669
+ return Math.max(...[
3670
+ shard.divergence ? confidenceWeight(shard.divergence.confidence) : 0,
3671
+ ...shard.hypotheses.map((hypothesis) => confidenceWeight(hypothesis.confidence))
3672
+ ]);
3673
+ }
3674
+ function traceShardSearchText(shard) {
3675
+ return stableStringify({
3676
+ id: shard.id,
3677
+ jobId: shard.jobId,
3678
+ lane: shard.lane,
3679
+ subject: shard.subject,
3680
+ status: shard.status,
3681
+ divergence: shard.divergence,
3682
+ rowWindows: shard.rowWindows,
3683
+ hypotheses: shard.hypotheses,
3684
+ executableOwnershipRegions: shard.executableOwnershipRegions
3685
+ }).toLowerCase();
3686
+ }
3687
+ function confidenceWeight(confidence) {
3688
+ if (confidence === 'high')
3689
+ return 1;
3690
+ if (confidence === 'medium')
3691
+ return 0.65;
3692
+ if (confidence === 'low')
3693
+ return 0.35;
3694
+ return 0.5;
3695
+ }
3696
+ function createCoordinatorTraceSummary(shards) {
3697
+ const summary = summarizeTraceShards(shards);
3698
+ const openDivergenceCount = shards.filter((shard) => (shard.status === 'failed'
3699
+ || shard.divergence?.status === 'failed'
3700
+ || shard.divergence?.severity === 'error'
3701
+ || shard.divergence?.severity === 'critical')).length;
3702
+ return {
3703
+ shardCount: summary.shardCount,
3704
+ rowWindowCount: summary.rowWindowCount,
3705
+ hypothesisCount: summary.hypothesisCount,
3706
+ executableOwnershipRegionCount: summary.executableOwnershipRegionCount,
3707
+ focusedTestCount: summary.focusedTestCount,
3708
+ referenceEvidenceCount: summary.referenceEvidenceCount,
3709
+ divergenceCount: summary.divergenceCount,
3710
+ openDivergenceCount
3711
+ };
3712
+ }
3444
3713
  function clamp01(value) {
3445
3714
  if (!Number.isFinite(value))
3446
3715
  return 0;
@@ -3503,7 +3772,7 @@ function coordinatorDuplicateKeys(entry) {
3503
3772
  keys.push(`path:${entry.changedPaths.slice().sort().join('|')}`);
3504
3773
  return keys;
3505
3774
  }
3506
- function scoreCoordinatorMergeJob(entry, bundle, evidenceEntryCount, duplicateGroup, admissionStatus, admissionReasons) {
3775
+ function scoreCoordinatorMergeJob(entry, bundle, evidenceEntryCount, duplicateGroup, admissionStatus, admissionReasons, traceShards = []) {
3507
3776
  if (!entry)
3508
3777
  return { score: 10, reasons: ['no-merge-index-entry'] };
3509
3778
  let score = entry.disposition === 'auto-mergeable' && entry.autoMergeable ? 85 : entry.disposition === 'needs-port' ? 60 : entry.disposition === 'discovery-only' ? 35 : 15;
@@ -3572,6 +3841,32 @@ function scoreCoordinatorMergeJob(entry, bundle, evidenceEntryCount, duplicateGr
3572
3841
  score -= 5;
3573
3842
  reasons.push('missing-semantic-sidecar');
3574
3843
  }
3844
+ const traceSummary = createCoordinatorTraceSummary(traceShards);
3845
+ if (traceSummary.shardCount > 0) {
3846
+ score += Math.min(6, traceSummary.shardCount * 2);
3847
+ reasons.push('trace-shard-evidence');
3848
+ }
3849
+ if (traceSummary.referenceEvidenceCount > 0) {
3850
+ score += Math.min(6, traceSummary.referenceEvidenceCount * 2);
3851
+ reasons.push('reference-evidence-attached');
3852
+ }
3853
+ if (traceSummary.focusedTestCount > 0) {
3854
+ score += Math.min(6, traceSummary.focusedTestCount * 2);
3855
+ reasons.push('focused-tests-attached');
3856
+ }
3857
+ if (traceSummary.executableOwnershipRegionCount > 0) {
3858
+ score += Math.min(6, traceSummary.executableOwnershipRegionCount * 2);
3859
+ reasons.push('executable-ownership-regions');
3860
+ }
3861
+ if (traceSummary.openDivergenceCount > 0) {
3862
+ score -= Math.min(20, traceSummary.openDivergenceCount * 10);
3863
+ reasons.push('trace-divergence-open');
3864
+ }
3865
+ const conflictingAssumptionCount = traceShards.reduce((total, shard) => total + shard.executableOwnershipRegions.reduce((inner, region) => inner + region.conflictingAssumptions.length, 0), 0);
3866
+ if (conflictingAssumptionCount > 0) {
3867
+ score -= Math.min(16, conflictingAssumptionCount * 4);
3868
+ reasons.push('conflicting-trace-assumptions');
3869
+ }
3575
3870
  if (bundle?.commandsPassed.length)
3576
3871
  score += Math.min(8, bundle.commandsPassed.length * 2);
3577
3872
  return { score: clampScore(score), reasons: uniqueStrings(reasons) };
@@ -4160,12 +4455,73 @@ function normalizeSemanticImportSummary(input) {
4160
4455
  semanticIndex: normalizeSemanticIndexSummary(object.semanticIndex),
4161
4456
  semanticSidecars: normalizeSemanticSidecarSummary(object.semanticSidecars),
4162
4457
  proofSpec: normalizeProofSpecSummary(object.proofSpec),
4458
+ paradigmSemantics: normalizeParadigmSemanticsSummary(object.paradigmSemantics),
4163
4459
  sourceProjections: normalizeSourceProjectionSummary(object.sourceProjections),
4164
4460
  nativeCompiles: normalizeNativeCompileSummary(object.nativeCompiles),
4165
4461
  readiness: normalizeCounterRecord(object.readiness),
4166
4462
  ...(metadata ? { metadata } : {})
4167
4463
  };
4168
4464
  }
4465
+ const paradigmSemanticsSummaryGroups = [
4466
+ 'bindingScopes',
4467
+ 'bindings',
4468
+ 'patterns',
4469
+ 'typeConstraints',
4470
+ 'evaluationModels',
4471
+ 'memoryLocations',
4472
+ 'effectRegions',
4473
+ 'controlRegions',
4474
+ 'logicPrograms',
4475
+ 'actorSystems',
4476
+ 'stackEffects',
4477
+ 'arrayShapes',
4478
+ 'numericKernels',
4479
+ 'dataflowNetworks',
4480
+ 'clockModels',
4481
+ 'objectModels',
4482
+ 'macroExpansions',
4483
+ 'reflectionBoundaries',
4484
+ 'loweringRecords'
4485
+ ];
4486
+ function normalizeParadigmSemanticsSummary(input) {
4487
+ const object = toJsonObject(input);
4488
+ const counts = Object.fromEntries(paradigmSemanticsSummaryGroups.map((group) => [
4489
+ group,
4490
+ nonNegativeCount(object?.[group])
4491
+ ]));
4492
+ const total = nonNegativeCount(object?.total) || Object.values(counts).reduce((sum, count) => sum + count, 0);
4493
+ const byGroup = normalizeCounterRecord(object?.byGroup);
4494
+ const byKind = normalizeCounterRecord(object?.byKind);
4495
+ const hasRuntimeSemantics = object?.hasRuntimeSemantics === true
4496
+ || counts.evaluationModels > 0
4497
+ || counts.memoryLocations > 0
4498
+ || counts.effectRegions > 0
4499
+ || counts.controlRegions > 0
4500
+ || counts.actorSystems > 0
4501
+ || counts.clockModels > 0;
4502
+ const hasLogicSemantics = object?.hasLogicSemantics === true || counts.logicPrograms > 0;
4503
+ const hasStackSemantics = object?.hasStackSemantics === true || counts.stackEffects > 0;
4504
+ const hasArraySemantics = object?.hasArraySemantics === true || counts.arrayShapes > 0 || counts.numericKernels > 0;
4505
+ const hasMacroOrReflection = object?.hasMacroOrReflection === true || counts.macroExpansions > 0 || counts.reflectionBoundaries > 0;
4506
+ const hasLowering = object?.hasLowering === true || counts.loweringRecords > 0;
4507
+ return {
4508
+ total,
4509
+ ids: uniqueStrings(stringArray(object?.ids)),
4510
+ groups: uniqueStrings(stringArray(object?.groups)),
4511
+ kinds: uniqueStrings(stringArray(object?.kinds)),
4512
+ evidence: nonNegativeCount(object?.evidence),
4513
+ ...counts,
4514
+ byGroup,
4515
+ byKind,
4516
+ hasRuntimeSemantics,
4517
+ hasLogicSemantics,
4518
+ hasStackSemantics,
4519
+ hasArraySemantics,
4520
+ hasMacroOrReflection,
4521
+ hasLowering,
4522
+ empty: object?.empty === true || total === 0
4523
+ };
4524
+ }
4169
4525
  function normalizeProofSpecSummary(input) {
4170
4526
  const object = toJsonObject(input);
4171
4527
  const total = nonNegativeCount(object?.total);