@kontextmind/kxm 0.7.39 → 0.7.43

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 (178) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +41 -7
  3. package/docs/README.md +5 -3
  4. package/docs/agent-skills.md +1 -1
  5. package/docs/architecture.md +1 -1
  6. package/docs/configuration.md +28 -5
  7. package/docs/{vnext → contracts}/README.md +7 -7
  8. package/docs/{vnext → contracts}/architecture.md +2 -2
  9. package/docs/{vnext → contracts}/migration.md +25 -25
  10. package/docs/{vnext → contracts}/routing.md +2 -2
  11. package/docs/{vnext → contracts}/synchronization.md +1 -1
  12. package/docs/{vnext → contracts}/validation.md +7 -7
  13. package/docs/getting-started.md +1 -1
  14. package/docs/kb/qa-authentik-authentication.md +47 -0
  15. package/docs/kb/qa-extension-install-and-hub-bootstrap.md +68 -0
  16. package/docs/kb/qa-hub-on-a-public-host.md +31 -0
  17. package/docs/kb/qa-sqlite-vs-duckdb.md +18 -0
  18. package/docs/kb/qa-what-the-hub-stores.md +47 -0
  19. package/docs/packages.md +91 -0
  20. package/docs/templates/architecture.md +1 -1
  21. package/docs/test-matrix.md +6 -6
  22. package/docs/tui-components.md +131 -0
  23. package/examples/README.md +2 -2
  24. package/examples/{vnext → project}/.kxm/agents/critic-3.yaml +1 -1
  25. package/examples/{vnext → project}/README.md +4 -4
  26. package/package.json +18 -8
  27. package/packages/core/tui/CHANGELOG.md +19 -0
  28. package/packages/core/tui/LICENSE +21 -0
  29. package/packages/core/tui/README.md +45 -0
  30. package/packages/core/tui/dist/index.js +1439 -0
  31. package/packages/core/tui/src/adapters/pi.ts +73 -0
  32. package/packages/core/tui/src/adapters/terminal.ts +106 -0
  33. package/packages/core/tui/src/exports/index.ts +30 -0
  34. package/packages/core/tui/src/services/registry.ts +274 -0
  35. package/packages/core/tui/src/tui/keys.ts +130 -0
  36. package/packages/core/tui/src/tui/layout.ts +117 -0
  37. package/packages/core/tui/src/tui/panel.ts +435 -0
  38. package/packages/core/tui/src/tui/panelComponent.ts +208 -0
  39. package/packages/core/tui/src/tui/render.ts +309 -0
  40. package/packages/core/tui/src/tui/theme.ts +145 -0
  41. package/packages/core/tui/src/types/surface.ts +407 -0
  42. package/plugins/kxm/.claude-plugin/plugin.json +1 -1
  43. package/plugins/kxm/dist/cli.js +681 -553
  44. package/plugins/kxm/dist/extension.js +18 -18
  45. package/plugins/kxm/dist/mcp-server.js +1 -1
  46. package/plugins/kxm/dist/{vnext-runtime-supervisor.js → runtime-supervisor.js} +553 -553
  47. package/plugins/kxm/dist/runtime.js +608 -608
  48. package/plugins/kxm/dist/server.js +13 -13
  49. package/plugins/kxm/package.json +2 -2
  50. package/plugins/kxm/skills/kxm-project-setup/SKILL.md +2 -2
  51. package/plugins/kxm/skills/kxm-runs/SKILL.md +3 -3
  52. package/plugins/kxm/skills/kxm-session/SKILL.md +1 -1
  53. package/plugins/kxm/skills/kxm-workflow/SKILL.md +1 -1
  54. package/plugins/kxm/src/autocomplete.ts +4 -4
  55. package/plugins/kxm/src/{vnext-bindings.ts → bindings.ts} +48 -48
  56. package/plugins/kxm/src/cli/hub.ts +3 -3
  57. package/plugins/kxm/src/cli/{vnext.ts → project.ts} +106 -106
  58. package/plugins/kxm/src/cli/roles.ts +9 -9
  59. package/plugins/kxm/src/cli/system.ts +2 -2
  60. package/plugins/kxm/src/cli/tasks.ts +8 -8
  61. package/plugins/kxm/src/cli/workflows.ts +8 -8
  62. package/plugins/kxm/src/cli.ts +47 -47
  63. package/plugins/kxm/src/config.ts +69 -14
  64. package/plugins/kxm/src/database.ts +4 -4
  65. package/plugins/kxm/src/{vnext-engine-artifacts.ts → engine-artifacts.ts} +7 -7
  66. package/plugins/kxm/src/{vnext-engine-command.ts → engine-command.ts} +40 -40
  67. package/plugins/kxm/src/{vnext-engine-compile.ts → engine-compile.ts} +64 -64
  68. package/plugins/kxm/src/{vnext-engine-evidence.ts → engine-evidence.ts} +26 -26
  69. package/plugins/kxm/src/{vnext-engine-fold.ts → engine-fold.ts} +99 -99
  70. package/plugins/kxm/src/{vnext-engine-gate-records.ts → engine-gate-records.ts} +105 -105
  71. package/plugins/kxm/src/{vnext-engine-plan.ts → engine-plan.ts} +69 -69
  72. package/plugins/kxm/src/{vnext-engine.ts → engine.ts} +502 -502
  73. package/plugins/kxm/src/gate-hash.ts +10 -0
  74. package/plugins/kxm/src/{vnext-harness.ts → harness.ts} +1 -1
  75. package/plugins/kxm/src/hub.ts +1 -1
  76. package/plugins/kxm/src/init-guide-setup.ts +3 -3
  77. package/plugins/kxm/src/{vnext-init.ts → init.ts} +93 -93
  78. package/plugins/kxm/src/kxm-install-kind.ts +1 -1
  79. package/plugins/kxm/src/kxm-update-config.ts +2 -2
  80. package/plugins/kxm/src/local-snapshot.ts +23 -23
  81. package/plugins/kxm/src/mcp-server.ts +1 -1
  82. package/plugins/kxm/src/{vnext-migrate.ts → migrate.ts} +123 -123
  83. package/plugins/kxm/src/model-inventory.ts +1 -1
  84. package/plugins/kxm/src/{vnext-oneshot-evidence.ts → oneshot-evidence.ts} +2 -2
  85. package/plugins/kxm/src/{vnext-oneshot-process.ts → oneshot-process.ts} +4 -4
  86. package/plugins/kxm/src/{vnext-oneshot-producer.ts → oneshot-producer.ts} +24 -24
  87. package/plugins/kxm/src/{vnext-permission.ts → permission.ts} +86 -86
  88. package/plugins/kxm/src/{vnext-pi-producer.ts → pi-producer.ts} +13 -13
  89. package/plugins/kxm/src/{vnext-config.ts → project-config.ts} +177 -177
  90. package/plugins/kxm/src/{vnext-repair.ts → repair.ts} +159 -159
  91. package/plugins/kxm/src/restricted-yaml.d.mts +3 -3
  92. package/plugins/kxm/src/restricted-yaml.mjs +4 -4
  93. package/plugins/kxm/src/{vnext-runtime-owner.ts → runtime-owner.ts} +35 -35
  94. package/plugins/kxm/src/{vnext-runtime.ts → runtime-service.ts} +136 -136
  95. package/plugins/kxm/src/{vnext-runtime-store.ts → runtime-store.ts} +145 -145
  96. package/plugins/kxm/src/{vnext-runtime-supervisor.ts → runtime-supervisor.ts} +80 -80
  97. package/plugins/kxm/src/runtime.ts +6 -6
  98. package/plugins/kxm/src/session-work.ts +3 -3
  99. package/plugins/kxm/src/studio-layout.ts +6 -6
  100. package/plugins/kxm/src/{vnext-template.ts → template.ts} +33 -33
  101. package/plugins/kxm/src/tui.ts +10 -24
  102. package/schemas/{vnext/README.md → README.md} +3 -3
  103. package/schemas/{vnext/agent.schema.json → agent.schema.json} +1 -1
  104. package/schemas/{vnext/assignment-result.schema.json → assignment-result.schema.json} +1 -1
  105. package/schemas/{vnext/backup-manifest.schema.json → backup-manifest.schema.json} +1 -1
  106. package/schemas/{vnext/candidate.schema.json → candidate.schema.json} +1 -1
  107. package/schemas/{vnext/common.schema.json → common.schema.json} +2 -2
  108. package/schemas/{vnext/context-candidate.schema.json → context-candidate.schema.json} +1 -1
  109. package/schemas/{vnext/context-packet.schema.json → context-packet.schema.json} +1 -1
  110. package/schemas/{vnext/delivery-manifest.schema.json → delivery-manifest.schema.json} +1 -1
  111. package/schemas/{vnext/drive-receipt.schema.json → drive-receipt.schema.json} +2 -2
  112. package/schemas/{vnext/environment.schema.json → environment.schema.json} +1 -1
  113. package/schemas/{vnext/gate-registry.schema.json → gate-registry.schema.json} +1 -1
  114. package/schemas/{vnext/handoff-manifest.schema.json → handoff-manifest.schema.json} +1 -1
  115. package/schemas/{vnext/init-operation.schema.json → init-operation.schema.json} +1 -1
  116. package/schemas/{vnext/local-repository-bindings.schema.json → local-repository-bindings.schema.json} +1 -1
  117. package/schemas/{vnext/memory-record.schema.json → memory-record.schema.json} +1 -1
  118. package/schemas/{vnext/migration-decision.schema.json → migration-decision.schema.json} +1 -1
  119. package/schemas/{vnext/migration-plan.schema.json → migration-plan.schema.json} +1 -1
  120. package/schemas/{vnext/migration-receipt.schema.json → migration-receipt.schema.json} +1 -1
  121. package/schemas/{vnext/model.schema.json → model.schema.json} +1 -1
  122. package/schemas/{vnext/modes.schema.json → modes.schema.json} +1 -1
  123. package/schemas/{vnext/permission-diff.schema.json → permission-diff.schema.json} +1 -1
  124. package/schemas/policy-draft/README.md +2 -2
  125. package/schemas/{vnext/prices.schema.json → prices.schema.json} +1 -1
  126. package/schemas/{vnext/project.schema.json → project.schema.json} +1 -1
  127. package/schemas/{vnext/repository.schema.json → repository.schema.json} +1 -1
  128. package/schemas/{vnext/role.schema.json → role.schema.json} +1 -1
  129. package/schemas/{vnext/run-event.schema.json → run-event.schema.json} +1 -1
  130. package/schemas/{vnext/session-brief.schema.json → session-brief.schema.json} +2 -2
  131. package/schemas/{vnext/sync-event.schema.json → sync-event.schema.json} +1 -1
  132. package/schemas/{vnext/template-provenance.schema.json → template-provenance.schema.json} +1 -1
  133. package/schemas/{vnext/workflow.schema.json → workflow.schema.json} +1 -1
  134. package/scripts/build-package.mjs +59 -0
  135. package/scripts/build-runtime.mjs +3 -2
  136. package/scripts/check-generated.mjs +2 -1
  137. package/scripts/check-versions.mjs +12 -1
  138. package/scripts/docker-install-smoke.mjs +268 -0
  139. package/scripts/emit-codex-artifacts.mjs +1 -1
  140. package/scripts/kxm-bump-version.mjs +53 -3
  141. package/scripts/kxm-runtime-supervisor.mjs +3 -3
  142. package/scripts/package-surfaces.mjs +39 -0
  143. package/scripts/roster-policy.mjs +1 -1
  144. package/plugins/kxm/src/vnext-gate-hash.ts +0 -10
  145. /package/docs/{vnext → contracts}/effects-and-recovery.md +0 -0
  146. /package/docs/{vnext → contracts}/lifecycles.md +0 -0
  147. /package/docs/{vnext → contracts}/terminology.md +0 -0
  148. /package/examples/{vnext → project}/.kxm/agents/coordinator.yaml +0 -0
  149. /package/examples/{vnext → project}/.kxm/agents/critic-1.yaml +0 -0
  150. /package/examples/{vnext → project}/.kxm/agents/critic-2.yaml +0 -0
  151. /package/examples/{vnext → project}/.kxm/agents/implementer.yaml +0 -0
  152. /package/examples/{vnext → project}/.kxm/agents/planner.yaml +0 -0
  153. /package/examples/{vnext → project}/.kxm/agents/reproducer.yaml +0 -0
  154. /package/examples/{vnext → project}/.kxm/agents/reviewer.yaml +0 -0
  155. /package/examples/{vnext → project}/.kxm/gates.yaml +0 -0
  156. /package/examples/{vnext → project}/.kxm/models/critic-claude.yaml +0 -0
  157. /package/examples/{vnext → project}/.kxm/models/critic-gemini.yaml +0 -0
  158. /package/examples/{vnext → project}/.kxm/models/critic-grok.yaml +0 -0
  159. /package/examples/{vnext → project}/.kxm/models/implementation.yaml +0 -0
  160. /package/examples/{vnext → project}/.kxm/models/primary.yaml +0 -0
  161. /package/examples/{vnext → project}/.kxm/prices.yaml +0 -0
  162. /package/examples/{vnext → project}/.kxm/project/env.yaml +0 -0
  163. /package/examples/{vnext → project}/.kxm/project.yaml +0 -0
  164. /package/examples/{vnext → project}/.kxm/repo/repo.yaml +0 -0
  165. /package/examples/{vnext → project}/.kxm/workflows/default.yaml +0 -0
  166. /package/examples/{vnext → project}/.kxm/workflows/fix.yaml +0 -0
  167. /package/examples/{vnext → project}/.kxm/workflows/improve.yaml +0 -0
  168. /package/examples/{vnext → project}/records/assignment-result-recorded.json +0 -0
  169. /package/examples/{vnext → project}/records/assignment-result.json +0 -0
  170. /package/examples/{vnext → project}/records/context-candidate.json +0 -0
  171. /package/examples/{vnext → project}/records/delivery-manifest.json +0 -0
  172. /package/examples/{vnext → project}/records/effect-uncertainty-resolved-sync.json +0 -0
  173. /package/examples/{vnext → project}/records/effect-uncertainty-resolved.json +0 -0
  174. /package/examples/{vnext → project}/records/run-created.json +0 -0
  175. /package/examples/{vnext → project}/records/sync-event.json +0 -0
  176. /package/examples/{vnext → project}/repositories/api/.kxm/repo/env.yaml +0 -0
  177. /package/examples/{vnext → project}/repositories/api/.kxm/repo/repo.yaml +0 -0
  178. /package/examples/{vnext → project}/repositories/web/.kxm/repo/repo.yaml +0 -0
