@kaelio/ktx 0.1.0-rc.6 → 0.1.0

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.
Files changed (55) hide show
  1. package/assets/python/{kaelio_ktx-0.1.0rc6-py3-none-any.whl → kaelio_ktx-0.1.0-py3-none-any.whl} +0 -0
  2. package/assets/python/manifest.json +4 -4
  3. package/dist/commands/mcp-commands.js +11 -3
  4. package/dist/commands/mcp-commands.test.js +30 -1
  5. package/dist/ingest.test.js +2 -26
  6. package/dist/next-steps.js +1 -1
  7. package/dist/next-steps.test.js +2 -0
  8. package/dist/runtime-requirements.d.ts +1 -2
  9. package/dist/runtime-requirements.js +0 -7
  10. package/dist/runtime-requirements.test.js +2 -2
  11. package/dist/setup-agents.d.ts +11 -3
  12. package/dist/setup-agents.js +397 -134
  13. package/dist/setup-agents.test.js +359 -61
  14. package/dist/setup-runtime.d.ts +0 -1
  15. package/dist/setup-runtime.js +0 -1
  16. package/dist/setup-runtime.test.js +7 -13
  17. package/dist/setup.d.ts +3 -0
  18. package/dist/setup.js +51 -25
  19. package/dist/setup.test.js +112 -16
  20. package/node_modules/@ktx/connector-clickhouse/dist/package-exports.test.js +1 -1
  21. package/node_modules/@ktx/context/dist/core/git.service.d.ts +0 -1
  22. package/node_modules/@ktx/context/dist/core/git.service.js +0 -12
  23. package/node_modules/@ktx/context/dist/ingest/adapters/historic-sql/historic-sql.adapter.d.ts +1 -2
  24. package/node_modules/@ktx/context/dist/ingest/adapters/historic-sql/historic-sql.adapter.js +0 -18
  25. package/node_modules/@ktx/context/dist/ingest/adapters/historic-sql/local-ingest-acceptance.test.js +6 -6
  26. package/node_modules/@ktx/context/dist/ingest/adapters/historic-sql/post-processor.d.ts +4 -0
  27. package/node_modules/@ktx/context/dist/ingest/adapters/historic-sql/post-processor.js +38 -0
  28. package/node_modules/@ktx/context/dist/ingest/adapters/historic-sql/post-processor.test.js +63 -0
  29. package/node_modules/@ktx/context/dist/ingest/adapters/historic-sql/projection.d.ts +0 -5
  30. package/node_modules/@ktx/context/dist/ingest/adapters/historic-sql/projection.js +0 -48
  31. package/node_modules/@ktx/context/dist/ingest/adapters/historic-sql/projection.test.js +0 -83
  32. package/node_modules/@ktx/context/dist/ingest/index.d.ts +2 -1
  33. package/node_modules/@ktx/context/dist/ingest/index.js +1 -0
  34. package/node_modules/@ktx/context/dist/ingest/ingest-bundle.runner.d.ts +0 -2
  35. package/node_modules/@ktx/context/dist/ingest/ingest-bundle.runner.isolated-diff.test.js +0 -166
  36. package/node_modules/@ktx/context/dist/ingest/ingest-bundle.runner.js +45 -235
  37. package/node_modules/@ktx/context/dist/ingest/ingest-bundle.runner.test.js +38 -193
  38. package/node_modules/@ktx/context/dist/ingest/local-bundle-ingest.test.js +3 -22
  39. package/node_modules/@ktx/context/dist/ingest/local-bundle-runtime.js +4 -0
  40. package/node_modules/@ktx/context/dist/ingest/local-ingest.js +7 -0
  41. package/node_modules/@ktx/context/dist/ingest/memory-flow/schema.d.ts +4 -4
  42. package/node_modules/@ktx/context/dist/ingest/memory-flow/schema.js +1 -1
  43. package/node_modules/@ktx/context/dist/ingest/memory-flow/types.d.ts +1 -1
  44. package/node_modules/@ktx/context/dist/ingest/ports.d.ts +20 -1
  45. package/node_modules/@ktx/context/dist/ingest/report-snapshot.d.ts +2 -73
  46. package/node_modules/@ktx/context/dist/ingest/report-snapshot.js +0 -27
  47. package/node_modules/@ktx/context/dist/ingest/reports.d.ts +5 -23
  48. package/node_modules/@ktx/context/dist/ingest/reports.js +24 -7
  49. package/node_modules/@ktx/context/dist/ingest/types.d.ts +0 -33
  50. package/node_modules/@ktx/context/dist/package-exports.test.js +1 -2
  51. package/package.json +4 -4
  52. package/node_modules/@ktx/context/dist/ingest/finalization-scope.d.ts +0 -22
  53. package/node_modules/@ktx/context/dist/ingest/finalization-scope.js +0 -95
  54. package/node_modules/@ktx/context/dist/ingest/finalization-scope.test.js +0 -114
  55. /package/node_modules/@ktx/context/dist/ingest/{finalization-scope.test.d.ts → adapters/historic-sql/post-processor.test.d.ts} +0 -0
