@kaelio/ktx 0.1.0-rc.5 → 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 (180) hide show
  1. package/assets/python/kaelio_ktx-0.1.0-py3-none-any.whl +0 -0
  2. package/assets/python/manifest.json +2 -2
  3. package/dist/clack.d.ts +6 -0
  4. package/dist/clack.js +23 -0
  5. package/dist/cli-program.js +5 -2
  6. package/dist/cli-program.test.js +7 -1
  7. package/dist/cli-runtime.d.ts +4 -0
  8. package/dist/cli-runtime.js +8 -1
  9. package/dist/command-schemas.d.ts +1 -1
  10. package/dist/commands/ingest-commands.js +1 -0
  11. package/dist/commands/knowledge-commands.js +5 -0
  12. package/dist/commands/mcp-commands.js +11 -3
  13. package/dist/commands/mcp-commands.test.js +30 -1
  14. package/dist/commands/sql-commands.d.ts +3 -0
  15. package/dist/commands/sql-commands.js +43 -0
  16. package/dist/commands/sql-commands.test.d.ts +1 -0
  17. package/dist/commands/sql-commands.test.js +68 -0
  18. package/dist/context-build-view.js +5 -1
  19. package/dist/dev.test.js +27 -0
  20. package/dist/index.d.ts +1 -0
  21. package/dist/index.js +1 -0
  22. package/dist/index.test.js +56 -21
  23. package/dist/ingest.js +123 -18
  24. package/dist/ingest.test.js +206 -0
  25. package/dist/io/print-list.d.ts +2 -1
  26. package/dist/io/print-list.js +7 -0
  27. package/dist/io/print-list.test.js +13 -11
  28. package/dist/io/symbols.d.ts +2 -2
  29. package/dist/knowledge.d.ts +1 -0
  30. package/dist/knowledge.js +34 -16
  31. package/dist/knowledge.test.js +27 -0
  32. package/dist/managed-python-command.d.ts +2 -0
  33. package/dist/managed-python-command.js +17 -9
  34. package/dist/managed-python-command.test.js +59 -4
  35. package/dist/next-steps.js +1 -1
  36. package/dist/next-steps.test.js +2 -0
  37. package/dist/print-command-tree.js +7 -1
  38. package/dist/public-ingest.d.ts +9 -1
  39. package/dist/public-ingest.js +50 -7
  40. package/dist/public-ingest.test.js +69 -2
  41. package/dist/release-version.d.ts +5 -0
  42. package/dist/release-version.js +44 -0
  43. package/dist/runtime-requirements.d.ts +23 -0
  44. package/dist/runtime-requirements.js +99 -0
  45. package/dist/runtime-requirements.test.d.ts +1 -0
  46. package/dist/runtime-requirements.test.js +63 -0
  47. package/dist/setup-agents.d.ts +11 -3
  48. package/dist/setup-agents.js +397 -134
  49. package/dist/setup-agents.test.js +359 -61
  50. package/dist/setup-embeddings.js +3 -6
  51. package/dist/setup-embeddings.test.js +18 -2
  52. package/dist/setup-models.js +2 -2
  53. package/dist/setup-models.test.js +5 -3
  54. package/dist/setup-ready-menu.d.ts +1 -1
  55. package/dist/setup-ready-menu.js +2 -0
  56. package/dist/setup-ready-menu.test.js +3 -0
  57. package/dist/setup-runtime.d.ts +45 -0
  58. package/dist/setup-runtime.js +47 -0
  59. package/dist/setup-runtime.test.d.ts +1 -0
  60. package/dist/setup-runtime.test.js +110 -0
  61. package/dist/setup-sources-notion.test.d.ts +1 -0
  62. package/dist/setup-sources-notion.test.js +107 -0
  63. package/dist/setup-sources.js +5 -2
  64. package/dist/setup.d.ts +19 -1
  65. package/dist/setup.js +104 -29
  66. package/dist/setup.test.js +221 -57
  67. package/dist/sl.js +2 -2
  68. package/dist/sl.test.js +10 -0
  69. package/dist/source-mapping.js +9 -1
  70. package/dist/source-mapping.test.d.ts +1 -0
  71. package/dist/source-mapping.test.js +65 -0
  72. package/dist/sql.d.ts +22 -0
  73. package/dist/sql.js +125 -0
  74. package/dist/sql.test.d.ts +1 -0
  75. package/dist/sql.test.js +226 -0
  76. package/node_modules/@ktx/connector-clickhouse/dist/package-exports.test.js +1 -1
  77. package/node_modules/@ktx/context/dist/connections/connection-type.d.ts +4 -4
  78. package/node_modules/@ktx/context/dist/core/git.service.d.ts +3 -0
  79. package/node_modules/@ktx/context/dist/core/git.service.js +47 -1
  80. package/node_modules/@ktx/context/dist/core/git.service.patch.test.d.ts +1 -0
  81. package/node_modules/@ktx/context/dist/core/git.service.patch.test.js +40 -0
  82. package/node_modules/@ktx/context/dist/ingest/adapters/historic-sql/types.d.ts +5 -5
  83. package/node_modules/@ktx/context/dist/ingest/adapters/looker/looker.adapter.d.ts +2 -2
  84. package/node_modules/@ktx/context/dist/ingest/adapters/looker/tools/looker-query-to-sl.tool.d.ts +2 -2
  85. package/node_modules/@ktx/context/dist/ingest/adapters/looker/types.d.ts +16 -16
  86. package/node_modules/@ktx/context/dist/ingest/adapters/lookml/pull-config.d.ts +1 -1
  87. package/node_modules/@ktx/context/dist/ingest/adapters/metabase/fetch.js +16 -0
  88. package/node_modules/@ktx/context/dist/ingest/adapters/metabase/fetch.test.js +41 -0
  89. package/node_modules/@ktx/context/dist/ingest/adapters/metricflow/metricflow.adapter.d.ts +2 -1
  90. package/node_modules/@ktx/context/dist/ingest/adapters/metricflow/metricflow.adapter.js +40 -0
  91. package/node_modules/@ktx/context/dist/ingest/adapters/metricflow/metricflow.adapter.test.js +116 -1
  92. package/node_modules/@ktx/context/dist/ingest/adapters/metricflow/projection-config.d.ts +29 -0
  93. package/node_modules/@ktx/context/dist/ingest/adapters/metricflow/projection-config.js +40 -0
  94. package/node_modules/@ktx/context/dist/ingest/adapters/metricflow/pull-config.d.ts +1 -1
  95. package/node_modules/@ktx/context/dist/ingest/artifact-gates.d.ts +25 -0
  96. package/node_modules/@ktx/context/dist/ingest/artifact-gates.js +149 -0
  97. package/node_modules/@ktx/context/dist/ingest/artifact-gates.test.d.ts +1 -0
  98. package/node_modules/@ktx/context/dist/ingest/artifact-gates.test.js +167 -0
  99. package/node_modules/@ktx/context/dist/ingest/final-gate-repair.d.ts +29 -0
  100. package/node_modules/@ktx/context/dist/ingest/final-gate-repair.js +178 -0
  101. package/node_modules/@ktx/context/dist/ingest/final-gate-repair.test.d.ts +1 -0
  102. package/node_modules/@ktx/context/dist/ingest/final-gate-repair.test.js +109 -0
  103. package/node_modules/@ktx/context/dist/ingest/index.d.ts +8 -1
  104. package/node_modules/@ktx/context/dist/ingest/index.js +7 -0
  105. package/node_modules/@ktx/context/dist/ingest/ingest-bundle.runner.d.ts +18 -2
  106. package/node_modules/@ktx/context/dist/ingest/ingest-bundle.runner.isolated-diff.test.d.ts +1 -0
  107. package/node_modules/@ktx/context/dist/ingest/ingest-bundle.runner.isolated-diff.test.js +1761 -0
  108. package/node_modules/@ktx/context/dist/ingest/ingest-bundle.runner.js +1695 -901
  109. package/node_modules/@ktx/context/dist/ingest/ingest-bundle.runner.test.js +135 -118
  110. package/node_modules/@ktx/context/dist/ingest/ingest-trace.d.ts +50 -0
  111. package/node_modules/@ktx/context/dist/ingest/ingest-trace.js +88 -0
  112. package/node_modules/@ktx/context/dist/ingest/ingest-trace.test.d.ts +1 -0
  113. package/node_modules/@ktx/context/dist/ingest/ingest-trace.test.js +76 -0
  114. package/node_modules/@ktx/context/dist/ingest/isolated-diff/git-patch.d.ts +16 -0
  115. package/node_modules/@ktx/context/dist/ingest/isolated-diff/git-patch.js +78 -0
  116. package/node_modules/@ktx/context/dist/ingest/isolated-diff/git-patch.test.d.ts +1 -0
  117. package/node_modules/@ktx/context/dist/ingest/isolated-diff/git-patch.test.js +76 -0
  118. package/node_modules/@ktx/context/dist/ingest/isolated-diff/patch-integrator.d.ts +58 -0
  119. package/node_modules/@ktx/context/dist/ingest/isolated-diff/patch-integrator.js +223 -0
  120. package/node_modules/@ktx/context/dist/ingest/isolated-diff/patch-integrator.test.d.ts +1 -0
  121. package/node_modules/@ktx/context/dist/ingest/isolated-diff/patch-integrator.test.js +369 -0
  122. package/node_modules/@ktx/context/dist/ingest/isolated-diff/textual-conflict-resolver.d.ts +23 -0
  123. package/node_modules/@ktx/context/dist/ingest/isolated-diff/textual-conflict-resolver.js +190 -0
  124. package/node_modules/@ktx/context/dist/ingest/isolated-diff/textual-conflict-resolver.test.d.ts +1 -0
  125. package/node_modules/@ktx/context/dist/ingest/isolated-diff/textual-conflict-resolver.test.js +101 -0
  126. package/node_modules/@ktx/context/dist/ingest/isolated-diff/work-unit-executor.d.ts +15 -0
  127. package/node_modules/@ktx/context/dist/ingest/isolated-diff/work-unit-executor.js +61 -0
  128. package/node_modules/@ktx/context/dist/ingest/isolated-diff/work-unit-executor.test.d.ts +1 -0
  129. package/node_modules/@ktx/context/dist/ingest/isolated-diff/work-unit-executor.test.js +137 -0
  130. package/node_modules/@ktx/context/dist/ingest/local-bundle-ingest.test.js +7 -0
  131. package/node_modules/@ktx/context/dist/ingest/local-bundle-runtime.js +54 -10
  132. package/node_modules/@ktx/context/dist/ingest/local-bundle-runtime.test.js +65 -0
  133. package/node_modules/@ktx/context/dist/ingest/memory-flow/schema.d.ts +23 -5
  134. package/node_modules/@ktx/context/dist/ingest/memory-flow/schema.js +17 -0
  135. package/node_modules/@ktx/context/dist/ingest/memory-flow/schema.test.js +1 -0
  136. package/node_modules/@ktx/context/dist/ingest/memory-flow/types.d.ts +6 -0
  137. package/node_modules/@ktx/context/dist/ingest/parsed-target-table.d.ts +1 -1
  138. package/node_modules/@ktx/context/dist/ingest/ports.d.ts +3 -0
  139. package/node_modules/@ktx/context/dist/ingest/report-snapshot.d.ts +32 -7
  140. package/node_modules/@ktx/context/dist/ingest/report-snapshot.js +25 -0
  141. package/node_modules/@ktx/context/dist/ingest/report-snapshot.test.js +124 -0
  142. package/node_modules/@ktx/context/dist/ingest/reports.d.ts +23 -0
  143. package/node_modules/@ktx/context/dist/ingest/semantic-layer-target-policy.d.ts +11 -0
  144. package/node_modules/@ktx/context/dist/ingest/semantic-layer-target-policy.js +26 -0
  145. package/node_modules/@ktx/context/dist/ingest/semantic-layer-target-policy.test.d.ts +1 -0
  146. package/node_modules/@ktx/context/dist/ingest/semantic-layer-target-policy.test.js +25 -0
  147. package/node_modules/@ktx/context/dist/ingest/stages/stage-3-work-units.d.ts +4 -0
  148. package/node_modules/@ktx/context/dist/ingest/stages/stage-3-work-units.js +4 -0
  149. package/node_modules/@ktx/context/dist/ingest/stages/stage-3-work-units.test.js +29 -0
  150. package/node_modules/@ktx/context/dist/ingest/tools/emit-unmapped-fallback.tool.d.ts +1 -1
  151. package/node_modules/@ktx/context/dist/ingest/types.d.ts +24 -0
  152. package/node_modules/@ktx/context/dist/ingest/wiki-body-refs.d.ts +24 -0
  153. package/node_modules/@ktx/context/dist/ingest/wiki-body-refs.js +111 -0
  154. package/node_modules/@ktx/context/dist/ingest/wiki-body-refs.test.d.ts +1 -0
  155. package/node_modules/@ktx/context/dist/ingest/wiki-body-refs.test.js +138 -0
  156. package/node_modules/@ktx/context/dist/llm/claude-code-runtime.js +19 -2
  157. package/node_modules/@ktx/context/dist/llm/claude-code-runtime.test.js +33 -0
  158. package/node_modules/@ktx/context/dist/project/setup-config.d.ts +1 -1
  159. package/node_modules/@ktx/context/dist/project/setup-config.js +10 -1
  160. package/node_modules/@ktx/context/dist/project/setup-config.test.js +3 -2
  161. package/node_modules/@ktx/context/dist/sl/tools/sl-edit-source.tool.js +5 -1
  162. package/node_modules/@ktx/context/dist/sl/tools/sl-edit-source.tool.test.js +15 -0
  163. package/node_modules/@ktx/context/dist/sl/tools/sl-write-source.tool.js +5 -1
  164. package/node_modules/@ktx/context/dist/sl/tools/sl-write-source.tool.test.js +22 -0
  165. package/node_modules/@ktx/context/dist/tools/action-target-connection.d.ts +9 -0
  166. package/node_modules/@ktx/context/dist/tools/action-target-connection.js +14 -0
  167. package/node_modules/@ktx/context/dist/tools/context-candidate-write.tool.d.ts +4 -4
  168. package/node_modules/@ktx/context/dist/tools/index.d.ts +1 -0
  169. package/node_modules/@ktx/context/dist/tools/index.js +1 -0
  170. package/node_modules/@ktx/context/dist/wiki/local-knowledge.js +4 -1
  171. package/node_modules/@ktx/context/dist/wiki/local-knowledge.test.js +44 -0
  172. package/node_modules/@ktx/context/dist/wiki/tools/wiki-write.tool.js +3 -48
  173. package/node_modules/@ktx/context/dist/wiki/tools/wiki-write.tool.test.js +28 -0
  174. package/node_modules/@ktx/context/dist/wiki/wiki-ref-validation.d.ts +17 -0
  175. package/node_modules/@ktx/context/dist/wiki/wiki-ref-validation.js +79 -0
  176. package/node_modules/@ktx/context/dist/wiki/wiki-ref-validation.test.d.ts +1 -0
  177. package/node_modules/@ktx/context/dist/wiki/wiki-ref-validation.test.js +64 -0
  178. package/node_modules/@ktx/context/prompts/memory_agent_bundle_ingest_work_unit.md +23 -4
  179. package/node_modules/@ktx/context/skills/ingest_triage/SKILL.md +7 -3
  180. package/package.json +4 -4