@@ -16,33 +16,33 @@ import {
16
16
  } from "node:fs";
17
17
  import { dirname, isAbsolute, join, relative, resolve } from "node:path";
18
18
  import {
19
- VnextConfigError,
20
- VnextSchemaRegistry,
21
- loadVnextProject,
19
+ KxmConfigError,
20
+ KxmSchemaRegistry,
21
+ loadKxmProject,
22
22
  assertNoRegisteredGates,
23
23
  parseRestrictedYaml,
24
24
  type JsonObject,
25
- type VnextConfigIssue,
26
- type VnextConfigOptions,
27
- type VnextProjectBundle,
28
- } from "./vnext-config.ts";
25
+ type KxmConfigIssue,
26
+ type KxmConfigOptions,
27
+ type KxmProjectBundle,
28
+ } from "./project-config.ts";
29
29
  import {
30
- CURRENT_VNEXT_TEMPLATE_VARIANT,
31
- VNEXT_TEMPLATE_ID,
32
- VNEXT_TEMPLATE_PROVENANCE_PATH,
33
- renderVnextTemplate,
34
- resolveVnextTemplateBaseline,
35
- SUPPORTED_VNEXT_TEMPLATE_VARIANTS,
36
- vnextContentSha256,
37
- type VnextRenderedTemplate,
38
- type VnextTemplateProvenance,
39
- type VnextTemplateVariant,
40
- } from "./vnext-template.ts";
41
- import { computeVnextResourcePermissionDiff } from "./vnext-permission.ts";
42
- import type { VnextResourceKind } from "./vnext-config.ts";
30
+ CURRENT_KXM_TEMPLATE_VARIANT,
31
+ KXM_TEMPLATE_ID,
32
+ KXM_TEMPLATE_PROVENANCE_PATH,
33
+ renderKxmTemplate,
34
+ resolveKxmTemplateBaseline,
35
+ SUPPORTED_KXM_TEMPLATE_VARIANTS,
36
+ kxmContentSha256,
37
+ type KxmRenderedTemplate,
38
+ type KxmTemplateProvenance,
39
+ type KxmTemplateVariant,
40
+ } from "./template.ts";
41
+ import { computeKxmResourcePermissionDiff } from "./permission.ts";
42
+ import type { KxmResourceKind } from "./project-config.ts";
43
43
 