@@ -11,14 +11,13 @@ import { NOTION_DEFAULT_MAX_KNOWLEDGE_CREATES_PER_RUN } from './adapters/notion/
11
11
  import { validateFinalIngestArtifacts, validateProvenanceRawPaths } from './artifact-gates.js';
12
12
  import { selectRelevantCanonicalPins } from './canonical-pins.js';
13
13
  import { finalGateRepairPaths, repairFinalGateFailure } from './final-gate-repair.js';
14
- import { compareFinalizationDeclarations, deriveFinalizationTouchedSources, deriveFinalizationWikiPageKeys, } from './finalization-scope.js';
15
14
  import { FileIngestTraceWriter, ingestTracePathForJob, traceTimed } from './ingest-trace.js';
16
15
  import { integrateWorkUnitPatch } from './isolated-diff/patch-integrator.js';
17
16
  import { resolveTextualConflict } from './isolated-diff/textual-conflict-resolver.js';
18
17
  import { runIsolatedWorkUnit } from './isolated-diff/work-unit-executor.js';
19
18
  import { sanitizeMemoryFlowError } from './memory-flow/live-buffer.js';
20
19
  import { buildSyncId, rawSourcesDirForSync } from './raw-sources-paths.js';
21
- import { buildStageIndexFromReportBody, } from './reports.js';
20
+ import { buildStageIndexFromReportBody, postProcessorSavedMemoryCounts, } from './reports.js';
22
21
  import { buildReconcileSystemPrompt, buildReconcileToolSet, buildReconcileUserPrompt, } from './stages/build-reconcile-context.js';
23
22
  import { buildWuSystemPrompt, buildWuToolSet, buildWuUserPrompt } from './stages/build-wu-context.js';
24
23
  import { stageRawFilesStage1 } from './stages/stage-1-stage-raw-files.js';
@@ -287,15 +286,6 @@ export class IngestBundleRunner {
287
286
  }
288
287
  return false;
289
288
  }
290
- async loadSourcesByConnection(workdir, connectionIds) {
291
- const service = this.deps.semanticLayerService.forWorktree(workdir);
292
- const result = new Map();
293
- for (const connectionId of connectionIds) {
294
- const { sources } = await service.loadAllSources(connectionId);
295
- result.set(connectionId, sources);
296
- }
297
- return result;
298
- }
299
289
  resolveContextCuratorBudget(bundleRef, stageIndex) {
300
290
  const rawConfig = bundleRef.kind === 'scheduled_pull' && bundleRef.config && typeof bundleRef.config === 'object'
301
291
  ? bundleRef.config
@@ -384,15 +374,6 @@ export class IngestBundleRunner {
384
374
  });
385
375
  }
386
376
  });