@@ -0,0 +1,76 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { assertPatchAllowedForWorkUnit, parsePatchTouchedPaths, textArtifactRoots } from './git-patch.js';
3
+ describe('isolated diff patch contract', () => {
4
+ it('parses touched paths from no-rename git patches', () => {
5
+ const patch = [
6
+ 'diff --git a/wiki/global/a.md b/wiki/global/a.md',
7
+ 'index 1111111..2222222 100644',
8
+ '--- a/wiki/global/a.md',
9
+ '+++ b/wiki/global/a.md',
10
+ '@@ -1 +1 @@',
11
+ '-old',
12
+ '+new',
13
+ 'diff --git a/semantic-layer/c1/orders.yaml b/semantic-layer/c1/orders.yaml',
14
+ 'new file mode 100644',
15
+ '--- /dev/null',
16
+ '+++ b/semantic-layer/c1/orders.yaml',
17
+ '@@ -0,0 +1 @@',
18
+ '+name: orders',
19
+ '',
20
+ ].join('\n');
21
+ expect(parsePatchTouchedPaths(patch)).toEqual([
22
+ {
23
+ path: 'wiki/global/a.md',
24
+ oldPath: 'wiki/global/a.md',
25
+ newPath: 'wiki/global/a.md',
26
+ mode: '100644',
27
+ binary: false,
28
+ },
29
+ {
30
+ path: 'semantic-layer/c1/orders.yaml',
31
+ oldPath: 'semantic-layer/c1/orders.yaml',
32
+ newPath: 'semantic-layer/c1/orders.yaml',
33
+ mode: '100644',
34
+ binary: false,
35
+ },
36
+ ]);
37
+ });
38
+ it('rejects semantic-layer paths for slDisallowed work units', () => {
39
+ const patch = 'diff --git a/semantic-layer/c1/orders.yaml b/semantic-layer/c1/orders.yaml\nindex 1..2 100644\n';
40
+ expect(() => assertPatchAllowedForWorkUnit({
41
+ unitKey: 'lookml-mismatch',
42
+ patch,
43
+ slDisallowed: true,
44
+ })).toThrow(/slDisallowed WorkUnit lookml-mismatch touched semantic-layer\/c1\/orders.yaml/);
45
+ });
46
+ it('rejects semantic-layer paths outside allowed target connections', () => {
47
+ const patch = 'diff --git a/semantic-layer/finance/orders.yaml b/semantic-layer/finance/orders.yaml\nindex 1..2 100644\n';
48
+ expect(() => assertPatchAllowedForWorkUnit({
49
+ unitKey: 'wu-finance',
50
+ patch,
51
+ slDisallowed: false,
52
+ allowedTargetConnectionIds: new Set(['warehouse']),
53
+ })).toThrow(/semantic-layer target connection not allowed: semantic-layer\/finance\/orders.yaml \(finance\); allowed: warehouse/);
54
+ });
55
+ it('rejects executable and binary changes under known text artifact roots', () => {
56
+ expect(textArtifactRoots).toEqual(['wiki/', 'semantic-layer/']);
57
+ const executablePatch = 'diff --git a/wiki/global/a.md b/wiki/global/a.md\nold mode 100644\nnew mode 100755\nindex 1..2\n';
58
+ expect(() => assertPatchAllowedForWorkUnit({
59
+ unitKey: 'wu-1',
60
+ patch: executablePatch,
61
+ slDisallowed: false,
62
+ })).toThrow(/unexpected executable mode under wiki\/global\/a.md/);
63
+ const binaryPatch = [
64
+ 'diff --git a/semantic-layer/c1/orders.yaml b/semantic-layer/c1/orders.yaml',
65
+ 'index 1111111..2222222 100644',
66
+ 'GIT binary patch',
67
+ 'literal 0',
68
+ '',
69
+ ].join('\n');
70
+ expect(() => assertPatchAllowedForWorkUnit({
71
+ unitKey: 'wu-2',
72
+ patch: binaryPatch,
73
+ slDisallowed: false,
74
+ })).toThrow(/unexpected binary patch under semantic-layer\/c1\/orders.yaml/);
75
+ });
76
+ });
@@ -0,0 +1,58 @@
1
+ import type { GitService } from '../../core/index.js';
2
+ import type { FinalGateRepairResult } from '../final-gate-repair.js';
3
+ import type { IngestTraceWriter } from '../ingest-trace.js';
4
+ import type { TextualConflictResolutionResult } from './textual-conflict-resolver.js';
5
+ export type PatchIntegrationTextualResolution = {
6
+ status: 'repaired';
7
+ attempts: number;
8
+ changedPaths: string[];
9
+ } | {
10
+ status: 'failed';
11
+ attempts: number;
12
+ reason: string;
13
+ };
14
+ export type PatchIntegrationResult = {
15
+ status: 'accepted';
16
+ commitSha: string;
17
+ touchedPaths: string[];
18
+ textualResolution?: PatchIntegrationTextualResolution;
19
+ gateRepair?: FinalGateRepairResult;
20
+ } | {
21
+ status: 'textual_conflict';
22
+ reason: string;
23
+ touchedPaths: string[];
24
+ textualResolution?: PatchIntegrationTextualResolution;
25
+ gateRepair?: FinalGateRepairResult;
26
+ } | {
27
+ status: 'semantic_conflict';
28
+ reason: string;
29
+ touchedPaths: string[];
30
+ textualResolution?: PatchIntegrationTextualResolution;
31
+ gateRepair?: FinalGateRepairResult;
32
+ };
33
+ export interface IntegrateWorkUnitPatchInput {
34
+ unitKey: string;
35
+ patchPath: string;
36
+ integrationGit: GitService;
37
+ trace: IngestTraceWriter;
38
+ author: {
39
+ name: string;
40
+ email: string;
41
+ };
42
+ slDisallowed: boolean;
43
+ allowedTargetConnectionIds: ReadonlySet<string>;
44
+ validateAppliedTree(touchedPaths: string[]): Promise<void>;
45
+ resolveTextualConflict?(input: {
46
+ unitKey: string;
47
+ patchPath: string;
48
+ touchedPaths: string[];
49
+ reason: string;
50
+ }): Promise<TextualConflictResolutionResult>;
51
+ repairGateFailure?(input: {
52
+ unitKey: string;
53
+ patchPath: string;
54
+ touchedPaths: string[];
55
+ reason: string;
56
+ }): Promise<FinalGateRepairResult>;
57
+ }
58
+ export declare function integrateWorkUnitPatch(input: IntegrateWorkUnitPatchInput): Promise<PatchIntegrationResult>;
@@ -0,0 +1,223 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { traceTimed } from '../ingest-trace.js';
3
+ import { assertPatchAllowedForWorkUnit, parsePatchTouchedPaths } from './git-patch.js';
4
+ function errorMessage(error) {
5
+ return error instanceof Error ? error.message : String(error);
6
+ }
7
+ export async function integrateWorkUnitPatch(input) {
8
+ const preApplyHead = await input.integrationGit.revParseHead();
9
+ const patch = await readFile(input.patchPath, 'utf-8');
10
+ const touchedPaths = parsePatchTouchedPaths(patch).map((entry) => entry.path);
11
+ if (touchedPaths.length === 0) {
12
+ await input.trace.event('debug', 'integration', 'patch_noop_accepted', {
13
+ unitKey: input.unitKey,
14
+ patchPath: input.patchPath,
15
+ patchBytes: Buffer.byteLength(patch),
16
+ });
17
+ return { status: 'accepted', commitSha: preApplyHead ?? '', touchedPaths };
18
+ }
19
+ try {
20
+ assertPatchAllowedForWorkUnit({
21
+ unitKey: input.unitKey,
22
+ patch,
23
+ slDisallowed: input.slDisallowed,
24
+ allowedTargetConnectionIds: input.allowedTargetConnectionIds,
25
+ });
26
+ }
27
+ catch (error) {
28
+ await input.trace.event('error', 'integration', 'patch_policy_rejected', {
29
+ unitKey: input.unitKey,
30
+ patchPath: input.patchPath,
31
+ touchedPaths,
32
+ allowedTargetConnectionIds: [...input.allowedTargetConnectionIds].sort(),
33
+ reason: errorMessage(error),
34
+ });
35
+ return {
36
+ status: 'textual_conflict',
37
+ reason: errorMessage(error),
38
+ touchedPaths,
39
+ };
40
+ }
41
+ try {
42
+ await traceTimed(input.trace, 'integration', 'patch_apply', { unitKey: input.unitKey, patchPath: input.patchPath, touchedPaths }, async () => {
43
+ await input.integrationGit.applyPatchFile3WayIndex(input.patchPath);
44
+ await input.integrationGit.assertWorktreeClean();
45
+ });
46
+ }
47
+ catch (error) {
48
+ if (preApplyHead) {
49
+ await input.integrationGit.resetHardTo(preApplyHead);
50
+ }
51
+ const reason = errorMessage(error);
52
+ await input.trace.event('error', 'integration', 'patch_textual_conflict', {
53
+ unitKey: input.unitKey,
54
+ patchPath: input.patchPath,
55
+ touchedPaths,
56
+ reason,
57
+ });
58
+ if (!input.resolveTextualConflict) {
59
+ return {
60
+ status: 'textual_conflict',
61
+ reason,
62
+ touchedPaths,
63
+ };
64
+ }
65
+ const textualResolution = await input.resolveTextualConflict({
66
+ unitKey: input.unitKey,
67
+ patchPath: input.patchPath,
68
+ touchedPaths,
69
+ reason,
70
+ });
71
+ if (textualResolution.status === 'failed') {
72
+ if (preApplyHead) {
73
+ await input.integrationGit.resetHardTo(preApplyHead);
74
+ }
75
+ return {
76
+ status: 'textual_conflict',
77
+ reason: textualResolution.reason,
78
+ touchedPaths,
79
+ textualResolution,
80
+ };
81
+ }
82
+ try {
83
+ await traceTimed(input.trace, 'integration', 'semantic_gate_after_textual_resolution', { unitKey: input.unitKey, touchedPaths: textualResolution.changedPaths }, async () => {
84
+ await input.validateAppliedTree(textualResolution.changedPaths);
85
+ });
86
+ }
87
+ catch (semanticError) {
88
+ if (preApplyHead) {
89
+ await input.integrationGit.resetHardTo(preApplyHead);
90
+ }
91
+ await input.trace.event('error', 'integration', 'patch_semantic_conflict_after_textual_resolution', {
92
+ unitKey: input.unitKey,
93
+ patchPath: input.patchPath,
94
+ touchedPaths: textualResolution.changedPaths,
95
+ reason: errorMessage(semanticError),
96
+ });
97
+ return {
98
+ status: 'semantic_conflict',
99
+ reason: errorMessage(semanticError),
100
+ touchedPaths: textualResolution.changedPaths,
101
+ textualResolution,
102
+ };
103
+ }
104
+ const commit = await input.integrationGit.commitFiles(textualResolution.changedPaths, `ingest: resolve WorkUnit ${input.unitKey} conflict`, input.author.name, input.author.email);
105
+ if (!commit.created) {
106
+ if (preApplyHead) {
107
+ await input.integrationGit.resetHardTo(preApplyHead);
108
+ }
109
+ const noChangeReason = 'textual resolver produced no committable changes';
110
+ await input.trace.event('error', 'integration', 'textual_conflict_resolver_noop', {
111
+ unitKey: input.unitKey,
112
+ patchPath: input.patchPath,
113
+ touchedPaths: textualResolution.changedPaths,
114
+ });
115
+ return {
116
+ status: 'textual_conflict',
117
+ reason: noChangeReason,
118
+ touchedPaths: textualResolution.changedPaths,
119
+ textualResolution,
120
+ };
121
+ }
122
+ await input.trace.event('debug', 'integration', 'patch_accepted_after_textual_resolution', {
123
+ unitKey: input.unitKey,
124
+ commitSha: commit.commitHash,
125
+ touchedPaths: textualResolution.changedPaths,
126
+ attempts: textualResolution.attempts,
127
+ });
128
+ return {
129
+ status: 'accepted',
130
+ commitSha: commit.commitHash,
131
+ touchedPaths: textualResolution.changedPaths,
132
+ textualResolution,
133
+ };
134
+ }
135
+ try {
136
+ await traceTimed(input.trace, 'integration', 'semantic_gate', { unitKey: input.unitKey, touchedPaths }, async () => {
137
+ await input.validateAppliedTree(touchedPaths);
138
+ });
139
+ }
140
+ catch (error) {
141
+ const reason = errorMessage(error);
142
+ await input.trace.event('error', 'integration', 'patch_semantic_conflict', {
143
+ unitKey: input.unitKey,
144
+ patchPath: input.patchPath,
145
+ touchedPaths,
146
+ reason,
147
+ });
148
+ if (input.repairGateFailure) {
149
+ const gateRepair = await input.repairGateFailure({
150
+ unitKey: input.unitKey,
151
+ patchPath: input.patchPath,
152
+ touchedPaths,
153
+ reason,
154
+ });
155
+ if (gateRepair.status === 'failed') {
156
+ if (preApplyHead) {
157
+ await input.integrationGit.resetHardTo(preApplyHead);
158
+ }
159
+ return {
160
+ status: 'semantic_conflict',
161
+ reason: gateRepair.reason,
162
+ touchedPaths,
163
+ gateRepair,
164
+ };
165
+ }
166
+ try {
167
+ await traceTimed(input.trace, 'integration', 'semantic_gate_after_gate_repair', { unitKey: input.unitKey, touchedPaths: gateRepair.changedPaths }, async () => {
168
+ await input.validateAppliedTree(gateRepair.changedPaths);
169
+ });
170
+ }
171
+ catch (repairValidationError) {
172
+ if (preApplyHead) {
173
+ await input.integrationGit.resetHardTo(preApplyHead);
174
+ }
175
+ return {
176
+ status: 'semantic_conflict',
177
+ reason: errorMessage(repairValidationError),
178
+ touchedPaths: gateRepair.changedPaths,
179
+ gateRepair,
180
+ };
181
+ }
182
+ const commit = await input.integrationGit.commitFiles(gateRepair.changedPaths, `ingest: repair WorkUnit ${input.unitKey} gates`, input.author.name, input.author.email);
183
+ if (!commit.created) {
184
+ if (preApplyHead) {
185
+ await input.integrationGit.resetHardTo(preApplyHead);
186
+ }
187
+ return {
188
+ status: 'semantic_conflict',
189
+ reason: 'gate repair produced no committable changes',
190
+ touchedPaths: gateRepair.changedPaths,
191
+ gateRepair,
192
+ };
193
+ }
194
+ await input.trace.event('debug', 'integration', 'patch_accepted_after_gate_repair', {
195
+ unitKey: input.unitKey,
196
+ commitSha: commit.commitHash,
197
+ touchedPaths: gateRepair.changedPaths,
198
+ attempts: gateRepair.attempts,
199
+ });
200
+ return {
201
+ status: 'accepted',
202
+ commitSha: commit.commitHash,
203
+ touchedPaths: gateRepair.changedPaths,
204
+ gateRepair,
205
+ };
206
+ }
207
+ if (preApplyHead) {
208
+ await input.integrationGit.resetHardTo(preApplyHead);
209
+ }
210
+ return {
211
+ status: 'semantic_conflict',
212
+ reason,
213
+ touchedPaths,
214
+ };
215
+ }
216
+ const commit = await input.integrationGit.commitStaged(`ingest: accept WorkUnit ${input.unitKey}`, input.author.name, input.author.email);
217
+ await input.trace.event('debug', 'integration', 'patch_accepted', {
218
+ unitKey: input.unitKey,
219
+ commitSha: commit.commitHash,
220
+ touchedPaths,
221
+ });
222
+ return { status: 'accepted', commitSha: commit.commitHash, touchedPaths };
223
+ }