44
44
  /** Map a managed template path to its resource kind for permission diffing. */
45
- function resourceKindForTemplatePath(path: string): VnextResourceKind {
45
+ function resourceKindForTemplatePath(path: string): KxmResourceKind {
46
46
  if (path === ".kxm/project.yaml") return "project";
47
47
  if (path === ".kxm/gates.yaml") return "gate-registry";
48
48
  if (path.endsWith("repo.yaml")) return "repository";
@@ -58,11 +58,11 @@ const MAX_MANAGED_FILE_BYTES = 256 * 1024;
58
58
  const MAX_MANAGED_TOTAL_BYTES = 8 * 1024 * 1024;
59
59
  const PORTABLE_PATH = /^(?:\.|(?!.*(?:^|\/)\.{1,2}(?:\/|$))(?!.*\/\/)(?!.*[. ](?:\/|$))[^/\\\u0000-\u001F]+(?:\/[^/\\\u0000-\u001F]+)*)$/;
60
60
 
61
- export type VnextTemplateClassification = "unchanged" | "user-only" | "template-only" | "converged" | "conflict";
61
+ export type KxmTemplateClassification = "unchanged" | "user-only" | "template-only" | "converged" | "conflict";
62
62
 
63
- export interface VnextTemplateChange {
63
+ export interface KxmTemplateChange {
64
64
  path: string;
65
- classification: VnextTemplateClassification;
65
+ classification: KxmTemplateClassification;
66
66
  baseSha256?: string;
67
67
  localSha256?: string;
68
68
  targetSha256?: string;
@@ -71,7 +71,7 @@ export interface VnextTemplateChange {
71
71
  reason?: string;
72
72
  }
73
73
 
74
- export interface VnextTemplateRepairPlan {
74
+ export interface KxmTemplateRepairPlan {
75
75
  projectRoot: string;
76
76
  projectId: string;
77
77
  projectName: string;
@@ -79,11 +79,11 @@ export interface VnextTemplateRepairPlan {
79
79
  targetTemplateRevision: string;
80
80
  changesRequired: boolean;
81
81
  canApply: boolean;
82
- changes: readonly VnextTemplateChange[];
83
- issues: readonly VnextConfigIssue[];
82
+ changes: readonly KxmTemplateChange[];
83
+ issues: readonly KxmConfigIssue[];
84
84
  }
85
85
 
86
- interface VnextInitOperationFile {
86
+ interface KxmInitOperationFile {
87
87
  path: string;
88
88
  observedSha256: string | null;
89
89
  targetSha256: string;
@@ -91,7 +91,7 @@ interface VnextInitOperationFile {
91
91
  action: "create" | "replace" | "none";
92
92
  }
93
93
 
94
- interface VnextInitOperation {
94
+ interface KxmInitOperation {
95
95
  schema: "kxm.init-operation.v1";
96
96
  operationId: string;
97
97
  kind: "create" | "repair";
@@ -99,26 +99,26 @@ interface VnextInitOperation {
99
99
  projectRoot: string;
100
100
  projectId: string;
101
101
  projectName: string;
102
- templateId: typeof VNEXT_TEMPLATE_ID;
102
+ templateId: typeof KXM_TEMPLATE_ID;
103
103
  sourceTemplateRevision: string | null;
104
104
  targetTemplateRevision: string;
105
105
  planSha256: string;
106
- files: readonly VnextInitOperationFile[];
106
+ files: readonly KxmInitOperationFile[];
107
107
  }
108
108
 
109
- export interface VnextOperationResult {
109
+ export interface KxmOperationResult {
110
110
  kind: "create" | "repair";
111
111
  resumed: boolean;
112
- bundle: VnextProjectBundle;
112
+ bundle: KxmProjectBundle;
113
113
  files: readonly string[];
114
114
  }
115
115
 
116
- export interface VnextRepairRuntimeOptions {
116
+ export interface KxmRepairRuntimeOptions {
117
117
  schemasDir?: string;
118
118
  repositoryBindings?: Readonly<Record<string, string>>;
119
119
  registeredExecutors?: Iterable<string>;
120
120
  registeredToolPresets?: Iterable<string>;
121
- templateVariant?: VnextTemplateVariant;
121
+ templateVariant?: KxmTemplateVariant;
122
122
  testFaultAt?: "prepared" | "first-resource" | "provenance" | "verified";
123
123
  }
124
124
 
@@ -126,12 +126,12 @@ function compareCodeUnits(left: string, right: string): number {
126
126
  return left < right ? -1 : left > right ? 1 : 0;
127
127
  }
128
128
 
129
- function repairIssue(code: string, file: string, message: string, phase: VnextConfigIssue["phase"] = "semantic"): VnextConfigIssue {
129
+ function repairIssue(code: string, file: string, message: string, phase: KxmConfigIssue["phase"] = "semantic"): KxmConfigIssue {
130
130
  return { phase, code, file, message };
131
131
  }
132
132
 
133
- function fail(code: string, file: string, message: string, phase: VnextConfigIssue["phase"] = "semantic"): never {
134
- throw new VnextConfigError([repairIssue(code, file, message, phase)]);
133
+ function fail(code: string, file: string, message: string, phase: KxmConfigIssue["phase"] = "semantic"): never {
134
+ throw new KxmConfigError([repairIssue(code, file, message, phase)]);
135
135
  }
136
136
 
137
137
  function syncDirectory(path: string): void {
@@ -189,7 +189,7 @@ function transactionRoot(projectRoot: string): string {
189
189
  return join(resolve(projectRoot), TRANSACTION_NAME);
190
190
  }
191
191
 
192
- export function vnextInitTransactionPath(projectRoot: string): string {
192
+ export function kxmInitTransactionPath(projectRoot: string): string {
193
193
  return transactionRoot(projectRoot);
194
194
  }
195
195
 
@@ -211,7 +211,7 @@ function backupFile(projectRoot: string, portablePath: string): string {
211
211
 
212
212
  function portableManagedPath(path: string): boolean {
213
213
  return path.startsWith(".kxm/")
214
- && path !== VNEXT_TEMPLATE_PROVENANCE_PATH
214
+ && path !== KXM_TEMPLATE_PROVENANCE_PATH
215
215
  && path.length <= 1024
216
216
  && !path.includes("\\")
217
217
  && !isAbsolute(path)
@@ -239,81 +239,81 @@ function readOptionalManaged(projectRoot: string, path: string): Buffer | undefi
239
239
  return readRegularBounded(file, path);
240
240
  }
241
241
 
242
- function readProjectAndProvenance(projectRoot: string, schemasDir?: string): { project: JsonObject; provenance: VnextTemplateProvenance; provenanceBytes: Buffer } | undefined {
242
+ function readProjectAndProvenance(projectRoot: string, schemasDir?: string): { project: JsonObject; provenance: KxmTemplateProvenance; provenanceBytes: Buffer } | undefined {
243
243
  const projectFile = join(projectRoot, ".kxm", "project.yaml");
244
- const provenanceFile = join(projectRoot, ...VNEXT_TEMPLATE_PROVENANCE_PATH.split("/"));
244
+ const provenanceFile = join(projectRoot, ...KXM_TEMPLATE_PROVENANCE_PATH.split("/"));
245
245
  if (!existsSync(projectFile) || !existsSync(provenanceFile)) return undefined;
246
246
  const projectBytes = readOptionalManaged(projectRoot, ".kxm/project.yaml");
247
- const provenanceBytes = readOptionalManaged(projectRoot, VNEXT_TEMPLATE_PROVENANCE_PATH);
247
+ const provenanceBytes = readOptionalManaged(projectRoot, KXM_TEMPLATE_PROVENANCE_PATH);
248
248
  if (!projectBytes || !provenanceBytes) return undefined;
249
249
  const project = parseRestrictedYaml(projectBytes, ".kxm/project.yaml");
250
- const provenanceValue = parseRestrictedYaml(provenanceBytes, VNEXT_TEMPLATE_PROVENANCE_PATH);
251
- const registry = new VnextSchemaRegistry(schemasDir);
250
+ const provenanceValue = parseRestrictedYaml(provenanceBytes, KXM_TEMPLATE_PROVENANCE_PATH);
251
+ const registry = new KxmSchemaRegistry(schemasDir);
252
252
  const issues = [
253
253
  ...registry.validate("project", project, ".kxm/project.yaml"),
254
- ...registry.validateTemplateProvenance(provenanceValue, VNEXT_TEMPLATE_PROVENANCE_PATH),
254
+ ...registry.validateTemplateProvenance(provenanceValue, KXM_TEMPLATE_PROVENANCE_PATH),
255
255
  ];
256
- if (issues.length > 0) throw new VnextConfigError(issues);
257
- const provenance = resolveVnextTemplateBaseline(provenanceValue);
258
- if (!provenance) fail("template_provenance_revision_invalid", VNEXT_TEMPLATE_PROVENANCE_PATH, "template provenance does not exactly match a supported built-in baseline");
256
+ if (issues.length > 0) throw new KxmConfigError(issues);
257
+ const provenance = resolveKxmTemplateBaseline(provenanceValue);
258
+ if (!provenance) fail("template_provenance_revision_invalid", KXM_TEMPLATE_PROVENANCE_PATH, "template provenance does not exactly match a supported built-in baseline");
259
259
  if (project.id !== provenance.inputs.projectId) {
260
- fail("template_provenance_project_mismatch", VNEXT_TEMPLATE_PROVENANCE_PATH, "template provenance belongs to a different project identity");
260
+ fail("template_provenance_project_mismatch", KXM_TEMPLATE_PROVENANCE_PATH, "template provenance belongs to a different project identity");
261
261
  }
262
262
  const seen = new Set<string>();
263
263
  let prior = "";
264
264
  let totalBytes = 0;
265
265
  for (const record of provenance.files) {
266
- if (!portableManagedPath(record.path)) fail("template_provenance_path_invalid", VNEXT_TEMPLATE_PROVENANCE_PATH, `managed path ${record.path} is invalid`, "path");
266
+ if (!portableManagedPath(record.path)) fail("template_provenance_path_invalid", KXM_TEMPLATE_PROVENANCE_PATH, `managed path ${record.path} is invalid`, "path");
267
267
  const folded = record.path.toLocaleLowerCase("en-US");
268
- if (seen.has(folded)) fail("template_provenance_path_collision", VNEXT_TEMPLATE_PROVENANCE_PATH, `managed path ${record.path} collides after case folding`, "path");
269
- if (prior && compareCodeUnits(prior, record.path) >= 0) fail("template_provenance_order_invalid", VNEXT_TEMPLATE_PROVENANCE_PATH, "managed files are not in strict code-unit order");
268
+ if (seen.has(folded)) fail("template_provenance_path_collision", KXM_TEMPLATE_PROVENANCE_PATH, `managed path ${record.path} collides after case folding`, "path");
269
+ if (prior && compareCodeUnits(prior, record.path) >= 0) fail("template_provenance_order_invalid", KXM_TEMPLATE_PROVENANCE_PATH, "managed files are not in strict code-unit order");
270
270
  totalBytes += record.bytes;
271
271
  seen.add(folded);
272
272
  prior = record.path;
273
273
  }
274
274
  if (provenance.files.length > MAX_MANAGED_FILES || totalBytes > MAX_MANAGED_TOTAL_BYTES) {
275
- fail("template_provenance_bounds_exceeded", VNEXT_TEMPLATE_PROVENANCE_PATH, "managed template manifest exceeds bounded file or byte limits", "parse");
275
+ fail("template_provenance_bounds_exceeded", KXM_TEMPLATE_PROVENANCE_PATH, "managed template manifest exceeds bounded file or byte limits", "parse");
276
276
  }
277
277
  return { project, provenance, provenanceBytes };
278
278
  }
279
279
 
280
280
  /** Classify exact whole-file B/L/T states without writing or inferring a missing baseline. */
281
- export function planVnextTemplateRepair(
281
+ export function planKxmTemplateRepair(
282
282
  projectRoot: string,
283
- options: VnextRepairRuntimeOptions = {},
284
- ): VnextTemplateRepairPlan | undefined {
283
+ options: KxmRepairRuntimeOptions = {},
284
+ ): KxmTemplateRepairPlan | undefined {
285
285
  assertNoRegisteredGates(options);
286
286
  const root = resolve(projectRoot);
287
287
  const source = readProjectAndProvenance(root, options.schemasDir);
288
288
  if (!source) return undefined;
289
- const target = renderVnextTemplate(
289
+ const target = renderKxmTemplate(
290
290
  source.provenance.inputs.projectId,
291
291
  source.provenance.inputs.projectName,
292
- options.templateVariant ?? CURRENT_VNEXT_TEMPLATE_VARIANT,
292
+ options.templateVariant ?? CURRENT_KXM_TEMPLATE_VARIANT,
293
293
  );
294
294
  const baseByPath = new Map(source.provenance.files.map((record) => [record.path, record]));
295
295
  const targetByPath = new Map(target.provenance.files.map((record) => [record.path, record]));
296
296
  const paths = [...new Set([...baseByPath.keys(), ...targetByPath.keys()])].sort(compareCodeUnits);
297
- const sourceRenderer = SUPPORTED_VNEXT_TEMPLATE_VARIANTS
298
- .map((variant) => renderVnextTemplate(source.provenance.inputs.projectId, source.provenance.inputs.projectName, variant))
297
+ const sourceRenderer = SUPPORTED_KXM_TEMPLATE_VARIANTS
298
+ .map((variant) => renderKxmTemplate(source.provenance.inputs.projectId, source.provenance.inputs.projectName, variant))
299
299
  .find((candidate) => candidate.templateRevision === source.provenance.templateRevision);
300
- const expectedProvenance = sourceRenderer?.files.get(VNEXT_TEMPLATE_PROVENANCE_PATH);
301
- const issues: VnextConfigIssue[] = [];
302
- if (!expectedProvenance || vnextContentSha256(source.provenanceBytes) !== vnextContentSha256(expectedProvenance)) {
300
+ const expectedProvenance = sourceRenderer?.files.get(KXM_TEMPLATE_PROVENANCE_PATH);
301
+ const issues: KxmConfigIssue[] = [];
302
+ if (!expectedProvenance || kxmContentSha256(source.provenanceBytes) !== kxmContentSha256(expectedProvenance)) {
303
303
  issues.push(repairIssue(
304
304
  "template_provenance_user_modified",
305
- VNEXT_TEMPLATE_PROVENANCE_PATH,
305
+ KXM_TEMPLATE_PROVENANCE_PATH,
306
306
  "template provenance formatting or bytes differ from the supported baseline and require review",
307
307
  ));
308
308
  }
309
- const changes = paths.map((path): VnextTemplateChange => {
309
+ const changes = paths.map((path): KxmTemplateChange => {
310
310
  const base = baseByPath.get(path);
311
311
  const targetRecord = targetByPath.get(path);
312
312
  const local = readOptionalManaged(root, path);
313
- const localSha256 = local && vnextContentSha256(local);
313
+ const localSha256 = local && kxmContentSha256(local);
314
314
  const baseSha256 = base?.sha256;
315
315
  if (base && localSha256 === base.sha256 && local?.byteLength !== base.bytes) {
316
- fail("template_provenance_bytes_invalid", VNEXT_TEMPLATE_PROVENANCE_PATH, `recorded byte count for ${path} does not match its baseline content`);
316
+ fail("template_provenance_bytes_invalid", KXM_TEMPLATE_PROVENANCE_PATH, `recorded byte count for ${path} does not match its baseline content`);
317
317
  }
318
318
  const targetSha256 = targetRecord?.sha256;
319
319
  if (baseSha256 === localSha256 && localSha256 === targetSha256) {
@@ -336,7 +336,7 @@ export function planVnextTemplateRepair(
336
336
  const baseValue = base ? sourceRenderer?.values.get(path) : undefined;
337
337
  const targetValue = target.values.get(path);
338
338
  const detail = baseValue && targetValue
339
- ? computeVnextResourcePermissionDiff(resourceKindForTemplatePath(path), path, baseValue, targetValue)
339
+ ? computeKxmResourcePermissionDiff(resourceKindForTemplatePath(path), path, baseValue, targetValue)
340
340
  .map((change) => `${change.path} ${change.field} ${change.direction}`)
341
341
  .join("; ")
342
342
  : "";
@@ -403,8 +403,8 @@ export function planVnextTemplateRepair(
403
403
  };
404
404
  }
405
405
 
406
- function operationPlanSha(operation: Omit<VnextInitOperation, "planSha256" | "phase">): string {
407
- return vnextContentSha256(JSON.stringify({
406
+ function operationPlanSha(operation: Omit<KxmInitOperation, "planSha256" | "phase">): string {
407
+ return kxmContentSha256(JSON.stringify({
408
408
  kind: operation.kind,
409
409
  projectRoot: operation.projectRoot,
410
410
  projectId: operation.projectId,
@@ -416,7 +416,7 @@ function operationPlanSha(operation: Omit<VnextInitOperation, "planSha256" | "ph
416
416
  }));
417
417
  }
418
418
 
419
- function writeOperation(projectRoot: string, operation: VnextInitOperation): void {
419
+ function writeOperation(projectRoot: string, operation: KxmInitOperation): void {
420
420
  const root = transactionRoot(projectRoot);
421
421
  const file = operationFile(projectRoot);
422
422
  const temporary = join(root, `.operation-${operation.operationId}-${randomUUID()}.tmp`);
@@ -429,13 +429,13 @@ function writeOperation(projectRoot: string, operation: VnextInitOperation): voi
429
429
  }
430
430
  }
431
431
 
432
- function updatePhase(projectRoot: string, operation: VnextInitOperation, phase: VnextInitOperation["phase"]): VnextInitOperation {
432
+ function updatePhase(projectRoot: string, operation: KxmInitOperation, phase: KxmInitOperation["phase"]): KxmInitOperation {
433
433
  const updated = { ...operation, phase };
434
434
  writeOperation(projectRoot, updated);
435
435
  return updated;
436
436
  }
437
437
 
438
- function readOperation(projectRoot: string, schemasDir?: string): VnextInitOperation | undefined {
438
+ function readOperation(projectRoot: string, schemasDir?: string): KxmInitOperation | undefined {
439
439
  const root = transactionRoot(projectRoot);
440
440
  if (!existsSync(root)) return undefined;
441
441
  const stat = lstatSync(root);
@@ -448,10 +448,10 @@ function readOperation(projectRoot: string, schemasDir?: string): VnextInitOpera
448
448
  fail("init_transaction_record_missing", TRANSACTION_NAME, "initialization transaction without an operation record contains unrecognized state");
449
449
  }
450
450
  const value = parseRestrictedYaml(readRegularBounded(file, `${TRANSACTION_NAME}/${OPERATION_FILE}`), `${TRANSACTION_NAME}/${OPERATION_FILE}`);
451
- const registry = new VnextSchemaRegistry(schemasDir);
451
+ const registry = new KxmSchemaRegistry(schemasDir);
452
452
  const issues = registry.validateInitOperation(value, `${TRANSACTION_NAME}/${OPERATION_FILE}`);
453
- if (issues.length > 0) throw new VnextConfigError(issues);
454
- const operation = value as unknown as VnextInitOperation;
453
+ if (issues.length > 0) throw new KxmConfigError(issues);
454
+ const operation = value as unknown as KxmInitOperation;
455
455
  if (!sameHostPath(operation.projectRoot, projectRoot)) fail("init_transaction_project_mismatch", TRANSACTION_NAME, "operation belongs to a different project root");
456
456
  const expectedPlanSha = operationPlanSha(operation);
457
457
  if (operation.planSha256 !== expectedPlanSha) fail("init_transaction_plan_hash_invalid", TRANSACTION_NAME, "operation plan hash does not match its immutable intent");
@@ -469,7 +469,7 @@ function readOperation(projectRoot: string, schemasDir?: string): VnextInitOpera
469
469
  return operation;
470
470
  }
471
471
 
472
- export function hasVnextInitTransaction(projectRoot: string): boolean {
472
+ export function hasKxmInitTransaction(projectRoot: string): boolean {
473
473
  return existsSync(transactionRoot(projectRoot));
474
474
  }
475
475
 
@@ -484,12 +484,12 @@ function writeTarget(projectRoot: string, path: string, bytes: Buffer): void {
484
484
  writeDurableNew(file, bytes, 0o600);
485
485
  }
486
486
 
487
- function writeAndVerifyBackups(projectRoot: string, operation: VnextInitOperation): void {
487
+ function writeAndVerifyBackups(projectRoot: string, operation: KxmInitOperation): void {
488
488
  if (operation.kind !== "repair") return;
489
489
  for (const entry of operation.files) {
490
490
  if (entry.observedSha256 === null) continue;
491
491
  const current = readOptionalManaged(projectRoot, entry.path);
492
- if (!current || vnextContentSha256(current) !== entry.observedSha256) {
492
+ if (!current || kxmContentSha256(current) !== entry.observedSha256) {
493
493
  fail("repair_preimage_changed", entry.path, "destination changed before transaction preparation; local bytes were preserved");
494
494
  }
495
495
  const file = backupFile(projectRoot, entry.path);
@@ -498,14 +498,14 @@ function writeAndVerifyBackups(projectRoot: string, operation: VnextInitOperatio
498
498
  }
499
499
  }
500
500
 
501
- function writeKnownBackups(projectRoot: string, operation: VnextInitOperation): void {
501
+ function writeKnownBackups(projectRoot: string, operation: KxmInitOperation): void {
502
502
  if (operation.kind !== "repair" || !operation.sourceTemplateRevision) return;
503
503
  const source = rendererForRevision(operation, operation.sourceTemplateRevision);
504
504
  if (!source) fail("init_transaction_source_unknown", TRANSACTION_NAME, "operation source is not a supported built-in template");
505
505
  for (const entry of operation.files) {
506
506
  if (entry.observedSha256 === null) continue;
507
507
  const bytes = source.files.get(entry.path);
508
- if (!bytes || vnextContentSha256(bytes) !== entry.observedSha256) {
508
+ if (!bytes || kxmContentSha256(bytes) !== entry.observedSha256) {
509
509
  fail("init_transaction_backup_source_invalid", entry.path, "supported source template cannot reproduce the pinned preimage");
510
510
  }
511
511
  const file = backupFile(projectRoot, entry.path);
@@ -514,29 +514,29 @@ function writeKnownBackups(projectRoot: string, operation: VnextInitOperation):
514
514
  }
515
515
  }
516
516
 
517
- function verifyBackups(projectRoot: string, operation: VnextInitOperation): void {
517
+ function verifyBackups(projectRoot: string, operation: KxmInitOperation): void {
518
518
  if (operation.kind !== "repair") return;
519
519
  for (const entry of operation.files) {
520
520
  if (entry.observedSha256 === null) continue;
521
521
  const bytes = readOptionalManaged(join(transactionRoot(projectRoot), "backups"), entry.path);
522
- if (!bytes || vnextContentSha256(bytes) !== entry.observedSha256) {
522
+ if (!bytes || kxmContentSha256(bytes) !== entry.observedSha256) {
523
523
  fail("init_transaction_backup_invalid", entry.path, "pinned preimage backup is missing or corrupt");
524
524
  }
525
525
  }
526
526
  }
527
527
 
528
- function verifyTargetArtifacts(projectRoot: string, operation: VnextInitOperation): void {
528
+ function verifyTargetArtifacts(projectRoot: string, operation: KxmInitOperation): void {
529
529
  let total = 0;
530
530
  for (const entry of operation.files) {
531
531
  const bytes = readTarget(projectRoot, entry.path);
532
532
  if (!bytes) fail("init_transaction_target_missing", entry.path, "pinned target artifact is missing");
533
533
  total += bytes.byteLength;
534
- if (vnextContentSha256(bytes) !== entry.targetSha256) fail("init_transaction_target_mismatch", entry.path, "pinned target artifact hash does not match the operation");
534
+ if (kxmContentSha256(bytes) !== entry.targetSha256) fail("init_transaction_target_mismatch", entry.path, "pinned target artifact hash does not match the operation");
535
535
  }
536
536
  if (operation.files.length > MAX_MANAGED_FILES || total > MAX_MANAGED_TOTAL_BYTES) fail("init_transaction_bounds_exceeded", TRANSACTION_NAME, "operation exceeds bounded file or byte limits", "parse");
537
537
  }
538
538
 
539
- function loaderOptions(options: VnextRepairRuntimeOptions): VnextConfigOptions {
539
+ function loaderOptions(options: KxmRepairRuntimeOptions): KxmConfigOptions {
540
540
  assertNoRegisteredGates(options);
541
541
  return {
542
542
  ...(options.schemasDir === undefined ? {} : { schemasDir: options.schemasDir }),
@@ -550,7 +550,7 @@ function sourceConfigFiles(projectRoot: string): string[] {
550
550
  const fixed = [
551
551
  ".kxm/project.yaml",
552
552
  ".kxm/gates.yaml",
553
- VNEXT_TEMPLATE_PROVENANCE_PATH,
553
+ KXM_TEMPLATE_PROVENANCE_PATH,
554
554
  ".kxm/project/env.yaml",
555
555
  ".kxm/repo/repo.yaml",
556
556
  ".kxm/repo/env.yaml",
@@ -587,7 +587,7 @@ function absoluteMemberBindings(projectRoot: string, project: JsonObject, explic
587
587
  return bindings;
588
588
  }
589
589
 
590
- function prepareShadow(projectRoot: string, operation: VnextInitOperation, options: VnextRepairRuntimeOptions): void {
590
+ function prepareShadow(projectRoot: string, operation: KxmInitOperation, options: KxmRepairRuntimeOptions): void {
591
591
  const shadow = shadowRoot(projectRoot);
592
592
  mkdirSync(shadow, { recursive: true, mode: 0o700 });
593
593
  let total = 0;
@@ -613,20 +613,20 @@ function prepareShadow(projectRoot: string, operation: VnextInitOperation, optio
613
613
  }
614
614
  const project = parseRestrictedYaml(readFileSync(join(shadow, ".kxm", "project.yaml")), ".kxm/project.yaml");
615
615
  const bound = absoluteMemberBindings(projectRoot, project, options.repositoryBindings);
616
- loadVnextProject(shadow, { ...loaderOptions(options), repositoryBindings: bound });
616
+ loadKxmProject(shadow, { ...loaderOptions(options), repositoryBindings: bound });
617
617
  const provenance = readProjectAndProvenance(shadow, options.schemasDir)?.provenance;
618
618
  if (!provenance || provenance.templateRevision !== operation.targetTemplateRevision) {
619
- fail("repair_shadow_provenance_invalid", VNEXT_TEMPLATE_PROVENANCE_PATH, "prospective template provenance does not match the pinned target");
619
+ fail("repair_shadow_provenance_invalid", KXM_TEMPLATE_PROVENANCE_PATH, "prospective template provenance does not match the pinned target");
620
620
  }
621
621
  }
622
622
 
623
623
  function createOperation(
624
624
  projectRoot: string,
625
625
  kind: "create" | "repair",
626
- rendered: VnextRenderedTemplate,
627
- files: readonly VnextInitOperationFile[],
626
+ rendered: KxmRenderedTemplate,
627
+ files: readonly KxmInitOperationFile[],
628
628
  sourceTemplateRevision: string | null,
629
- ): VnextInitOperation {
629
+ ): KxmInitOperation {
630
630
  const root = resolve(projectRoot);
631
631
  const operationWithoutHash = {
632
632
  schema: "kxm.init-operation.v1" as const,
@@ -635,7 +635,7 @@ function createOperation(
635
635
  projectRoot: root,
636
636
  projectId: rendered.projectId,
637
637
  projectName: rendered.projectName,
638
- templateId: VNEXT_TEMPLATE_ID as typeof VNEXT_TEMPLATE_ID,
638
+ templateId: KXM_TEMPLATE_ID as typeof KXM_TEMPLATE_ID,
639
639
  sourceTemplateRevision,
640
640
  targetTemplateRevision: rendered.templateRevision,
641
641
  files: [...files].sort((left, right) => compareCodeUnits(left.path, right.path)),
@@ -647,19 +647,19 @@ function createOperation(
647
647
  };
648
648
  }
649
649
 
650
- function validateOperationRecord(operation: VnextInitOperation, schemasDir?: string): void {
650
+ function validateOperationRecord(operation: KxmInitOperation, schemasDir?: string): void {
651
651
  const label = `${TRANSACTION_NAME}/${OPERATION_FILE}`;
652
652
  const value = parseRestrictedYaml(Buffer.from(JSON.stringify(operation), "utf8"), label);
653
- const issues = new VnextSchemaRegistry(schemasDir).validateInitOperation(value, label);
654
- if (issues.length > 0) throw new VnextConfigError(issues);
653
+ const issues = new KxmSchemaRegistry(schemasDir).validateInitOperation(value, label);
654
+ if (issues.length > 0) throw new KxmConfigError(issues);
655
655
  }
656
656
 
657
657
  function prepareOperation(
658
658
  projectRoot: string,
659
- operation: VnextInitOperation,
660
- rendered: VnextRenderedTemplate,
661
- options: VnextRepairRuntimeOptions,
662
- ): VnextInitOperation {
659
+ operation: KxmInitOperation,
660
+ rendered: KxmRenderedTemplate,
661
+ options: KxmRepairRuntimeOptions,
662
+ ): KxmInitOperation {
663
663
  const transaction = transactionRoot(projectRoot);
664
664
  validateOperationRecord(operation, options.schemasDir);
665
665
  validateOperationIntent(projectRoot, operation);
@@ -670,7 +670,7 @@ function prepareOperation(
670
670
  try {
671
671
  for (const entry of operation.files) {
672
672
  const bytes = rendered.files.get(entry.path);
673
- if (!bytes || vnextContentSha256(bytes) !== entry.targetSha256) fail("template_target_unavailable", entry.path, "renderer cannot reproduce the pinned target bytes");
673
+ if (!bytes || kxmContentSha256(bytes) !== entry.targetSha256) fail("template_target_unavailable", entry.path, "renderer cannot reproduce the pinned target bytes");
674
674
  writeTarget(projectRoot, entry.path, bytes);
675
675
  }
676
676
  writeAndVerifyBackups(projectRoot, operation);
@@ -700,7 +700,7 @@ function ensureDestinationParents(projectRoot: string, path: string): void {
700
700
  function destinationSha(projectRoot: string, path: string): string | undefined {
701
701
  const file = join(projectRoot, ...path.split("/"));
702
702
  if (!existsSync(file)) return undefined;
703
- return vnextContentSha256(readRegularBounded(file, path));
703
+ return kxmContentSha256(readRegularBounded(file, path));
704
704
  }
705
705
 
706
706
  function requireConditionalLinkSupport(directory: string, operationId: string, path: string): void {
@@ -718,17 +718,17 @@ function requireConditionalLinkSupport(directory: string, operationId: string, p
718
718
  }
719
719
  }
720
720
 
721
- function atomicInstallTarget(projectRoot: string, operation: VnextInitOperation, entry: VnextInitOperationFile): void {
721
+ function atomicInstallTarget(projectRoot: string, operation: KxmInitOperation, entry: KxmInitOperationFile): void {
722
722
  const destination = join(projectRoot, ...entry.path.split("/"));
723
723
  ensureDestinationParents(projectRoot, entry.path);
724
724
  const directory = dirname(destination);
725
725
  const temporaryPrefix = `.kxm-repair-${operation.operationId}-`;
726
- const pathKey = vnextContentSha256(entry.path).slice("sha256:".length, "sha256:".length + 16);
726
+ const pathKey = kxmContentSha256(entry.path).slice("sha256:".length, "sha256:".length + 16);
727
727
  const displaced = join(directory, `${temporaryPrefix}${pathKey}.preimage`);
728
728
  if (existsSync(displaced)) {
729
729
  const stat = lstatSync(displaced);
730
730
  if (stat.isSymbolicLink() || !stat.isFile()) fail("repair_preimage_temporary_invalid", entry.path, "stale displaced preimage is not a regular file", "path");
731
- if (entry.observedSha256 === null || vnextContentSha256(readFileSync(displaced)) !== entry.observedSha256) {
731
+ if (entry.observedSha256 === null || kxmContentSha256(readFileSync(displaced)) !== entry.observedSha256) {
732
732
  fail("repair_preimage_temporary_mismatch", entry.path, "stale displaced preimage does not match the pinned operation");
733
733
  }
734
734
  if (!existsSync(destination)) {
@@ -762,7 +762,7 @@ function atomicInstallTarget(projectRoot: string, operation: VnextInitOperation,
762
762
  if (entry.observedSha256 !== null) {
763
763
  renameSync(destination, displaced);
764
764
  syncDirectory(directory);
765
- if (vnextContentSha256(readFileSync(displaced)) !== entry.observedSha256) {
765
+ if (kxmContentSha256(readFileSync(displaced)) !== entry.observedSha256) {
766
766
  if (!existsSync(destination)) {
767
767
  try { linkSync(displaced, destination); }
768
768
  catch { fail("repair_preimage_restore_blocked", entry.path, "changed destination was displaced but could not be conditionally restored; its bytes remain in the operation preimage file"); }
@@ -795,7 +795,7 @@ function atomicInstallTarget(projectRoot: string, operation: VnextInitOperation,
795
795
  if (destinationSha(projectRoot, entry.path) !== entry.targetSha256) fail("repair_install_verification_failed", entry.path, "installed target hash does not match the pinned operation");
796
796
  }
797
797
 
798
- function installedCreateMatches(projectRoot: string, operation: VnextInitOperation): boolean {
798
+ function installedCreateMatches(projectRoot: string, operation: KxmInitOperation): boolean {
799
799
  const configRoot = join(projectRoot, ".kxm");
800
800
  if (!existsSync(configRoot)) return false;
801
801
  const actual: string[] = [];
@@ -833,7 +833,7 @@ function syncTreeDirectories(root: string): void {
833
833
  for (const directory of directories.reverse()) syncDirectory(directory);
834
834
  }
835
835
 
836
- function rebuildCreateShadow(projectRoot: string, operation: VnextInitOperation, options: VnextRepairRuntimeOptions): void {
836
+ function rebuildCreateShadow(projectRoot: string, operation: KxmInitOperation, options: KxmRepairRuntimeOptions): void {
837
837
  const shadow = shadowRoot(projectRoot);
838
838
  rmSync(shadow, { recursive: true, force: true });
839
839
  prepareShadow(projectRoot, operation, options);
@@ -846,10 +846,10 @@ function rebuildCreateShadow(projectRoot: string, operation: VnextInitOperation,
846
846
 
847
847
  function applyOperation(
848
848
  projectRoot: string,
849
- original: VnextInitOperation,
850
- options: VnextRepairRuntimeOptions,
849
+ original: KxmInitOperation,
850
+ options: KxmRepairRuntimeOptions,
851
851
  resumed: boolean,
852
- ): VnextOperationResult {
852
+ ): KxmOperationResult {
853
853
  assertNoRegisteredGates(options);
854
854
  let operation = original;
855
855
  const effectiveOptions = options;
@@ -866,23 +866,23 @@ function applyOperation(
866
866
  fail("create_resume_conflict", ".kxm", "existing project configuration does not match the pinned create operation");
867
867
  }
868
868
  } else {
869
- const resources = operation.files.filter((entry) => entry.path !== VNEXT_TEMPLATE_PROVENANCE_PATH && entry.action !== "none");
869
+ const resources = operation.files.filter((entry) => entry.path !== KXM_TEMPLATE_PROVENANCE_PATH && entry.action !== "none");
870
870
  let installed = 0;
871
871
  for (const entry of resources) {
872
872
  atomicInstallTarget(projectRoot, operation, entry);
873
873
  installed += 1;
874
874
  if (installed === 1 && options.testFaultAt === "first-resource") throw new Error("injected init fault after first resource");
875
875
  }
876
- loadVnextProject(projectRoot, loaderOptions(effectiveOptions));
877
- const provenance = operation.files.find((entry) => entry.path === VNEXT_TEMPLATE_PROVENANCE_PATH);
876
+ loadKxmProject(projectRoot, loaderOptions(effectiveOptions));
877
+ const provenance = operation.files.find((entry) => entry.path === KXM_TEMPLATE_PROVENANCE_PATH);
878
878
  if (!provenance) fail("repair_provenance_target_missing", TRANSACTION_NAME, "repair operation has no final provenance target");
879
879
  atomicInstallTarget(projectRoot, operation, provenance);
880
880
  if (options.testFaultAt === "provenance") throw new Error("injected init fault after provenance");
881
881
  }
882
- const bundle = loadVnextProject(projectRoot, loaderOptions(effectiveOptions));
882
+ const bundle = loadKxmProject(projectRoot, loaderOptions(effectiveOptions));
883
883
  const source = readProjectAndProvenance(projectRoot, effectiveOptions.schemasDir);
884
884
  if (!source || source.provenance.templateRevision !== operation.targetTemplateRevision) {
885
- fail("init_operation_verification_failed", VNEXT_TEMPLATE_PROVENANCE_PATH, "installed provenance does not match the pinned transaction");
885
+ fail("init_operation_verification_failed", KXM_TEMPLATE_PROVENANCE_PATH, "installed provenance does not match the pinned transaction");
886
886
  }
887
887
  operation = updatePhase(projectRoot, operation, "verified");
888
888
  if (options.testFaultAt === "verified") throw new Error("injected init fault after verification");
@@ -891,16 +891,16 @@ function applyOperation(
891
891
  return { kind: operation.kind, resumed, bundle, files };
892
892
  }
893
893
 
894
- export function prepareAndApplyVnextCreate(
894
+ export function prepareAndApplyKxmCreate(
895
895
  projectRoot: string,
896
- rendered: VnextRenderedTemplate,
897
- options: VnextRepairRuntimeOptions = {},
898
- ): VnextOperationResult {
896
+ rendered: KxmRenderedTemplate,
897
+ options: KxmRepairRuntimeOptions = {},
898
+ ): KxmOperationResult {
899
899
  assertNoRegisteredGates(options);
900
- const files = [...rendered.files.entries()].map(([path, bytes]): VnextInitOperationFile => ({
900
+ const files = [...rendered.files.entries()].map(([path, bytes]): KxmInitOperationFile => ({
901
901
  path,
902
902
  observedSha256: null,
903
- targetSha256: vnextContentSha256(bytes),
903
+ targetSha256: kxmContentSha256(bytes),
904
904
  classification: "template-only",
905
905
  action: "create",
906
906
  }));
@@ -910,20 +910,20 @@ export function prepareAndApplyVnextCreate(
910
910
  return applyOperation(projectRoot, prepared, options, false);
911
911
  }
912
912
 
913
- export function prepareAndApplyVnextRepair(
914
- plan: VnextTemplateRepairPlan,
915
- options: VnextRepairRuntimeOptions = {},
916
- ): VnextOperationResult {
913
+ export function prepareAndApplyKxmRepair(
914
+ plan: KxmTemplateRepairPlan,
915
+ options: KxmRepairRuntimeOptions = {},
916
+ ): KxmOperationResult {
917
917
  assertNoRegisteredGates(options);
918
918
  if (!plan.canApply) fail("template_repair_not_applicable", ".kxm", "template repair has conflicts, policy changes, or no safe template-only update");
919
- const rendered = renderVnextTemplate(plan.projectId, plan.projectName, options.templateVariant ?? CURRENT_VNEXT_TEMPLATE_VARIANT);
919
+ const rendered = renderKxmTemplate(plan.projectId, plan.projectName, options.templateVariant ?? CURRENT_KXM_TEMPLATE_VARIANT);
920
920
  if (rendered.templateRevision !== plan.targetTemplateRevision) fail("template_repair_target_changed", ".kxm", "template target changed after planning");
921
921
  const actionable = plan.changes.filter((change) => change.classification === "template-only");
922
- const provenanceBytes = rendered.files.get(VNEXT_TEMPLATE_PROVENANCE_PATH);
923
- if (!provenanceBytes) fail("template_provenance_target_missing", VNEXT_TEMPLATE_PROVENANCE_PATH, "renderer did not produce provenance");
924
- const sourceProvenance = readOptionalManaged(plan.projectRoot, VNEXT_TEMPLATE_PROVENANCE_PATH);
925
- if (!sourceProvenance) fail("template_provenance_missing", VNEXT_TEMPLATE_PROVENANCE_PATH, "repair requires recorded provenance");
926
- const files: VnextInitOperationFile[] = actionable.map((change) => ({
922
+ const provenanceBytes = rendered.files.get(KXM_TEMPLATE_PROVENANCE_PATH);
923
+ if (!provenanceBytes) fail("template_provenance_target_missing", KXM_TEMPLATE_PROVENANCE_PATH, "renderer did not produce provenance");
924
+ const sourceProvenance = readOptionalManaged(plan.projectRoot, KXM_TEMPLATE_PROVENANCE_PATH);
925
+ if (!sourceProvenance) fail("template_provenance_missing", KXM_TEMPLATE_PROVENANCE_PATH, "repair requires recorded provenance");
926
+ const files: KxmInitOperationFile[] = actionable.map((change) => ({
927
927
  path: change.path,
928
928
  observedSha256: change.localSha256 ?? null,
929
929
  targetSha256: change.targetSha256 as string,
@@ -931,9 +931,9 @@ export function prepareAndApplyVnextRepair(
931
931
  action: change.action,
932
932
  }));
933
933
  files.push({
934
- path: VNEXT_TEMPLATE_PROVENANCE_PATH,
935
- observedSha256: vnextContentSha256(sourceProvenance),
936
- targetSha256: vnextContentSha256(provenanceBytes),
934
+ path: KXM_TEMPLATE_PROVENANCE_PATH,
935
+ observedSha256: kxmContentSha256(sourceProvenance),
936
+ targetSha256: kxmContentSha256(provenanceBytes),
937
937
  classification: "template-only",
938
938
  action: "replace",
939
939
  });
@@ -943,20 +943,20 @@ export function prepareAndApplyVnextRepair(
943
943
  return applyOperation(plan.projectRoot, prepared, options, false);
944
944
  }
945
945
 
946
- function rendererForRevision(operation: VnextInitOperation, revision: string): VnextRenderedTemplate | undefined {
947
- for (const variant of SUPPORTED_VNEXT_TEMPLATE_VARIANTS) {
948
- const rendered = renderVnextTemplate(operation.projectId, operation.projectName, variant);
946
+ function rendererForRevision(operation: KxmInitOperation, revision: string): KxmRenderedTemplate | undefined {
947
+ for (const variant of SUPPORTED_KXM_TEMPLATE_VARIANTS) {
948
+ const rendered = renderKxmTemplate(operation.projectId, operation.projectName, variant);
949
949
  if (rendered.templateRevision === revision) return rendered;
950
950
  }
951
951
  return undefined;
952
952
  }
953
953
 
954
- function rendererForOperation(operation: VnextInitOperation): VnextRenderedTemplate | undefined {
954
+ function rendererForOperation(operation: KxmInitOperation): KxmRenderedTemplate | undefined {
955
955
  return rendererForRevision(operation, operation.targetTemplateRevision);
956
956
  }
957
957
 
958
958
  /** Re-derive every executable operation field from immutable built-in templates. */
959
- function validateOperationIntent(projectRoot: string, operation: VnextInitOperation): void {
959
+ function validateOperationIntent(projectRoot: string, operation: KxmInitOperation): void {
960
960
  const target = rendererForOperation(operation);
961
961
  if (!target) fail("init_transaction_target_unknown", TRANSACTION_NAME, "operation target is not a supported built-in template");
962
962
  const entries = new Map(operation.files.map((entry) => [entry.path, entry]));
@@ -969,7 +969,7 @@ function validateOperationIntent(projectRoot: string, operation: VnextInitOperat
969
969
  const entry = entries.get(path);
970
970
  if (!entry
971
971
  || entry.observedSha256 !== null
972
- || entry.targetSha256 !== vnextContentSha256(bytes)
972
+ || entry.targetSha256 !== kxmContentSha256(bytes)
973
973
  || entry.classification !== "template-only"
974
974
  || entry.action !== "create") {
975
975
  fail("init_transaction_create_file_invalid", path, "create operation file does not match its built-in target");
@@ -997,18 +997,18 @@ function validateOperationIntent(projectRoot: string, operation: VnextInitOperat
997
997
  }
998
998
  if (base.sha256 !== next.sha256) safeChangedPaths.push(path);
999
999
  }
1000
- const provenanceEntry = entries.get(VNEXT_TEMPLATE_PROVENANCE_PATH);
1001
- const sourceProvenanceBytes = source.files.get(VNEXT_TEMPLATE_PROVENANCE_PATH) as Buffer;
1002
- const targetProvenanceBytes = target.files.get(VNEXT_TEMPLATE_PROVENANCE_PATH) as Buffer;
1000
+ const provenanceEntry = entries.get(KXM_TEMPLATE_PROVENANCE_PATH);
1001
+ const sourceProvenanceBytes = source.files.get(KXM_TEMPLATE_PROVENANCE_PATH) as Buffer;
1002
+ const targetProvenanceBytes = target.files.get(KXM_TEMPLATE_PROVENANCE_PATH) as Buffer;
1003
1003
  if (!provenanceEntry
1004
- || provenanceEntry.observedSha256 !== vnextContentSha256(sourceProvenanceBytes)
1005
- || provenanceEntry.targetSha256 !== vnextContentSha256(targetProvenanceBytes)
1004
+ || provenanceEntry.observedSha256 !== kxmContentSha256(sourceProvenanceBytes)
1005
+ || provenanceEntry.targetSha256 !== kxmContentSha256(targetProvenanceBytes)
1006
1006
  || provenanceEntry.classification !== "template-only"
1007
1007
  || provenanceEntry.action !== "replace") {
1008
- fail("init_transaction_provenance_intent_invalid", VNEXT_TEMPLATE_PROVENANCE_PATH, "repair provenance action does not match supported source and target templates");
1008
+ fail("init_transaction_provenance_intent_invalid", KXM_TEMPLATE_PROVENANCE_PATH, "repair provenance action does not match supported source and target templates");
1009
1009
  }
1010
1010
  for (const [path, entry] of entries) {
1011
- if (path === VNEXT_TEMPLATE_PROVENANCE_PATH) continue;
1011
+ if (path === KXM_TEMPLATE_PROVENANCE_PATH) continue;
1012
1012
  const base = sourceRecords.get(path);
1013
1013
  const next = targetRecords.get(path);
1014
1014
  if (!base || !next || base.sha256 === next.sha256
@@ -1028,9 +1028,9 @@ function validateOperationIntent(projectRoot: string, operation: VnextInitOperat
1028
1028
 
1029
1029
  function finishPreparingOperation(
1030
1030
  projectRoot: string,
1031
- operation: VnextInitOperation,
1032
- options: VnextRepairRuntimeOptions,
1033
- ): VnextInitOperation {
1031
+ operation: KxmInitOperation,
1032
+ options: KxmRepairRuntimeOptions,
1033
+ ): KxmInitOperation {
1034
1034
  const rendered = rendererForOperation(operation);
1035
1035
  if (!rendered) fail("init_transaction_renderer_unavailable", TRANSACTION_NAME, "this binary cannot reproduce the pinned pre-application target");
1036
1036
  for (const directory of ["targets", "backups", "shadow"]) {
@@ -1038,7 +1038,7 @@ function finishPreparingOperation(
1038
1038
  }
1039
1039
  for (const entry of operation.files) {
1040
1040
  const bytes = rendered.files.get(entry.path);
1041
- if (!bytes || vnextContentSha256(bytes) !== entry.targetSha256) fail("template_target_unavailable", entry.path, "renderer cannot reproduce the pinned target bytes");
1041
+ if (!bytes || kxmContentSha256(bytes) !== entry.targetSha256) fail("template_target_unavailable", entry.path, "renderer cannot reproduce the pinned target bytes");
1042
1042
  writeTarget(projectRoot, entry.path, bytes);
1043
1043
  }
1044
1044
  writeKnownBackups(projectRoot, operation);
@@ -1050,10 +1050,10 @@ function finishPreparingOperation(
1050
1050
  }
1051
1051
 
1052
1052
  /** Resume only a validated fixed transaction; filesystem truth wins over its phase hint. */
1053
- export function resumeVnextInitTransaction(
1053
+ export function resumeKxmInitTransaction(
1054
1054
  projectRoot: string,
1055
- options: VnextRepairRuntimeOptions = {},
1056
- ): VnextOperationResult | undefined {
1055
+ options: KxmRepairRuntimeOptions = {},
1056
+ ): KxmOperationResult | undefined {
1057
1057
  assertNoRegisteredGates(options);
1058
1058
  let operation = readOperation(projectRoot, options.schemasDir);
1059
1059
  if (!operation) {
@@ -1070,7 +1070,7 @@ export function resumeVnextInitTransaction(
1070
1070
  }
1071
1071
 
1072
1072
  /** Remove a verified transaction only after associated local binding intent is durable. */
1073
- export function commitVnextInitTransaction(projectRoot: string, schemasDir?: string): void {
1073
+ export function commitKxmInitTransaction(projectRoot: string, schemasDir?: string): void {
1074
1074
  const operation = readOperation(projectRoot, schemasDir);
1075
1075
  if (!operation || operation.phase !== "verified") {
1076
1076
  fail("init_transaction_not_verified", TRANSACTION_NAME, "initialization transaction cannot commit before installed state is verified");
@@ -1084,7 +1084,7 @@ export function commitVnextInitTransaction(projectRoot: string, schemasDir?: str
1084
1084
  }
1085
1085
 
1086
1086
  /** Validate a pending transaction for dry-run reporting without writing or cleanup. */
1087
- export function inspectVnextInitTransaction(projectRoot: string, schemasDir?: string): VnextInitOperation | undefined {
1087
+ export function inspectKxmInitTransaction(projectRoot: string, schemasDir?: string): KxmInitOperation | undefined {
1088
1088
  const operation = readOperation(projectRoot, schemasDir);
1089
1089
  if (operation && operation.phase !== "preparing") {
1090
1090
  verifyTargetArtifacts(projectRoot, operation);