387
- input.finalizationActions.forEach((action, actionIndex) => {
388
- for (const rawPath of action.rawPaths ?? []) {
389
- pushActionProvenance(rawPath, action, {
390
- source: 'finalization_action',
391
- actionIndex,
392
- action,
393
- });
394
- }
395
- });
396
377
  (input.stageIndex.artifactResolutions ?? []).forEach((resolution, resolutionIndex) => {
397
378
  const hash = input.currentHashes.get(resolution.rawPath) ?? '';
398
379
  pushRow({
@@ -431,29 +412,6 @@ export class IngestBundleRunner {
431
412
  }
432
413
  return { rows, diagnostics };
433
414
  }
434
- partitionFinalizationActionsForProvenance(input) {
435
- const defensible = new Set([
436
- ...input.currentRawPaths,
437
- ...input.currentEvictionRawPaths,
438
- ...input.overrideEvictionRawPaths,
439
- ]);
440
- const actions = [];
441
- const exclusions = [];
442
- for (const action of input.actions) {
443
- const rawPaths = action.rawPaths ?? [];
444
- if (rawPaths.length === 0) {
445
- exclusions.push({ action, reason: 'missing_raw_paths' });
446
- continue;
447
- }
448
- const invalidRawPaths = rawPaths.filter((rawPath) => !defensible.has(rawPath)).sort();
449
- if (invalidRawPaths.length > 0) {
450
- exclusions.push({ action, reason: 'raw_path_not_defensible', invalidRawPaths });
451
- continue;
452
- }
453
- actions.push(action);
454
- }
455
- return { actions, exclusions };
456
- }
457
415
  toReportProvenanceRows(rows) {
458
416
  return rows.map(({ rawPath, artifactKind, artifactKey, actionType, targetConnectionId }) => ({
459
417
  rawPath,
@@ -739,7 +697,6 @@ export class IngestBundleRunner {
739
697
  let latestEvictionInputs = [];
740
698
  let latestUnresolvedCards = [];
741
699
  let latestReportProvenanceRows = [];
742
- let latestFinalizationOutcome;
743
700
  let activeFailureDetails;
744
701
  let latestIsolatedDiffSummary;
745
702
  await trace.event('info', 'run', 'ingest_started', {
@@ -891,7 +848,7 @@ export class IngestBundleRunner {
891
848
  let unresolvedCards;
892
849
  let sourceContextReport;
893
850
  let parseArtifacts;
894
- let finalizationOutcome;
851
+ let postProcessorOutcome;
895
852
  let wikiSlRefRepairResult = null;
896
853
  let reconcileNotes = [];
897
854
  let triageResult = null;
@@ -1534,187 +1491,55 @@ export class IngestBundleRunner {
1534
1491
  artifactResolutionCount: stageIndex.artifactResolutions?.length ?? 0,
1535
1492
  });
1536
1493
  await stage4?.updateProgress(1.0, reconcileOutcome.skipped ? 'No reconciliation needed' : 'Reconciled');
1537
- const preFinalizationSha = await sessionWorktree.git.revParseHead();
1538
- const preFinalizationSourcesByConnection = await this.loadSourcesByConnection(sessionWorktree.workdir, slConnectionIds);
1539
- let finalizationActions = [];
1540
- let finalizationTouchedPaths = [];
1541
- let finalizationTouchedSources = [];
1542
- let finalizationChangedWikiPageKeys = [];
1543
- let finalizationSha = null;
1544
- activePhase = 'finalization';
1545
- if (adapter.finalize) {
1546
- const stageFinalization = ctx?.startPhase(0.04);
1547
- emitStageProgress('finalization', 87, 'Running deterministic finalization');
1548
- await stageFinalization?.updateProgress(0.0, 'Running deterministic finalization');
1549
- await runTrace.event('debug', 'finalization', 'finalization_started', { sourceKey: job.sourceKey });
1550
- const result = await adapter.finalize({
1551
- connectionId: job.connectionId,
1552
- sourceKey: job.sourceKey,
1553
- syncId,
1554
- jobId: job.jobId,
1555
- runId: createdRunRow.id,
1556
- stagedDir,
1557
- workdir: sessionWorktree.workdir,
1558
- ...(overrideReport ? {} : { parseArtifacts }),
1559
- stageIndex,
1560
- workUnitOutcomes,
1561
- reconciliationActions: reconcileActions,
1562
- ...(overrideReport
1563
- ? {
1564
- overrideReplay: {
1565
- priorJobId: overrideReport.jobId,
1566
- priorRunId: overrideReport.runId,
1567
- priorSyncId: overrideReport.body.syncId,
1568
- evictionRawPaths: overrideReport.body.evictionInputs,
1569
- },
1570
- }
1571
- : {}),
1572
- });
1573
- if (result.errors.length > 0) {
1574
- finalizationOutcome = {
1494
+ const postProcessor = this.deps.postProcessors?.[job.sourceKey];
1495
+ activePhase = 'post_processor';
1496
+ if (postProcessor) {
1497
+ const stagePostProcessor = ctx?.startPhase(0.04);
1498
+ emitStageProgress('post_processor', 87, 'Running deterministic imports');
1499
+ await stagePostProcessor?.updateProgress(0.0, 'Running deterministic imports');
1500
+ try {
1501
+ const result = await traceTimed(runTrace, 'post_processor', 'post_processor', { sourceKey: job.sourceKey }, () => postProcessor.run({
1502
+ connectionId: job.connectionId,
1575
1503
  sourceKey: job.sourceKey,
1576
- status: 'failed',
1577
- commitSha: null,
1578
- touchedPaths: [],
1579
- declaredTouchedSources: result.touchedSources,
1580
- derivedTouchedSources: [],
1581
- declaredChangedWikiPageKeys: result.changedWikiPageKeys,
1582
- derivedChangedWikiPageKeys: [],
1583
- mismatches: [],
1504
+ syncId,
1505
+ jobId: job.jobId,
1506
+ runId: createdRunRow.id,
1507
+ workdir: sessionWorktree.workdir,
1508
+ parseArtifacts,
1509
+ }));
1510
+ postProcessorOutcome = {
1511
+ sourceKey: job.sourceKey,
1512
+ status: result.errors.length > 0 && result.touchedSources.length === 0 ? 'failed' : 'success',
1584
1513
  result: result.result,
1585
1514
  errors: result.errors,
1586
1515
  warnings: result.warnings,
1587
- actions: result.actions ?? [],
1588
- provenanceExclusions: [],
1516
+ touchedSources: result.touchedSources,
1589
1517
  };
1590
- latestFinalizationOutcome = finalizationOutcome;
1591
- await runTrace.event('error', 'finalization', 'finalization_failed', {
1592
- sourceKey: job.sourceKey,
1593
- errors: result.errors,
1594
- warnings: result.warnings,
1595
- });
1596
- throw new Error(`deterministic finalization failed: ${result.errors.join('; ')}`);
1518
+ emitStageProgress('post_processor', 88, 'Deterministic imports complete');
1519
+ await stagePostProcessor?.updateProgress(1.0, 'Deterministic imports complete');
1597
1520
  }
1598
- const changedBeforeFinalization = new Set([
1599
- ...projectionTouchedPaths,
1600
- ...workUnitOutcomes.flatMap((outcome) => outcome.patchTouchedPaths ?? []),
1601
- ...(preReconciliationSha && preFinalizationSha !== preReconciliationSha
1602
- ? (await sessionWorktree.git.diffNameStatus(preReconciliationSha, preFinalizationSha)).map((entry) => entry.path)
1603
- : []),
1604
- ]);
1605
- finalizationTouchedPaths = await sessionWorktree.git.changedPaths();
1606
- const overlapping = finalizationTouchedPaths.filter((path) => changedBeforeFinalization.has(path));
1607
- if (overlapping.length > 0) {
1608
- await runTrace.event('error', 'finalization', 'finalization_failed', {
1609
- sourceKey: job.sourceKey,
1610
- reason: 'path_overlap',
1611
- overlappingPaths: overlapping.sort(),
1612
- });
1613
- throw new Error(`finalization modified path(s) already changed earlier in this run: ${overlapping.sort().join(', ')}`);
1614
- }
1615
- const finalizationCommit = finalizationTouchedPaths.length > 0
1616
- ? await sessionWorktree.git.commitFiles(finalizationTouchedPaths, `ingest(${job.sourceKey}): deterministic finalization syncId=${syncId}`, this.deps.storage.systemGitAuthor.name, this.deps.storage.systemGitAuthor.email)
1617
- : await sessionWorktree.git.commitStaged(`ingest(${job.sourceKey}): deterministic finalization syncId=${syncId}`, this.deps.storage.systemGitAuthor.name, this.deps.storage.systemGitAuthor.email);
1618
- finalizationSha = finalizationCommit.created ? finalizationCommit.commitHash : null;
1619
- const postFinalizationSha = await sessionWorktree.git.revParseHead();
1620
- finalizationTouchedPaths =
1621
- preFinalizationSha !== postFinalizationSha
1622
- ? (await sessionWorktree.git.diffNameStatus(preFinalizationSha, postFinalizationSha)).map((entry) => entry.path)
1623
- : [];
1624
- const changedConnectionIds = [
1625
- ...new Set([
1626
- ...slConnectionIds,
1627
- ...finalizationTouchedPaths
1628
- .filter((path) => path.startsWith('semantic-layer/'))
1629
- .map((path) => path.split('/')[1])
1630
- .filter((connectionId) => Boolean(connectionId)),
1631
- ]),
1632
- ].sort();
1633
- const postFinalizationSourcesByConnection = await this.loadSourcesByConnection(sessionWorktree.workdir, changedConnectionIds);
1634
- const scope = await deriveFinalizationTouchedSources({
1635
- changedPaths: finalizationTouchedPaths,
1636
- beforeSourcesByConnection: preFinalizationSourcesByConnection,
1637
- afterSourcesByConnection: postFinalizationSourcesByConnection,
1638
- });
1639
- if (scope.unresolvedPaths.length > 0) {
1640
- await runTrace.event('error', 'finalization', 'finalization_failed', {
1641
- sourceKey: job.sourceKey,
1642
- reason: 'unresolved_semantic_layer_paths',
1643
- unresolvedPaths: scope.unresolvedPaths,
1644
- });
1645
- throw new Error(`could not resolve finalization semantic-layer path(s): ${scope.unresolvedPaths.join(', ')}`);
1646
- }
1647
- finalizationTouchedSources = scope.touchedSources;
1648
- finalizationChangedWikiPageKeys = deriveFinalizationWikiPageKeys(finalizationTouchedPaths);
1649
- const mismatches = compareFinalizationDeclarations({
1650
- declaredTouchedSources: result.touchedSources,
1651
- derivedTouchedSources: finalizationTouchedSources,
1652
- declaredChangedWikiPageKeys: result.changedWikiPageKeys,
1653
- derivedChangedWikiPageKeys: finalizationChangedWikiPageKeys,
1654
- });
1655
- if (mismatches.length > 0) {
1656
- finalizationOutcome = {
1521
+ catch (error) {
1522
+ postProcessorOutcome = {
1657
1523
  sourceKey: job.sourceKey,
1658
1524
  status: 'failed',
1659
- commitSha: finalizationSha,
1660
- touchedPaths: finalizationTouchedPaths,
1661
- declaredTouchedSources: result.touchedSources,
1662
- derivedTouchedSources: finalizationTouchedSources,
1663
- declaredChangedWikiPageKeys: result.changedWikiPageKeys,
1664
- derivedChangedWikiPageKeys: finalizationChangedWikiPageKeys,
1665
- mismatches,
1666
- result: result.result,
1667
- errors: ['finalization touched artifact declaration mismatch'],
1668
- warnings: result.warnings,
1669
- actions: result.actions ?? [],
1670
- provenanceExclusions: [],
1525
+ errors: [error instanceof Error ? error.message : String(error)],
1526
+ warnings: [],
1527
+ touchedSources: [],
1671
1528
  };
1672
- latestFinalizationOutcome = finalizationOutcome;
1673
- await runTrace.event('error', 'finalization', 'finalization_failed', {
1674
- sourceKey: job.sourceKey,
1675
- reason: 'declaration_mismatch',
1676
- mismatches,
1677
- });
1678
- throw new Error(`finalization touched artifact declaration mismatch: ${mismatches
1679
- .map((mismatch) => `${mismatch.direction}:${mismatch.artifactKind}:${mismatch.key}`)
1680
- .join(', ')}`);
1529
+ await this.deps.runs.markFailed(runRow.id);
1530
+ throw error;
1681
1531
  }
1682
- finalizationActions = result.actions ?? [];
1683
- finalizationOutcome = {
1684
- sourceKey: job.sourceKey,
1685
- status: 'success',
1686
- commitSha: finalizationSha,
1687
- touchedPaths: finalizationTouchedPaths,
1688
- declaredTouchedSources: result.touchedSources,
1689
- derivedTouchedSources: finalizationTouchedSources,
1690
- declaredChangedWikiPageKeys: result.changedWikiPageKeys,
1691
- derivedChangedWikiPageKeys: finalizationChangedWikiPageKeys,
1692
- mismatches,
1693
- result: result.result,
1694
- errors: [],
1695
- warnings: result.warnings,
1696
- actions: finalizationActions,
1697
- provenanceExclusions: [],
1698
- };
1699
- latestFinalizationOutcome = finalizationOutcome;
1700
- emitStageProgress('finalization', 88, 'Deterministic finalization complete');
1701
- await stageFinalization?.updateProgress(1.0, 'Deterministic finalization complete');
1702
- await runTrace.event('debug', 'finalization', 'finalization_committed', {
1703
- sourceKey: job.sourceKey,
1704
- commitSha: finalizationSha,
1705
- touchedPaths: finalizationTouchedPaths,
1706
- touchedSources: finalizationTouchedSources,
1707
- changedWikiPageKeys: finalizationChangedWikiPageKeys,
1708
- warnings: result.warnings,
1709
- });
1710
- }
1711
- else {
1712
- await runTrace.event('debug', 'finalization', 'finalization_skipped', { sourceKey: job.sourceKey });
1713
1532
  }
1533
+ await runTrace.event('debug', 'post_processor', 'post_processor_finished', {
1534
+ sourceKey: job.sourceKey,
1535
+ status: postProcessorOutcome?.status ?? 'skipped',
1536
+ touchedSources: postProcessorOutcome?.touchedSources ?? [],
1537
+ warnings: postProcessorOutcome?.warnings ?? [],
1538
+ });
1714
1539
  const repairConnectionIds = [
1715
1540
  ...new Set([
1716
1541
  ...slConnectionIds,
1717
- ...finalizationTouchedSources.map((source) => source.connectionId),
1542
+ ...(postProcessorOutcome?.touchedSources ?? []).map((source) => source.connectionId),
1718
1543
  ]),
1719
1544
  ].sort();
1720
1545
  activePhase = 'wiki_sl_ref_repair';
@@ -1741,7 +1566,6 @@ export class IngestBundleRunner {
1741
1566
  .flatMap((outcome) => outcome.patchTouchedPaths ?? [])
1742
1567
  .flatMap((path) => this.wikiPageKeysFromPaths([path])),
1743
1568
  ...this.wikiPageKeysFromActions(reconcileActions),
1744
- ...finalizationChangedWikiPageKeys,
1745
1569
  ...postReconciliationPaths.flatMap((path) => this.wikiPageKeysFromPaths([path])),
1746
1570
  ...wikiSlRefRepairResult.repairs.filter((repair) => repair.scope === 'GLOBAL').map((repair) => repair.pageKey),
1747
1571
  ]);
@@ -1750,7 +1574,7 @@ export class IngestBundleRunner {
1750
1574
  ...workUnitOutcomes.flatMap((outcome) => outcome.touchedSlSources),
1751
1575
  ...this.touchedSlSourcesFromActions(reconcileActions, job.connectionId),
1752
1576
  ...this.touchedSlSourcesFromPaths(postReconciliationPaths),
1753
- ...finalizationTouchedSources,
1577
+ ...(postProcessorOutcome?.touchedSources ?? []),
1754
1578
  ]);
1755
1579
  const finalWikiGateScope = await this.wikiPageKeysForFinalGates({
1756
1580
  wikiService: this.deps.wikiService.forWorktree(sessionWorktree.workdir),
@@ -1763,7 +1587,7 @@ export class IngestBundleRunner {
1763
1587
  ...projectionTouchedPaths,
1764
1588
  ...workUnitOutcomes.flatMap((outcome) => outcome.patchTouchedPaths ?? []),
1765
1589
  ...postReconciliationPaths,
1766
- ...finalizationTouchedPaths,
1590
+ ...(postProcessorOutcome?.touchedSources ?? []).map((source) => `semantic-layer/${source.connectionId}/${source.sourceName}.yaml`),
1767
1591
  ];
1768
1592
  const targetPolicyTraceData = {
1769
1593
  allowedTargetConnectionIds: slConnectionIds,
@@ -1891,23 +1715,12 @@ export class IngestBundleRunner {
1891
1715
  latestArtifactResolutions = stageIndex.artifactResolutions ?? [];
1892
1716
  latestEvictionInputs = eviction?.deletedRawPaths ?? [];
1893
1717
  latestUnresolvedCards = unresolvedCards ?? [];
1894
- const finalizationProvenance = this.partitionFinalizationActionsForProvenance({
1895
- actions: finalizationActions,
1896
- currentRawPaths: new Set(currentHashes.keys()),
1897
- currentEvictionRawPaths: new Set(stageIndex.evictionsApplied.map((entry) => entry.rawPath)),
1898
- overrideEvictionRawPaths: new Set(overrideReport?.body.evictionInputs ?? []),
1899
- });
1900
- if (finalizationOutcome) {
1901
- finalizationOutcome.provenanceExclusions = finalizationProvenance.exclusions;
1902
- latestFinalizationOutcome = finalizationOutcome;
1903
- }
1904
1718
  const provenancePlan = this.buildProvenancePlan({
1905
1719
  job,
1906
1720
  syncId,
1907
1721
  currentHashes,
1908
1722
  stageIndex,
1909
1723
  reconcileActions,
1910
- finalizationActions: finalizationProvenance.actions,
1911
1724
  });
1912
1725
  const provenanceRows = provenancePlan.rows;
1913
1726
  const currentRawPaths = new Set(currentHashes.keys());
@@ -1956,15 +1769,13 @@ export class IngestBundleRunner {
1956
1769
  commitSha,
1957
1770
  touchedPaths: mergeResult.touchedPaths,
1958
1771
  });
1959
- const memoryFlowSavedActions = stageIndex.workUnits
1960
- .flatMap((wu) => wu.actions)
1961
- .concat(reconcileActions)
1962
- .concat(finalizationActions);
1772
+ const memoryFlowSavedActions = stageIndex.workUnits.flatMap((wu) => wu.actions).concat(reconcileActions);
1773
+ const postProcessorMemoryCounts = postProcessorSavedMemoryCounts(postProcessorOutcome);
1963
1774
  memoryFlow?.emit({
1964
1775
  type: 'saved',
1965
1776
  commitSha,
1966
- wikiCount: countMemoryFlowActions(memoryFlowSavedActions, 'wiki'),
1967
- slCount: countMemoryFlowActions(memoryFlowSavedActions, 'sl'),
1777
+ wikiCount: countMemoryFlowActions(memoryFlowSavedActions, 'wiki') + postProcessorMemoryCounts.wikiCount,
1778
+ slCount: countMemoryFlowActions(memoryFlowSavedActions, 'sl') + postProcessorMemoryCounts.slCount,
1968
1779
  });
1969
1780
  await stage6?.updateProgress(1.0, commitSha ? `Saved changes (${commitSha.slice(0, 8)})` : 'No changes to save');
1970
1781
  // Sync the shared `knowledge` index from the squashed diff in a single
@@ -1981,7 +1792,7 @@ export class IngestBundleRunner {
1981
1792
  ...new Set(memoryFlowSavedActions
1982
1793
  .filter((action) => action.target === 'sl')
1983
1794
  .map((action) => actionTargetConnectionId(action, job.connectionId))
1984
- .concat(finalizationTouchedSources.map((source) => source.connectionId))),
1795
+ .concat((postProcessorOutcome?.touchedSources ?? []).map((source) => source.connectionId))),
1985
1796
  ].sort();
1986
1797
  for (const connectionId of touchedConnections) {
1987
1798
  try {
@@ -2062,7 +1873,7 @@ export class IngestBundleRunner {
2062
1873
  overrideOf: overrideReport?.jobId ?? null,
2063
1874
  provenanceRows: reportProvenanceRows,
2064
1875
  toolTranscripts: reportToolTranscripts,
2065
- finalization: finalizationOutcome,
1876
+ postProcessor: postProcessorOutcome,
2066
1877
  wikiSlRefRepairs: wikiSlRefRepairResult.repairs,
2067
1878
  wikiSlRefRepairWarnings: wikiSlRefRepairResult.warnings,
2068
1879
  ...(reportMemoryFlow ? { memoryFlow: reportMemoryFlow } : {}),
@@ -2220,7 +2031,6 @@ export class IngestBundleRunner {
2220
2031
  artifactResolutions: latestArtifactResolutions,
2221
2032
  evictionInputs: latestEvictionInputs,
2222
2033
  reconciliationActions: latestReconciliationActions,
2223
- finalization: latestFinalizationOutcome,
2224
2034
  evictionDecisions: [],
2225
2035
  unresolvedCards: latestUnresolvedCards,
2226
2036
  supersededBy: null,