@kontextmind/kxm 0.7.40 → 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.
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +41 -7
- package/docs/README.md +5 -3
- package/docs/agent-skills.md +1 -1
- package/docs/architecture.md +1 -1
- package/docs/configuration.md +28 -5
- package/docs/{vnext → contracts}/README.md +7 -7
- package/docs/{vnext → contracts}/architecture.md +2 -2
- package/docs/{vnext → contracts}/migration.md +25 -25
- package/docs/{vnext → contracts}/routing.md +2 -2
- package/docs/{vnext → contracts}/synchronization.md +1 -1
- package/docs/{vnext → contracts}/validation.md +7 -7
- package/docs/getting-started.md +1 -1
- package/docs/kb/qa-authentik-authentication.md +47 -0
- package/docs/kb/qa-extension-install-and-hub-bootstrap.md +68 -0
- package/docs/kb/qa-hub-on-a-public-host.md +31 -0
- package/docs/kb/qa-sqlite-vs-duckdb.md +18 -0
- package/docs/kb/qa-what-the-hub-stores.md +47 -0
- package/docs/packages.md +91 -0
- package/docs/templates/architecture.md +1 -1
- package/docs/test-matrix.md +6 -6
- package/docs/tui-components.md +131 -0
- package/examples/README.md +2 -2
- package/examples/{vnext → project}/.kxm/agents/critic-3.yaml +1 -1
- package/examples/{vnext → project}/README.md +4 -4
- package/package.json +18 -8
- package/packages/core/tui/CHANGELOG.md +19 -0
- package/packages/core/tui/LICENSE +21 -0
- package/packages/core/tui/README.md +45 -0
- package/packages/core/tui/dist/index.js +1439 -0
- package/packages/core/tui/src/adapters/pi.ts +73 -0
- package/packages/core/tui/src/adapters/terminal.ts +106 -0
- package/packages/core/tui/src/exports/index.ts +30 -0
- package/packages/core/tui/src/services/registry.ts +274 -0
- package/packages/core/tui/src/tui/keys.ts +130 -0
- package/packages/core/tui/src/tui/layout.ts +117 -0
- package/packages/core/tui/src/tui/panel.ts +435 -0
- package/packages/core/tui/src/tui/panelComponent.ts +208 -0
- package/packages/core/tui/src/tui/render.ts +309 -0
- package/packages/core/tui/src/tui/theme.ts +145 -0
- package/packages/core/tui/src/types/surface.ts +407 -0
- package/plugins/kxm/.claude-plugin/plugin.json +1 -1
- package/plugins/kxm/dist/cli.js +681 -553
- package/plugins/kxm/dist/extension.js +18 -18
- package/plugins/kxm/dist/mcp-server.js +1 -1
- package/plugins/kxm/dist/{vnext-runtime-supervisor.js → runtime-supervisor.js} +553 -553
- package/plugins/kxm/dist/runtime.js +608 -608
- package/plugins/kxm/dist/server.js +13 -13
- package/plugins/kxm/package.json +2 -2
- package/plugins/kxm/skills/kxm-project-setup/SKILL.md +2 -2
- package/plugins/kxm/skills/kxm-runs/SKILL.md +3 -3
- package/plugins/kxm/skills/kxm-session/SKILL.md +1 -1
- package/plugins/kxm/skills/kxm-workflow/SKILL.md +1 -1
- package/plugins/kxm/src/autocomplete.ts +4 -4
- package/plugins/kxm/src/{vnext-bindings.ts → bindings.ts} +48 -48
- package/plugins/kxm/src/cli/hub.ts +3 -3
- package/plugins/kxm/src/cli/{vnext.ts → project.ts} +106 -106
- package/plugins/kxm/src/cli/roles.ts +9 -9
- package/plugins/kxm/src/cli/system.ts +2 -2
- package/plugins/kxm/src/cli/tasks.ts +8 -8
- package/plugins/kxm/src/cli/workflows.ts +8 -8
- package/plugins/kxm/src/cli.ts +47 -47
- package/plugins/kxm/src/config.ts +69 -14
- package/plugins/kxm/src/database.ts +4 -4
- package/plugins/kxm/src/{vnext-engine-artifacts.ts → engine-artifacts.ts} +7 -7
- package/plugins/kxm/src/{vnext-engine-command.ts → engine-command.ts} +40 -40
- package/plugins/kxm/src/{vnext-engine-compile.ts → engine-compile.ts} +64 -64
- package/plugins/kxm/src/{vnext-engine-evidence.ts → engine-evidence.ts} +26 -26
- package/plugins/kxm/src/{vnext-engine-fold.ts → engine-fold.ts} +99 -99
- package/plugins/kxm/src/{vnext-engine-gate-records.ts → engine-gate-records.ts} +105 -105
- package/plugins/kxm/src/{vnext-engine-plan.ts → engine-plan.ts} +69 -69
- package/plugins/kxm/src/{vnext-engine.ts → engine.ts} +502 -502
- package/plugins/kxm/src/gate-hash.ts +10 -0
- package/plugins/kxm/src/{vnext-harness.ts → harness.ts} +1 -1
- package/plugins/kxm/src/hub.ts +1 -1
- package/plugins/kxm/src/init-guide-setup.ts +3 -3
- package/plugins/kxm/src/{vnext-init.ts → init.ts} +93 -93
- package/plugins/kxm/src/kxm-install-kind.ts +1 -1
- package/plugins/kxm/src/kxm-update-config.ts +2 -2
- package/plugins/kxm/src/local-snapshot.ts +23 -23
- package/plugins/kxm/src/mcp-server.ts +1 -1
- package/plugins/kxm/src/{vnext-migrate.ts → migrate.ts} +123 -123
- package/plugins/kxm/src/model-inventory.ts +1 -1
- package/plugins/kxm/src/{vnext-oneshot-evidence.ts → oneshot-evidence.ts} +2 -2
- package/plugins/kxm/src/{vnext-oneshot-process.ts → oneshot-process.ts} +4 -4
- package/plugins/kxm/src/{vnext-oneshot-producer.ts → oneshot-producer.ts} +24 -24
- package/plugins/kxm/src/{vnext-permission.ts → permission.ts} +86 -86
- package/plugins/kxm/src/{vnext-pi-producer.ts → pi-producer.ts} +13 -13
- package/plugins/kxm/src/{vnext-config.ts → project-config.ts} +177 -177
- package/plugins/kxm/src/{vnext-repair.ts → repair.ts} +159 -159
- package/plugins/kxm/src/restricted-yaml.d.mts +3 -3
- package/plugins/kxm/src/restricted-yaml.mjs +4 -4
- package/plugins/kxm/src/{vnext-runtime-owner.ts → runtime-owner.ts} +35 -35
- package/plugins/kxm/src/{vnext-runtime.ts → runtime-service.ts} +136 -136
- package/plugins/kxm/src/{vnext-runtime-store.ts → runtime-store.ts} +145 -145
- package/plugins/kxm/src/{vnext-runtime-supervisor.ts → runtime-supervisor.ts} +80 -80
- package/plugins/kxm/src/runtime.ts +6 -6
- package/plugins/kxm/src/session-work.ts +3 -3
- package/plugins/kxm/src/studio-layout.ts +6 -6
- package/plugins/kxm/src/{vnext-template.ts → template.ts} +33 -33
- package/plugins/kxm/src/tui.ts +10 -24
- package/schemas/{vnext/README.md → README.md} +3 -3
- package/schemas/{vnext/agent.schema.json → agent.schema.json} +1 -1
- package/schemas/{vnext/assignment-result.schema.json → assignment-result.schema.json} +1 -1
- package/schemas/{vnext/backup-manifest.schema.json → backup-manifest.schema.json} +1 -1
- package/schemas/{vnext/candidate.schema.json → candidate.schema.json} +1 -1
- package/schemas/{vnext/common.schema.json → common.schema.json} +2 -2
- package/schemas/{vnext/context-candidate.schema.json → context-candidate.schema.json} +1 -1
- package/schemas/{vnext/context-packet.schema.json → context-packet.schema.json} +1 -1
- package/schemas/{vnext/delivery-manifest.schema.json → delivery-manifest.schema.json} +1 -1
- package/schemas/{vnext/drive-receipt.schema.json → drive-receipt.schema.json} +2 -2
- package/schemas/{vnext/environment.schema.json → environment.schema.json} +1 -1
- package/schemas/{vnext/gate-registry.schema.json → gate-registry.schema.json} +1 -1
- package/schemas/{vnext/handoff-manifest.schema.json → handoff-manifest.schema.json} +1 -1
- package/schemas/{vnext/init-operation.schema.json → init-operation.schema.json} +1 -1
- package/schemas/{vnext/local-repository-bindings.schema.json → local-repository-bindings.schema.json} +1 -1
- package/schemas/{vnext/memory-record.schema.json → memory-record.schema.json} +1 -1
- package/schemas/{vnext/migration-decision.schema.json → migration-decision.schema.json} +1 -1
- package/schemas/{vnext/migration-plan.schema.json → migration-plan.schema.json} +1 -1
- package/schemas/{vnext/migration-receipt.schema.json → migration-receipt.schema.json} +1 -1
- package/schemas/{vnext/model.schema.json → model.schema.json} +1 -1
- package/schemas/{vnext/modes.schema.json → modes.schema.json} +1 -1
- package/schemas/{vnext/permission-diff.schema.json → permission-diff.schema.json} +1 -1
- package/schemas/policy-draft/README.md +2 -2
- package/schemas/{vnext/prices.schema.json → prices.schema.json} +1 -1
- package/schemas/{vnext/project.schema.json → project.schema.json} +1 -1
- package/schemas/{vnext/repository.schema.json → repository.schema.json} +1 -1
- package/schemas/{vnext/role.schema.json → role.schema.json} +1 -1
- package/schemas/{vnext/run-event.schema.json → run-event.schema.json} +1 -1
- package/schemas/{vnext/session-brief.schema.json → session-brief.schema.json} +2 -2
- package/schemas/{vnext/sync-event.schema.json → sync-event.schema.json} +1 -1
- package/schemas/{vnext/template-provenance.schema.json → template-provenance.schema.json} +1 -1
- package/schemas/{vnext/workflow.schema.json → workflow.schema.json} +1 -1
- package/scripts/build-package.mjs +59 -0
- package/scripts/build-runtime.mjs +3 -2
- package/scripts/check-generated.mjs +2 -1
- package/scripts/check-versions.mjs +12 -1
- package/scripts/docker-install-smoke.mjs +268 -0
- package/scripts/emit-codex-artifacts.mjs +1 -1
- package/scripts/kxm-bump-version.mjs +53 -3
- package/scripts/kxm-runtime-supervisor.mjs +3 -3
- package/scripts/package-surfaces.mjs +39 -0
- package/plugins/kxm/src/vnext-gate-hash.ts +0 -10
- /package/docs/{vnext → contracts}/effects-and-recovery.md +0 -0
- /package/docs/{vnext → contracts}/lifecycles.md +0 -0
- /package/docs/{vnext → contracts}/terminology.md +0 -0
- /package/examples/{vnext → project}/.kxm/agents/coordinator.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/agents/critic-1.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/agents/critic-2.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/agents/implementer.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/agents/planner.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/agents/reproducer.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/agents/reviewer.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/gates.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/models/critic-claude.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/models/critic-gemini.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/models/critic-grok.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/models/implementation.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/models/primary.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/prices.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/project/env.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/project.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/repo/repo.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/workflows/default.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/workflows/fix.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/workflows/improve.yaml +0 -0
- /package/examples/{vnext → project}/records/assignment-result-recorded.json +0 -0
- /package/examples/{vnext → project}/records/assignment-result.json +0 -0
- /package/examples/{vnext → project}/records/context-candidate.json +0 -0
- /package/examples/{vnext → project}/records/delivery-manifest.json +0 -0
- /package/examples/{vnext → project}/records/effect-uncertainty-resolved-sync.json +0 -0
- /package/examples/{vnext → project}/records/effect-uncertainty-resolved.json +0 -0
- /package/examples/{vnext → project}/records/run-created.json +0 -0
- /package/examples/{vnext → project}/records/sync-event.json +0 -0
- /package/examples/{vnext → project}/repositories/api/.kxm/repo/env.yaml +0 -0
- /package/examples/{vnext → project}/repositories/api/.kxm/repo/repo.yaml +0 -0
- /package/examples/{vnext → project}/repositories/web/.kxm/repo/repo.yaml +0 -0
|
@@ -14777,12 +14777,12 @@ var require_dist = __commonJS({
|
|
|
14777
14777
|
}
|
|
14778
14778
|
});
|
|
14779
14779
|
|
|
14780
|
-
// plugins/kxm/src/
|
|
14780
|
+
// plugins/kxm/src/runtime-service.ts
|
|
14781
14781
|
import { createHash as createHash6 } from "node:crypto";
|
|
14782
14782
|
import { existsSync as existsSync6, readdirSync as readdirSync3, readFileSync as readFileSync4 } from "node:fs";
|
|
14783
14783
|
import { join as join6 } from "node:path";
|
|
14784
14784
|
|
|
14785
|
-
// plugins/kxm/src/
|
|
14785
|
+
// plugins/kxm/src/project-config.ts
|
|
14786
14786
|
var import__ = __toESM(require__(), 1);
|
|
14787
14787
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
14788
14788
|
import { createHash as createHash2 } from "node:crypto";
|
|
@@ -14791,7 +14791,7 @@ import { basename, dirname as dirname2, extname, isAbsolute, join as join2, rela
|
|
|
14791
14791
|
|
|
14792
14792
|
// plugins/kxm/src/restricted-yaml.mjs
|
|
14793
14793
|
var import_yaml = __toESM(require_dist(), 1);
|
|
14794
|
-
var
|
|
14794
|
+
var KXM_YAML_LIMITS = Object.freeze({
|
|
14795
14795
|
maxDocumentBytes: 256 * 1024,
|
|
14796
14796
|
maxDepth: 32,
|
|
14797
14797
|
maxScalarBytes: 64 * 1024,
|
|
@@ -14862,7 +14862,7 @@ function assertJsonValue(value, label, path = "$", seen = /* @__PURE__ */ new Se
|
|
|
14862
14862
|
}
|
|
14863
14863
|
seen.delete(value);
|
|
14864
14864
|
}
|
|
14865
|
-
function parseRestrictedYaml(input, label = "<yaml>", limits =
|
|
14865
|
+
function parseRestrictedYaml(input, label = "<yaml>", limits = KXM_YAML_LIMITS) {
|
|
14866
14866
|
const byteLength = typeof input === "string" ? Buffer.byteLength(input, "utf8") : input.byteLength;
|
|
14867
14867
|
if (byteLength > limits.maxDocumentBytes) {
|
|
14868
14868
|
fail("parse", "document_too_large", label, `document exceeds ${limits.maxDocumentBytes} bytes`);
|
|
@@ -14914,13 +14914,13 @@ function parseRestrictedYaml(input, label = "<yaml>", limits = VNEXT_YAML_LIMITS
|
|
|
14914
14914
|
return value;
|
|
14915
14915
|
}
|
|
14916
14916
|
|
|
14917
|
-
// plugins/kxm/src/
|
|
14917
|
+
// plugins/kxm/src/template.ts
|
|
14918
14918
|
var import_yaml2 = __toESM(require_dist(), 1);
|
|
14919
14919
|
import { createHash } from "node:crypto";
|
|
14920
|
-
var
|
|
14921
|
-
var
|
|
14922
|
-
var
|
|
14923
|
-
var
|
|
14920
|
+
var KXM_TEMPLATE_ID = "builtin-minimal";
|
|
14921
|
+
var KXM_TEMPLATE_PROVENANCE_PATH = ".kxm/template-provenance.yaml";
|
|
14922
|
+
var CURRENT_KXM_TEMPLATE_VARIANT = "v4-registry";
|
|
14923
|
+
var SUPPORTED_KXM_TEMPLATE_VARIANTS = ["v1", "v2", "v3-policy", "v4-registry"];
|
|
14924
14924
|
function compareCodeUnits2(left, right) {
|
|
14925
14925
|
return left < right ? -1 : left > right ? 1 : 0;
|
|
14926
14926
|
}
|
|
@@ -14931,7 +14931,7 @@ function canonicalJson(value) {
|
|
|
14931
14931
|
if (Array.isArray(value)) return `[${value.map((candidate) => canonicalJson(candidate)).join(",")}]`;
|
|
14932
14932
|
return `{${Object.keys(value).sort(compareCodeUnits2).map((key) => `${JSON.stringify(key)}:${canonicalJson(value[key])}`).join(",")}}`;
|
|
14933
14933
|
}
|
|
14934
|
-
function
|
|
14934
|
+
function kxmContentSha256(input) {
|
|
14935
14935
|
return `sha256:${createHash("sha256").update(input).digest("hex")}`;
|
|
14936
14936
|
}
|
|
14937
14937
|
function authorityProjection(value) {
|
|
@@ -14942,8 +14942,8 @@ function authorityProjection(value) {
|
|
|
14942
14942
|
if (projected.schema === "kxm.workflow.v1") delete projected.description;
|
|
14943
14943
|
return projected;
|
|
14944
14944
|
}
|
|
14945
|
-
function
|
|
14946
|
-
return
|
|
14945
|
+
function kxmAuthoritySha256(value) {
|
|
14946
|
+
return kxmContentSha256(canonicalJson(authorityProjection(value)));
|
|
14947
14947
|
}
|
|
14948
14948
|
function coreTemplate(projectId, projectName, variant) {
|
|
14949
14949
|
const files = /* @__PURE__ */ new Map([
|
|
@@ -15059,14 +15059,14 @@ function coreTemplate(projectId, projectName, variant) {
|
|
|
15059
15059
|
return files;
|
|
15060
15060
|
}
|
|
15061
15061
|
function provenanceRevision(files) {
|
|
15062
|
-
return
|
|
15062
|
+
return kxmContentSha256(canonicalJson(files.map((file) => ({
|
|
15063
15063
|
path: file.path,
|
|
15064
15064
|
sha256: file.sha256,
|
|
15065
15065
|
authoritySha256: file.authoritySha256,
|
|
15066
15066
|
bytes: file.bytes
|
|
15067
15067
|
}))));
|
|
15068
15068
|
}
|
|
15069
|
-
function
|
|
15069
|
+
function renderKxmTemplate(projectId, projectName, variant = CURRENT_KXM_TEMPLATE_VARIANT) {
|
|
15070
15070
|
const values = coreTemplate(projectId, projectName, variant);
|
|
15071
15071
|
const coreFiles = /* @__PURE__ */ new Map();
|
|
15072
15072
|
const records = [...values.entries()].map(([path, value]) => {
|
|
@@ -15074,22 +15074,22 @@ function renderVnextTemplate(projectId, projectName, variant = CURRENT_VNEXT_TEM
|
|
|
15074
15074
|
coreFiles.set(path, bytes);
|
|
15075
15075
|
return {
|
|
15076
15076
|
path,
|
|
15077
|
-
sha256:
|
|
15078
|
-
authoritySha256:
|
|
15077
|
+
sha256: kxmContentSha256(bytes),
|
|
15078
|
+
authoritySha256: kxmAuthoritySha256(value),
|
|
15079
15079
|
bytes: bytes.byteLength
|
|
15080
15080
|
};
|
|
15081
15081
|
}).sort((left, right) => compareCodeUnits2(left.path, right.path));
|
|
15082
15082
|
const templateRevision = provenanceRevision(records);
|
|
15083
15083
|
const provenance = {
|
|
15084
15084
|
schema: "kxm.template-provenance.v1",
|
|
15085
|
-
templateId:
|
|
15085
|
+
templateId: KXM_TEMPLATE_ID,
|
|
15086
15086
|
templateRevision,
|
|
15087
15087
|
inputs: { projectId, projectName },
|
|
15088
15088
|
files: records
|
|
15089
15089
|
};
|
|
15090
15090
|
const fileEntries = [...coreFiles.entries()];
|
|
15091
15091
|
fileEntries.push([
|
|
15092
|
-
|
|
15092
|
+
KXM_TEMPLATE_PROVENANCE_PATH,
|
|
15093
15093
|
Buffer.from((0, import_yaml2.stringify)(provenance, { lineWidth: 0 }), "utf8")
|
|
15094
15094
|
]);
|
|
15095
15095
|
fileEntries.sort(([left], [right]) => compareCodeUnits2(left, right));
|
|
@@ -15097,15 +15097,15 @@ function renderVnextTemplate(projectId, projectName, variant = CURRENT_VNEXT_TEM
|
|
|
15097
15097
|
return { projectId, projectName, templateRevision, provenance, files, values };
|
|
15098
15098
|
}
|
|
15099
15099
|
function validatedTemplateProvenance(value) {
|
|
15100
|
-
if (value.schema !== "kxm.template-provenance.v1" || value.templateId !==
|
|
15100
|
+
if (value.schema !== "kxm.template-provenance.v1" || value.templateId !== KXM_TEMPLATE_ID) return void 0;
|
|
15101
15101
|
const candidate = value;
|
|
15102
15102
|
return provenanceRevision(candidate.files) === candidate.templateRevision ? candidate : void 0;
|
|
15103
15103
|
}
|
|
15104
|
-
function
|
|
15104
|
+
function resolveKxmTemplateBaseline(value) {
|
|
15105
15105
|
const candidate = validatedTemplateProvenance(value);
|
|
15106
15106
|
if (!candidate) return void 0;
|
|
15107
|
-
for (const variant of
|
|
15108
|
-
const known =
|
|
15107
|
+
for (const variant of SUPPORTED_KXM_TEMPLATE_VARIANTS) {
|
|
15108
|
+
const known = renderKxmTemplate(candidate.inputs.projectId, candidate.inputs.projectName, variant).provenance;
|
|
15109
15109
|
if (known.templateRevision === candidate.templateRevision && canonicalJson(known) === canonicalJson(candidate)) {
|
|
15110
15110
|
return candidate;
|
|
15111
15111
|
}
|
|
@@ -15132,12 +15132,12 @@ function findKxmRepoRoot(fromUrl = import.meta.url) {
|
|
|
15132
15132
|
);
|
|
15133
15133
|
}
|
|
15134
15134
|
|
|
15135
|
-
// plugins/kxm/src/
|
|
15135
|
+
// plugins/kxm/src/harness.ts
|
|
15136
15136
|
import { spawnSync } from "node:child_process";
|
|
15137
15137
|
import { existsSync as existsSync2 } from "node:fs";
|
|
15138
15138
|
import { win32 as win32Path } from "node:path";
|
|
15139
15139
|
|
|
15140
|
-
// plugins/kxm/src/
|
|
15140
|
+
// plugins/kxm/src/oneshot-process.ts
|
|
15141
15141
|
import { spawn } from "node:child_process";
|
|
15142
15142
|
var OUTPUT_LIMIT = 8 * 1024 * 1024;
|
|
15143
15143
|
var KILL_GRACE_MS = 250;
|
|
@@ -15290,7 +15290,7 @@ function defaultSpawn(command, args, options) {
|
|
|
15290
15290
|
});
|
|
15291
15291
|
}
|
|
15292
15292
|
|
|
15293
|
-
// plugins/kxm/src/
|
|
15293
|
+
// plugins/kxm/src/harness.ts
|
|
15294
15294
|
var DEFAULT_HARNESS = "pi";
|
|
15295
15295
|
var UNKNOWN_AUTH_HARNESSES = /* @__PURE__ */ new Set(["deepseek"]);
|
|
15296
15296
|
var GROK_LOGIN_LINE = "You are logged in with grok.com.";
|
|
@@ -16356,20 +16356,20 @@ function formatHarnessUpdate(steps) {
|
|
|
16356
16356
|
}).join("\n");
|
|
16357
16357
|
}
|
|
16358
16358
|
|
|
16359
|
-
// plugins/kxm/src/
|
|
16360
|
-
var
|
|
16359
|
+
// plugins/kxm/src/project-config.ts
|
|
16360
|
+
var KxmConfigError = class extends Error {
|
|
16361
16361
|
issues;
|
|
16362
16362
|
constructor(issues) {
|
|
16363
16363
|
const sorted = sortIssues2(issues);
|
|
16364
16364
|
super(sorted.map((issue3) => `${issue3.file}: ${issue3.code}: ${issue3.message}`).join("\n"));
|
|
16365
|
-
this.name = "
|
|
16365
|
+
this.name = "KxmConfigError";
|
|
16366
16366
|
this.issues = sorted;
|
|
16367
16367
|
}
|
|
16368
16368
|
};
|
|
16369
|
-
function
|
|
16370
|
-
return join2(findKxmRepoRoot(import.meta.url), "schemas"
|
|
16369
|
+
function defaultKxmSchemaDir() {
|
|
16370
|
+
return join2(findKxmRepoRoot(import.meta.url), "schemas");
|
|
16371
16371
|
}
|
|
16372
|
-
var DEFAULT_SCHEMA_DIR =
|
|
16372
|
+
var DEFAULT_SCHEMA_DIR = defaultKxmSchemaDir();
|
|
16373
16373
|
var RESOURCE_SCHEMA = Object.freeze({
|
|
16374
16374
|
project: { identity: "kxm.project.v1", file: "project.schema.json" },
|
|
16375
16375
|
repository: { identity: "kxm.repository.v1", file: "repository.schema.json" },
|
|
@@ -16401,16 +16401,16 @@ function issue2(phase, code, file, message) {
|
|
|
16401
16401
|
return { phase, code, file, message };
|
|
16402
16402
|
}
|
|
16403
16403
|
function fail2(phase, code, file, message) {
|
|
16404
|
-
throw new
|
|
16404
|
+
throw new KxmConfigError([issue2(phase, code, file, message)]);
|
|
16405
16405
|
}
|
|
16406
16406
|
function isJsonObject2(value) {
|
|
16407
16407
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
16408
16408
|
}
|
|
16409
|
-
function parseRestrictedYaml2(input, label = "<yaml>", limits =
|
|
16409
|
+
function parseRestrictedYaml2(input, label = "<yaml>", limits = KXM_YAML_LIMITS) {
|
|
16410
16410
|
try {
|
|
16411
16411
|
return parseRestrictedYaml(input, label, limits);
|
|
16412
16412
|
} catch (error) {
|
|
16413
|
-
if (error instanceof RestrictedYamlError) throw new
|
|
16413
|
+
if (error instanceof RestrictedYamlError) throw new KxmConfigError(error.issues);
|
|
16414
16414
|
throw error;
|
|
16415
16415
|
}
|
|
16416
16416
|
}
|
|
@@ -16419,7 +16419,7 @@ function readJsonObject(file) {
|
|
|
16419
16419
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error(`${file} is not a JSON object`);
|
|
16420
16420
|
return parsed;
|
|
16421
16421
|
}
|
|
16422
|
-
var
|
|
16422
|
+
var KxmSchemaRegistry = class {
|
|
16423
16423
|
schemasDir;
|
|
16424
16424
|
ajv;
|
|
16425
16425
|
validators = /* @__PURE__ */ new Map();
|
|
@@ -16459,19 +16459,19 @@ var VnextSchemaRegistry = class {
|
|
|
16459
16459
|
this.ajv.addSchema(readJsonObject(join2(this.schemasDir, runEventFile)));
|
|
16460
16460
|
this.ajv.addSchema(readJsonObject(join2(this.schemasDir, driveReceiptFile)));
|
|
16461
16461
|
for (const [kind, definition] of Object.entries(RESOURCE_SCHEMA)) {
|
|
16462
|
-
const validator = this.ajv.getSchema(`https://schemas.kxm.dev
|
|
16462
|
+
const validator = this.ajv.getSchema(`https://schemas.kxm.dev/${definition.file}`);
|
|
16463
16463
|
if (!validator) throw new Error(`schema did not compile: ${definition.file}`);
|
|
16464
16464
|
this.validators.set(kind, validator);
|
|
16465
16465
|
}
|
|
16466
|
-
const localBindingsValidator = this.ajv.getSchema(`https://schemas.kxm.dev
|
|
16467
|
-
const templateProvenanceValidator = this.ajv.getSchema(`https://schemas.kxm.dev
|
|
16468
|
-
const initOperationValidator = this.ajv.getSchema(`https://schemas.kxm.dev
|
|
16469
|
-
const migrationPlanValidator = this.ajv.getSchema(`https://schemas.kxm.dev
|
|
16470
|
-
const migrationDecisionValidator = this.ajv.getSchema(`https://schemas.kxm.dev
|
|
16471
|
-
const migrationReceiptValidator = this.ajv.getSchema(`https://schemas.kxm.dev
|
|
16472
|
-
const permissionDiffValidator = this.ajv.getSchema(`https://schemas.kxm.dev
|
|
16473
|
-
const runEventValidator = this.ajv.getSchema(`https://schemas.kxm.dev
|
|
16474
|
-
const driveReceiptValidator = this.ajv.getSchema(`https://schemas.kxm.dev
|
|
16466
|
+
const localBindingsValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${localBindingsFile}`);
|
|
16467
|
+
const templateProvenanceValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${templateProvenanceFile}`);
|
|
16468
|
+
const initOperationValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${initOperationFile}`);
|
|
16469
|
+
const migrationPlanValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${migrationPlanFile}`);
|
|
16470
|
+
const migrationDecisionValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${migrationDecisionFile}`);
|
|
16471
|
+
const migrationReceiptValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${migrationReceiptFile}`);
|
|
16472
|
+
const permissionDiffValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${permissionDiffFile}`);
|
|
16473
|
+
const runEventValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${runEventFile}`);
|
|
16474
|
+
const driveReceiptValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${driveReceiptFile}`);
|
|
16475
16475
|
if (!localBindingsValidator) throw new Error(`schema did not compile: ${localBindingsFile}`);
|
|
16476
16476
|
if (!templateProvenanceValidator) throw new Error(`schema did not compile: ${templateProvenanceFile}`);
|
|
16477
16477
|
if (!initOperationValidator) throw new Error(`schema did not compile: ${initOperationFile}`);
|
|
@@ -16497,7 +16497,7 @@ var VnextSchemaRegistry = class {
|
|
|
16497
16497
|
return [issue2("schema", "schema_identity_mismatch", file, `expected ${definition.identity}, received ${String(value.schema)}`)];
|
|
16498
16498
|
}
|
|
16499
16499
|
const validator = this.validators.get(kind);
|
|
16500
|
-
if (!validator) throw new Error(`missing
|
|
16500
|
+
if (!validator) throw new Error(`missing KXM validator for ${kind}`);
|
|
16501
16501
|
if (validator(value)) return [];
|
|
16502
16502
|
return (validator.errors ?? []).map((error) => schemaIssue(file, error));
|
|
16503
16503
|
}
|
|
@@ -16535,9 +16535,9 @@ var VnextSchemaRegistry = class {
|
|
|
16535
16535
|
};
|
|
16536
16536
|
var cachedRunEventRegistry;
|
|
16537
16537
|
function validateRunEvent(value, file) {
|
|
16538
|
-
const registry = cachedRunEventRegistry ??= new
|
|
16538
|
+
const registry = cachedRunEventRegistry ??= new KxmSchemaRegistry();
|
|
16539
16539
|
if (!registry.runEventValidator(value)) {
|
|
16540
|
-
throw new
|
|
16540
|
+
throw new KxmConfigError([issue2(
|
|
16541
16541
|
"schema",
|
|
16542
16542
|
"run_event_invalid",
|
|
16543
16543
|
file,
|
|
@@ -16546,9 +16546,9 @@ function validateRunEvent(value, file) {
|
|
|
16546
16546
|
}
|
|
16547
16547
|
}
|
|
16548
16548
|
function validateDriveReceipt(value, file) {
|
|
16549
|
-
const registry = cachedRunEventRegistry ??= new
|
|
16549
|
+
const registry = cachedRunEventRegistry ??= new KxmSchemaRegistry();
|
|
16550
16550
|
if (!value || typeof value !== "object" || Array.isArray(value) || value.schema !== "kxm.drive-receipt.v1") {
|
|
16551
|
-
throw new
|
|
16551
|
+
throw new KxmConfigError([issue2(
|
|
16552
16552
|
"schema",
|
|
16553
16553
|
"drive_receipt_invalid",
|
|
16554
16554
|
file,
|
|
@@ -16556,7 +16556,7 @@ function validateDriveReceipt(value, file) {
|
|
|
16556
16556
|
)]);
|
|
16557
16557
|
}
|
|
16558
16558
|
if (!registry.driveReceiptValidator(value)) {
|
|
16559
|
-
throw new
|
|
16559
|
+
throw new KxmConfigError([issue2(
|
|
16560
16560
|
"schema",
|
|
16561
16561
|
"drive_receipt_invalid",
|
|
16562
16562
|
file,
|
|
@@ -16606,7 +16606,7 @@ function portableBindingIssue(root, pathHint, repositoryId) {
|
|
|
16606
16606
|
}
|
|
16607
16607
|
return void 0;
|
|
16608
16608
|
}
|
|
16609
|
-
function
|
|
16609
|
+
function kxmPortablePath(path) {
|
|
16610
16610
|
return portablePath(path);
|
|
16611
16611
|
}
|
|
16612
16612
|
function portablePath(path) {
|
|
@@ -16615,11 +16615,11 @@ function portablePath(path) {
|
|
|
16615
16615
|
const segments = path.split("/");
|
|
16616
16616
|
return segments.every((segment) => segment.length > 0 && segment !== "." && segment !== ".." && !WINDOWS_RESERVED.test((segment.split(".")[0] ?? segment).replace(/[ .]+$/g, "")) && !segment.endsWith(".") && !segment.endsWith(" ") && !segment.includes(":"));
|
|
16617
16617
|
}
|
|
16618
|
-
function
|
|
16618
|
+
function kxmResourceIdentifier(id) {
|
|
16619
16619
|
return id.length <= 64 && IDENTIFIER.test(id) && !WINDOWS_RESERVED.test(id);
|
|
16620
16620
|
}
|
|
16621
16621
|
function resourceIdentifier(id) {
|
|
16622
|
-
return
|
|
16622
|
+
return kxmResourceIdentifier(id);
|
|
16623
16623
|
}
|
|
16624
16624
|
function displayPath(root, file) {
|
|
16625
16625
|
const candidate = relative(root, file).replaceAll("\\", "/");
|
|
@@ -16650,7 +16650,7 @@ function readResource(registry, root, file, logicalPath, kind, id, containmentRo
|
|
|
16650
16650
|
if (!stat.isFile()) fail2("path", "resource_not_file", label, "configuration resource must be a regular file");
|
|
16651
16651
|
const value = parseRestrictedYaml2(readFileSync(file), label);
|
|
16652
16652
|
const issues = registry.validate(kind, value, label);
|
|
16653
|
-
if (issues.length > 0) throw new
|
|
16653
|
+
if (issues.length > 0) throw new KxmConfigError(issues);
|
|
16654
16654
|
return { kind, ...id === void 0 ? {} : { id }, file, logicalPath, value };
|
|
16655
16655
|
}
|
|
16656
16656
|
function readTemplateProvenance(registry, root) {
|
|
@@ -16673,8 +16673,8 @@ function readTemplateProvenance(registry, root) {
|
|
|
16673
16673
|
}
|
|
16674
16674
|
const value = parseRestrictedYaml2(readFileSync(file), label);
|
|
16675
16675
|
const issues = registry.validateTemplateProvenance(value, label);
|
|
16676
|
-
if (issues.length > 0) throw new
|
|
16677
|
-
if (!
|
|
16676
|
+
if (issues.length > 0) throw new KxmConfigError(issues);
|
|
16677
|
+
if (!resolveKxmTemplateBaseline(value)) {
|
|
16678
16678
|
fail2("semantic", "template_provenance_revision_invalid", label, "template provenance does not exactly match a supported built-in baseline");
|
|
16679
16679
|
}
|
|
16680
16680
|
const files = Array.isArray(value.files) ? value.files : [];
|
|
@@ -16734,11 +16734,11 @@ function listNamedResources(registry, root, directory, logicalDirectory, kind) {
|
|
|
16734
16734
|
const resource = readResource(registry, root, join2(directory, entry.name), `${logicalDirectory}/${id}.yaml`, kind, id);
|
|
16735
16735
|
resources.set(id, resource);
|
|
16736
16736
|
} catch (error) {
|
|
16737
|
-
if (error instanceof
|
|
16737
|
+
if (error instanceof KxmConfigError) issues.push(...error.issues);
|
|
16738
16738
|
else throw error;
|
|
16739
16739
|
}
|
|
16740
16740
|
}
|
|
16741
|
-
if (issues.length > 0) throw new
|
|
16741
|
+
if (issues.length > 0) throw new KxmConfigError(issues);
|
|
16742
16742
|
return resources;
|
|
16743
16743
|
}
|
|
16744
16744
|
function valuesOf(object, field) {
|
|
@@ -17258,7 +17258,7 @@ function validateBundle(project, repositories, agents, models, workflows, enviro
|
|
|
17258
17258
|
}
|
|
17259
17259
|
}
|
|
17260
17260
|
} catch (error) {
|
|
17261
|
-
if (error instanceof
|
|
17261
|
+
if (error instanceof KxmConfigError) {
|
|
17262
17262
|
issues.push(...error.issues);
|
|
17263
17263
|
}
|
|
17264
17264
|
}
|
|
@@ -17266,13 +17266,13 @@ function validateBundle(project, repositories, agents, models, workflows, enviro
|
|
|
17266
17266
|
}
|
|
17267
17267
|
return sortIssues2(issues);
|
|
17268
17268
|
}
|
|
17269
|
-
function
|
|
17269
|
+
function kxmCanonicalJson(value) {
|
|
17270
17270
|
if (value === null || typeof value !== "object") return JSON.stringify(value);
|
|
17271
|
-
if (Array.isArray(value)) return `[${value.map((candidate) =>
|
|
17272
|
-
return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${
|
|
17271
|
+
if (Array.isArray(value)) return `[${value.map((candidate) => kxmCanonicalJson(candidate)).join(",")}]`;
|
|
17272
|
+
return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${kxmCanonicalJson(value[key])}`).join(",")}}`;
|
|
17273
17273
|
}
|
|
17274
17274
|
function canonicalize(value) {
|
|
17275
|
-
return
|
|
17275
|
+
return kxmCanonicalJson(value);
|
|
17276
17276
|
}
|
|
17277
17277
|
function bundleRevision(resources) {
|
|
17278
17278
|
const hash = createHash2("sha256");
|
|
@@ -17302,19 +17302,19 @@ function discoverGitRoot(start = process.cwd()) {
|
|
|
17302
17302
|
}
|
|
17303
17303
|
function assertNoRegisteredGates(options) {
|
|
17304
17304
|
if ("registeredGates" in options) {
|
|
17305
|
-
throw new
|
|
17305
|
+
throw new KxmConfigError([issue2("semantic", "registered_gates_removed", ".kxm/gates.yaml", "registeredGates was removed; declare gates in .kxm/gates.yaml")]);
|
|
17306
17306
|
}
|
|
17307
17307
|
}
|
|
17308
|
-
function
|
|
17308
|
+
function loadKxmProject(projectRoot, options = {}) {
|
|
17309
17309
|
assertNoRegisteredGates(options);
|
|
17310
17310
|
const root = resolve(projectRoot);
|
|
17311
17311
|
let migrationReceipt;
|
|
17312
17312
|
if (legacyConfigFilesAt(root).length > 0 && options.allowUnreceiptedLegacyConfig !== true) {
|
|
17313
|
-
const receiptCheck =
|
|
17314
|
-
if (receiptCheck.issues.length > 0) throw new
|
|
17313
|
+
const receiptCheck = readKxmMigrationReceipt(root, options);
|
|
17314
|
+
if (receiptCheck.issues.length > 0) throw new KxmConfigError(receiptCheck.issues);
|
|
17315
17315
|
migrationReceipt = receiptCheck.receipt;
|
|
17316
17316
|
}
|
|
17317
|
-
const registry = new
|
|
17317
|
+
const registry = new KxmSchemaRegistry(options.schemasDir);
|
|
17318
17318
|
const project = readResource(registry, root, join2(root, ".kxm", "project.yaml"), ".kxm/project.yaml", "project");
|
|
17319
17319
|
const earlyIssues = [];
|
|
17320
17320
|
validatePortablePaths(project, earlyIssues);
|
|
@@ -17326,7 +17326,7 @@ function loadVnextProject(projectRoot, options = {}) {
|
|
|
17326
17326
|
}
|
|
17327
17327
|
}
|
|
17328
17328
|
if (migrationReceipt && stringValue(migrationReceipt.projectId) !== stringValue(project.value.id)) {
|
|
17329
|
-
earlyIssues.push(issue2("semantic", "migration_project_mismatch",
|
|
17329
|
+
earlyIssues.push(issue2("semantic", "migration_project_mismatch", KXM_MIGRATION_RECEIPT_PATH, "migration receipt belongs to a different project identity"));
|
|
17330
17330
|
}
|
|
17331
17331
|
const declaredRepositoryIds = new Set(valuesOf(project.value, "repositories").map((candidate) => stringValue(objectValue(candidate)?.id)).filter((candidate) => candidate !== void 0));
|
|
17332
17332
|
for (const repositoryId of Object.keys(options.repositoryBindings ?? {}).sort(compareCodeUnits3)) {
|
|
@@ -17336,7 +17336,7 @@ function loadVnextProject(projectRoot, options = {}) {
|
|
|
17336
17336
|
earlyIssues.push(issue2("reference", "repository_binding_unknown", ".kxm/project.yaml", `host-local binding references unknown repository ${repositoryId}`));
|
|
17337
17337
|
}
|
|
17338
17338
|
}
|
|
17339
|
-
if (earlyIssues.length > 0) throw new
|
|
17339
|
+
if (earlyIssues.length > 0) throw new KxmConfigError(earlyIssues);
|
|
17340
17340
|
const agents = listNamedResources(registry, root, join2(root, ".kxm", "agents"), ".kxm/agents", "agent");
|
|
17341
17341
|
const models = listNamedResources(registry, root, join2(root, ".kxm", "models"), ".kxm/models", "model");
|
|
17342
17342
|
const workflows = listNamedResources(registry, root, join2(root, ".kxm", "workflows"), ".kxm/workflows", "workflow");
|
|
@@ -17350,7 +17350,7 @@ function loadVnextProject(projectRoot, options = {}) {
|
|
|
17350
17350
|
try {
|
|
17351
17351
|
environments.push(readResource(registry, root, projectEnvironment, ".kxm/project/env.yaml", "environment"));
|
|
17352
17352
|
} catch (error) {
|
|
17353
|
-
if (error instanceof
|
|
17353
|
+
if (error instanceof KxmConfigError) loadIssues.push(...error.issues);
|
|
17354
17354
|
else throw error;
|
|
17355
17355
|
}
|
|
17356
17356
|
}
|
|
@@ -17423,7 +17423,7 @@ function loadVnextProject(projectRoot, options = {}) {
|
|
|
17423
17423
|
definitionValidated = repositories.get(repositoryId) === resource;
|
|
17424
17424
|
}
|
|
17425
17425
|
} catch (error) {
|
|
17426
|
-
if (error instanceof
|
|
17426
|
+
if (error instanceof KxmConfigError) loadIssues.push(...error.issues);
|
|
17427
17427
|
else throw error;
|
|
17428
17428
|
}
|
|
17429
17429
|
} else if (required || hasLocalBinding) {
|
|
@@ -17437,15 +17437,15 @@ function loadVnextProject(projectRoot, options = {}) {
|
|
|
17437
17437
|
try {
|
|
17438
17438
|
environments.push(readResource(registry, root, environmentFile, `.kxm/repositories/${repositoryId}/env.yaml`, "environment", void 0, binding));
|
|
17439
17439
|
} catch (error) {
|
|
17440
|
-
if (error instanceof
|
|
17440
|
+
if (error instanceof KxmConfigError) loadIssues.push(...error.issues);
|
|
17441
17441
|
else throw error;
|
|
17442
17442
|
}
|
|
17443
17443
|
}
|
|
17444
17444
|
}
|
|
17445
17445
|
}
|
|
17446
|
-
if (loadIssues.length > 0) throw new
|
|
17446
|
+
if (loadIssues.length > 0) throw new KxmConfigError(loadIssues);
|
|
17447
17447
|
const issues = validateBundle(project, repositories, agents, models, workflows, environments, options, gateRegistry, root);
|
|
17448
|
-
if (issues.length > 0) throw new
|
|
17448
|
+
if (issues.length > 0) throw new KxmConfigError(issues);
|
|
17449
17449
|
const resources = [project, ...repositories.values(), ...agents.values(), ...models.values(), ...workflows.values(), ...environments, ...gateRegistry ? [gateRegistry] : []].sort((left, right) => compareCodeUnits3(left.logicalPath, right.logicalPath));
|
|
17450
17450
|
return {
|
|
17451
17451
|
projectRoot: root,
|
|
@@ -17462,7 +17462,7 @@ function loadVnextProject(projectRoot, options = {}) {
|
|
|
17462
17462
|
configRevision: bundleRevision(resources)
|
|
17463
17463
|
};
|
|
17464
17464
|
}
|
|
17465
|
-
var
|
|
17465
|
+
var KXM_MIGRATION_RECEIPT_PATH = ".kxm/migration-receipt.yaml";
|
|
17466
17466
|
var LEGACY_CONFIG_FILES = [".kxm/config/agents.json", ".kxm/config/gates.json"];
|
|
17467
17467
|
function legacyConfigFilesAt(root) {
|
|
17468
17468
|
const files = [];
|
|
@@ -17500,32 +17500,32 @@ function hashFileRecord(root, relativePath) {
|
|
|
17500
17500
|
}
|
|
17501
17501
|
function migrationReceiptSelfHash(receipt) {
|
|
17502
17502
|
const { receiptSha256: _ignored, ...unsigned } = receipt;
|
|
17503
|
-
return `sha256:${createHash2("sha256").update(
|
|
17503
|
+
return `sha256:${createHash2("sha256").update(kxmCanonicalJson(unsigned), "utf8").digest("hex")}`;
|
|
17504
17504
|
}
|
|
17505
|
-
function
|
|
17506
|
-
const receiptPath = join2(root, ...
|
|
17505
|
+
function readKxmMigrationReceipt(root, options = {}) {
|
|
17506
|
+
const receiptPath = join2(root, ...KXM_MIGRATION_RECEIPT_PATH.split("/"));
|
|
17507
17507
|
const legacyFiles = legacyConfigFilesAt(root);
|
|
17508
17508
|
if (!existsSync3(receiptPath)) {
|
|
17509
17509
|
return {
|
|
17510
|
-
issues: legacyFiles.map((file) => issue2("semantic", "
|
|
17510
|
+
issues: legacyFiles.map((file) => issue2("semantic", "legacy_kxm_conflict", file, "legacy and KXM configuration cannot coexist before an accepted migration receipt"))
|
|
17511
17511
|
};
|
|
17512
17512
|
}
|
|
17513
17513
|
const receiptStat = lstatSync(receiptPath);
|
|
17514
17514
|
if (receiptStat.isSymbolicLink() || !receiptStat.isFile()) {
|
|
17515
|
-
return { issues: [issue2("path", "migration_receipt_invalid",
|
|
17515
|
+
return { issues: [issue2("path", "migration_receipt_invalid", KXM_MIGRATION_RECEIPT_PATH, "migration receipt must be a regular file, not a link")] };
|
|
17516
17516
|
}
|
|
17517
17517
|
let receipt;
|
|
17518
17518
|
try {
|
|
17519
|
-
receipt = parseRestrictedYaml2(readFileSync(receiptPath),
|
|
17519
|
+
receipt = parseRestrictedYaml2(readFileSync(receiptPath), KXM_MIGRATION_RECEIPT_PATH);
|
|
17520
17520
|
} catch (error) {
|
|
17521
|
-
if (error instanceof
|
|
17521
|
+
if (error instanceof KxmConfigError) return { issues: [...error.issues] };
|
|
17522
17522
|
throw error;
|
|
17523
17523
|
}
|
|
17524
|
-
const registry = new
|
|
17525
|
-
const schemaIssues = registry.validateMigrationReceipt(receipt,
|
|
17524
|
+
const registry = new KxmSchemaRegistry(options.schemasDir);
|
|
17525
|
+
const schemaIssues = registry.validateMigrationReceipt(receipt, KXM_MIGRATION_RECEIPT_PATH);
|
|
17526
17526
|
if (schemaIssues.length > 0) return { issues: schemaIssues };
|
|
17527
17527
|
if (receipt.receiptSha256 !== migrationReceiptSelfHash(receipt)) {
|
|
17528
|
-
return { issues: [issue2("semantic", "migration_receipt_hash_mismatch",
|
|
17528
|
+
return { issues: [issue2("semantic", "migration_receipt_hash_mismatch", KXM_MIGRATION_RECEIPT_PATH, "receipt self-hash does not match its content")] };
|
|
17529
17529
|
}
|
|
17530
17530
|
const sources = (Array.isArray(receipt.sources) ? receipt.sources : []).map((candidate) => candidate && typeof candidate === "object" && !Array.isArray(candidate) ? candidate.path : void 0).filter((candidate) => typeof candidate === "string").sort(compareCodeUnits3);
|
|
17531
17531
|
const issues = [];
|
|
@@ -17549,12 +17549,12 @@ function readVnextMigrationReceipt(root, options = {}) {
|
|
|
17549
17549
|
return issues.length > 0 ? { issues } : { receipt, issues: [] };
|
|
17550
17550
|
}
|
|
17551
17551
|
|
|
17552
|
-
// plugins/kxm/src/
|
|
17552
|
+
// plugins/kxm/src/runtime-store.ts
|
|
17553
17553
|
import { createHash as createHash4, randomUUID } from "node:crypto";
|
|
17554
17554
|
import { existsSync as existsSync5, lstatSync as lstatSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, realpathSync as realpathSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
17555
17555
|
import { dirname as dirname5, join as join5, resolve as resolve4 } from "node:path";
|
|
17556
17556
|
|
|
17557
|
-
// plugins/kxm/src/
|
|
17557
|
+
// plugins/kxm/src/bindings.ts
|
|
17558
17558
|
import { homedir } from "node:os";
|
|
17559
17559
|
|
|
17560
17560
|
// plugins/kxm/src/sqlite.ts
|
|
@@ -17596,7 +17596,7 @@ var DatabaseSync = class {
|
|
|
17596
17596
|
}
|
|
17597
17597
|
};
|
|
17598
17598
|
|
|
17599
|
-
// plugins/kxm/src/
|
|
17599
|
+
// plugins/kxm/src/bindings.ts
|
|
17600
17600
|
import { dirname as dirname3, isAbsolute as isAbsolute2, join as join3, parse, relative as relative2, resolve as resolve2, sep as sep2 } from "node:path";
|
|
17601
17601
|
var MAX_BINDING_RECORD_BYTES = 256 * 1024;
|
|
17602
17602
|
var BINDING_LABEL = "Runtime-local repository bindings";
|
|
@@ -17604,9 +17604,9 @@ function bindingIssue(phase, code, message) {
|
|
|
17604
17604
|
return { phase, code, file: BINDING_LABEL, message };
|
|
17605
17605
|
}
|
|
17606
17606
|
function bindingError(phase, code, message) {
|
|
17607
|
-
throw new
|
|
17607
|
+
throw new KxmConfigError([bindingIssue(phase, code, message)]);
|
|
17608
17608
|
}
|
|
17609
|
-
function
|
|
17609
|
+
function kxmUserStateRoot(options = {}) {
|
|
17610
17610
|
const env = options.env ?? process.env;
|
|
17611
17611
|
const platform = options.platform ?? process.platform;
|
|
17612
17612
|
const home = options.homeDir ?? homedir();
|
|
@@ -17642,7 +17642,7 @@ import {
|
|
|
17642
17642
|
import { basename as basename2, dirname as dirname4, join as join4, resolve as resolve3 } from "node:path";
|
|
17643
17643
|
function databaseError(code, file, message) {
|
|
17644
17644
|
const issue3 = { phase: "semantic", code, file, message };
|
|
17645
|
-
return new
|
|
17645
|
+
return new KxmConfigError([issue3]);
|
|
17646
17646
|
}
|
|
17647
17647
|
function checkedParent(path, description) {
|
|
17648
17648
|
const parent = dirname4(path);
|
|
@@ -18065,9 +18065,9 @@ function restoreBackup(manifestPathOrDir, options = {}) {
|
|
|
18065
18065
|
};
|
|
18066
18066
|
}
|
|
18067
18067
|
|
|
18068
|
-
// plugins/kxm/src/
|
|
18069
|
-
function
|
|
18070
|
-
const stateRoot = options.stateRoot ? resolve4(options.stateRoot) :
|
|
18068
|
+
// plugins/kxm/src/runtime-store.ts
|
|
18069
|
+
function kxmRuntimePaths(options = {}) {
|
|
18070
|
+
const stateRoot = options.stateRoot ? resolve4(options.stateRoot) : kxmUserStateRoot({ ...options.env ? { env: options.env } : {}, ...options.homeDir ? { homeDir: options.homeDir } : {} });
|
|
18071
18071
|
const runtimeDir = join5(stateRoot, "runtime");
|
|
18072
18072
|
return {
|
|
18073
18073
|
stateRoot,
|
|
@@ -18080,7 +18080,7 @@ function runtimeIssue(phase, code, file, message) {
|
|
|
18080
18080
|
return { phase, code, file, message };
|
|
18081
18081
|
}
|
|
18082
18082
|
function runtimeError(code, file, message) {
|
|
18083
|
-
return new
|
|
18083
|
+
return new KxmConfigError([runtimeIssue("semantic", code, file, message)]);
|
|
18084
18084
|
}
|
|
18085
18085
|
function projectRuntimeKey(projectRoot) {
|
|
18086
18086
|
let canonical;
|
|
@@ -18092,7 +18092,7 @@ function projectRuntimeKey(projectRoot) {
|
|
|
18092
18092
|
const folded = process.platform === "win32" ? canonical.toLocaleLowerCase("en-US") : canonical;
|
|
18093
18093
|
return createHash4("sha256").update(folded, "utf8").digest("hex").slice(0, 24);
|
|
18094
18094
|
}
|
|
18095
|
-
var
|
|
18095
|
+
var KXM_REGISTRY_SCHEMA_VERSION = 1;
|
|
18096
18096
|
var REGISTRY_TABLES = {
|
|
18097
18097
|
supervisor: ["singleton_id", "runtime_id", "pid", "port", "token_hash", "started_at", "heartbeat_at", "state"],
|
|
18098
18098
|
projects: ["project_id", "project_root", "project_key", "home_runtime_id", "config_revision", "registered_at"]
|
|
@@ -18117,14 +18117,14 @@ CREATE TABLE projects (
|
|
|
18117
18117
|
registered_at TEXT NOT NULL
|
|
18118
18118
|
) STRICT;
|
|
18119
18119
|
`;
|
|
18120
|
-
var
|
|
18120
|
+
var KxmRuntimeRegistry = class {
|
|
18121
18121
|
path;
|
|
18122
18122
|
database;
|
|
18123
18123
|
constructor(path) {
|
|
18124
18124
|
this.path = resolve4(path);
|
|
18125
18125
|
this.database = openDatabase(this.path, "runtime registry", {
|
|
18126
18126
|
schema: REGISTRY_SCHEMA,
|
|
18127
|
-
version:
|
|
18127
|
+
version: KXM_REGISTRY_SCHEMA_VERSION,
|
|
18128
18128
|
tables: REGISTRY_TABLES
|
|
18129
18129
|
});
|
|
18130
18130
|
}
|
|
@@ -18283,13 +18283,13 @@ var VnextRuntimeRegistry = class {
|
|
|
18283
18283
|
} : void 0;
|
|
18284
18284
|
}
|
|
18285
18285
|
};
|
|
18286
|
-
var
|
|
18287
|
-
var
|
|
18288
|
-
function
|
|
18286
|
+
var KXM_RUN_EVENT_SCHEMA = "kxm.run-event.v1";
|
|
18287
|
+
var KXM_ABSENT_MEMORY_REVISION = "ctxrev_absent";
|
|
18288
|
+
function hashKxmDriveLog(events) {
|
|
18289
18289
|
const body = events.map((event) => `${event.eventId}:${event.sequence}`).join("\n");
|
|
18290
18290
|
return `sha256:${createHash4("sha256").update(body, "utf8").digest("hex")}`;
|
|
18291
18291
|
}
|
|
18292
|
-
function
|
|
18292
|
+
function verifyKxmDriveReceipt(receipt, events, foldedStatus, binding) {
|
|
18293
18293
|
const reasons = [];
|
|
18294
18294
|
if (receipt.runId !== binding.runId) {
|
|
18295
18295
|
reasons.push(`runId ${receipt.runId} != binding ${binding.runId}`);
|
|
@@ -18303,7 +18303,7 @@ function verifyVnextDriveReceipt(receipt, events, foldedStatus, binding) {
|
|
|
18303
18303
|
reasons.push(`lastSequence ${receipt.lastSequence} != log ${currentLast}`);
|
|
18304
18304
|
}
|
|
18305
18305
|
const prefix = events.filter((event) => event.sequence >= 1 && event.sequence <= receipt.lastSequence);
|
|
18306
|
-
if (
|
|
18306
|
+
if (hashKxmDriveLog(prefix) !== receipt.logHash) {
|
|
18307
18307
|
reasons.push("logHash mismatch");
|
|
18308
18308
|
}
|
|
18309
18309
|
if (receipt.settlement.status !== foldedStatus) {
|
|
@@ -18312,8 +18312,8 @@ function verifyVnextDriveReceipt(receipt, events, foldedStatus, binding) {
|
|
|
18312
18312
|
if (reasons.length === 0) return { verified: true };
|
|
18313
18313
|
return { verified: false, divergence: reasons.join("; ") };
|
|
18314
18314
|
}
|
|
18315
|
-
var
|
|
18316
|
-
var
|
|
18315
|
+
var KXM_EVENT_STORE_SCHEMA_VERSION = 4;
|
|
18316
|
+
var KXM_DRIVE_RECEIPT_SCHEMA = "kxm.drive-receipt.v1";
|
|
18317
18317
|
var DRIVE_RECEIPT_MAX_BYTES = 8 * 1024;
|
|
18318
18318
|
var EVENT_STORE_TABLES = {
|
|
18319
18319
|
runs: ["run_id", "project_id", "home_runtime_id", "workflow_id", "prompt_sha256", "status", "config_revision", "memory_revision", "executor_policy_revision", "tool_policy_revision", "created_at", "updated_at"],
|
|
@@ -18570,14 +18570,14 @@ var EVENT_STORE_MIGRATIONS = [
|
|
|
18570
18570
|
}
|
|
18571
18571
|
}
|
|
18572
18572
|
];
|
|
18573
|
-
var
|
|
18573
|
+
var KxmRunEventStore = class {
|
|
18574
18574
|
path;
|
|
18575
18575
|
database;
|
|
18576
18576
|
constructor(path) {
|
|
18577
18577
|
this.path = resolve4(path);
|
|
18578
18578
|
this.database = openDatabase(this.path, "run event store", {
|
|
18579
18579
|
schema: EVENT_STORE_SCHEMA,
|
|
18580
|
-
version:
|
|
18580
|
+
version: KXM_EVENT_STORE_SCHEMA_VERSION,
|
|
18581
18581
|
tables: EVENT_STORE_TABLES,
|
|
18582
18582
|
migrations: EVENT_STORE_MIGRATIONS
|
|
18583
18583
|
});
|
|
@@ -18738,7 +18738,7 @@ var VnextRunEventStore = class {
|
|
|
18738
18738
|
}
|
|
18739
18739
|
insertDriveReceipt(receipt) {
|
|
18740
18740
|
validateDriveReceipt(receipt, "drive-receipt");
|
|
18741
|
-
const canonical =
|
|
18741
|
+
const canonical = kxmCanonicalJson(receipt);
|
|
18742
18742
|
if (Buffer.byteLength(canonical, "utf8") > DRIVE_RECEIPT_MAX_BYTES) {
|
|
18743
18743
|
throw runtimeError("drive_receipt_invalid", receipt.driveId, `drive receipt exceeds ${DRIVE_RECEIPT_MAX_BYTES} bytes`);
|
|
18744
18744
|
}
|
|
@@ -19032,28 +19032,28 @@ function runFromRow(row) {
|
|
|
19032
19032
|
updatedAt: row.updated_at
|
|
19033
19033
|
};
|
|
19034
19034
|
}
|
|
19035
|
-
function
|
|
19035
|
+
function newKxmRunId() {
|
|
19036
19036
|
return `run_${randomUUID().replaceAll("-", "")}`;
|
|
19037
19037
|
}
|
|
19038
|
-
function
|
|
19038
|
+
function newKxmEventId() {
|
|
19039
19039
|
return `evt_${randomUUID().replaceAll("-", "")}`;
|
|
19040
19040
|
}
|
|
19041
|
-
function
|
|
19041
|
+
function newKxmCommandId() {
|
|
19042
19042
|
return `cmd_${randomUUID().replaceAll("-", "")}`;
|
|
19043
19043
|
}
|
|
19044
|
-
function
|
|
19044
|
+
function newKxmAssignmentId() {
|
|
19045
19045
|
return `asg_${randomUUID().replaceAll("-", "")}`;
|
|
19046
19046
|
}
|
|
19047
|
-
function
|
|
19047
|
+
function newKxmAttemptId() {
|
|
19048
19048
|
return `att_${randomUUID().replaceAll("-", "")}`;
|
|
19049
19049
|
}
|
|
19050
|
-
function
|
|
19050
|
+
function newKxmEffectId() {
|
|
19051
19051
|
return `eff_${randomUUID().replaceAll("-", "")}`;
|
|
19052
19052
|
}
|
|
19053
|
-
function
|
|
19053
|
+
function newKxmObservationId() {
|
|
19054
19054
|
return `obs_${randomUUID().replaceAll("-", "")}`;
|
|
19055
19055
|
}
|
|
19056
|
-
function
|
|
19056
|
+
function newKxmEvidenceId() {
|
|
19057
19057
|
return `gev_${randomUUID().replaceAll("-", "")}`;
|
|
19058
19058
|
}
|
|
19059
19059
|
var SHA256 = /^sha256:[a-f0-9]{64}$/;
|
|
@@ -19135,7 +19135,7 @@ function gateRowContentHash(table, row) {
|
|
|
19135
19135
|
const copy = { ...row };
|
|
19136
19136
|
delete copy.contentHash;
|
|
19137
19137
|
void table;
|
|
19138
|
-
return `sha256:${createHash4("sha256").update(
|
|
19138
|
+
return `sha256:${createHash4("sha256").update(kxmCanonicalJson(copy), "utf8").digest("hex")}`;
|
|
19139
19139
|
}
|
|
19140
19140
|
function assertClosedGateObservation(kind, row, id = "observation") {
|
|
19141
19141
|
if (row.completeness === "incomplete") return;
|
|
@@ -19364,8 +19364,8 @@ function capabilityFromRow(row) {
|
|
|
19364
19364
|
} : void 0;
|
|
19365
19365
|
}
|
|
19366
19366
|
|
|
19367
|
-
// plugins/kxm/src/
|
|
19368
|
-
var
|
|
19367
|
+
// plugins/kxm/src/engine-fold.ts
|
|
19368
|
+
var KXM_RUN_STATE_SCHEMA = "kxm.run-state.v2";
|
|
19369
19369
|
var FOLD_PANEL_BOUND = 1;
|
|
19370
19370
|
var RUN_STATUSES = /* @__PURE__ */ new Set(["created", "preparing", "running", "waiting", "blocked_uncertain", "cancelling", "cancelled", "completed", "failed"]);
|
|
19371
19371
|
var TERMINAL_RUN = /* @__PURE__ */ new Set(["cancelled", "completed", "failed"]);
|
|
@@ -19431,7 +19431,7 @@ function panelAttempt(current) {
|
|
|
19431
19431
|
const attemptId = assignment?.currentAttemptId;
|
|
19432
19432
|
return attemptId ? assignment.attempts[attemptId] : void 0;
|
|
19433
19433
|
}
|
|
19434
|
-
function
|
|
19434
|
+
function kxmFoldPanelAttempt(step, attemptId) {
|
|
19435
19435
|
if (!step) return void 0;
|
|
19436
19436
|
for (const assignmentId of step.panel.order) {
|
|
19437
19437
|
const assignment = step.panel.assignments[assignmentId];
|
|
@@ -19529,7 +19529,7 @@ function expectedStatusForDeclaredOutcome(step, outcome) {
|
|
|
19529
19529
|
if (outcome === "cancelled") return "cancelled";
|
|
19530
19530
|
return "failed";
|
|
19531
19531
|
}
|
|
19532
|
-
function
|
|
19532
|
+
function kxmJoinAll(step, panel) {
|
|
19533
19533
|
if (panel.order.length < step.assignments.minimum) return { tag: "unsatisfied" };
|
|
19534
19534
|
const members = [];
|
|
19535
19535
|
for (const assignmentId of panel.order) {
|
|
@@ -19585,7 +19585,7 @@ function putAssignment(current, assignmentId, assignment) {
|
|
|
19585
19585
|
}
|
|
19586
19586
|
};
|
|
19587
19587
|
}
|
|
19588
|
-
function
|
|
19588
|
+
function kxmFoldPanelAttemptIds(step) {
|
|
19589
19589
|
if (!step) return [];
|
|
19590
19590
|
const ids = [];
|
|
19591
19591
|
for (const assignmentId of step.panel.order) {
|
|
@@ -19595,12 +19595,12 @@ function vnextFoldPanelAttemptIds(step) {
|
|
|
19595
19595
|
}
|
|
19596
19596
|
return ids;
|
|
19597
19597
|
}
|
|
19598
|
-
function
|
|
19598
|
+
function foldKxmRunState(run, plan, events, options = {}) {
|
|
19599
19599
|
if (events.length === 0) {
|
|
19600
19600
|
throw runtimeError("run_events_illegal", run.runId, "run has no events");
|
|
19601
19601
|
}
|
|
19602
19602
|
const state = {
|
|
19603
|
-
schema:
|
|
19603
|
+
schema: KXM_RUN_STATE_SCHEMA,
|
|
19604
19604
|
runId: run.runId,
|
|
19605
19605
|
status: "created",
|
|
19606
19606
|
stepAttempts: /* @__PURE__ */ Object.create(null),
|
|
@@ -19837,7 +19837,7 @@ function isProvenFailure(state, plan) {
|
|
|
19837
19837
|
if (stepTerminal && settled) {
|
|
19838
19838
|
const step2 = plan?.steps[current.stepId];
|
|
19839
19839
|
if (step2 && current.status === "failed") {
|
|
19840
|
-
const joined =
|
|
19840
|
+
const joined = kxmJoinAll(step2, current.panel);
|
|
19841
19841
|
if (joined.tag === "rejected" || joined.tag === "conflict") return true;
|
|
19842
19842
|
}
|
|
19843
19843
|
if (plan && current.outcome) {
|
|
@@ -19960,7 +19960,7 @@ function foldStepStatus(state, plan, event) {
|
|
|
19960
19960
|
}
|
|
19961
19961
|
const step = plan ? requireStep(plan, current.stepId, state.runId) : void 0;
|
|
19962
19962
|
if (step) {
|
|
19963
|
-
const joined =
|
|
19963
|
+
const joined = kxmJoinAll(step, current.panel);
|
|
19964
19964
|
if (joined.tag === "outcome") {
|
|
19965
19965
|
const expectedStatus = expectedStatusForDeclaredOutcome(step, joined.outcome);
|
|
19966
19966
|
const selected = step.transitions[joined.outcome];
|
|
@@ -20020,7 +20020,7 @@ function foldOutcome(state, plan, event) {
|
|
|
20020
20020
|
throw runtimeError("run_events_illegal", state.runId, "step.outcome_recorded cannot overwrite a recorded outcome");
|
|
20021
20021
|
}
|
|
20022
20022
|
const step = requireStep(plan, stepId, state.runId);
|
|
20023
|
-
const joined =
|
|
20023
|
+
const joined = kxmJoinAll(step, current.panel);
|
|
20024
20024
|
if (joined.tag !== "outcome" || joined.outcome !== outcome) {
|
|
20025
20025
|
throw runtimeError("run_events_illegal", state.runId, "step.outcome_recorded does not match the recorded assignment outcome");
|
|
20026
20026
|
}
|
|
@@ -20048,7 +20048,7 @@ function foldTransitioned(state, plan, event) {
|
|
|
20048
20048
|
throw runtimeError("run_events_illegal", state.runId, "step.transitioned requires every panel assignment and issued attempt to be terminal");
|
|
20049
20049
|
}
|
|
20050
20050
|
const step = requireStep(plan, fromStepId, state.runId);
|
|
20051
|
-
const joined =
|
|
20051
|
+
const joined = kxmJoinAll(step, current.panel);
|
|
20052
20052
|
if (joined.tag !== "outcome" || joined.outcome !== outcome) {
|
|
20053
20053
|
throw runtimeError("run_events_illegal", state.runId, "step.transitioned requires a matching joined declared outcome");
|
|
20054
20054
|
}
|
|
@@ -20263,7 +20263,7 @@ function foldAttemptCreated(state, event) {
|
|
|
20263
20263
|
function foldAttemptStatus(state, plan, event) {
|
|
20264
20264
|
requireActiveStep(state, "attempt.status_changed");
|
|
20265
20265
|
const current = state.currentStep;
|
|
20266
|
-
if (
|
|
20266
|
+
if (kxmFoldPanelAttemptIds(current).length === 0) {
|
|
20267
20267
|
throw runtimeError("run_events_illegal", state.runId, "attempt.status_changed has no active attempt");
|
|
20268
20268
|
}
|
|
20269
20269
|
const attemptId = stringPayload(event, "attemptId");
|
|
@@ -20537,7 +20537,7 @@ function freezeCurrentStep(current) {
|
|
|
20537
20537
|
}
|
|
20538
20538
|
function freezeState(state) {
|
|
20539
20539
|
const frozen = {
|
|
20540
|
-
schema:
|
|
20540
|
+
schema: KXM_RUN_STATE_SCHEMA,
|
|
20541
20541
|
runId: state.runId,
|
|
20542
20542
|
status: state.status,
|
|
20543
20543
|
...state.runPlanHash !== void 0 ? { runPlanHash: state.runPlanHash } : {},
|
|
@@ -20565,11 +20565,11 @@ function isTerminalRunStatus(status) {
|
|
|
20565
20565
|
return TERMINAL_RUN.has(status);
|
|
20566
20566
|
}
|
|
20567
20567
|
|
|
20568
|
-
// plugins/kxm/src/
|
|
20568
|
+
// plugins/kxm/src/engine-plan.ts
|
|
20569
20569
|
import { createHash as createHash5 } from "node:crypto";
|
|
20570
20570
|
|
|
20571
|
-
// plugins/kxm/src/
|
|
20572
|
-
var
|
|
20571
|
+
// plugins/kxm/src/engine-compile.ts
|
|
20572
|
+
var KXM_COMPILED_WORKFLOW_SCHEMA = "kxm.compiled-workflow.v1";
|
|
20573
20573
|
var WORKFLOW_SCHEMA = "kxm.workflow.v1";
|
|
20574
20574
|
var STEP_ID_PATTERN = /^[a-z][a-z0-9]*(?:[-_][a-z0-9]+)*$/;
|
|
20575
20575
|
var SUPPORTED_STEP_KINDS = /* @__PURE__ */ new Set(["agent", "moa", "gate", "approval", "wait"]);
|
|
@@ -20579,16 +20579,16 @@ var EVIDENCE_KINDS = /* @__PURE__ */ new Set(["assignment-result", "gate", "rece
|
|
|
20579
20579
|
var REPOSITORY_ACCESS = /* @__PURE__ */ new Set(["none", "read", "write"]);
|
|
20580
20580
|
var DISTINCT_BY = /* @__PURE__ */ new Set(["provider", "model", "profile"]);
|
|
20581
20581
|
var BANNED_RUNTIME_HINT = "not yet supported";
|
|
20582
|
-
var
|
|
20582
|
+
var KxmEngineCompileError = class extends Error {
|
|
20583
20583
|
issues;
|
|
20584
20584
|
constructor(issues) {
|
|
20585
20585
|
const sorted = sortIssues3(issues);
|
|
20586
20586
|
super(sorted.map((issue3) => `${issue3.workflowId}: ${issue3.code}: ${issue3.message}`).join("\n"));
|
|
20587
|
-
this.name = "
|
|
20587
|
+
this.name = "KxmEngineCompileError";
|
|
20588
20588
|
this.issues = sorted;
|
|
20589
20589
|
}
|
|
20590
20590
|
};
|
|
20591
|
-
function
|
|
20591
|
+
function compileKxmWorkflow(input) {
|
|
20592
20592
|
const sink = { workflowId: input.id, issues: [] };
|
|
20593
20593
|
const value = input.value;
|
|
20594
20594
|
if (value.schema !== WORKFLOW_SCHEMA) {
|
|
@@ -20634,16 +20634,16 @@ function compileVnextWorkflow(input) {
|
|
|
20634
20634
|
pushIssue(sink, { code: "plan_hash_stage_unknown", message: `requirePlanHash references unknown stage ${stageId}` });
|
|
20635
20635
|
}
|
|
20636
20636
|
}
|
|
20637
|
-
if (sink.issues.length > 0) throw new
|
|
20637
|
+
if (sink.issues.length > 0) throw new KxmEngineCompileError(sink.issues);
|
|
20638
20638
|
const order = compiledSteps.map((step) => step.id);
|
|
20639
20639
|
const steps = /* @__PURE__ */ Object.create(null);
|
|
20640
20640
|
for (const step of compiledSteps) steps[step.id] = step;
|
|
20641
20641
|
const entryStepId = order[0];
|
|
20642
|
-
if (!entryStepId) throw new
|
|
20642
|
+
if (!entryStepId) throw new KxmEngineCompileError(sink.issues);
|
|
20643
20643
|
const coordinator = stringValue2(value.coordinator) ?? "coordinator";
|
|
20644
20644
|
const transitionBudget = limits.maxTransitions ?? order.length;
|
|
20645
20645
|
const plan = {
|
|
20646
|
-
schema:
|
|
20646
|
+
schema: KXM_COMPILED_WORKFLOW_SCHEMA,
|
|
20647
20647
|
workflowId: input.id,
|
|
20648
20648
|
...input.logicalPath !== void 0 ? { sourcePath: input.logicalPath } : {},
|
|
20649
20649
|
coordinator,
|
|
@@ -21071,8 +21071,8 @@ function pushIssue(sink, issue3) {
|
|
|
21071
21071
|
sink.issues.push({ workflowId: sink.workflowId, ...issue3 });
|
|
21072
21072
|
}
|
|
21073
21073
|
|
|
21074
|
-
// plugins/kxm/src/
|
|
21075
|
-
var
|
|
21074
|
+
// plugins/kxm/src/engine-plan.ts
|
|
21075
|
+
var KXM_RUN_PLAN_SCHEMA = "kxm.run-plan.v2";
|
|
21076
21076
|
var SUPPORTED_KINDS = /* @__PURE__ */ new Set(["agent", "moa", "gate", "approval", "wait"]);
|
|
21077
21077
|
var TERMINAL = /* @__PURE__ */ new Set(["completed", "failed", "cancelled"]);
|
|
21078
21078
|
var JOIN_STRATEGIES2 = /* @__PURE__ */ new Set(["all", "all-settled", "quorum", "first-success"]);
|
|
@@ -21112,13 +21112,13 @@ var JOIN_REQUIRED = ["strategy"];
|
|
|
21112
21112
|
var JOIN_OPTIONAL = ["minimumPassed", "cancelRemaining"];
|
|
21113
21113
|
var EVIDENCE_REQUIRED = ["key", "kind", "minimum", "reusableAcrossAttempts"];
|
|
21114
21114
|
var EVIDENCE_OPTIONAL = ["producerPolicy"];
|
|
21115
|
-
function
|
|
21115
|
+
function kxmSha256(input) {
|
|
21116
21116
|
return `sha256:${createHash5("sha256").update(input, "utf8").digest("hex")}`;
|
|
21117
21117
|
}
|
|
21118
|
-
function
|
|
21119
|
-
return
|
|
21118
|
+
function hashKxmRunPlanEnvelope(envelope) {
|
|
21119
|
+
return kxmSha256(kxmCanonicalJson(envelope));
|
|
21120
21120
|
}
|
|
21121
|
-
function
|
|
21121
|
+
function freezeKxmCompiledPlan(plan) {
|
|
21122
21122
|
const steps = /* @__PURE__ */ Object.create(null);
|
|
21123
21123
|
for (const id of plan.order) {
|
|
21124
21124
|
const step = plan.steps[id];
|
|
@@ -21156,7 +21156,7 @@ function freezeStep(step) {
|
|
|
21156
21156
|
join: { ...step.join }
|
|
21157
21157
|
});
|
|
21158
21158
|
}
|
|
21159
|
-
function
|
|
21159
|
+
function parseKxmRunPlanEnvelope(raw, run, expectedHash) {
|
|
21160
21160
|
let parsed;
|
|
21161
21161
|
try {
|
|
21162
21162
|
parsed = JSON.parse(raw);
|
|
@@ -21164,16 +21164,16 @@ function parseVnextRunPlanEnvelope(raw, run, expectedHash) {
|
|
|
21164
21164
|
throw runtimeError("run_plan_corrupt", run.runId, "run plan envelope is not JSON");
|
|
21165
21165
|
}
|
|
21166
21166
|
const envelope = parseEnvelope(parsed, run);
|
|
21167
|
-
const hash =
|
|
21167
|
+
const hash = hashKxmRunPlanEnvelope(envelope);
|
|
21168
21168
|
if (hash !== expectedHash) {
|
|
21169
21169
|
throw runtimeError("run_plan_corrupt", run.runId, "run plan envelope hash does not match");
|
|
21170
21170
|
}
|
|
21171
21171
|
return envelope;
|
|
21172
21172
|
}
|
|
21173
|
-
function
|
|
21173
|
+
function rehydrateKxmCompiledPlanFromStore(store, run) {
|
|
21174
21174
|
return loadPinnedEnvelope(store, run).plan;
|
|
21175
21175
|
}
|
|
21176
|
-
function
|
|
21176
|
+
function loadKxmRunPlanEnvelope(store, run) {
|
|
21177
21177
|
return loadPinnedEnvelope(store, run);
|
|
21178
21178
|
}
|
|
21179
21179
|
function loadPinnedEnvelope(store, run) {
|
|
@@ -21185,12 +21185,12 @@ function loadPinnedEnvelope(store, run) {
|
|
|
21185
21185
|
if (typeof eventHash !== "string" || eventHash !== row.runPlanHash) {
|
|
21186
21186
|
throw runtimeError("run_plan_corrupt", run.runId, "pinned runPlanHash does not match the plan row");
|
|
21187
21187
|
}
|
|
21188
|
-
return
|
|
21188
|
+
return parseKxmRunPlanEnvelope(row.envelope, run, row.runPlanHash);
|
|
21189
21189
|
}
|
|
21190
21190
|
function parseEnvelope(parsed, run) {
|
|
21191
21191
|
const value = asObject(parsed, run.runId, "run plan envelope");
|
|
21192
21192
|
assertExactKeys(value, ENVELOPE_REQUIRED, [], run.runId, "run plan envelope");
|
|
21193
|
-
if (value.schema !==
|
|
21193
|
+
if (value.schema !== KXM_RUN_PLAN_SCHEMA) {
|
|
21194
21194
|
throw runtimeError("run_plan_corrupt", run.runId, "schema is not kxm.run-plan.v2");
|
|
21195
21195
|
}
|
|
21196
21196
|
const runId = asString(value.runId, run.runId, "runId");
|
|
@@ -21218,9 +21218,9 @@ function parseEnvelope(parsed, run) {
|
|
|
21218
21218
|
...limitsValue.maxRunDurationMs !== void 0 ? { maxRunDurationMs: asDuration(limitsValue.maxRunDurationMs, run.runId, "projectLimits.maxRunDurationMs") } : {},
|
|
21219
21219
|
...limitsValue.maxAgentTimeMs !== void 0 ? { maxAgentTimeMs: asDuration(limitsValue.maxAgentTimeMs, run.runId, "projectLimits.maxAgentTimeMs") } : {}
|
|
21220
21220
|
};
|
|
21221
|
-
const plan =
|
|
21221
|
+
const plan = freezeKxmCompiledPlan(parseCompiledPlan(value.plan, run.runId));
|
|
21222
21222
|
return {
|
|
21223
|
-
schema:
|
|
21223
|
+
schema: KXM_RUN_PLAN_SCHEMA,
|
|
21224
21224
|
runId,
|
|
21225
21225
|
projectId,
|
|
21226
21226
|
homeRuntimeId,
|
|
@@ -21328,7 +21328,7 @@ function parseGateDefinition(raw, gateId, runId) {
|
|
|
21328
21328
|
throw runtimeError("run_plan_corrupt", runId, `gates.definitions.${gateId}.paths are not unique`);
|
|
21329
21329
|
}
|
|
21330
21330
|
for (const path of paths) {
|
|
21331
|
-
if (path === "." || !
|
|
21331
|
+
if (path === "." || !kxmPortablePath(path) || path.startsWith("/") || path.includes("\\")) {
|
|
21332
21332
|
throw runtimeError("run_plan_corrupt", runId, `gates.definitions.${gateId} path is not a portable relative path`);
|
|
21333
21333
|
}
|
|
21334
21334
|
}
|
|
@@ -21354,7 +21354,7 @@ function freezeGates(gates) {
|
|
|
21354
21354
|
function parseCompiledPlan(raw, runId) {
|
|
21355
21355
|
const value = asObject(raw, runId, "compiled plan");
|
|
21356
21356
|
assertExactKeys(value, PLAN_REQUIRED, PLAN_OPTIONAL, runId, "compiled plan");
|
|
21357
|
-
if (value.schema !==
|
|
21357
|
+
if (value.schema !== KXM_COMPILED_WORKFLOW_SCHEMA) {
|
|
21358
21358
|
throw runtimeError("run_plan_corrupt", runId, "compiled plan schema is not kxm.compiled-workflow.v1");
|
|
21359
21359
|
}
|
|
21360
21360
|
const order = asStringArray(value.order, runId, "order");
|
|
@@ -21385,7 +21385,7 @@ function parseCompiledPlan(raw, runId) {
|
|
|
21385
21385
|
if (!steps[stageId]) throw runtimeError("run_plan_corrupt", runId, `requirePlanHash references unknown step ${stageId}`);
|
|
21386
21386
|
}
|
|
21387
21387
|
const plan = {
|
|
21388
|
-
schema:
|
|
21388
|
+
schema: KXM_COMPILED_WORKFLOW_SCHEMA,
|
|
21389
21389
|
workflowId: asString(value.workflowId, runId, "workflowId"),
|
|
21390
21390
|
...value.sourcePath !== void 0 ? { sourcePath: asStringAllowEmpty(value.sourcePath, runId, "sourcePath") } : {},
|
|
21391
21391
|
coordinator: asString(value.coordinator, runId, "coordinator"),
|
|
@@ -21669,16 +21669,16 @@ function deepFreeze2(value) {
|
|
|
21669
21669
|
return Object.freeze(value);
|
|
21670
21670
|
}
|
|
21671
21671
|
|
|
21672
|
-
// plugins/kxm/src/
|
|
21672
|
+
// plugins/kxm/src/gate-hash.ts
|
|
21673
21673
|
function gateDefinitionHash(id, definition) {
|
|
21674
|
-
return
|
|
21674
|
+
return kxmSha256(kxmCanonicalJson({ id, ...definition }));
|
|
21675
21675
|
}
|
|
21676
21676
|
function gateRegistryHash(registryValue) {
|
|
21677
|
-
return
|
|
21677
|
+
return kxmSha256(kxmCanonicalJson(registryValue));
|
|
21678
21678
|
}
|
|
21679
21679
|
|
|
21680
|
-
// plugins/kxm/src/
|
|
21681
|
-
function
|
|
21680
|
+
// plugins/kxm/src/engine-evidence.ts
|
|
21681
|
+
function verifyKxmGateEvidence(store, run, envelope, events, state) {
|
|
21682
21682
|
const attempts = store.gateAttemptsForRun(run.runId);
|
|
21683
21683
|
const observations = store.gateObservationsForRun(run.runId);
|
|
21684
21684
|
const evidence = store.gateEvidenceForRun(run.runId);
|
|
@@ -21844,7 +21844,7 @@ function verifyVnextGateEvidence(store, run, envelope, events, state) {
|
|
|
21844
21844
|
throw runtimeError("gate_evidence_unexpected", run.runId, "non-settled attempt has evidence");
|
|
21845
21845
|
}
|
|
21846
21846
|
}
|
|
21847
|
-
void
|
|
21847
|
+
void kxmCanonicalJson;
|
|
21848
21848
|
}
|
|
21849
21849
|
function lastEffectByAttempt(events) {
|
|
21850
21850
|
const last = /* @__PURE__ */ new Map();
|
|
@@ -21905,7 +21905,7 @@ function stringField(event, field) {
|
|
|
21905
21905
|
return value;
|
|
21906
21906
|
}
|
|
21907
21907
|
|
|
21908
|
-
// plugins/kxm/src/
|
|
21908
|
+
// plugins/kxm/src/runtime-owner.ts
|
|
21909
21909
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
21910
21910
|
var owners = /* @__PURE__ */ new Map();
|
|
21911
21911
|
function record(storePath) {
|
|
@@ -21933,16 +21933,16 @@ function clearImplicitIfIdle(owner) {
|
|
|
21933
21933
|
delete owner.implicit;
|
|
21934
21934
|
}
|
|
21935
21935
|
}
|
|
21936
|
-
function
|
|
21936
|
+
function registerKxmRuntimeHandle(storePath) {
|
|
21937
21937
|
record(storePath).handles += 1;
|
|
21938
21938
|
}
|
|
21939
|
-
function
|
|
21939
|
+
function unregisterKxmRuntimeHandle(storePath) {
|
|
21940
21940
|
const owner = owners.get(storePath);
|
|
21941
21941
|
if (!owner) return;
|
|
21942
21942
|
owner.handles = Math.max(0, owner.handles - 1);
|
|
21943
21943
|
maybeDelete(storePath, owner);
|
|
21944
21944
|
}
|
|
21945
|
-
function
|
|
21945
|
+
function registerKxmAttemptController(storePath, runId, attempt) {
|
|
21946
21946
|
const owner = record(storePath);
|
|
21947
21947
|
let runAttempts = owner.attempts.get(runId);
|
|
21948
21948
|
if (!runAttempts) {
|
|
@@ -21954,15 +21954,15 @@ function registerVnextAttemptController(storePath, runId, attempt) {
|
|
|
21954
21954
|
}
|
|
21955
21955
|
runAttempts.set(attempt.attemptId, attempt);
|
|
21956
21956
|
}
|
|
21957
|
-
function
|
|
21957
|
+
function kxmAttemptController(storePath, runId, attemptId) {
|
|
21958
21958
|
return owners.get(storePath)?.attempts.get(runId)?.get(attemptId);
|
|
21959
21959
|
}
|
|
21960
|
-
function
|
|
21960
|
+
function kxmAttemptControllers(storePath, runId) {
|
|
21961
21961
|
const runAttempts = owners.get(storePath)?.attempts.get(runId);
|
|
21962
21962
|
if (!runAttempts) return [];
|
|
21963
21963
|
return [...runAttempts.values()];
|
|
21964
21964
|
}
|
|
21965
|
-
function
|
|
21965
|
+
function unregisterKxmAttemptController(storePath, runId, attemptId) {
|
|
21966
21966
|
const owner = owners.get(storePath);
|
|
21967
21967
|
if (!owner) return;
|
|
21968
21968
|
const runAttempts = owner.attempts.get(runId);
|
|
@@ -21972,7 +21972,7 @@ function unregisterVnextAttemptController(storePath, runId, attemptId) {
|
|
|
21972
21972
|
if (runAttempts.size === 0) owner.attempts.delete(runId);
|
|
21973
21973
|
maybeDelete(storePath, owner);
|
|
21974
21974
|
}
|
|
21975
|
-
function
|
|
21975
|
+
function bindKxmSchedulerPolicy(storePath, bound, configRevision) {
|
|
21976
21976
|
const owner = record(storePath);
|
|
21977
21977
|
const current = activePolicy(owner);
|
|
21978
21978
|
if (current && (current.configRevision !== configRevision || current.bound !== bound)) {
|
|
@@ -21983,10 +21983,10 @@ function bindVnextSchedulerPolicy(storePath, bound, configRevision) {
|
|
|
21983
21983
|
owner.scheduler = { bound, configRevision };
|
|
21984
21984
|
delete owner.implicit;
|
|
21985
21985
|
}
|
|
21986
|
-
function
|
|
21986
|
+
function kxmSchedulerPolicy(storePath) {
|
|
21987
21987
|
return owners.get(storePath)?.scheduler;
|
|
21988
21988
|
}
|
|
21989
|
-
function
|
|
21989
|
+
function admitKxmRun(storePath, runId, envelopeRevision, envelopeBound) {
|
|
21990
21990
|
const owner = record(storePath);
|
|
21991
21991
|
if (owner.admitted.has(runId)) {
|
|
21992
21992
|
throw runtimeError("run_busy", runId, `run ${runId} is already admitted`);
|
|
@@ -22013,7 +22013,7 @@ function admitVnextRun(storePath, runId, envelopeRevision, envelopeBound) {
|
|
|
22013
22013
|
owner.admitted.set(runId, { token, configRevision: envelopeRevision });
|
|
22014
22014
|
return token;
|
|
22015
22015
|
}
|
|
22016
|
-
function
|
|
22016
|
+
function releaseKxmRun(storePath, runId, token) {
|
|
22017
22017
|
const owner = owners.get(storePath);
|
|
22018
22018
|
if (!owner) return;
|
|
22019
22019
|
const current = owner.admitted.get(runId);
|
|
@@ -22024,7 +22024,7 @@ function releaseVnextRun(storePath, runId, token) {
|
|
|
22024
22024
|
clearImplicitIfIdle(owner);
|
|
22025
22025
|
maybeDelete(storePath, owner);
|
|
22026
22026
|
}
|
|
22027
|
-
function
|
|
22027
|
+
function armKxmGateHold(storePath, runId, token, attemptId, stop) {
|
|
22028
22028
|
const owner = record(storePath);
|
|
22029
22029
|
const current = owner.admitted.get(runId);
|
|
22030
22030
|
if (!current || current.token !== token) {
|
|
@@ -22035,7 +22035,7 @@ function armVnextGateHold(storePath, runId, token, attemptId, stop) {
|
|
|
22035
22035
|
}
|
|
22036
22036
|
current.gateHold = { attemptId, token, state: "active", stop };
|
|
22037
22037
|
}
|
|
22038
|
-
function
|
|
22038
|
+
function markKxmGateHoldUnsettled(storePath, runId, token, attemptId) {
|
|
22039
22039
|
const owner = owners.get(storePath);
|
|
22040
22040
|
const current = owner?.admitted.get(runId);
|
|
22041
22041
|
if (!current || current.token !== token) {
|
|
@@ -22047,7 +22047,7 @@ function markVnextGateHoldUnsettled(storePath, runId, token, attemptId) {
|
|
|
22047
22047
|
}
|
|
22048
22048
|
hold.state = "unsettled";
|
|
22049
22049
|
}
|
|
22050
|
-
function
|
|
22050
|
+
function finishKxmOwnedGate(storePath, runId, token, attemptId) {
|
|
22051
22051
|
const owner = owners.get(storePath);
|
|
22052
22052
|
const current = owner?.admitted.get(runId);
|
|
22053
22053
|
if (!current || current.token !== token) {
|
|
@@ -22062,12 +22062,12 @@ function finishVnextOwnedGate(storePath, runId, token, attemptId) {
|
|
|
22062
22062
|
}
|
|
22063
22063
|
delete current.gateHold;
|
|
22064
22064
|
}
|
|
22065
|
-
function
|
|
22065
|
+
function dropKxmGateStopHook(storePath, runId, attemptId) {
|
|
22066
22066
|
const hold = owners.get(storePath)?.admitted.get(runId)?.gateHold;
|
|
22067
22067
|
if (!hold || hold.attemptId !== attemptId) return;
|
|
22068
22068
|
delete hold.stop;
|
|
22069
22069
|
}
|
|
22070
|
-
function
|
|
22070
|
+
function resolveKxmGateHold(storePath, runId, attemptId) {
|
|
22071
22071
|
const owner = owners.get(storePath);
|
|
22072
22072
|
if (!owner) return;
|
|
22073
22073
|
const current = owner.admitted.get(runId);
|
|
@@ -22084,15 +22084,15 @@ function resolveVnextGateHold(storePath, runId, attemptId) {
|
|
|
22084
22084
|
clearImplicitIfIdle(owner);
|
|
22085
22085
|
maybeDelete(storePath, owner);
|
|
22086
22086
|
}
|
|
22087
|
-
function
|
|
22087
|
+
function kxmGateHold(storePath, runId) {
|
|
22088
22088
|
const hold = owners.get(storePath)?.admitted.get(runId)?.gateHold;
|
|
22089
22089
|
if (!hold) return void 0;
|
|
22090
22090
|
return { attemptId: hold.attemptId, token: hold.token, state: hold.state };
|
|
22091
22091
|
}
|
|
22092
|
-
function
|
|
22092
|
+
function kxmAdmittedToken(storePath, runId) {
|
|
22093
22093
|
return owners.get(storePath)?.admitted.get(runId)?.token;
|
|
22094
22094
|
}
|
|
22095
|
-
function
|
|
22095
|
+
function attachKxmDriveSession(storePath, runId, token, session) {
|
|
22096
22096
|
const owner = record(storePath);
|
|
22097
22097
|
const current = owner.admitted.get(runId);
|
|
22098
22098
|
if (!current || current.token !== token) {
|
|
@@ -22103,16 +22103,16 @@ function attachVnextDriveSession(storePath, runId, token, session) {
|
|
|
22103
22103
|
}
|
|
22104
22104
|
current.driveSession = session;
|
|
22105
22105
|
}
|
|
22106
|
-
function
|
|
22106
|
+
function clearKxmDriveSession(storePath, runId, token) {
|
|
22107
22107
|
const owner = owners.get(storePath);
|
|
22108
22108
|
const current = owner?.admitted.get(runId);
|
|
22109
22109
|
if (!current || current.token !== token) return;
|
|
22110
22110
|
delete current.driveSession;
|
|
22111
22111
|
}
|
|
22112
|
-
function
|
|
22112
|
+
function kxmDriveSession(storePath, runId) {
|
|
22113
22113
|
return owners.get(storePath)?.admitted.get(runId)?.driveSession;
|
|
22114
22114
|
}
|
|
22115
|
-
function
|
|
22115
|
+
function kxmOpenDriveSessions(storePath) {
|
|
22116
22116
|
const owner = owners.get(storePath);
|
|
22117
22117
|
if (!owner) return [];
|
|
22118
22118
|
const sessions = [];
|
|
@@ -22121,7 +22121,7 @@ function vnextOpenDriveSessions(storePath) {
|
|
|
22121
22121
|
}
|
|
22122
22122
|
return sessions;
|
|
22123
22123
|
}
|
|
22124
|
-
function
|
|
22124
|
+
function enqueueKxmScheduledRun(storePath, runId, configRevision, bound, start) {
|
|
22125
22125
|
const owner = record(storePath);
|
|
22126
22126
|
if (owner.admitted.has(runId) || owner.queue.some((item) => item.runId === runId)) {
|
|
22127
22127
|
return Promise.reject(runtimeError("run_busy", runId, `run ${runId} is already admitted or queued`));
|
|
@@ -22144,18 +22144,18 @@ function pump(storePath, owner) {
|
|
|
22144
22144
|
if (!next) break;
|
|
22145
22145
|
let token;
|
|
22146
22146
|
try {
|
|
22147
|
-
token =
|
|
22147
|
+
token = admitKxmRun(storePath, next.runId, next.configRevision, next.bound);
|
|
22148
22148
|
} catch (error) {
|
|
22149
22149
|
next.fail(error);
|
|
22150
22150
|
continue;
|
|
22151
22151
|
}
|
|
22152
22152
|
void next.start(token).finally(() => {
|
|
22153
|
-
|
|
22153
|
+
releaseKxmRun(storePath, next.runId, token);
|
|
22154
22154
|
});
|
|
22155
22155
|
}
|
|
22156
22156
|
}
|
|
22157
22157
|
|
|
22158
|
-
// plugins/kxm/src/
|
|
22158
|
+
// plugins/kxm/src/runtime-service.ts
|
|
22159
22159
|
function compareCodeUnits5(left, right) {
|
|
22160
22160
|
return left < right ? -1 : left > right ? 1 : 0;
|
|
22161
22161
|
}
|
|
@@ -22165,7 +22165,7 @@ function sha256Of(input) {
|
|
|
22165
22165
|
function objectValue3(value) {
|
|
22166
22166
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
22167
22167
|
}
|
|
22168
|
-
function
|
|
22168
|
+
function kxmExecutorPolicyRevision(bundle) {
|
|
22169
22169
|
const executors = /* @__PURE__ */ new Set();
|
|
22170
22170
|
const defaultExecutor = bundle.project.value.defaultExecutor;
|
|
22171
22171
|
if (typeof defaultExecutor === "string") executors.add(defaultExecutor);
|
|
@@ -22173,9 +22173,9 @@ function vnextExecutorPolicyRevision(bundle) {
|
|
|
22173
22173
|
const executor = agent.value.executor;
|
|
22174
22174
|
if (typeof executor === "string") executors.add(executor);
|
|
22175
22175
|
}
|
|
22176
|
-
return sha256Of(
|
|
22176
|
+
return sha256Of(kxmCanonicalJson([...executors].sort()));
|
|
22177
22177
|
}
|
|
22178
|
-
function
|
|
22178
|
+
function kxmToolPolicyRevision(bundle) {
|
|
22179
22179
|
const policies = [];
|
|
22180
22180
|
for (const agent of [...bundle.agents.values()].sort((left, right) => String(left.id).localeCompare(String(right.id)))) {
|
|
22181
22181
|
policies.push({ agent: agent.id ?? "unknown", tools: objectValue3(agent.value.tools) ?? null });
|
|
@@ -22189,7 +22189,7 @@ function vnextToolPolicyRevision(bundle) {
|
|
|
22189
22189
|
}
|
|
22190
22190
|
}
|
|
22191
22191
|
}
|
|
22192
|
-
return sha256Of(
|
|
22192
|
+
return sha256Of(kxmCanonicalJson({ policies, gateRegistry: bundle.gateRegistry?.value ?? null }));
|
|
22193
22193
|
}
|
|
22194
22194
|
function collectMemoryFiles(dir, baseDir, ignoreSubdirs = /* @__PURE__ */ new Set()) {
|
|
22195
22195
|
if (!existsSync6(dir)) return [];
|
|
@@ -22207,7 +22207,7 @@ function collectMemoryFiles(dir, baseDir, ignoreSubdirs = /* @__PURE__ */ new Se
|
|
|
22207
22207
|
}
|
|
22208
22208
|
return results;
|
|
22209
22209
|
}
|
|
22210
|
-
function
|
|
22210
|
+
function computeKxmMemoryRevision(bundle, options = {}) {
|
|
22211
22211
|
const hash = createHash6("sha256");
|
|
22212
22212
|
const memoryDir = options.memoryDir ?? join6(bundle.projectRoot, ".kxm", "memory");
|
|
22213
22213
|
const memoryFiles = collectMemoryFiles(memoryDir, memoryDir, /* @__PURE__ */ new Set(["candidates"])).sort((left, right) => compareCodeUnits5(left.relPath, right.relPath));
|
|
@@ -22228,38 +22228,38 @@ function computeVnextMemoryRevision(bundle, options = {}) {
|
|
|
22228
22228
|
const currentItems = options.promotedState.filter((item) => !item.status || item.status === "current").slice().sort((left, right) => compareCodeUnits5(left.id, right.id));
|
|
22229
22229
|
for (const item of currentItems) {
|
|
22230
22230
|
hash.update(`state:${item.id}\0`, "utf8");
|
|
22231
|
-
hash.update(
|
|
22231
|
+
hash.update(kxmCanonicalJson(item), "utf8");
|
|
22232
22232
|
hash.update("\0", "utf8");
|
|
22233
22233
|
}
|
|
22234
22234
|
}
|
|
22235
22235
|
return `ctxrev_${hash.digest("hex")}`;
|
|
22236
22236
|
}
|
|
22237
22237
|
function checkMemoryRevisionDrift(pinnedRevision, bundle, options) {
|
|
22238
|
-
const currentRevision =
|
|
22238
|
+
const currentRevision = computeKxmMemoryRevision(bundle, options);
|
|
22239
22239
|
return {
|
|
22240
22240
|
drifted: currentRevision !== pinnedRevision,
|
|
22241
22241
|
currentRevision,
|
|
22242
22242
|
pinnedRevision
|
|
22243
22243
|
};
|
|
22244
22244
|
}
|
|
22245
|
-
function
|
|
22245
|
+
function kxmPolicyRevisions(bundle, options) {
|
|
22246
22246
|
return {
|
|
22247
22247
|
configRevision: bundle.configRevision,
|
|
22248
|
-
memoryRevision:
|
|
22249
|
-
executorPolicyRevision:
|
|
22250
|
-
toolPolicyRevision:
|
|
22248
|
+
memoryRevision: computeKxmMemoryRevision(bundle, options),
|
|
22249
|
+
executorPolicyRevision: kxmExecutorPolicyRevision(bundle),
|
|
22250
|
+
toolPolicyRevision: kxmToolPolicyRevision(bundle)
|
|
22251
22251
|
};
|
|
22252
22252
|
}
|
|
22253
|
-
function
|
|
22253
|
+
function kxmDeclaredRepositoryIds(bundle) {
|
|
22254
22254
|
return [...bundle.repositories.keys()].sort();
|
|
22255
22255
|
}
|
|
22256
|
-
function
|
|
22256
|
+
function kxmDeclaredExecutorIds(bundle) {
|
|
22257
22257
|
return [...new Set([
|
|
22258
22258
|
typeof bundle.project.value.defaultExecutor === "string" ? bundle.project.value.defaultExecutor : void 0,
|
|
22259
22259
|
...[...bundle.agents.values()].map((agent) => agent.value.executor).filter((value) => typeof value === "string")
|
|
22260
22260
|
].filter((value) => value !== void 0))].sort();
|
|
22261
22261
|
}
|
|
22262
|
-
function
|
|
22262
|
+
function kxmProjectAdmissionLimits(bundle) {
|
|
22263
22263
|
const limits = objectValue3(bundle.project.value.limits);
|
|
22264
22264
|
const maxConcurrentRuns = typeof limits?.maxConcurrentRuns === "number" && Number.isInteger(limits.maxConcurrentRuns) && limits.maxConcurrentRuns >= 1 ? limits.maxConcurrentRuns : 1;
|
|
22265
22265
|
return {
|
|
@@ -22270,10 +22270,10 @@ function vnextProjectAdmissionLimits(bundle) {
|
|
|
22270
22270
|
}
|
|
22271
22271
|
var closedRuntimeContexts = /* @__PURE__ */ new WeakSet();
|
|
22272
22272
|
var runtimeCloseHooks = /* @__PURE__ */ new WeakMap();
|
|
22273
|
-
function
|
|
22273
|
+
function isKxmRuntimeContextClosed(context) {
|
|
22274
22274
|
return closedRuntimeContexts.has(context);
|
|
22275
22275
|
}
|
|
22276
|
-
function
|
|
22276
|
+
function registerKxmRuntimeCloseHook(context, hook) {
|
|
22277
22277
|
if (closedRuntimeContexts.has(context)) {
|
|
22278
22278
|
hook();
|
|
22279
22279
|
return () => void 0;
|
|
@@ -22288,11 +22288,11 @@ function registerVnextRuntimeCloseHook(context, hook) {
|
|
|
22288
22288
|
hooks.delete(hook);
|
|
22289
22289
|
};
|
|
22290
22290
|
}
|
|
22291
|
-
function
|
|
22292
|
-
const paths =
|
|
22293
|
-
const registry = new
|
|
22291
|
+
function openKxmRuntimeContext(projectRoot, options) {
|
|
22292
|
+
const paths = kxmRuntimePaths(options.stateRoot !== void 0 ? { stateRoot: options.stateRoot } : {});
|
|
22293
|
+
const registry = new KxmRuntimeRegistry(paths.registryDb);
|
|
22294
22294
|
try {
|
|
22295
|
-
const bundle =
|
|
22295
|
+
const bundle = loadKxmProject(projectRoot, options);
|
|
22296
22296
|
const projectId = String(bundle.project.value.id);
|
|
22297
22297
|
const registration = registry.registerProject({
|
|
22298
22298
|
projectId,
|
|
@@ -22301,8 +22301,8 @@ function openVnextRuntimeContext(projectRoot, options) {
|
|
|
22301
22301
|
configRevision: bundle.configRevision,
|
|
22302
22302
|
now: options.now ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
22303
22303
|
});
|
|
22304
|
-
const eventStore = new
|
|
22305
|
-
|
|
22304
|
+
const eventStore = new KxmRunEventStore(join6(paths.projectsDir, registration.projectKey, "run-events.db"));
|
|
22305
|
+
registerKxmRuntimeHandle(eventStore.path);
|
|
22306
22306
|
return {
|
|
22307
22307
|
registry,
|
|
22308
22308
|
projectRoot: bundle.projectRoot,
|
|
@@ -22315,7 +22315,7 @@ function openVnextRuntimeContext(projectRoot, options) {
|
|
|
22315
22315
|
throw error;
|
|
22316
22316
|
}
|
|
22317
22317
|
}
|
|
22318
|
-
function
|
|
22318
|
+
function closeKxmRuntimeContext(context) {
|
|
22319
22319
|
if (closedRuntimeContexts.has(context)) return;
|
|
22320
22320
|
closedRuntimeContexts.add(context);
|
|
22321
22321
|
const hooks = runtimeCloseHooks.get(context);
|
|
@@ -22328,20 +22328,20 @@ function closeVnextRuntimeContext(context) {
|
|
|
22328
22328
|
}
|
|
22329
22329
|
}
|
|
22330
22330
|
}
|
|
22331
|
-
|
|
22331
|
+
unregisterKxmRuntimeHandle(context.eventStore.path);
|
|
22332
22332
|
context.eventStore.close();
|
|
22333
22333
|
context.registry.close();
|
|
22334
22334
|
}
|
|
22335
22335
|
var RUNTIME_EPOCH_NS = process.hrtime.bigint();
|
|
22336
|
-
function
|
|
22336
|
+
function kxmMonotonicNs() {
|
|
22337
22337
|
return (process.hrtime.bigint() - RUNTIME_EPOCH_NS).toString();
|
|
22338
22338
|
}
|
|
22339
|
-
function
|
|
22339
|
+
function kxmIncrementMonotonicNs(value) {
|
|
22340
22340
|
return (BigInt(value) + 1n).toString();
|
|
22341
22341
|
}
|
|
22342
|
-
function
|
|
22342
|
+
function kxmEventBase(context, run, now, monotonicNs, commandId) {
|
|
22343
22343
|
return {
|
|
22344
|
-
schema:
|
|
22344
|
+
schema: KXM_RUN_EVENT_SCHEMA,
|
|
22345
22345
|
projectId: context.projectId,
|
|
22346
22346
|
runId: run.runId,
|
|
22347
22347
|
homeRuntimeId: run.homeRuntimeId,
|
|
@@ -22355,15 +22355,15 @@ function vnextEventBase(context, run, now, monotonicNs, commandId) {
|
|
|
22355
22355
|
...commandId !== void 0 ? { commandId } : {}
|
|
22356
22356
|
};
|
|
22357
22357
|
}
|
|
22358
|
-
function
|
|
22359
|
-
const commandId = request.commandId ??
|
|
22358
|
+
function acceptKxmRun(context, bundle, request, options = {}) {
|
|
22359
|
+
const commandId = request.commandId ?? newKxmCommandId();
|
|
22360
22360
|
const now = options.now ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
22361
|
-
const monotonicNs = options.monotonicNs ??
|
|
22361
|
+
const monotonicNs = options.monotonicNs ?? kxmMonotonicNs();
|
|
22362
22362
|
const workflow = bundle.workflows.get(request.workflowId);
|
|
22363
22363
|
if (!workflow) {
|
|
22364
22364
|
throw runtimeError("run_workflow_unknown", ".kxm/workflows", `workflow ${request.workflowId} does not exist in this project`);
|
|
22365
22365
|
}
|
|
22366
|
-
const revisions =
|
|
22366
|
+
const revisions = kxmPolicyRevisions(bundle, options);
|
|
22367
22367
|
const memoryRevision = options.memoryRevision ?? revisions.memoryRevision;
|
|
22368
22368
|
const promptSha256 = `sha256:${createHash6("sha256").update(request.prompt, "utf8").digest("hex")}`;
|
|
22369
22369
|
return context.eventStore.transaction(() => {
|
|
@@ -22381,17 +22381,17 @@ function acceptVnextRun(context, bundle, request, options = {}) {
|
|
|
22381
22381
|
if (events.length === 0) throw runtimeError("run_command_corrupt", commandId, "idempotent command references a run with no creation event");
|
|
22382
22382
|
return { accepted: true, idempotent: true, run: run2, event: events[0] };
|
|
22383
22383
|
}
|
|
22384
|
-
const runId =
|
|
22384
|
+
const runId = newKxmRunId();
|
|
22385
22385
|
const payload = {
|
|
22386
22386
|
workflowId: request.workflowId,
|
|
22387
22387
|
status: "created",
|
|
22388
22388
|
promptHash: promptSha256,
|
|
22389
|
-
repositoryIds:
|
|
22390
|
-
executorIds:
|
|
22389
|
+
repositoryIds: kxmDeclaredRepositoryIds(bundle),
|
|
22390
|
+
executorIds: kxmDeclaredExecutorIds(bundle)
|
|
22391
22391
|
};
|
|
22392
22392
|
const event = {
|
|
22393
|
-
schema:
|
|
22394
|
-
eventId:
|
|
22393
|
+
schema: KXM_RUN_EVENT_SCHEMA,
|
|
22394
|
+
eventId: newKxmEventId(),
|
|
22395
22395
|
eventType: "run.created",
|
|
22396
22396
|
projectId: context.projectId,
|
|
22397
22397
|
runId,
|
|
@@ -22434,14 +22434,14 @@ function acceptVnextRun(context, bundle, request, options = {}) {
|
|
|
22434
22434
|
return { accepted: true, idempotent: false, run, event };
|
|
22435
22435
|
});
|
|
22436
22436
|
}
|
|
22437
|
-
function
|
|
22437
|
+
function foldStoredKxmRun(context, run) {
|
|
22438
22438
|
const events = context.eventStore.events(run.runId, 0, 1e6);
|
|
22439
22439
|
const planRow = context.eventStore.runPlan(run.runId);
|
|
22440
22440
|
if (!planRow && events.some((event) => event.eventType.startsWith("step.") || event.eventType.startsWith("effect.") || event.payload.status === "preparing" || event.payload.status === "running" || event.payload.status === "cancelling")) {
|
|
22441
22441
|
throw runtimeError("run_plan_missing", run.runId, "run reached preparing or later without a pinned plan");
|
|
22442
22442
|
}
|
|
22443
|
-
const envelope = planRow ?
|
|
22444
|
-
const state =
|
|
22443
|
+
const envelope = planRow ? loadKxmRunPlanEnvelope(context.eventStore, run) : void 0;
|
|
22444
|
+
const state = foldKxmRunState(run, envelope?.plan, events, envelope ? {
|
|
22445
22445
|
observationLookup: (attemptId, observationId) => {
|
|
22446
22446
|
const row = context.eventStore.gateObservationForAttempt(attemptId);
|
|
22447
22447
|
if (!row || row.observationId !== observationId) return void 0;
|
|
@@ -22454,7 +22454,7 @@ function foldStoredVnextRun(context, run) {
|
|
|
22454
22454
|
},
|
|
22455
22455
|
projectLimits: envelope.projectLimits
|
|
22456
22456
|
} : {});
|
|
22457
|
-
if (envelope)
|
|
22457
|
+
if (envelope) verifyKxmGateEvidence(context.eventStore, run, envelope, events, state);
|
|
22458
22458
|
assertStoredProjection(context, run);
|
|
22459
22459
|
return state;
|
|
22460
22460
|
}
|
|
@@ -22470,15 +22470,15 @@ function assertStoredProjection(context, run) {
|
|
|
22470
22470
|
const stored = context.eventStore.runState(run.runId);
|
|
22471
22471
|
if (!stored) return;
|
|
22472
22472
|
const schema = storedProjectionSchema(stored.state);
|
|
22473
|
-
if (schema !==
|
|
22473
|
+
if (schema !== KXM_RUN_STATE_SCHEMA) {
|
|
22474
22474
|
throw runtimeError("run_projection_divergent", run.runId, "stored run_state does not match the folded projection");
|
|
22475
22475
|
}
|
|
22476
22476
|
}
|
|
22477
|
-
function
|
|
22478
|
-
return
|
|
22477
|
+
function readKxmRunStatus(context, run) {
|
|
22478
|
+
return foldStoredKxmRun(context, run).status;
|
|
22479
22479
|
}
|
|
22480
22480
|
function persistProjection(context, run, state, now) {
|
|
22481
|
-
const canonical =
|
|
22481
|
+
const canonical = kxmCanonicalJson(state);
|
|
22482
22482
|
const stored = context.eventStore.runState(run.runId);
|
|
22483
22483
|
if (stored && stored.state !== canonical) {
|
|
22484
22484
|
throw runtimeError("run_projection_divergent", run.runId, "stored run_state does not match the folded projection");
|
|
@@ -22494,42 +22494,42 @@ function persistProjection(context, run, state, now) {
|
|
|
22494
22494
|
if (run.status !== state.status) context.eventStore.updateRunStatus(run.runId, state.status, now);
|
|
22495
22495
|
return updated;
|
|
22496
22496
|
}
|
|
22497
|
-
function
|
|
22497
|
+
function rebuildKxmRunProjection(context, runId) {
|
|
22498
22498
|
const stored = context.eventStore.run(runId);
|
|
22499
22499
|
if (!stored) throw runtimeError("run_unknown", runId, "run does not exist in this event store");
|
|
22500
|
-
const state =
|
|
22500
|
+
const state = foldStoredKxmRun(context, stored);
|
|
22501
22501
|
const events = context.eventStore.events(runId, 0, 1e6);
|
|
22502
22502
|
if (events.length === 0) throw runtimeError("run_events_corrupt", runId, "run has no events");
|
|
22503
22503
|
const last = events[events.length - 1];
|
|
22504
22504
|
return persistProjection(context, stored, state, last.occurredAt);
|
|
22505
22505
|
}
|
|
22506
|
-
function
|
|
22506
|
+
function projectKxmRunReadOnly(context, runId) {
|
|
22507
22507
|
const stored = context.eventStore.run(runId);
|
|
22508
22508
|
if (!stored) throw runtimeError("run_unknown", runId, "run does not exist in this event store");
|
|
22509
|
-
const state =
|
|
22509
|
+
const state = foldStoredKxmRun(context, stored);
|
|
22510
22510
|
const events = context.eventStore.events(runId, 0, 1e6);
|
|
22511
22511
|
if (events.length === 0) throw runtimeError("run_events_corrupt", runId, "run has no events");
|
|
22512
22512
|
const last = events[events.length - 1];
|
|
22513
22513
|
return { ...stored, status: state.status, updatedAt: last.occurredAt };
|
|
22514
22514
|
}
|
|
22515
|
-
function
|
|
22515
|
+
function persistKxmRunState(context, runId, state, lastSequence) {
|
|
22516
22516
|
const stored = context.eventStore.runState(runId);
|
|
22517
22517
|
if (stored) {
|
|
22518
22518
|
const schema = storedProjectionSchema(stored.state);
|
|
22519
|
-
if (schema !==
|
|
22519
|
+
if (schema !== KXM_RUN_STATE_SCHEMA) {
|
|
22520
22520
|
throw runtimeError("run_projection_divergent", runId, "stored run_state does not match the folded projection");
|
|
22521
22521
|
}
|
|
22522
22522
|
}
|
|
22523
22523
|
context.eventStore.upsertRunState({
|
|
22524
22524
|
runId,
|
|
22525
22525
|
lastSequence,
|
|
22526
|
-
state:
|
|
22526
|
+
state: kxmCanonicalJson(state)
|
|
22527
22527
|
});
|
|
22528
22528
|
}
|
|
22529
|
-
function
|
|
22530
|
-
const commandId = options.commandId ??
|
|
22529
|
+
function cancelKxmRun(context, runId, options = {}) {
|
|
22530
|
+
const commandId = options.commandId ?? newKxmCommandId();
|
|
22531
22531
|
const now = options.now ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
22532
|
-
const monotonicNs = options.monotonicNs ??
|
|
22532
|
+
const monotonicNs = options.monotonicNs ?? kxmMonotonicNs();
|
|
22533
22533
|
const abortControllers = [];
|
|
22534
22534
|
const result = context.eventStore.transaction(() => {
|
|
22535
22535
|
const prior = context.eventStore.command(commandId);
|
|
@@ -22543,7 +22543,7 @@ function cancelVnextRun(context, runId, options = {}) {
|
|
|
22543
22543
|
}
|
|
22544
22544
|
const run = context.eventStore.run(runId);
|
|
22545
22545
|
if (!run) throw runtimeError("run_unknown", runId, "run does not exist in this event store");
|
|
22546
|
-
const folded =
|
|
22546
|
+
const folded = foldStoredKxmRun(context, run);
|
|
22547
22547
|
if (isTerminalRunStatus(folded.status) || folded.status === "cancelling") {
|
|
22548
22548
|
context.eventStore.insertCommand({
|
|
22549
22549
|
commandId,
|
|
@@ -22559,18 +22559,18 @@ function cancelVnextRun(context, runId, options = {}) {
|
|
|
22559
22559
|
let nextMono = monotonicNs;
|
|
22560
22560
|
const push = (eventType, payload) => {
|
|
22561
22561
|
const event = {
|
|
22562
|
-
...
|
|
22563
|
-
eventId:
|
|
22562
|
+
...kxmEventBase(context, run, now, nextMono, commandId),
|
|
22563
|
+
eventId: newKxmEventId(),
|
|
22564
22564
|
eventType,
|
|
22565
22565
|
sequence: sequence++,
|
|
22566
22566
|
payload
|
|
22567
22567
|
};
|
|
22568
|
-
nextMono =
|
|
22568
|
+
nextMono = kxmIncrementMonotonicNs(nextMono);
|
|
22569
22569
|
events.push(event);
|
|
22570
22570
|
return event;
|
|
22571
22571
|
};
|
|
22572
22572
|
const cancelReason = options.reason ?? "operator_cancel";
|
|
22573
|
-
const activeAttempt = Boolean(folded.currentStep?.attemptId) ||
|
|
22573
|
+
const activeAttempt = Boolean(folded.currentStep?.attemptId) || kxmFoldPanelAttemptIds(folded.currentStep).length > 0;
|
|
22574
22574
|
const cancelPayload = {
|
|
22575
22575
|
actor: { kind: "runtime", id: context.homeRuntimeId },
|
|
22576
22576
|
reason: cancelReason
|
|
@@ -22586,7 +22586,7 @@ function cancelVnextRun(context, runId, options = {}) {
|
|
|
22586
22586
|
if (folded.status === "running" && activeAttempt) {
|
|
22587
22587
|
status = "cancelling";
|
|
22588
22588
|
push("run.status_changed", { status: "cancelling", reason: cancelReason });
|
|
22589
|
-
const attemptIds = new Set(
|
|
22589
|
+
const attemptIds = new Set(kxmFoldPanelAttemptIds(folded.currentStep));
|
|
22590
22590
|
if (folded.currentStep?.attemptId) attemptIds.add(folded.currentStep.attemptId);
|
|
22591
22591
|
for (const attemptId of attemptIds) {
|
|
22592
22592
|
const capability = context.eventStore.capabilityByAttempt(attemptId);
|
|
@@ -22594,7 +22594,7 @@ function cancelVnextRun(context, runId, options = {}) {
|
|
|
22594
22594
|
context.eventStore.settleCapability(attemptId, "revoked");
|
|
22595
22595
|
}
|
|
22596
22596
|
}
|
|
22597
|
-
for (const owned of
|
|
22597
|
+
for (const owned of kxmAttemptControllers(context.eventStore.path, runId)) {
|
|
22598
22598
|
abortControllers.push(owned.controller);
|
|
22599
22599
|
}
|
|
22600
22600
|
} else if (folded.status === "blocked_uncertain") {
|
|
@@ -22605,9 +22605,9 @@ function cancelVnextRun(context, runId, options = {}) {
|
|
|
22605
22605
|
if (capability && (capability.state === "issued" || capability.state === "revoked")) {
|
|
22606
22606
|
context.eventStore.settleCapability(attemptId, "revoked");
|
|
22607
22607
|
}
|
|
22608
|
-
|
|
22608
|
+
resolveKxmGateHold(context.eventStore.path, runId, attemptId);
|
|
22609
22609
|
}
|
|
22610
|
-
for (const owned of
|
|
22610
|
+
for (const owned of kxmAttemptControllers(context.eventStore.path, runId)) {
|
|
22611
22611
|
abortControllers.push(owned.controller);
|
|
22612
22612
|
}
|
|
22613
22613
|
push("run.status_changed", { status: "cancelled", reason: cancelReason });
|
|
@@ -22619,8 +22619,8 @@ function cancelVnextRun(context, runId, options = {}) {
|
|
|
22619
22619
|
push("run.status_changed", { status: "cancelled", reason: cancelReason });
|
|
22620
22620
|
}
|
|
22621
22621
|
for (const event of events) context.eventStore.appendEvent(event);
|
|
22622
|
-
const nextState =
|
|
22623
|
-
|
|
22622
|
+
const nextState = foldStoredKxmRun(context, run);
|
|
22623
|
+
persistKxmRunState(context, runId, nextState, events[events.length - 1].sequence);
|
|
22624
22624
|
context.eventStore.updateRunStatus(runId, status, now);
|
|
22625
22625
|
context.eventStore.insertCommand({
|
|
22626
22626
|
commandId,
|
|
@@ -22634,28 +22634,28 @@ function cancelVnextRun(context, runId, options = {}) {
|
|
|
22634
22634
|
for (const controller of abortControllers) controller.abort();
|
|
22635
22635
|
return result;
|
|
22636
22636
|
}
|
|
22637
|
-
function
|
|
22637
|
+
function kxmRunRevisionDrift(run, bundle) {
|
|
22638
22638
|
return {
|
|
22639
22639
|
configDrift: run.configRevision !== bundle.configRevision,
|
|
22640
22640
|
currentRevision: bundle.configRevision,
|
|
22641
22641
|
pinnedRevision: run.configRevision
|
|
22642
22642
|
};
|
|
22643
22643
|
}
|
|
22644
|
-
function
|
|
22645
|
-
if (!(error instanceof
|
|
22644
|
+
function assertKxmConfigError(error) {
|
|
22645
|
+
if (!(error instanceof KxmConfigError)) throw error;
|
|
22646
22646
|
}
|
|
22647
22647
|
|
|
22648
|
-
// plugins/kxm/src/
|
|
22648
|
+
// plugins/kxm/src/runtime-supervisor.ts
|
|
22649
22649
|
import { spawn as spawn3 } from "node:child_process";
|
|
22650
22650
|
import { createHash as createHash12, createHmac, randomBytes as randomBytes3, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
|
|
22651
22651
|
import { chmodSync as chmodSync2, existsSync as existsSync10, lstatSync as lstatSync5, mkdirSync as mkdirSync4, readFileSync as readFileSync8, renameSync, rmSync, writeFileSync as writeFileSync4 } from "node:fs";
|
|
22652
22652
|
import { createServer } from "node:http";
|
|
22653
22653
|
import { dirname as dirname6, isAbsolute as isAbsolute4, join as join13 } from "node:path";
|
|
22654
22654
|
|
|
22655
|
-
// plugins/kxm/src/
|
|
22655
|
+
// plugins/kxm/src/oneshot-producer.ts
|
|
22656
22656
|
import { join as join12 } from "node:path";
|
|
22657
22657
|
|
|
22658
|
-
// plugins/kxm/src/
|
|
22658
|
+
// plugins/kxm/src/oneshot-evidence.ts
|
|
22659
22659
|
import { createHash as createHash7, randomUUID as randomUUID3 } from "node:crypto";
|
|
22660
22660
|
import { lstat, mkdir, open, rename } from "node:fs/promises";
|
|
22661
22661
|
import { join as join7 } from "node:path";
|
|
@@ -22948,7 +22948,7 @@ function loadPriceCatalogForEstimate(options) {
|
|
|
22948
22948
|
return { catalog, unavailable: false, stale: false };
|
|
22949
22949
|
}
|
|
22950
22950
|
|
|
22951
|
-
// plugins/kxm/src/
|
|
22951
|
+
// plugins/kxm/src/engine.ts
|
|
22952
22952
|
var import_yaml5 = __toESM(require_dist(), 1);
|
|
22953
22953
|
import { createHash as createHash11, randomBytes as randomBytes2, timingSafeEqual } from "node:crypto";
|
|
22954
22954
|
import { existsSync as existsSync9, readFileSync as readFileSync7 } from "node:fs";
|
|
@@ -23244,7 +23244,7 @@ function pruneContextPacket(packet, tokenBudget) {
|
|
|
23244
23244
|
};
|
|
23245
23245
|
}
|
|
23246
23246
|
|
|
23247
|
-
// plugins/kxm/src/
|
|
23247
|
+
// plugins/kxm/src/engine-artifacts.ts
|
|
23248
23248
|
import { join as join10 } from "node:path";
|
|
23249
23249
|
|
|
23250
23250
|
// plugins/kxm/src/artifacts-exist.ts
|
|
@@ -23289,8 +23289,8 @@ function verifyArtifactExists(rootInput, pathInput) {
|
|
|
23289
23289
|
}
|
|
23290
23290
|
}
|
|
23291
23291
|
|
|
23292
|
-
// plugins/kxm/src/
|
|
23293
|
-
var
|
|
23292
|
+
// plugins/kxm/src/engine-artifacts.ts
|
|
23293
|
+
var kxmArtifactsGateSeams = {};
|
|
23294
23294
|
function evaluateArtifactsGate(context, definition) {
|
|
23295
23295
|
const root = join10(context.projectRoot, ".kxm", "assets");
|
|
23296
23296
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -23301,7 +23301,7 @@ function evaluateArtifactsGate(context, definition) {
|
|
|
23301
23301
|
checkedCount += 1;
|
|
23302
23302
|
const result = verifyArtifactExists(root, join10(root, path));
|
|
23303
23303
|
if (!result.ok) failedCount += 1;
|
|
23304
|
-
|
|
23304
|
+
kxmArtifactsGateSeams.afterPathChecked?.({ path, index, checkedCount, failedCount });
|
|
23305
23305
|
}
|
|
23306
23306
|
const elapsedNs = process.hrtime.bigint() - startTime;
|
|
23307
23307
|
const finishedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -23330,7 +23330,7 @@ function evaluateArtifactsGate(context, definition) {
|
|
|
23330
23330
|
};
|
|
23331
23331
|
}
|
|
23332
23332
|
|
|
23333
|
-
// plugins/kxm/src/
|
|
23333
|
+
// plugins/kxm/src/engine-command.ts
|
|
23334
23334
|
import { spawn as spawn2 } from "node:child_process";
|
|
23335
23335
|
import { createHash as createHash9 } from "node:crypto";
|
|
23336
23336
|
|
|
@@ -23369,12 +23369,12 @@ function assertPinnedSshHostKeyPolicy(sshArgs) {
|
|
|
23369
23369
|
}
|
|
23370
23370
|
}
|
|
23371
23371
|
|
|
23372
|
-
// plugins/kxm/src/
|
|
23372
|
+
// plugins/kxm/src/engine-command.ts
|
|
23373
23373
|
var MAX_DIRECT_TIMER_MS = 2147483647;
|
|
23374
23374
|
var COMMAND_TERM_GRACE_MS = 2e3;
|
|
23375
23375
|
var COMMAND_FINAL_WAIT_MS = 2e3;
|
|
23376
23376
|
var COMMAND_LINGER_MS = 2e3;
|
|
23377
|
-
var
|
|
23377
|
+
var kxmCommandGateSeams = {};
|
|
23378
23378
|
var POST_SPAWN_CHILD_ERROR_CLASS = "stream-error";
|
|
23379
23379
|
function createCommandObserver(input) {
|
|
23380
23380
|
return new CommandObserver(input);
|
|
@@ -23431,7 +23431,7 @@ var CommandObserver = class {
|
|
|
23431
23431
|
this.cwd = input.cwd;
|
|
23432
23432
|
this.signal = input.signal;
|
|
23433
23433
|
this.onSpawned = input.onSpawned;
|
|
23434
|
-
const timing =
|
|
23434
|
+
const timing = kxmCommandGateSeams.timing;
|
|
23435
23435
|
this.termGraceMs = clampTimer(timing?.termGraceMs ?? COMMAND_TERM_GRACE_MS);
|
|
23436
23436
|
this.finalWaitMs = clampTimer(timing?.finalWaitMs ?? COMMAND_FINAL_WAIT_MS);
|
|
23437
23437
|
this.lingerMs = clampTimer(timing?.lingerMs ?? COMMAND_LINGER_MS);
|
|
@@ -23443,7 +23443,7 @@ var CommandObserver = class {
|
|
|
23443
23443
|
if (this.stopCause === "none") {
|
|
23444
23444
|
this.stopCause = cause;
|
|
23445
23445
|
if (errorClass && this.errorClass === null) this.errorClass = errorClass;
|
|
23446
|
-
|
|
23446
|
+
kxmCommandGateSeams.afterStopRequested?.(cause);
|
|
23447
23447
|
this.clearTimer("linger");
|
|
23448
23448
|
this.beginSignalSequence();
|
|
23449
23449
|
return;
|
|
@@ -23474,7 +23474,7 @@ var CommandObserver = class {
|
|
|
23474
23474
|
return;
|
|
23475
23475
|
}
|
|
23476
23476
|
try {
|
|
23477
|
-
|
|
23477
|
+
kxmCommandGateSeams.beforeSpawn?.(this.definition);
|
|
23478
23478
|
} catch {
|
|
23479
23479
|
this.finishNoStart("validation");
|
|
23480
23480
|
return;
|
|
@@ -23584,9 +23584,9 @@ var CommandObserver = class {
|
|
|
23584
23584
|
this.clearTimer("timeout");
|
|
23585
23585
|
child.stdout?.destroy();
|
|
23586
23586
|
child.stderr?.destroy();
|
|
23587
|
-
|
|
23587
|
+
dropKxmCommandStopCapability(this);
|
|
23588
23588
|
try {
|
|
23589
|
-
|
|
23589
|
+
kxmCommandGateSeams.afterChildClose?.();
|
|
23590
23590
|
} catch {
|
|
23591
23591
|
}
|
|
23592
23592
|
this.handoff();
|
|
@@ -23607,7 +23607,7 @@ var CommandObserver = class {
|
|
|
23607
23607
|
this.requestStop("error", "recording-error");
|
|
23608
23608
|
}
|
|
23609
23609
|
try {
|
|
23610
|
-
|
|
23610
|
+
kxmCommandGateSeams.afterSpawned?.(this.observedPid);
|
|
23611
23611
|
} catch {
|
|
23612
23612
|
this.requestStop("error", "recording-error");
|
|
23613
23613
|
}
|
|
@@ -23774,7 +23774,7 @@ var CommandObserver = class {
|
|
|
23774
23774
|
this.clearTimer("final");
|
|
23775
23775
|
this.clearTimer("linger");
|
|
23776
23776
|
this.child?.unref();
|
|
23777
|
-
|
|
23777
|
+
dropKxmCommandStopCapability(this);
|
|
23778
23778
|
this.resolveOutcome?.(outcome);
|
|
23779
23779
|
}
|
|
23780
23780
|
clearTimer(name) {
|
|
@@ -23783,7 +23783,7 @@ var CommandObserver = class {
|
|
|
23783
23783
|
this[`${name}Timer`] = void 0;
|
|
23784
23784
|
}
|
|
23785
23785
|
};
|
|
23786
|
-
function
|
|
23786
|
+
function dropKxmCommandStopCapability(observer) {
|
|
23787
23787
|
observer.requestStop = () => void 0;
|
|
23788
23788
|
}
|
|
23789
23789
|
function isCompleteNormal(observation) {
|
|
@@ -23799,20 +23799,20 @@ function schedule(ms, fn) {
|
|
|
23799
23799
|
return setTimeout(fn, clampTimer(ms));
|
|
23800
23800
|
}
|
|
23801
23801
|
|
|
23802
|
-
// plugins/kxm/src/
|
|
23802
|
+
// plugins/kxm/src/engine-gate-records.ts
|
|
23803
23803
|
function recordGateIntentInTransaction(context, run, envelope, stepId) {
|
|
23804
23804
|
const step = requireGateStep(envelope, stepId, run.runId);
|
|
23805
23805
|
const definition = envelope.gates.definitions[step.gate];
|
|
23806
23806
|
if (!definition || definition.kind === "reserved") {
|
|
23807
23807
|
throw runtimeError("gate_row_invalid", run.runId, "reserved gates cannot record intent in this slice");
|
|
23808
23808
|
}
|
|
23809
|
-
const folded =
|
|
23809
|
+
const folded = foldStoredKxmRun(context, run);
|
|
23810
23810
|
const used = folded.stepAttempts[stepId] ?? 0;
|
|
23811
23811
|
const stepAttempt = used + 1;
|
|
23812
|
-
const assignmentId =
|
|
23813
|
-
const attemptId =
|
|
23814
|
-
const effectId =
|
|
23815
|
-
const minted =
|
|
23812
|
+
const assignmentId = newKxmAssignmentId();
|
|
23813
|
+
const attemptId = newKxmAttemptId();
|
|
23814
|
+
const effectId = newKxmEffectId();
|
|
23815
|
+
const minted = mintKxmCapabilitySecret();
|
|
23816
23816
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
23817
23817
|
const seq = sequencer(context, run, now);
|
|
23818
23818
|
seq.push("step.entered", { stepId, stepAttempt, status: "pending" });
|
|
@@ -23902,7 +23902,7 @@ function recordGateSettlementInTransaction(context, run, envelope, stepId, obser
|
|
|
23902
23902
|
});
|
|
23903
23903
|
}
|
|
23904
23904
|
seq.push("attempt.status_changed", { attemptId: ids.attemptId, assignmentId: ids.assignmentId, stepId, stepAttempt: ids.stepAttempt, status: "settling" });
|
|
23905
|
-
const observationId =
|
|
23905
|
+
const observationId = newKxmObservationId();
|
|
23906
23906
|
const observed = seq.push("effect.observed", {
|
|
23907
23907
|
effect: { id: ids.effectId, policy: { class: ids.gateKind === "artifacts-exist" ? "read-only" : "unknown", sharedMutable: false } },
|
|
23908
23908
|
stepId,
|
|
@@ -23913,7 +23913,7 @@ function recordGateSettlementInTransaction(context, run, envelope, stepId, obser
|
|
|
23913
23913
|
});
|
|
23914
23914
|
const observationRow = buildObservation(ids, observation, observationId, observed.eventId);
|
|
23915
23915
|
patchReceipt(observed, observationRow);
|
|
23916
|
-
const evidenceId =
|
|
23916
|
+
const evidenceId = newKxmEvidenceId();
|
|
23917
23917
|
const evidenceDraft = {
|
|
23918
23918
|
evidenceId,
|
|
23919
23919
|
attemptId: ids.attemptId,
|
|
@@ -23961,7 +23961,7 @@ function recordGateNoStartInTransaction(context, run, envelope, stepId, observat
|
|
|
23961
23961
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
23962
23962
|
const seq = sequencer(context, run, now);
|
|
23963
23963
|
const cancelReason = cancelled ? ensureOperatorCancel(seq, ids.state, run, context) : void 0;
|
|
23964
|
-
const observationId =
|
|
23964
|
+
const observationId = newKxmObservationId();
|
|
23965
23965
|
const observed = seq.push("effect.observed", {
|
|
23966
23966
|
effect: { id: ids.effectId, policy: { class: ids.gateKind === "artifacts-exist" ? "read-only" : "unknown", sharedMutable: false } },
|
|
23967
23967
|
stepId,
|
|
@@ -24019,7 +24019,7 @@ function recordGateUncertainInTransaction(context, run, envelope, stepId, reason
|
|
|
24019
24019
|
}
|
|
24020
24020
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
24021
24021
|
const seq = sequencer(context, run, now);
|
|
24022
|
-
const observationId =
|
|
24022
|
+
const observationId = newKxmObservationId();
|
|
24023
24023
|
const blocked = seq.push("effect.blocked_uncertain", {
|
|
24024
24024
|
effect: { id: ids.effectId, policy: { class: ids.gateKind === "artifacts-exist" ? "read-only" : "unknown", sharedMutable: false } },
|
|
24025
24025
|
stepId,
|
|
@@ -24059,7 +24059,7 @@ function recordGateCancelObservedInTransaction(context, run, envelope, stepId, o
|
|
|
24059
24059
|
});
|
|
24060
24060
|
}
|
|
24061
24061
|
seq.push("attempt.status_changed", { attemptId: ids.attemptId, assignmentId: ids.assignmentId, stepId, stepAttempt: ids.stepAttempt, status: "settling" });
|
|
24062
|
-
const observationId =
|
|
24062
|
+
const observationId = newKxmObservationId();
|
|
24063
24063
|
const policyClass = ids.gateKind === "artifacts-exist" ? "read-only" : "unknown";
|
|
24064
24064
|
const observed = seq.push("effect.observed", {
|
|
24065
24065
|
effect: { id: ids.effectId, policy: { class: policyClass, sharedMutable: false } },
|
|
@@ -24107,7 +24107,7 @@ function appendEvaluatedTail(seq, envelope, ids, stepId, outcome) {
|
|
|
24107
24107
|
seq.push("run.status_changed", { status: "failed", reason: "outcome_unknown", stepId, outcome });
|
|
24108
24108
|
return;
|
|
24109
24109
|
}
|
|
24110
|
-
const budget =
|
|
24110
|
+
const budget = kxmTransitionBudgetFailure(envelope.plan, ids.state, stepId, outcome);
|
|
24111
24111
|
if (budget) {
|
|
24112
24112
|
seq.push("run.status_changed", { status: "failed", reason: budget, stepId, outcome });
|
|
24113
24113
|
return;
|
|
@@ -24160,7 +24160,7 @@ function requireGateStep(envelope, stepId, runId) {
|
|
|
24160
24160
|
}
|
|
24161
24161
|
function requireIntent(context, run, envelope, stepId) {
|
|
24162
24162
|
const step = requireGateStep(envelope, stepId, run.runId);
|
|
24163
|
-
const folded =
|
|
24163
|
+
const folded = foldStoredKxmRun(context, run);
|
|
24164
24164
|
const attemptId = folded.currentStep?.attemptId;
|
|
24165
24165
|
if (!attemptId || folded.currentStep?.stepId !== stepId) {
|
|
24166
24166
|
throw runtimeError("run_events_illegal", run.runId, "gate intent has not been recorded");
|
|
@@ -24198,27 +24198,27 @@ function cancelReasonFromLog(context, runId) {
|
|
|
24198
24198
|
}
|
|
24199
24199
|
function sequencer(context, run, now) {
|
|
24200
24200
|
let sequence = context.eventStore.nextSequence(run.runId);
|
|
24201
|
-
let mono =
|
|
24201
|
+
let mono = kxmMonotonicNs();
|
|
24202
24202
|
const events = [];
|
|
24203
24203
|
return {
|
|
24204
24204
|
events,
|
|
24205
24205
|
push(eventType, payload) {
|
|
24206
24206
|
const event = {
|
|
24207
|
-
...
|
|
24208
|
-
eventId:
|
|
24207
|
+
...kxmEventBase(context, run, now, mono),
|
|
24208
|
+
eventId: newKxmEventId(),
|
|
24209
24209
|
eventType,
|
|
24210
24210
|
sequence: sequence++,
|
|
24211
24211
|
payload
|
|
24212
24212
|
};
|
|
24213
|
-
mono =
|
|
24213
|
+
mono = kxmIncrementMonotonicNs(mono);
|
|
24214
24214
|
events.push(event);
|
|
24215
24215
|
return event;
|
|
24216
24216
|
}
|
|
24217
24217
|
};
|
|
24218
24218
|
}
|
|
24219
24219
|
function persist(context, run, now, lastSequence) {
|
|
24220
|
-
const next =
|
|
24221
|
-
|
|
24220
|
+
const next = foldStoredKxmRun(context, run);
|
|
24221
|
+
persistKxmRunState(context, run.runId, next, lastSequence);
|
|
24222
24222
|
context.eventStore.updateRunStatus(run.runId, next.status, now);
|
|
24223
24223
|
return { state: next, run: { ...run, status: next.status, updatedAt: now } };
|
|
24224
24224
|
}
|
|
@@ -24382,10 +24382,10 @@ function parseRoutingRecordV2(value) {
|
|
|
24382
24382
|
return record2;
|
|
24383
24383
|
}
|
|
24384
24384
|
|
|
24385
|
-
// plugins/kxm/src/
|
|
24385
|
+
// plugins/kxm/src/engine.ts
|
|
24386
24386
|
var trustedProducers = /* @__PURE__ */ new WeakSet();
|
|
24387
24387
|
var CAPABILITY_PREFIX = "kxm-attempt-capability\0";
|
|
24388
|
-
function
|
|
24388
|
+
function createKxmSimulatedProducer(script) {
|
|
24389
24389
|
const producer = Object.freeze({
|
|
24390
24390
|
id: "driver-simulated",
|
|
24391
24391
|
async produce(request) {
|
|
@@ -24421,14 +24421,14 @@ function requireTrustedProducer(producer) {
|
|
|
24421
24421
|
function hashCapabilitySecret(secret) {
|
|
24422
24422
|
return `sha256:${createHash11("sha256").update(`${CAPABILITY_PREFIX}${secret}`, "utf8").digest("hex")}`;
|
|
24423
24423
|
}
|
|
24424
|
-
function
|
|
24424
|
+
function mintKxmCapabilitySecret() {
|
|
24425
24425
|
const secret = `kxmcap_${randomBytes2(32).toString("base64url")}`;
|
|
24426
24426
|
return { secret, hash: hashCapabilitySecret(secret) };
|
|
24427
24427
|
}
|
|
24428
24428
|
function mintCapabilitySecret() {
|
|
24429
|
-
return
|
|
24429
|
+
return mintKxmCapabilitySecret();
|
|
24430
24430
|
}
|
|
24431
|
-
function
|
|
24431
|
+
function pinKxmCompiledPlan(context, bundle, runId, options) {
|
|
24432
24432
|
return context.eventStore.transaction(() => {
|
|
24433
24433
|
const run = requireRun(context, runId);
|
|
24434
24434
|
if (run.projectId !== context.projectId || run.homeRuntimeId !== context.homeRuntimeId) {
|
|
@@ -24439,17 +24439,17 @@ function pinVnextCompiledPlan(context, bundle, runId, options) {
|
|
|
24439
24439
|
}
|
|
24440
24440
|
const workflow = bundle.workflows.get(run.workflowId);
|
|
24441
24441
|
if (!workflow) throw runtimeError("run_workflow_unknown", run.workflowId, `workflow ${run.workflowId} does not exist in this project`);
|
|
24442
|
-
const revisions =
|
|
24442
|
+
const revisions = kxmPolicyRevisions(bundle, options);
|
|
24443
24443
|
if (revisions.configRevision !== run.configRevision || revisions.executorPolicyRevision !== run.executorPolicyRevision || revisions.toolPolicyRevision !== run.toolPolicyRevision || revisions.memoryRevision !== run.memoryRevision) {
|
|
24444
24444
|
throw runtimeError("run_revision_drift", runId, "bundle revisions do not match the accepted run");
|
|
24445
24445
|
}
|
|
24446
|
-
const compiled =
|
|
24446
|
+
const compiled = freezeKxmCompiledPlan(compileKxmWorkflow({
|
|
24447
24447
|
id: run.workflowId,
|
|
24448
24448
|
value: workflow.value,
|
|
24449
24449
|
...workflow.logicalPath !== void 0 ? { logicalPath: workflow.logicalPath } : {}
|
|
24450
24450
|
}));
|
|
24451
24451
|
const envelope = {
|
|
24452
|
-
schema:
|
|
24452
|
+
schema: KXM_RUN_PLAN_SCHEMA,
|
|
24453
24453
|
runId: run.runId,
|
|
24454
24454
|
projectId: run.projectId,
|
|
24455
24455
|
homeRuntimeId: run.homeRuntimeId,
|
|
@@ -24460,11 +24460,11 @@ function pinVnextCompiledPlan(context, bundle, runId, options) {
|
|
|
24460
24460
|
toolPolicy: run.toolPolicyRevision,
|
|
24461
24461
|
memory: run.memoryRevision
|
|
24462
24462
|
},
|
|
24463
|
-
projectLimits:
|
|
24463
|
+
projectLimits: kxmProjectAdmissionLimits(bundle),
|
|
24464
24464
|
plan: compiled,
|
|
24465
24465
|
gates: pinnedGatesForCompiledPlan(compiled, bundle, context.projectRoot)
|
|
24466
24466
|
};
|
|
24467
|
-
const runPlanHash =
|
|
24467
|
+
const runPlanHash = hashKxmRunPlanEnvelope(envelope);
|
|
24468
24468
|
const existing = context.eventStore.runPlan(runId);
|
|
24469
24469
|
if (existing) {
|
|
24470
24470
|
if (existing.runPlanHash !== runPlanHash) {
|
|
@@ -24478,8 +24478,8 @@ function pinVnextCompiledPlan(context, bundle, runId, options) {
|
|
|
24478
24478
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
24479
24479
|
const sequence = context.eventStore.nextSequence(runId);
|
|
24480
24480
|
const event = {
|
|
24481
|
-
...
|
|
24482
|
-
eventId:
|
|
24481
|
+
...kxmEventBase(context, run, now, kxmMonotonicNs()),
|
|
24482
|
+
eventId: newKxmEventId(),
|
|
24483
24483
|
eventType: "run.status_changed",
|
|
24484
24484
|
sequence,
|
|
24485
24485
|
payload: { status: "preparing", runPlanHash }
|
|
@@ -24487,22 +24487,22 @@ function pinVnextCompiledPlan(context, bundle, runId, options) {
|
|
|
24487
24487
|
context.eventStore.insertRunPlan({
|
|
24488
24488
|
runId,
|
|
24489
24489
|
runPlanHash,
|
|
24490
|
-
envelope:
|
|
24490
|
+
envelope: kxmCanonicalJson(envelope),
|
|
24491
24491
|
pinnedSequence: sequence
|
|
24492
24492
|
});
|
|
24493
24493
|
context.eventStore.appendEvent(event);
|
|
24494
|
-
const state =
|
|
24495
|
-
|
|
24494
|
+
const state = foldStoredKxmRun(context, run);
|
|
24495
|
+
persistKxmRunState(context, runId, state, sequence);
|
|
24496
24496
|
context.eventStore.updateRunStatus(runId, "preparing", now);
|
|
24497
24497
|
return { plan: compiled, runPlanHash, idempotent: false, event };
|
|
24498
24498
|
});
|
|
24499
24499
|
}
|
|
24500
|
-
function
|
|
24500
|
+
function startKxmRun(context, runId, options = {}) {
|
|
24501
24501
|
return context.eventStore.transaction(() => {
|
|
24502
24502
|
const run = requireRun(context, runId);
|
|
24503
|
-
const envelope =
|
|
24503
|
+
const envelope = loadKxmRunPlanEnvelope(context.eventStore, run);
|
|
24504
24504
|
const unsupported = options.allowLimits ? void 0 : unsupportedLimit(envelope);
|
|
24505
|
-
const state =
|
|
24505
|
+
const state = foldStoredKxmRun(context, run);
|
|
24506
24506
|
if (unsupported) {
|
|
24507
24507
|
return { state, handoff: unsupported };
|
|
24508
24508
|
}
|
|
@@ -24512,15 +24512,15 @@ function startVnextRun(context, runId, options = {}) {
|
|
|
24512
24512
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
24513
24513
|
const sequence = context.eventStore.nextSequence(runId);
|
|
24514
24514
|
const event = {
|
|
24515
|
-
...
|
|
24516
|
-
eventId:
|
|
24515
|
+
...kxmEventBase(context, run, now, kxmMonotonicNs()),
|
|
24516
|
+
eventId: newKxmEventId(),
|
|
24517
24517
|
eventType: "run.status_changed",
|
|
24518
24518
|
sequence,
|
|
24519
24519
|
payload: { status: "running" }
|
|
24520
24520
|
};
|
|
24521
24521
|
context.eventStore.appendEvent(event);
|
|
24522
|
-
const next =
|
|
24523
|
-
|
|
24522
|
+
const next = foldStoredKxmRun(context, run);
|
|
24523
|
+
persistKxmRunState(context, runId, next, sequence);
|
|
24524
24524
|
context.eventStore.updateRunStatus(runId, "running", now);
|
|
24525
24525
|
return { state: next };
|
|
24526
24526
|
});
|
|
@@ -24528,10 +24528,10 @@ function startVnextRun(context, runId, options = {}) {
|
|
|
24528
24528
|
async function driveAdmitted(context, runId, producer, token, options = {}) {
|
|
24529
24529
|
const run = requireRun(context, runId);
|
|
24530
24530
|
if (run.status === "preparing") {
|
|
24531
|
-
const started =
|
|
24531
|
+
const started = startKxmRun(context, runId, options);
|
|
24532
24532
|
if (started.handoff || isTerminalRunStatus(started.state.status)) return started;
|
|
24533
24533
|
}
|
|
24534
|
-
let latest = { state:
|
|
24534
|
+
let latest = { state: foldStoredKxmRun(context, requireRun(context, runId)) };
|
|
24535
24535
|
while (latest.state.status === "running") {
|
|
24536
24536
|
const overBudget = cancelRunDurationIfExceeded(context, runId);
|
|
24537
24537
|
if (overBudget) return overBudget;
|
|
@@ -24551,9 +24551,9 @@ function newDriveId(runId, token, runtimeId, monotonicNs) {
|
|
|
24551
24551
|
return `drv_${createHash11("sha256").update(`${runId}\0${token}\0${runtimeId}\0${monotonicNs}`, "utf8").digest("hex").slice(0, 24)}`;
|
|
24552
24552
|
}
|
|
24553
24553
|
function driveErrorSummary(error) {
|
|
24554
|
-
const raw = error instanceof
|
|
24554
|
+
const raw = error instanceof KxmConfigError ? error.issues[0]?.code : void 0;
|
|
24555
24555
|
const className = raw && /^[a-z][a-z0-9]*(?:[-_][a-z0-9]+)*$/.test(raw) ? raw : "drive-failure";
|
|
24556
|
-
return { class: className, component: "
|
|
24556
|
+
return { class: className, component: "engine", retryable: false };
|
|
24557
24557
|
}
|
|
24558
24558
|
function receiptHandoff(handoff) {
|
|
24559
24559
|
return {
|
|
@@ -24569,24 +24569,24 @@ function appendDriveOpened(context, runId, driveId, mode) {
|
|
|
24569
24569
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
24570
24570
|
const sequence = context.eventStore.nextSequence(runId);
|
|
24571
24571
|
const event = {
|
|
24572
|
-
...
|
|
24573
|
-
eventId:
|
|
24572
|
+
...kxmEventBase(context, run, now, kxmMonotonicNs()),
|
|
24573
|
+
eventId: newKxmEventId(),
|
|
24574
24574
|
eventType: "run.drive_opened",
|
|
24575
24575
|
sequence,
|
|
24576
24576
|
payload: { driveId, mode }
|
|
24577
24577
|
};
|
|
24578
24578
|
context.eventStore.appendEvent(event);
|
|
24579
|
-
const next =
|
|
24580
|
-
|
|
24579
|
+
const next = foldStoredKxmRun(context, run);
|
|
24580
|
+
persistKxmRunState(context, runId, next, sequence);
|
|
24581
24581
|
return { sequence, occurredAt: now };
|
|
24582
24582
|
});
|
|
24583
24583
|
}
|
|
24584
24584
|
function recordDriveReceipt(context, session, closeInfo) {
|
|
24585
|
-
if (
|
|
24585
|
+
if (isKxmRuntimeContextClosed(context)) return;
|
|
24586
24586
|
try {
|
|
24587
24587
|
const run = context.eventStore.run(session.runId);
|
|
24588
24588
|
if (!run) return;
|
|
24589
|
-
const state =
|
|
24589
|
+
const state = foldStoredKxmRun(context, run);
|
|
24590
24590
|
const events = context.eventStore.events(session.runId, 0, 1e6);
|
|
24591
24591
|
if (events.length === 0) return;
|
|
24592
24592
|
const opened = state.drive;
|
|
@@ -24596,7 +24596,7 @@ function recordDriveReceipt(context, session, closeInfo) {
|
|
|
24596
24596
|
if (openedSequence === void 0) return;
|
|
24597
24597
|
const closedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
24598
24598
|
const receipt = {
|
|
24599
|
-
schema:
|
|
24599
|
+
schema: KXM_DRIVE_RECEIPT_SCHEMA,
|
|
24600
24600
|
driveId: session.driveId,
|
|
24601
24601
|
runId: session.runId,
|
|
24602
24602
|
projectId: run.projectId,
|
|
@@ -24606,7 +24606,7 @@ function recordDriveReceipt(context, session, closeInfo) {
|
|
|
24606
24606
|
openedSequence,
|
|
24607
24607
|
closedAt,
|
|
24608
24608
|
lastSequence: last.sequence,
|
|
24609
|
-
logHash:
|
|
24609
|
+
logHash: hashKxmDriveLog(events.filter((event) => event.sequence >= 1 && event.sequence <= last.sequence)),
|
|
24610
24610
|
settlement: {
|
|
24611
24611
|
kind: closeInfo.kind,
|
|
24612
24612
|
status: state.status,
|
|
@@ -24621,7 +24621,7 @@ function recordDriveReceipt(context, session, closeInfo) {
|
|
|
24621
24621
|
} catch {
|
|
24622
24622
|
}
|
|
24623
24623
|
}
|
|
24624
|
-
function
|
|
24624
|
+
function kxmDrivePollProjection(context, runId, state) {
|
|
24625
24625
|
if (!state.drive) return void 0;
|
|
24626
24626
|
const events = context.eventStore.events(runId, 0, 1e6);
|
|
24627
24627
|
const openedEvent = events.find((event) => event.sequence === state.drive.openedSequence);
|
|
@@ -24647,7 +24647,7 @@ function vnextDrivePollProjection(context, runId, state) {
|
|
|
24647
24647
|
projection.divergence = "no receipt";
|
|
24648
24648
|
return projection;
|
|
24649
24649
|
}
|
|
24650
|
-
const checked =
|
|
24650
|
+
const checked = verifyKxmDriveReceipt(receipt, events, state.status, {
|
|
24651
24651
|
runId,
|
|
24652
24652
|
driveId: state.drive.driveId
|
|
24653
24653
|
});
|
|
@@ -24659,7 +24659,7 @@ function inflightAttemptId(state) {
|
|
|
24659
24659
|
const leftover = unreconciledPanelAttemptId(state);
|
|
24660
24660
|
if (leftover) return leftover;
|
|
24661
24661
|
if (state.currentStep?.attemptId) {
|
|
24662
|
-
const located =
|
|
24662
|
+
const located = kxmFoldPanelAttempt(state.currentStep, state.currentStep.attemptId);
|
|
24663
24663
|
const status = located?.attempt.status;
|
|
24664
24664
|
if (status === "starting" || status === "executing" || status === "settling") return state.currentStep.attemptId;
|
|
24665
24665
|
}
|
|
@@ -24671,32 +24671,32 @@ function recordExecutingUnrecordedFailure(context, runId, attemptId, stepId) {
|
|
|
24671
24671
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
24672
24672
|
const sequence = context.eventStore.nextSequence(runId);
|
|
24673
24673
|
const event = {
|
|
24674
|
-
...
|
|
24675
|
-
eventId:
|
|
24674
|
+
...kxmEventBase(context, run, now, kxmMonotonicNs()),
|
|
24675
|
+
eventId: newKxmEventId(),
|
|
24676
24676
|
eventType: "run.status_changed",
|
|
24677
24677
|
sequence,
|
|
24678
24678
|
payload: { status: "failed", reason: "executing_unrecorded", stepId }
|
|
24679
24679
|
};
|
|
24680
24680
|
context.eventStore.appendEvent(event);
|
|
24681
24681
|
context.eventStore.settleCapability(attemptId, "revoked");
|
|
24682
|
-
const next =
|
|
24683
|
-
|
|
24682
|
+
const next = foldStoredKxmRun(context, run);
|
|
24683
|
+
persistKxmRunState(context, runId, next, sequence);
|
|
24684
24684
|
context.eventStore.updateRunStatus(runId, "failed", now);
|
|
24685
24685
|
});
|
|
24686
24686
|
}
|
|
24687
24687
|
function recordBareDriveFailure(context, runId) {
|
|
24688
|
-
if (
|
|
24688
|
+
if (isKxmRuntimeContextClosed(context)) return;
|
|
24689
24689
|
try {
|
|
24690
24690
|
const run = context.eventStore.run(runId);
|
|
24691
24691
|
if (!run) return;
|
|
24692
|
-
const state =
|
|
24692
|
+
const state = foldStoredKxmRun(context, run);
|
|
24693
24693
|
if (isTerminalRunStatus(state.status) || state.status === "cancelling") return;
|
|
24694
24694
|
const inflight = inflightAttemptId(state);
|
|
24695
24695
|
if (inflight) {
|
|
24696
24696
|
const currentStep = state.currentStep;
|
|
24697
|
-
const located =
|
|
24697
|
+
const located = kxmFoldPanelAttempt(currentStep, inflight);
|
|
24698
24698
|
if (currentStep && currentStep.panel.order.length === 1 && located?.attempt.status === "starting") {
|
|
24699
|
-
const plan =
|
|
24699
|
+
const plan = rehydrateKxmCompiledPlanFromStore(context.eventStore, run);
|
|
24700
24700
|
const step = plan.steps[currentStep.stepId];
|
|
24701
24701
|
if (step?.kind === "gate") return;
|
|
24702
24702
|
if (step && (step.kind === "agent" || step.kind === "moa") && step.assignments.maximum > 1) return;
|
|
@@ -24704,7 +24704,7 @@ function recordBareDriveFailure(context, runId) {
|
|
|
24704
24704
|
}
|
|
24705
24705
|
return;
|
|
24706
24706
|
}
|
|
24707
|
-
|
|
24707
|
+
cancelKxmRun(context, runId, { reason: "drive_error" });
|
|
24708
24708
|
} catch {
|
|
24709
24709
|
}
|
|
24710
24710
|
}
|
|
@@ -24715,7 +24715,7 @@ async function closeDriveProducer(producer) {
|
|
|
24715
24715
|
} catch {
|
|
24716
24716
|
}
|
|
24717
24717
|
}
|
|
24718
|
-
var
|
|
24718
|
+
var KxmRunScheduler = class _KxmRunScheduler {
|
|
24719
24719
|
context;
|
|
24720
24720
|
bundle;
|
|
24721
24721
|
configRevision;
|
|
@@ -24728,20 +24728,20 @@ var VnextRunScheduler = class _VnextRunScheduler {
|
|
|
24728
24728
|
if (String(bundle.project.value.id) !== context.projectId) {
|
|
24729
24729
|
throw runtimeError("run_owner_mismatch", context.projectId, "scheduler bundle project does not match the runtime context");
|
|
24730
24730
|
}
|
|
24731
|
-
const limits =
|
|
24732
|
-
|
|
24733
|
-
return new
|
|
24731
|
+
const limits = kxmProjectAdmissionLimits(bundle);
|
|
24732
|
+
bindKxmSchedulerPolicy(context.eventStore.path, limits.maxConcurrentRuns, bundle.configRevision);
|
|
24733
|
+
return new _KxmRunScheduler(context, bundle);
|
|
24734
24734
|
}
|
|
24735
24735
|
enqueue(runId, producer, options = {}) {
|
|
24736
24736
|
requireTrustedProducer(producer);
|
|
24737
|
-
const policy =
|
|
24737
|
+
const policy = kxmSchedulerPolicy(this.context.eventStore.path);
|
|
24738
24738
|
if (!policy || policy.configRevision !== this.configRevision) {
|
|
24739
24739
|
return Promise.reject(runtimeError("scheduler_policy_conflict", runId, "scheduler handle does not match the active policy"));
|
|
24740
24740
|
}
|
|
24741
24741
|
try {
|
|
24742
24742
|
const run = requireRun(this.context, runId);
|
|
24743
|
-
const envelope =
|
|
24744
|
-
return
|
|
24743
|
+
const envelope = loadKxmRunPlanEnvelope(this.context.eventStore, run);
|
|
24744
|
+
return enqueueKxmScheduledRun(
|
|
24745
24745
|
this.context.eventStore.path,
|
|
24746
24746
|
runId,
|
|
24747
24747
|
envelope.revisions.config,
|
|
@@ -24753,7 +24753,7 @@ var VnextRunScheduler = class _VnextRunScheduler {
|
|
|
24753
24753
|
}
|
|
24754
24754
|
}
|
|
24755
24755
|
openDriveSession(runId, options) {
|
|
24756
|
-
const policy =
|
|
24756
|
+
const policy = kxmSchedulerPolicy(this.context.eventStore.path);
|
|
24757
24757
|
if (!policy || policy.configRevision !== this.configRevision) {
|
|
24758
24758
|
return Promise.reject(runtimeError("scheduler_policy_conflict", runId, "scheduler handle does not match the active policy"));
|
|
24759
24759
|
}
|
|
@@ -24765,7 +24765,7 @@ var VnextRunScheduler = class _VnextRunScheduler {
|
|
|
24765
24765
|
} catch (error) {
|
|
24766
24766
|
return Promise.reject(error);
|
|
24767
24767
|
}
|
|
24768
|
-
const limits =
|
|
24768
|
+
const limits = kxmProjectAdmissionLimits(this.bundle);
|
|
24769
24769
|
const driveOptions = {
|
|
24770
24770
|
liveMode: options.liveMode ?? options.mode === "live"
|
|
24771
24771
|
};
|
|
@@ -24781,7 +24781,7 @@ var VnextRunScheduler = class _VnextRunScheduler {
|
|
|
24781
24781
|
});
|
|
24782
24782
|
void settled.then(void 0, () => void 0);
|
|
24783
24783
|
return new Promise((resolveOpen, rejectOpen) => {
|
|
24784
|
-
const queued =
|
|
24784
|
+
const queued = enqueueKxmScheduledRun(
|
|
24785
24785
|
this.context.eventStore.path,
|
|
24786
24786
|
runId,
|
|
24787
24787
|
this.configRevision,
|
|
@@ -24793,17 +24793,17 @@ var VnextRunScheduler = class _VnextRunScheduler {
|
|
|
24793
24793
|
requireTrustedProducer(producer);
|
|
24794
24794
|
const current = requireRun(this.context, runId);
|
|
24795
24795
|
if (current.status === "created") {
|
|
24796
|
-
|
|
24796
|
+
pinKxmCompiledPlan(this.context, this.bundle, runId);
|
|
24797
24797
|
}
|
|
24798
|
-
const started =
|
|
24798
|
+
const started = startKxmRun(this.context, runId, driveOptions);
|
|
24799
24799
|
if (started.handoff) {
|
|
24800
24800
|
const error = runtimeError("run_handoff_required", runId, started.handoff.detail);
|
|
24801
24801
|
Object.assign(error, { handoff: started.handoff });
|
|
24802
24802
|
throw error;
|
|
24803
24803
|
}
|
|
24804
|
-
const driveId = newDriveId(runId, token, this.context.homeRuntimeId,
|
|
24804
|
+
const driveId = newDriveId(runId, token, this.context.homeRuntimeId, kxmMonotonicNs());
|
|
24805
24805
|
const openedMeta = appendDriveOpened(this.context, runId, driveId, options.mode);
|
|
24806
|
-
const startedState =
|
|
24806
|
+
const startedState = foldStoredKxmRun(this.context, requireRun(this.context, runId));
|
|
24807
24807
|
const deadlineAt = driveDeadlineAt(this.context, runId, startedState);
|
|
24808
24808
|
const session = {
|
|
24809
24809
|
driveId,
|
|
@@ -24817,7 +24817,7 @@ var VnextRunScheduler = class _VnextRunScheduler {
|
|
|
24817
24817
|
settled,
|
|
24818
24818
|
...deadlineAt !== void 0 ? { deadlineAt } : {}
|
|
24819
24819
|
};
|
|
24820
|
-
|
|
24820
|
+
attachKxmDriveSession(this.context.eventStore.path, runId, token, session);
|
|
24821
24821
|
opened = true;
|
|
24822
24822
|
resolveOpen({ driveId, settled });
|
|
24823
24823
|
try {
|
|
@@ -24836,7 +24836,7 @@ var VnextRunScheduler = class _VnextRunScheduler {
|
|
|
24836
24836
|
recordBareDriveFailure(this.context, runId);
|
|
24837
24837
|
let foldedStatus;
|
|
24838
24838
|
try {
|
|
24839
|
-
foldedStatus =
|
|
24839
|
+
foldedStatus = foldStoredKxmRun(this.context, requireRun(this.context, runId)).status;
|
|
24840
24840
|
} catch {
|
|
24841
24841
|
foldedStatus = void 0;
|
|
24842
24842
|
}
|
|
@@ -24851,7 +24851,7 @@ var VnextRunScheduler = class _VnextRunScheduler {
|
|
|
24851
24851
|
}
|
|
24852
24852
|
} finally {
|
|
24853
24853
|
if (producer) await closeDriveProducer(producer);
|
|
24854
|
-
|
|
24854
|
+
clearKxmDriveSession(this.context.eventStore.path, runId, token);
|
|
24855
24855
|
}
|
|
24856
24856
|
}
|
|
24857
24857
|
);
|
|
@@ -24875,7 +24875,7 @@ function invokeProducer(producer, request) {
|
|
|
24875
24875
|
() => ({ error: true })
|
|
24876
24876
|
);
|
|
24877
24877
|
}
|
|
24878
|
-
var
|
|
24878
|
+
var kxmGateDispatchSeams = {};
|
|
24879
24879
|
async function stepLocked(context, runId, producer, token) {
|
|
24880
24880
|
const prepared = context.eventStore.transaction(() => prepareDispatch(context, runId, producer.id));
|
|
24881
24881
|
if (prepared.kind === "return") {
|
|
@@ -24893,15 +24893,15 @@ async function stepLocked(context, runId, producer, token) {
|
|
|
24893
24893
|
if (!definition || definition.kind !== "artifacts-exist") {
|
|
24894
24894
|
throw runtimeError("run_events_illegal", prepared.run.runId, "prepared gate is not artifacts-exist");
|
|
24895
24895
|
}
|
|
24896
|
-
|
|
24896
|
+
registerKxmAttemptController(context.eventStore.path, runId, { attemptId: prepared.attemptId, controller: prepared.controller });
|
|
24897
24897
|
const clearBudget = armRunDurationBudgetTimer(context, runId);
|
|
24898
24898
|
try {
|
|
24899
24899
|
const observation = evaluateArtifactsGate(context, definition);
|
|
24900
|
-
|
|
24900
|
+
kxmGateDispatchSeams.afterEvaluate?.(prepared);
|
|
24901
24901
|
return context.eventStore.transaction(() => settlePreparedGate(context, prepared, observation));
|
|
24902
24902
|
} finally {
|
|
24903
24903
|
clearBudget();
|
|
24904
|
-
|
|
24904
|
+
unregisterKxmAttemptController(context.eventStore.path, runId, prepared.attemptId);
|
|
24905
24905
|
}
|
|
24906
24906
|
}
|
|
24907
24907
|
return drivePanel(context, prepared.panel, producer);
|
|
@@ -24914,39 +24914,39 @@ async function runPreparedCommandGate(context, prepared, definition, token) {
|
|
|
24914
24914
|
cwd: context.projectRoot,
|
|
24915
24915
|
signal: prepared.controller.signal,
|
|
24916
24916
|
onSpawned: () => {
|
|
24917
|
-
if (
|
|
24917
|
+
if (isKxmRuntimeContextClosed(context)) return;
|
|
24918
24918
|
try {
|
|
24919
24919
|
context.eventStore.transaction(() => {
|
|
24920
24920
|
recordGateSpawnedInTransaction(context, prepared.run, prepared.envelope, prepared.stepId);
|
|
24921
|
-
|
|
24921
|
+
kxmGateDispatchSeams.afterSpawnRecord?.(prepared);
|
|
24922
24922
|
});
|
|
24923
24923
|
} catch (error) {
|
|
24924
24924
|
try {
|
|
24925
|
-
|
|
24925
|
+
markKxmGateHoldUnsettled(storePath, prepared.run.runId, token, prepared.attemptId);
|
|
24926
24926
|
} catch {
|
|
24927
24927
|
}
|
|
24928
24928
|
throw error;
|
|
24929
24929
|
}
|
|
24930
24930
|
}
|
|
24931
24931
|
});
|
|
24932
|
-
|
|
24933
|
-
|
|
24932
|
+
armKxmGateHold(storePath, prepared.run.runId, token, prepared.attemptId, () => observer.requestStop("cancel"));
|
|
24933
|
+
registerKxmAttemptController(storePath, prepared.run.runId, { attemptId: prepared.attemptId, controller: prepared.controller });
|
|
24934
24934
|
const clearBudget = armRunDurationBudgetTimer(context, prepared.run.runId);
|
|
24935
|
-
const unhookClose =
|
|
24935
|
+
const unhookClose = registerKxmRuntimeCloseHook(context, () => {
|
|
24936
24936
|
try {
|
|
24937
|
-
|
|
24937
|
+
markKxmGateHoldUnsettled(storePath, prepared.run.runId, token, prepared.attemptId);
|
|
24938
24938
|
} catch {
|
|
24939
24939
|
}
|
|
24940
|
-
|
|
24940
|
+
dropKxmGateStopHook(storePath, prepared.run.runId, prepared.attemptId);
|
|
24941
24941
|
observer.beginBoundedCleanup();
|
|
24942
24942
|
});
|
|
24943
24943
|
try {
|
|
24944
|
-
|
|
24944
|
+
kxmGateDispatchSeams.beforeCommandSpawn?.(prepared);
|
|
24945
24945
|
const outcome = await observer.run();
|
|
24946
|
-
|
|
24947
|
-
if (
|
|
24946
|
+
dropKxmGateStopHook(storePath, prepared.run.runId, prepared.attemptId);
|
|
24947
|
+
if (isKxmRuntimeContextClosed(context)) {
|
|
24948
24948
|
try {
|
|
24949
|
-
|
|
24949
|
+
markKxmGateHoldUnsettled(storePath, prepared.run.runId, token, prepared.attemptId);
|
|
24950
24950
|
} catch {
|
|
24951
24951
|
}
|
|
24952
24952
|
return closedCommandHandoff(context, prepared, outcome.kind === "uncertain" ? outcome.reason : "lost-close");
|
|
@@ -24956,13 +24956,13 @@ async function runPreparedCommandGate(context, prepared, definition, token) {
|
|
|
24956
24956
|
}
|
|
24957
24957
|
if (outcome.kind === "complete") {
|
|
24958
24958
|
try {
|
|
24959
|
-
|
|
24959
|
+
kxmGateDispatchSeams.beforeCommandSettle?.(prepared);
|
|
24960
24960
|
} catch (error) {
|
|
24961
24961
|
return recoverCommandRecordingFailure(context, prepared, token, outcome.observation, error);
|
|
24962
24962
|
}
|
|
24963
|
-
if (
|
|
24963
|
+
if (isKxmRuntimeContextClosed(context)) {
|
|
24964
24964
|
try {
|
|
24965
|
-
|
|
24965
|
+
markKxmGateHoldUnsettled(storePath, prepared.run.runId, token, prepared.attemptId);
|
|
24966
24966
|
} catch {
|
|
24967
24967
|
}
|
|
24968
24968
|
return closedCommandHandoff(context, prepared, "lost-close");
|
|
@@ -24973,13 +24973,13 @@ async function runPreparedCommandGate(context, prepared, definition, token) {
|
|
|
24973
24973
|
} finally {
|
|
24974
24974
|
unhookClose();
|
|
24975
24975
|
clearBudget();
|
|
24976
|
-
|
|
24976
|
+
unregisterKxmAttemptController(storePath, prepared.run.runId, prepared.attemptId);
|
|
24977
24977
|
}
|
|
24978
24978
|
}
|
|
24979
24979
|
function closedCommandHandoff(context, prepared, reason) {
|
|
24980
24980
|
let state;
|
|
24981
24981
|
try {
|
|
24982
|
-
state =
|
|
24982
|
+
state = foldStoredKxmRun(context, requireRun(context, prepared.run.runId));
|
|
24983
24983
|
} catch {
|
|
24984
24984
|
state = prepared.state;
|
|
24985
24985
|
}
|
|
@@ -25001,12 +25001,12 @@ function commitOwnedCommandSettlement(context, prepared, token, write, observati
|
|
|
25001
25001
|
return recoverCommandRecordingFailure(context, prepared, token, observation, error);
|
|
25002
25002
|
}
|
|
25003
25003
|
try {
|
|
25004
|
-
|
|
25004
|
+
kxmGateDispatchSeams.afterSettlementCommit?.(prepared);
|
|
25005
25005
|
} catch (error) {
|
|
25006
25006
|
return retainCommittedCommandProof(context, prepared, token, error);
|
|
25007
25007
|
}
|
|
25008
25008
|
try {
|
|
25009
|
-
|
|
25009
|
+
finishKxmOwnedGate(context.eventStore.path, prepared.run.runId, token, prepared.attemptId);
|
|
25010
25010
|
} catch (error) {
|
|
25011
25011
|
return retainCommittedCommandProof(context, prepared, token, error);
|
|
25012
25012
|
}
|
|
@@ -25020,7 +25020,7 @@ function retainCommittedCommandProof(context, prepared, token, error) {
|
|
|
25020
25020
|
throw error;
|
|
25021
25021
|
}
|
|
25022
25022
|
function finishOwnedGateAfterCommittedTerminalProof(context, prepared, token) {
|
|
25023
|
-
if (
|
|
25023
|
+
if (isKxmRuntimeContextClosed(context)) return;
|
|
25024
25024
|
const run = context.eventStore.run(prepared.run.runId);
|
|
25025
25025
|
if (!run || run.projectId !== context.projectId || run.homeRuntimeId !== context.homeRuntimeId) return;
|
|
25026
25026
|
const row = context.eventStore.gateAttempt(prepared.attemptId);
|
|
@@ -25039,7 +25039,7 @@ function finishOwnedGateAfterCommittedTerminalProof(context, prepared, token) {
|
|
|
25039
25039
|
const events = context.eventStore.events(prepared.run.runId, 0, 1e6);
|
|
25040
25040
|
let state;
|
|
25041
25041
|
try {
|
|
25042
|
-
state =
|
|
25042
|
+
state = foldStoredKxmRun(context, run);
|
|
25043
25043
|
} catch {
|
|
25044
25044
|
return;
|
|
25045
25045
|
}
|
|
@@ -25049,16 +25049,16 @@ function finishOwnedGateAfterCommittedTerminalProof(context, prepared, token) {
|
|
|
25049
25049
|
}
|
|
25050
25050
|
const terminalProof = isEvaluatedSettledProof(row, observation, evidence) || isExcludedTerminalProof(state, row, observation, evidence, events);
|
|
25051
25051
|
if (!terminalProof) return;
|
|
25052
|
-
const hold =
|
|
25053
|
-
const admittedToken =
|
|
25052
|
+
const hold = kxmGateHold(context.eventStore.path, prepared.run.runId);
|
|
25053
|
+
const admittedToken = kxmAdmittedToken(context.eventStore.path, prepared.run.runId);
|
|
25054
25054
|
if (!hold || hold.state !== "active" || hold.attemptId !== prepared.attemptId || hold.token !== token || admittedToken !== token) {
|
|
25055
25055
|
return;
|
|
25056
25056
|
}
|
|
25057
|
-
|
|
25057
|
+
finishKxmOwnedGate(context.eventStore.path, prepared.run.runId, token, prepared.attemptId);
|
|
25058
25058
|
}
|
|
25059
25059
|
function recoverCommandRecordingFailure(context, prepared, token, observation, error) {
|
|
25060
|
-
|
|
25061
|
-
if (
|
|
25060
|
+
markKxmGateHoldUnsettled(context.eventStore.path, prepared.run.runId, token, prepared.attemptId);
|
|
25061
|
+
if (isKxmRuntimeContextClosed(context)) {
|
|
25062
25062
|
throw error;
|
|
25063
25063
|
}
|
|
25064
25064
|
const existing = context.eventStore.gateObservationForAttempt(prepared.attemptId);
|
|
@@ -25069,7 +25069,7 @@ function recoverCommandRecordingFailure(context, prepared, token, observation, e
|
|
|
25069
25069
|
`command observation recording failed after committed proof: ${error instanceof Error ? error.message : String(error)}`
|
|
25070
25070
|
);
|
|
25071
25071
|
}
|
|
25072
|
-
const folded =
|
|
25072
|
+
const folded = foldStoredKxmRun(context, requireRun(context, prepared.run.runId));
|
|
25073
25073
|
if (folded.currentStep?.attemptId === prepared.attemptId && folded.currentStep.observationId) {
|
|
25074
25074
|
throw runtimeError(
|
|
25075
25075
|
"run_events_illegal",
|
|
@@ -25087,10 +25087,10 @@ function recoverCommandRecordingFailure(context, prepared, token, observation, e
|
|
|
25087
25087
|
}
|
|
25088
25088
|
function commitCommandUncertainty(context, prepared, token, reason, observation, priorError) {
|
|
25089
25089
|
try {
|
|
25090
|
-
|
|
25090
|
+
markKxmGateHoldUnsettled(context.eventStore.path, prepared.run.runId, token, prepared.attemptId);
|
|
25091
25091
|
} catch {
|
|
25092
25092
|
}
|
|
25093
|
-
if (
|
|
25093
|
+
if (isKxmRuntimeContextClosed(context)) {
|
|
25094
25094
|
if (priorError) throw priorError;
|
|
25095
25095
|
return closedCommandHandoff(context, prepared, reason);
|
|
25096
25096
|
}
|
|
@@ -25106,7 +25106,7 @@ function commitCommandUncertainty(context, prepared, token, reason, observation,
|
|
|
25106
25106
|
try {
|
|
25107
25107
|
const written = context.eventStore.transaction(() => {
|
|
25108
25108
|
const result = recordGateUncertainInTransaction(context, prepared.run, prepared.envelope, prepared.stepId, reason, incomplete);
|
|
25109
|
-
|
|
25109
|
+
kxmGateDispatchSeams.afterUncertaintyWrite?.(prepared);
|
|
25110
25110
|
return result;
|
|
25111
25111
|
});
|
|
25112
25112
|
return {
|
|
@@ -25123,7 +25123,7 @@ function commitCommandUncertainty(context, prepared, token, reason, observation,
|
|
|
25123
25123
|
throw error;
|
|
25124
25124
|
}
|
|
25125
25125
|
}
|
|
25126
|
-
var
|
|
25126
|
+
var kxmPanelDispatchSeams = {};
|
|
25127
25127
|
function unreconciledPanelAttemptId(state) {
|
|
25128
25128
|
const current = state.currentStep;
|
|
25129
25129
|
if (!current) return void 0;
|
|
@@ -25202,12 +25202,12 @@ function resolveProducerRoute(projectRoot, step, agentId) {
|
|
|
25202
25202
|
}
|
|
25203
25203
|
function prepareDispatch(context, runId, producerId) {
|
|
25204
25204
|
const run = requireRun(context, runId);
|
|
25205
|
-
const plan =
|
|
25206
|
-
const state =
|
|
25207
|
-
if (
|
|
25205
|
+
const plan = rehydrateKxmCompiledPlanFromStore(context.eventStore, run);
|
|
25206
|
+
const state = foldStoredKxmRun(context, run);
|
|
25207
|
+
if (kxmPanelDispatchSeams.skipDispatch?.()) {
|
|
25208
25208
|
return { kind: "return", state };
|
|
25209
25209
|
}
|
|
25210
|
-
if (state.status === "cancelling" &&
|
|
25210
|
+
if (state.status === "cancelling" && kxmAttemptControllers(context.eventStore.path, runId).length === 0) {
|
|
25211
25211
|
return {
|
|
25212
25212
|
kind: "return",
|
|
25213
25213
|
state,
|
|
@@ -25286,7 +25286,7 @@ function prepareDispatch(context, runId, producerId) {
|
|
|
25286
25286
|
return { kind: "return", ...failBudget(context, run, plan, state, "budget_unmetered_attempts", stepId) };
|
|
25287
25287
|
}
|
|
25288
25288
|
if (step.kind === "gate") {
|
|
25289
|
-
const envelope =
|
|
25289
|
+
const envelope = loadKxmRunPlanEnvelope(context.eventStore, run);
|
|
25290
25290
|
const unsupported2 = unsupportedGateStep(plan, step, envelope, context);
|
|
25291
25291
|
if (unsupported2) return { kind: "return", state, handoff: { ...unsupported2, stepId } };
|
|
25292
25292
|
const definition = envelope.gates.definitions[step.gate];
|
|
@@ -25345,23 +25345,23 @@ function prepareDispatch(context, runId, producerId) {
|
|
|
25345
25345
|
const stepAttempt = used + 1;
|
|
25346
25346
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
25347
25347
|
let sequence = context.eventStore.nextSequence(runId);
|
|
25348
|
-
let mono =
|
|
25348
|
+
let mono = kxmMonotonicNs();
|
|
25349
25349
|
const events = [];
|
|
25350
25350
|
const push = (eventType, payload) => {
|
|
25351
25351
|
events.push({
|
|
25352
|
-
...
|
|
25353
|
-
eventId:
|
|
25352
|
+
...kxmEventBase(context, run, now, mono),
|
|
25353
|
+
eventId: newKxmEventId(),
|
|
25354
25354
|
eventType,
|
|
25355
25355
|
sequence: sequence++,
|
|
25356
25356
|
payload
|
|
25357
25357
|
});
|
|
25358
|
-
mono =
|
|
25358
|
+
mono = kxmIncrementMonotonicNs(mono);
|
|
25359
25359
|
};
|
|
25360
25360
|
push("step.entered", { stepId, stepAttempt, status: "pending" });
|
|
25361
25361
|
push("step.status_changed", { stepId, status: "preparing", previousStatus: "pending" });
|
|
25362
25362
|
for (const event of events) context.eventStore.appendEvent(event);
|
|
25363
|
-
const entered =
|
|
25364
|
-
|
|
25363
|
+
const entered = foldStoredKxmRun(context, run);
|
|
25364
|
+
persistKxmRunState(context, runId, entered, events[events.length - 1].sequence);
|
|
25365
25365
|
const first = birthMember(context, {
|
|
25366
25366
|
run,
|
|
25367
25367
|
plan,
|
|
@@ -25414,7 +25414,7 @@ function birthAllowed(state, step) {
|
|
|
25414
25414
|
}
|
|
25415
25415
|
function birthMember(context, input) {
|
|
25416
25416
|
const run = requireRun(context, input.run.runId);
|
|
25417
|
-
const folded =
|
|
25417
|
+
const folded = foldStoredKxmRun(context, run);
|
|
25418
25418
|
if (!birthAllowed(folded, input.step)) {
|
|
25419
25419
|
throw runtimeError("run_events_illegal", run.runId, "member birth is not legal");
|
|
25420
25420
|
}
|
|
@@ -25437,23 +25437,23 @@ function birthMember(context, input) {
|
|
|
25437
25437
|
resolvedRoute = routeResult;
|
|
25438
25438
|
}
|
|
25439
25439
|
}
|
|
25440
|
-
const assignmentId =
|
|
25441
|
-
const attemptId =
|
|
25440
|
+
const assignmentId = newKxmAssignmentId();
|
|
25441
|
+
const attemptId = newKxmAttemptId();
|
|
25442
25442
|
const minted = mintCapabilitySecret();
|
|
25443
25443
|
const controller = new AbortController();
|
|
25444
25444
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
25445
25445
|
let sequence = context.eventStore.nextSequence(run.runId);
|
|
25446
|
-
let mono =
|
|
25446
|
+
let mono = kxmMonotonicNs();
|
|
25447
25447
|
const events = [];
|
|
25448
25448
|
const push = (eventType, payload) => {
|
|
25449
25449
|
events.push({
|
|
25450
|
-
...
|
|
25451
|
-
eventId:
|
|
25450
|
+
...kxmEventBase(context, run, now, mono),
|
|
25451
|
+
eventId: newKxmEventId(),
|
|
25452
25452
|
eventType,
|
|
25453
25453
|
sequence: sequence++,
|
|
25454
25454
|
payload
|
|
25455
25455
|
});
|
|
25456
|
-
mono =
|
|
25456
|
+
mono = kxmIncrementMonotonicNs(mono);
|
|
25457
25457
|
};
|
|
25458
25458
|
push("assignment.created", { assignmentId, stepId: input.stepId, stepAttempt: input.stepAttempt, agentId, status: "created" });
|
|
25459
25459
|
push("assignment.accepted", { assignmentId, status: "accepted" });
|
|
@@ -25479,8 +25479,8 @@ function birthMember(context, input) {
|
|
|
25479
25479
|
capabilityHash: minted.hash,
|
|
25480
25480
|
state: "issued"
|
|
25481
25481
|
});
|
|
25482
|
-
const next =
|
|
25483
|
-
|
|
25482
|
+
const next = foldStoredKxmRun(context, run);
|
|
25483
|
+
persistKxmRunState(context, run.runId, next, events[events.length - 1].sequence);
|
|
25484
25484
|
const rawContextPacket = buildFormalContextPacket({
|
|
25485
25485
|
project: run.projectId,
|
|
25486
25486
|
targetRole: agentId,
|
|
@@ -25540,33 +25540,33 @@ ${generatedPrompt}` : generatedPrompt,
|
|
|
25540
25540
|
controller,
|
|
25541
25541
|
state: next
|
|
25542
25542
|
};
|
|
25543
|
-
|
|
25543
|
+
kxmPanelDispatchSeams.afterBirth?.(member);
|
|
25544
25544
|
return member;
|
|
25545
25545
|
}
|
|
25546
25546
|
function appendExecuting(context, dispatch) {
|
|
25547
25547
|
const run = requireRun(context, dispatch.run.runId);
|
|
25548
25548
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
25549
25549
|
let sequence = context.eventStore.nextSequence(dispatch.run.runId);
|
|
25550
|
-
let mono =
|
|
25550
|
+
let mono = kxmMonotonicNs();
|
|
25551
25551
|
const events = [
|
|
25552
25552
|
{
|
|
25553
|
-
...
|
|
25554
|
-
eventId:
|
|
25553
|
+
...kxmEventBase(context, run, now, mono),
|
|
25554
|
+
eventId: newKxmEventId(),
|
|
25555
25555
|
eventType: "assignment.executing",
|
|
25556
25556
|
sequence: sequence++,
|
|
25557
25557
|
payload: { assignmentId: dispatch.assignmentId, status: "executing" }
|
|
25558
25558
|
},
|
|
25559
25559
|
{
|
|
25560
|
-
...
|
|
25561
|
-
eventId:
|
|
25560
|
+
...kxmEventBase(context, run, now, kxmIncrementMonotonicNs(mono)),
|
|
25561
|
+
eventId: newKxmEventId(),
|
|
25562
25562
|
eventType: "attempt.status_changed",
|
|
25563
25563
|
sequence: sequence++,
|
|
25564
25564
|
payload: { attemptId: dispatch.attemptId, status: "executing" }
|
|
25565
25565
|
}
|
|
25566
25566
|
];
|
|
25567
25567
|
for (const event of events) context.eventStore.appendEvent(event);
|
|
25568
|
-
const next =
|
|
25569
|
-
|
|
25568
|
+
const next = foldStoredKxmRun(context, run);
|
|
25569
|
+
persistKxmRunState(context, run.runId, next, events[events.length - 1].sequence);
|
|
25570
25570
|
}
|
|
25571
25571
|
function singletonPanel(step) {
|
|
25572
25572
|
return step.assignments.maximum === 1 && step.assignments.target === 1;
|
|
@@ -25600,7 +25600,7 @@ async function drivePanel(context, panel, producer) {
|
|
|
25600
25600
|
let settlementFailed = false;
|
|
25601
25601
|
const budgetClears = /* @__PURE__ */ new Map();
|
|
25602
25602
|
const register = (member) => {
|
|
25603
|
-
|
|
25603
|
+
registerKxmAttemptController(context.eventStore.path, runId, { attemptId: member.attemptId, controller: member.controller });
|
|
25604
25604
|
budgetClears.set(member.attemptId, armRunDurationBudgetTimer(context, runId));
|
|
25605
25605
|
owned.set(member.attemptId, member);
|
|
25606
25606
|
};
|
|
@@ -25611,15 +25611,15 @@ async function drivePanel(context, panel, producer) {
|
|
|
25611
25611
|
register(member);
|
|
25612
25612
|
const work = (async () => {
|
|
25613
25613
|
try {
|
|
25614
|
-
|
|
25614
|
+
kxmPanelDispatchSeams.beforeAppendExecuting?.(member);
|
|
25615
25615
|
const started = context.eventStore.transaction(() => {
|
|
25616
|
-
if (
|
|
25616
|
+
if (kxmPanelDispatchSeams.failAppendExecuting?.(member)) {
|
|
25617
25617
|
throw runtimeError("run_events_illegal", runId, "appendExecuting failed");
|
|
25618
25618
|
}
|
|
25619
25619
|
const run = requireRun(context, runId);
|
|
25620
|
-
const state =
|
|
25620
|
+
const state = foldStoredKxmRun(context, run);
|
|
25621
25621
|
const capability = context.eventStore.capabilityByAttempt(member.attemptId);
|
|
25622
|
-
const located =
|
|
25622
|
+
const located = kxmFoldPanelAttempt(state.currentStep, member.attemptId);
|
|
25623
25623
|
if (state.cancelRequested || state.status === "cancelling" || !capabilityMatchesDispatch(capability, member, ["issued"], producer.id) || !located || located.assignmentId !== member.assignmentId || located.attempt.status !== "starting") {
|
|
25624
25624
|
return false;
|
|
25625
25625
|
}
|
|
@@ -25629,16 +25629,16 @@ async function drivePanel(context, panel, producer) {
|
|
|
25629
25629
|
if (!started) return { attemptId: member.attemptId, invoked: false, skipped: true };
|
|
25630
25630
|
const executingBound = () => {
|
|
25631
25631
|
const run = requireRun(context, runId);
|
|
25632
|
-
const state =
|
|
25632
|
+
const state = foldStoredKxmRun(context, run);
|
|
25633
25633
|
const capability = context.eventStore.capabilityByAttempt(member.attemptId);
|
|
25634
|
-
const located =
|
|
25634
|
+
const located = kxmFoldPanelAttempt(state.currentStep, member.attemptId);
|
|
25635
25635
|
if (state.cancelRequested || state.status === "cancelling" || !capabilityMatchesDispatch(capability, member, ["issued"], producer.id) || !located || located.assignmentId !== member.assignmentId || located.attempt.status !== "executing") {
|
|
25636
25636
|
return false;
|
|
25637
25637
|
}
|
|
25638
25638
|
return true;
|
|
25639
25639
|
};
|
|
25640
25640
|
if (!executingBound()) return { attemptId: member.attemptId, invoked: false, skipped: true };
|
|
25641
|
-
|
|
25641
|
+
kxmPanelDispatchSeams.beforeInvoke?.(member);
|
|
25642
25642
|
if (!executingBound()) return { attemptId: member.attemptId, invoked: false, skipped: true };
|
|
25643
25643
|
const produced = await invokeProducer(producer, member.request);
|
|
25644
25644
|
return { attemptId: member.attemptId, invoked: true, produced };
|
|
@@ -25653,7 +25653,7 @@ async function drivePanel(context, panel, producer) {
|
|
|
25653
25653
|
if (stopBirths) return void 0;
|
|
25654
25654
|
return context.eventStore.transaction(() => {
|
|
25655
25655
|
const run = requireRun(context, runId);
|
|
25656
|
-
const state =
|
|
25656
|
+
const state = foldStoredKxmRun(context, run);
|
|
25657
25657
|
if (!birthAllowed(state, panel.step)) return void 0;
|
|
25658
25658
|
return birthMember(context, {
|
|
25659
25659
|
run,
|
|
@@ -25673,7 +25673,7 @@ async function drivePanel(context, panel, producer) {
|
|
|
25673
25673
|
}
|
|
25674
25674
|
try {
|
|
25675
25675
|
context.eventStore.transaction(() => {
|
|
25676
|
-
if (
|
|
25676
|
+
if (kxmPanelDispatchSeams.failSettleMember?.(member)) {
|
|
25677
25677
|
throw runtimeError("run_events_illegal", runId, "member settlement write failed");
|
|
25678
25678
|
}
|
|
25679
25679
|
settleMember(context, member, produced.result, produced.error);
|
|
@@ -25712,7 +25712,7 @@ async function drivePanel(context, panel, producer) {
|
|
|
25712
25712
|
stopBirths = true;
|
|
25713
25713
|
abortOwned();
|
|
25714
25714
|
await drainPendingInvoked();
|
|
25715
|
-
const state =
|
|
25715
|
+
const state = foldStoredKxmRun(context, requireRun(context, runId));
|
|
25716
25716
|
return unreconciledHandoff(state, panel.stepId);
|
|
25717
25717
|
}
|
|
25718
25718
|
}
|
|
@@ -25736,7 +25736,7 @@ async function drivePanel(context, panel, producer) {
|
|
|
25736
25736
|
settleInvoked(sibling, item.produced);
|
|
25737
25737
|
}
|
|
25738
25738
|
}
|
|
25739
|
-
const state =
|
|
25739
|
+
const state = foldStoredKxmRun(context, requireRun(context, runId));
|
|
25740
25740
|
return unreconciledHandoff(state, panel.stepId, member.attemptId);
|
|
25741
25741
|
}
|
|
25742
25742
|
if (!finished.invoked) {
|
|
@@ -25753,18 +25753,18 @@ async function drivePanel(context, panel, producer) {
|
|
|
25753
25753
|
settleInvoked(sibling, item.produced);
|
|
25754
25754
|
}
|
|
25755
25755
|
}
|
|
25756
|
-
const state =
|
|
25756
|
+
const state = foldStoredKxmRun(context, requireRun(context, runId));
|
|
25757
25757
|
return unreconciledHandoff(state, panel.stepId, member.attemptId);
|
|
25758
25758
|
}
|
|
25759
25759
|
}
|
|
25760
|
-
const folded =
|
|
25760
|
+
const folded = foldStoredKxmRun(context, requireRun(context, runId));
|
|
25761
25761
|
const leftover = unreconciledPanelAttemptId(folded);
|
|
25762
25762
|
if (leftover || settlementFailed) {
|
|
25763
25763
|
return unreconciledHandoff(folded, panel.stepId, leftover);
|
|
25764
25764
|
}
|
|
25765
25765
|
const born = folded.currentStep?.panel.order.length ?? 0;
|
|
25766
25766
|
const allTerminal = Boolean(
|
|
25767
|
-
folded.currentStep && born > 0 && folded.currentStep.panel.order.every((assignmentId) => folded.currentStep?.panel.assignments[assignmentId]?.status === "terminal") &&
|
|
25767
|
+
folded.currentStep && born > 0 && folded.currentStep.panel.order.every((assignmentId) => folded.currentStep?.panel.assignments[assignmentId]?.status === "terminal") && kxmFoldPanelAttemptIds(folded.currentStep).every((attemptId) => kxmFoldPanelAttempt(folded.currentStep, attemptId)?.attempt.status === "terminal")
|
|
25768
25768
|
);
|
|
25769
25769
|
if (!allTerminal) {
|
|
25770
25770
|
return unreconciledHandoff(folded, panel.stepId, leftover);
|
|
@@ -25775,7 +25775,7 @@ async function drivePanel(context, panel, producer) {
|
|
|
25775
25775
|
try {
|
|
25776
25776
|
return context.eventStore.transaction(() => joinPanel(context, panel));
|
|
25777
25777
|
} catch {
|
|
25778
|
-
const state =
|
|
25778
|
+
const state = foldStoredKxmRun(context, requireRun(context, runId));
|
|
25779
25779
|
return unreconciledHandoff(state, panel.stepId);
|
|
25780
25780
|
}
|
|
25781
25781
|
} catch (error) {
|
|
@@ -25785,7 +25785,7 @@ async function drivePanel(context, panel, producer) {
|
|
|
25785
25785
|
} finally {
|
|
25786
25786
|
for (const attemptId of owned.keys()) {
|
|
25787
25787
|
budgetClears.get(attemptId)?.();
|
|
25788
|
-
|
|
25788
|
+
unregisterKxmAttemptController(context.eventStore.path, runId, attemptId);
|
|
25789
25789
|
}
|
|
25790
25790
|
}
|
|
25791
25791
|
}
|
|
@@ -25800,7 +25800,7 @@ function producerRoutingRecord(context, dispatch, result, now) {
|
|
|
25800
25800
|
if (result.costBasis === "metered" && (typeof result.costUsd !== "number" || !Number.isFinite(result.costUsd) || result.costUsd < 0)) {
|
|
25801
25801
|
throw runtimeError("settle_invalid_cost", run.runId, "attempt settlement rejected: metered costBasis requires non-negative finite costUsd");
|
|
25802
25802
|
}
|
|
25803
|
-
const envelope =
|
|
25803
|
+
const envelope = loadKxmRunPlanEnvelope(context.eventStore, run);
|
|
25804
25804
|
const rawHash = result.behavioralSha256 ?? behavioralConfigHash({
|
|
25805
25805
|
requestedModel: result.requestedModel ?? "simulated",
|
|
25806
25806
|
effectiveModel: result.effectiveModel ?? result.requestedModel ?? "simulated",
|
|
@@ -25833,26 +25833,26 @@ function producerRoutingRecord(context, dispatch, result, now) {
|
|
|
25833
25833
|
}
|
|
25834
25834
|
function settleMember(context, dispatch, result, produceError) {
|
|
25835
25835
|
const run = requireRun(context, dispatch.run.runId);
|
|
25836
|
-
const state =
|
|
25836
|
+
const state = foldStoredKxmRun(context, run);
|
|
25837
25837
|
const capability = context.eventStore.capabilityByAttempt(dispatch.attemptId);
|
|
25838
|
-
const located =
|
|
25838
|
+
const located = kxmFoldPanelAttempt(state.currentStep, dispatch.attemptId);
|
|
25839
25839
|
if (!located || located.assignmentId !== dispatch.assignmentId || located.attempt.status !== "executing" || !capability || !capabilityMatchesDispatch(capability, dispatch, ["issued", "revoked"])) {
|
|
25840
25840
|
throw runtimeError("run_events_illegal", run.runId, "settle attempted for a non-current capability");
|
|
25841
25841
|
}
|
|
25842
25842
|
const cancelling = state.status === "cancelling" || capability.state === "revoked";
|
|
25843
25843
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
25844
25844
|
let sequence = context.eventStore.nextSequence(run.runId);
|
|
25845
|
-
let mono =
|
|
25845
|
+
let mono = kxmMonotonicNs();
|
|
25846
25846
|
const events = [];
|
|
25847
25847
|
const push = (eventType, payload) => {
|
|
25848
25848
|
events.push({
|
|
25849
|
-
...
|
|
25850
|
-
eventId:
|
|
25849
|
+
...kxmEventBase(context, run, now, mono),
|
|
25850
|
+
eventId: newKxmEventId(),
|
|
25851
25851
|
eventType,
|
|
25852
25852
|
sequence: sequence++,
|
|
25853
25853
|
payload
|
|
25854
25854
|
});
|
|
25855
|
-
mono =
|
|
25855
|
+
mono = kxmIncrementMonotonicNs(mono);
|
|
25856
25856
|
};
|
|
25857
25857
|
push("attempt.status_changed", { attemptId: dispatch.attemptId, status: "settling" });
|
|
25858
25858
|
if (cancelling) {
|
|
@@ -25866,7 +25866,7 @@ function settleMember(context, dispatch, result, produceError) {
|
|
|
25866
25866
|
push("attempt.status_changed", { attemptId: dispatch.attemptId, status: "terminal" });
|
|
25867
25867
|
push("assignment.terminal", { assignmentId: dispatch.assignmentId, outcome: "cancelled", status: "terminal" });
|
|
25868
25868
|
} else if (produceError) {
|
|
25869
|
-
const envelope =
|
|
25869
|
+
const envelope = loadKxmRunPlanEnvelope(context.eventStore, run);
|
|
25870
25870
|
const rawHash = result?.behavioralSha256 ?? behavioralConfigHash({
|
|
25871
25871
|
requestedModel: result?.requestedModel ?? "simulated",
|
|
25872
25872
|
effectiveModel: result?.effectiveModel ?? result?.requestedModel ?? "simulated",
|
|
@@ -25928,37 +25928,37 @@ function settleMember(context, dispatch, result, produceError) {
|
|
|
25928
25928
|
}
|
|
25929
25929
|
context.eventStore.settleCapability(dispatch.attemptId, "settled");
|
|
25930
25930
|
for (const event of events) context.eventStore.appendEvent(event);
|
|
25931
|
-
const next =
|
|
25932
|
-
|
|
25931
|
+
const next = foldStoredKxmRun(context, run);
|
|
25932
|
+
persistKxmRunState(context, run.runId, next, events[events.length - 1].sequence);
|
|
25933
25933
|
}
|
|
25934
25934
|
function joinPanel(context, panel) {
|
|
25935
25935
|
const run = requireRun(context, panel.run.runId);
|
|
25936
|
-
const state =
|
|
25936
|
+
const state = foldStoredKxmRun(context, run);
|
|
25937
25937
|
const current = state.currentStep;
|
|
25938
25938
|
if (!current || current.stepId !== panel.stepId) {
|
|
25939
25939
|
throw runtimeError("run_events_illegal", run.runId, "join attempted without the prepared step");
|
|
25940
25940
|
}
|
|
25941
|
-
const joined =
|
|
25941
|
+
const joined = kxmJoinAll(panel.step, current.panel);
|
|
25942
25942
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
25943
25943
|
let sequence = context.eventStore.nextSequence(run.runId);
|
|
25944
|
-
let mono =
|
|
25944
|
+
let mono = kxmMonotonicNs();
|
|
25945
25945
|
const events = [];
|
|
25946
25946
|
const push = (eventType, payload) => {
|
|
25947
25947
|
events.push({
|
|
25948
|
-
...
|
|
25949
|
-
eventId:
|
|
25948
|
+
...kxmEventBase(context, run, now, mono),
|
|
25949
|
+
eventId: newKxmEventId(),
|
|
25950
25950
|
eventType,
|
|
25951
25951
|
sequence: sequence++,
|
|
25952
25952
|
payload
|
|
25953
25953
|
});
|
|
25954
|
-
mono =
|
|
25954
|
+
mono = kxmIncrementMonotonicNs(mono);
|
|
25955
25955
|
};
|
|
25956
25956
|
const failRun = (reason) => {
|
|
25957
25957
|
push("step.status_changed", { stepId: panel.stepId, status: "failed", previousStatus: "running" });
|
|
25958
25958
|
push("run.status_changed", { status: "failed", reason, stepId: panel.stepId });
|
|
25959
25959
|
for (const event of events) context.eventStore.appendEvent(event);
|
|
25960
|
-
const next2 =
|
|
25961
|
-
|
|
25960
|
+
const next2 = foldStoredKxmRun(context, run);
|
|
25961
|
+
persistKxmRunState(context, run.runId, next2, events[events.length - 1].sequence);
|
|
25962
25962
|
context.eventStore.updateRunStatus(run.runId, "failed", now);
|
|
25963
25963
|
return { state: next2 };
|
|
25964
25964
|
};
|
|
@@ -25966,8 +25966,8 @@ function joinPanel(context, panel) {
|
|
|
25966
25966
|
push("step.status_changed", { stepId: panel.stepId, status: "cancelled", previousStatus: "running" });
|
|
25967
25967
|
push("run.status_changed", { status: "cancelled", reason: cancelReasonFromLog2(context, run.runId) });
|
|
25968
25968
|
for (const event of events) context.eventStore.appendEvent(event);
|
|
25969
|
-
const next2 =
|
|
25970
|
-
|
|
25969
|
+
const next2 = foldStoredKxmRun(context, run);
|
|
25970
|
+
persistKxmRunState(context, run.runId, next2, events[events.length - 1].sequence);
|
|
25971
25971
|
context.eventStore.updateRunStatus(run.runId, "cancelled", now);
|
|
25972
25972
|
return { state: next2 };
|
|
25973
25973
|
};
|
|
@@ -26003,8 +26003,8 @@ function joinPanel(context, panel) {
|
|
|
26003
26003
|
if (budget) {
|
|
26004
26004
|
push("run.status_changed", { status: "failed", reason: budget, stepId: panel.stepId, outcome });
|
|
26005
26005
|
for (const event of events) context.eventStore.appendEvent(event);
|
|
26006
|
-
const next2 =
|
|
26007
|
-
|
|
26006
|
+
const next2 = foldStoredKxmRun(context, run);
|
|
26007
|
+
persistKxmRunState(context, run.runId, next2, events[events.length - 1].sequence);
|
|
26008
26008
|
context.eventStore.updateRunStatus(run.runId, "failed", now);
|
|
26009
26009
|
return { state: next2 };
|
|
26010
26010
|
}
|
|
@@ -26015,8 +26015,8 @@ function joinPanel(context, panel) {
|
|
|
26015
26015
|
push("run.status_changed", { status: selected.terminalStatus });
|
|
26016
26016
|
}
|
|
26017
26017
|
for (const event of events) context.eventStore.appendEvent(event);
|
|
26018
|
-
const next =
|
|
26019
|
-
|
|
26018
|
+
const next = foldStoredKxmRun(context, run);
|
|
26019
|
+
persistKxmRunState(context, run.runId, next, events[events.length - 1].sequence);
|
|
26020
26020
|
context.eventStore.updateRunStatus(run.runId, next.status, now);
|
|
26021
26021
|
return { state: next };
|
|
26022
26022
|
}
|
|
@@ -26024,15 +26024,15 @@ function failBudget(context, run, plan, state, reason, stepId) {
|
|
|
26024
26024
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
26025
26025
|
const sequence = context.eventStore.nextSequence(run.runId);
|
|
26026
26026
|
const event = {
|
|
26027
|
-
...
|
|
26028
|
-
eventId:
|
|
26027
|
+
...kxmEventBase(context, run, now, kxmMonotonicNs()),
|
|
26028
|
+
eventId: newKxmEventId(),
|
|
26029
26029
|
eventType: "run.status_changed",
|
|
26030
26030
|
sequence,
|
|
26031
26031
|
payload: { status: "failed", reason, stepId }
|
|
26032
26032
|
};
|
|
26033
26033
|
context.eventStore.appendEvent(event);
|
|
26034
|
-
const next =
|
|
26035
|
-
|
|
26034
|
+
const next = foldStoredKxmRun(context, run);
|
|
26035
|
+
persistKxmRunState(context, run.runId, next, sequence);
|
|
26036
26036
|
context.eventStore.updateRunStatus(run.runId, "failed", now);
|
|
26037
26037
|
void state;
|
|
26038
26038
|
return { state: next };
|
|
@@ -26042,19 +26042,19 @@ function hardStopUnrecorded(context, dispatch, reason) {
|
|
|
26042
26042
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
26043
26043
|
const sequence = context.eventStore.nextSequence(run.runId);
|
|
26044
26044
|
const event = {
|
|
26045
|
-
...
|
|
26046
|
-
eventId:
|
|
26045
|
+
...kxmEventBase(context, run, now, kxmMonotonicNs()),
|
|
26046
|
+
eventId: newKxmEventId(),
|
|
26047
26047
|
eventType: "run.status_changed",
|
|
26048
26048
|
sequence,
|
|
26049
26049
|
payload: { status: "failed", reason, stepId: dispatch.stepId }
|
|
26050
26050
|
};
|
|
26051
26051
|
context.eventStore.appendEvent(event);
|
|
26052
26052
|
context.eventStore.settleCapability(dispatch.attemptId, "revoked");
|
|
26053
|
-
const next =
|
|
26054
|
-
|
|
26053
|
+
const next = foldStoredKxmRun(context, run);
|
|
26054
|
+
persistKxmRunState(context, run.runId, next, sequence);
|
|
26055
26055
|
context.eventStore.updateRunStatus(run.runId, "failed", now);
|
|
26056
26056
|
}
|
|
26057
|
-
function
|
|
26057
|
+
function kxmTransitionBudgetFailure(plan, state, fromStepId, outcome) {
|
|
26058
26058
|
return transitionBudgetFailure(plan, state, fromStepId, outcome);
|
|
26059
26059
|
}
|
|
26060
26060
|
function transitionBudgetFailure(plan, state, fromStepId, outcome) {
|
|
@@ -26082,7 +26082,7 @@ function declaredRunDurationBudget(context, runId) {
|
|
|
26082
26082
|
const run = context.eventStore.run(runId);
|
|
26083
26083
|
if (!run) return void 0;
|
|
26084
26084
|
try {
|
|
26085
|
-
const envelope =
|
|
26085
|
+
const envelope = loadKxmRunPlanEnvelope(context.eventStore, run);
|
|
26086
26086
|
return effectiveRunDurationBudget(envelope.plan.limits, envelope.projectLimits);
|
|
26087
26087
|
} catch {
|
|
26088
26088
|
return void 0;
|
|
@@ -26093,7 +26093,7 @@ function runDurationOverrunPayload(context, runId, nowIso2 = (/* @__PURE__ */ ne
|
|
|
26093
26093
|
if (!declared) return void 0;
|
|
26094
26094
|
const run = context.eventStore.run(runId);
|
|
26095
26095
|
if (!run) return void 0;
|
|
26096
|
-
const state =
|
|
26096
|
+
const state = foldStoredKxmRun(context, run);
|
|
26097
26097
|
if (!state.runningSince) return void 0;
|
|
26098
26098
|
if (isTerminalRunStatus(state.status) || state.status === "cancelling") return void 0;
|
|
26099
26099
|
const elapsedMs = elapsedMsBetween(state.runningSince, nowIso2);
|
|
@@ -26101,11 +26101,11 @@ function runDurationOverrunPayload(context, runId, nowIso2 = (/* @__PURE__ */ ne
|
|
|
26101
26101
|
return { budgetMs: declared.budgetMs, elapsedMs, source: declared.source };
|
|
26102
26102
|
}
|
|
26103
26103
|
function cancelRunDurationIfExceeded(context, runId) {
|
|
26104
|
-
if (
|
|
26104
|
+
if (isKxmRuntimeContextClosed(context)) return void 0;
|
|
26105
26105
|
const payload = runDurationOverrunPayload(context, runId);
|
|
26106
26106
|
if (!payload) return void 0;
|
|
26107
|
-
|
|
26108
|
-
return { state:
|
|
26107
|
+
cancelKxmRun(context, runId, { reason: "budget_run_duration", budget: payload });
|
|
26108
|
+
return { state: foldStoredKxmRun(context, requireRun(context, runId)) };
|
|
26109
26109
|
}
|
|
26110
26110
|
function driveDeadlineAt(context, runId, state) {
|
|
26111
26111
|
const declared = declaredRunDurationBudget(context, runId);
|
|
@@ -26141,7 +26141,7 @@ function armRunDurationBudgetTimer(context, runId) {
|
|
|
26141
26141
|
if (!declared) return () => void 0;
|
|
26142
26142
|
const run = context.eventStore.run(runId);
|
|
26143
26143
|
if (!run) return () => void 0;
|
|
26144
|
-
const state =
|
|
26144
|
+
const state = foldStoredKxmRun(context, run);
|
|
26145
26145
|
if (!state.runningSince) return () => void 0;
|
|
26146
26146
|
const startMs = Date.parse(state.runningSince);
|
|
26147
26147
|
if (!Number.isFinite(startMs)) return () => void 0;
|
|
@@ -26150,7 +26150,7 @@ function armRunDurationBudgetTimer(context, runId) {
|
|
|
26150
26150
|
let cleared = false;
|
|
26151
26151
|
const fire = () => {
|
|
26152
26152
|
timer = void 0;
|
|
26153
|
-
if (cleared ||
|
|
26153
|
+
if (cleared || isKxmRuntimeContextClosed(context)) return;
|
|
26154
26154
|
const nowIso2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
26155
26155
|
const elapsedMs = elapsedMsBetween(state.runningSince, nowIso2);
|
|
26156
26156
|
if (elapsedMs < declared.budgetMs) {
|
|
@@ -26158,7 +26158,7 @@ function armRunDurationBudgetTimer(context, runId) {
|
|
|
26158
26158
|
return;
|
|
26159
26159
|
}
|
|
26160
26160
|
try {
|
|
26161
|
-
|
|
26161
|
+
cancelKxmRun(context, runId, {
|
|
26162
26162
|
reason: "budget_run_duration",
|
|
26163
26163
|
budget: { budgetMs: declared.budgetMs, elapsedMs, source: declared.source }
|
|
26164
26164
|
});
|
|
@@ -26171,7 +26171,7 @@ function armRunDurationBudgetTimer(context, runId) {
|
|
|
26171
26171
|
timer = setTimeout(fire, delay);
|
|
26172
26172
|
timer.unref();
|
|
26173
26173
|
};
|
|
26174
|
-
const unhook =
|
|
26174
|
+
const unhook = registerKxmRuntimeCloseHook(context, () => {
|
|
26175
26175
|
cleared = true;
|
|
26176
26176
|
if (timer !== void 0) clearTimeout(timer);
|
|
26177
26177
|
timer = void 0;
|
|
@@ -26446,7 +26446,7 @@ function classifyRecoverableGateAttempt(context, row, capability) {
|
|
|
26446
26446
|
}
|
|
26447
26447
|
let state;
|
|
26448
26448
|
try {
|
|
26449
|
-
state =
|
|
26449
|
+
state = foldStoredKxmRun(context, run);
|
|
26450
26450
|
} catch (error) {
|
|
26451
26451
|
throw runtimeError(
|
|
26452
26452
|
"gate_recovery_corrupt",
|
|
@@ -26477,10 +26477,10 @@ function classifyRecoverableGateAttempt(context, row, capability) {
|
|
|
26477
26477
|
}
|
|
26478
26478
|
const current = state.currentStep;
|
|
26479
26479
|
const sameAttempt = current?.attemptId === row.attemptId && current.assignmentId === row.assignmentId && current.effectId === row.effectId && current.stepId === row.stepId;
|
|
26480
|
-
const controller =
|
|
26480
|
+
const controller = kxmAttemptController(context.eventStore.path, row.runId, row.attemptId);
|
|
26481
26481
|
if (row.gateKind === "command") {
|
|
26482
|
-
const hold =
|
|
26483
|
-
const admittedToken =
|
|
26482
|
+
const hold = kxmGateHold(context.eventStore.path, row.runId);
|
|
26483
|
+
const admittedToken = kxmAdmittedToken(context.eventStore.path, row.runId);
|
|
26484
26484
|
if (hold && hold.attemptId !== row.attemptId) {
|
|
26485
26485
|
throw runtimeError("gate_recovery_corrupt", row.attemptId, "gate recovery preflight: gate hold does not match the attempt");
|
|
26486
26486
|
}
|
|
@@ -26543,7 +26543,7 @@ function isExcludedTerminalProof(state, row, observation, evidence, events) {
|
|
|
26543
26543
|
}
|
|
26544
26544
|
function settlePreparedGate(context, prepared, observation) {
|
|
26545
26545
|
const run = requireRun(context, prepared.run.runId);
|
|
26546
|
-
const folded =
|
|
26546
|
+
const folded = foldStoredKxmRun(context, run);
|
|
26547
26547
|
const current = folded.currentStep;
|
|
26548
26548
|
if (!current || current.stepId !== prepared.stepId || current.stepAttempt !== prepared.stepAttempt || current.assignmentId !== prepared.assignmentId || current.attemptId !== prepared.attemptId || current.effectId !== prepared.effectId) {
|
|
26549
26549
|
throw runtimeError("run_events_illegal", run.runId, "settlement identity does not match the prepared gate attempt");
|
|
@@ -26557,7 +26557,7 @@ function settlePreparedGate(context, prepared, observation) {
|
|
|
26557
26557
|
throw runtimeError("gate_row_invalid", run.runId, "gate settlement requires a complete observation");
|
|
26558
26558
|
}
|
|
26559
26559
|
const settled = cancelled ? recordGateCancelObservedInTransaction(context, run, prepared.envelope, prepared.stepId, observation) : recordGateSettlementInTransaction(context, run, prepared.envelope, prepared.stepId, observation);
|
|
26560
|
-
|
|
26560
|
+
kxmGateDispatchSeams.afterObservationWrite?.(prepared);
|
|
26561
26561
|
return settled;
|
|
26562
26562
|
}
|
|
26563
26563
|
function requireRun(context, runId) {
|
|
@@ -26568,10 +26568,10 @@ function requireRun(context, runId) {
|
|
|
26568
26568
|
}
|
|
26569
26569
|
return run;
|
|
26570
26570
|
}
|
|
26571
|
-
function
|
|
26571
|
+
function recoverKxmRun(context, runId, request) {
|
|
26572
26572
|
return context.eventStore.transaction(() => {
|
|
26573
26573
|
const run = requireRun(context, runId);
|
|
26574
|
-
let state =
|
|
26574
|
+
let state = foldStoredKxmRun(context, run);
|
|
26575
26575
|
if (state.status !== "blocked_uncertain" && state.status !== "cancelling" && state.currentStep?.effectState !== "blocked_uncertain") {
|
|
26576
26576
|
throw runtimeError("run_events_illegal", runId, `run ${runId} is not in blocked_uncertain status`);
|
|
26577
26577
|
}
|
|
@@ -26580,17 +26580,17 @@ function recoverVnextRun(context, runId, request) {
|
|
|
26580
26580
|
}
|
|
26581
26581
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
26582
26582
|
let sequence = context.eventStore.nextSequence(runId);
|
|
26583
|
-
let mono =
|
|
26583
|
+
let mono = kxmMonotonicNs();
|
|
26584
26584
|
const events = [];
|
|
26585
26585
|
const push = (eventType, payload) => {
|
|
26586
26586
|
events.push({
|
|
26587
|
-
...
|
|
26588
|
-
eventId:
|
|
26587
|
+
...kxmEventBase(context, run, now, mono, request.commandId),
|
|
26588
|
+
eventId: newKxmEventId(),
|
|
26589
26589
|
eventType,
|
|
26590
26590
|
sequence: sequence++,
|
|
26591
26591
|
payload
|
|
26592
26592
|
});
|
|
26593
|
-
mono =
|
|
26593
|
+
mono = kxmIncrementMonotonicNs(mono);
|
|
26594
26594
|
};
|
|
26595
26595
|
if (state.status === "running" && state.currentStep?.effectState === "blocked_uncertain") {
|
|
26596
26596
|
push("run.status_changed", {
|
|
@@ -26600,13 +26600,13 @@ function recoverVnextRun(context, runId, request) {
|
|
|
26600
26600
|
});
|
|
26601
26601
|
for (const ev of events) context.eventStore.appendEvent(ev);
|
|
26602
26602
|
events.length = 0;
|
|
26603
|
-
state =
|
|
26603
|
+
state = foldStoredKxmRun(context, run);
|
|
26604
26604
|
context.eventStore.updateRunStatus(runId, "blocked_uncertain", now);
|
|
26605
26605
|
}
|
|
26606
26606
|
const attemptId = state.currentStep?.attemptId;
|
|
26607
26607
|
if (attemptId) {
|
|
26608
|
-
|
|
26609
|
-
|
|
26608
|
+
resolveKxmGateHold(context.eventStore.path, runId, attemptId);
|
|
26609
|
+
unregisterKxmAttemptController(context.eventStore.path, runId, attemptId);
|
|
26610
26610
|
const cap = context.eventStore.capabilityByAttempt(attemptId);
|
|
26611
26611
|
if (cap && cap.state !== "settled") {
|
|
26612
26612
|
context.eventStore.settleCapability(attemptId, "settled");
|
|
@@ -26619,8 +26619,8 @@ function recoverVnextRun(context, runId, request) {
|
|
|
26619
26619
|
reason: request.reason ?? "operator_retry"
|
|
26620
26620
|
});
|
|
26621
26621
|
for (const ev of events) context.eventStore.appendEvent(ev);
|
|
26622
|
-
const nextState =
|
|
26623
|
-
|
|
26622
|
+
const nextState = foldStoredKxmRun(context, run);
|
|
26623
|
+
persistKxmRunState(context, runId, nextState, events[events.length - 1].sequence);
|
|
26624
26624
|
context.eventStore.updateRunStatus(runId, "running", now);
|
|
26625
26625
|
return { state: nextState, unblocked: true };
|
|
26626
26626
|
}
|
|
@@ -26631,8 +26631,8 @@ function recoverVnextRun(context, runId, request) {
|
|
|
26631
26631
|
reason: request.reason ?? "operator_fail"
|
|
26632
26632
|
});
|
|
26633
26633
|
for (const ev of events) context.eventStore.appendEvent(ev);
|
|
26634
|
-
const nextState =
|
|
26635
|
-
|
|
26634
|
+
const nextState = foldStoredKxmRun(context, run);
|
|
26635
|
+
persistKxmRunState(context, runId, nextState, events[events.length - 1].sequence);
|
|
26636
26636
|
context.eventStore.updateRunStatus(runId, "failed", now);
|
|
26637
26637
|
return { state: nextState, unblocked: true };
|
|
26638
26638
|
}
|
|
@@ -26652,8 +26652,8 @@ function recoverVnextRun(context, runId, request) {
|
|
|
26652
26652
|
reason: request.reason ?? "operator_cancel"
|
|
26653
26653
|
});
|
|
26654
26654
|
for (const ev of events) context.eventStore.appendEvent(ev);
|
|
26655
|
-
const nextState =
|
|
26656
|
-
|
|
26655
|
+
const nextState = foldStoredKxmRun(context, run);
|
|
26656
|
+
persistKxmRunState(context, runId, nextState, events[events.length - 1].sequence);
|
|
26657
26657
|
context.eventStore.updateRunStatus(runId, "cancelled", now);
|
|
26658
26658
|
return { state: nextState, unblocked: true };
|
|
26659
26659
|
}
|
|
@@ -26661,7 +26661,7 @@ function recoverVnextRun(context, runId, request) {
|
|
|
26661
26661
|
});
|
|
26662
26662
|
}
|
|
26663
26663
|
|
|
26664
|
-
// plugins/kxm/src/
|
|
26664
|
+
// plugins/kxm/src/oneshot-producer.ts
|
|
26665
26665
|
function determineOutcome(text, allowedOutcomes) {
|
|
26666
26666
|
try {
|
|
26667
26667
|
const result = JSON.parse(text.trim());
|
|
@@ -26673,7 +26673,7 @@ function determineOutcome(text, allowedOutcomes) {
|
|
|
26673
26673
|
}
|
|
26674
26674
|
return "failed";
|
|
26675
26675
|
}
|
|
26676
|
-
function
|
|
26676
|
+
function createKxmOneShotProducer(options = {}) {
|
|
26677
26677
|
const defaultHarness = options.defaultHarness ?? "claude";
|
|
26678
26678
|
const running = /* @__PURE__ */ new Map();
|
|
26679
26679
|
let closed = false;
|
|
@@ -26835,7 +26835,7 @@ Return a final JSON object with an "outcome" field chosen from ${JSON.stringify(
|
|
|
26835
26835
|
}
|
|
26836
26836
|
const spawnFn = options.spawnProcess ?? defaultSpawn;
|
|
26837
26837
|
const cwd = options.projectRoot ?? process.cwd();
|
|
26838
|
-
const evidence = await beginOneShotEvidence(options.evidenceRoot ?? join12(
|
|
26838
|
+
const evidence = await beginOneShotEvidence(options.evidenceRoot ?? join12(kxmUserStateRoot(), "runtime", "oneshot-evidence"), {
|
|
26839
26839
|
runId: request.runId,
|
|
26840
26840
|
stepId: request.stepId,
|
|
26841
26841
|
attemptId: request.attemptId,
|
|
@@ -26978,12 +26978,12 @@ Return a final JSON object with an "outcome" field chosen from ${JSON.stringify(
|
|
|
26978
26978
|
return producer;
|
|
26979
26979
|
}
|
|
26980
26980
|
|
|
26981
|
-
// plugins/kxm/src/
|
|
26982
|
-
function
|
|
26981
|
+
// plugins/kxm/src/runtime-supervisor.ts
|
|
26982
|
+
function kxmSupervisorTokenFile(paths) {
|
|
26983
26983
|
return join13(paths.runtimeDir, "supervisor.token");
|
|
26984
26984
|
}
|
|
26985
|
-
function
|
|
26986
|
-
const file =
|
|
26985
|
+
function publishKxmSupervisorToken(paths, token) {
|
|
26986
|
+
const file = kxmSupervisorTokenFile(paths);
|
|
26987
26987
|
mkdirSync4(dirname6(file), { recursive: true, mode: 448 });
|
|
26988
26988
|
const temp = `${file}.${process.pid}.tmp`;
|
|
26989
26989
|
writeFileSync4(temp, `${token}
|
|
@@ -26998,11 +26998,11 @@ function publishVnextSupervisorToken(paths, token) {
|
|
|
26998
26998
|
} catch {
|
|
26999
26999
|
}
|
|
27000
27000
|
}
|
|
27001
|
-
function
|
|
27001
|
+
function hashKxmSupervisorToken(token) {
|
|
27002
27002
|
return `sha256:${createHash12("sha256").update(`kxm-runtime-supervisor\0${token}`, "utf8").digest("hex")}`;
|
|
27003
27003
|
}
|
|
27004
|
-
function
|
|
27005
|
-
const file =
|
|
27004
|
+
function readKxmSupervisorToken(paths) {
|
|
27005
|
+
const file = kxmSupervisorTokenFile(paths);
|
|
27006
27006
|
const stat = lstatSync5(file, { throwIfNoEntry: false });
|
|
27007
27007
|
if (!stat) return void 0;
|
|
27008
27008
|
if (stat.isSymbolicLink() || !stat.isFile()) {
|
|
@@ -27048,9 +27048,9 @@ function readRecentSupervisorError(paths) {
|
|
|
27048
27048
|
return void 0;
|
|
27049
27049
|
}
|
|
27050
27050
|
}
|
|
27051
|
-
function
|
|
27051
|
+
function kxmSupervisorStatus(paths) {
|
|
27052
27052
|
if (!existsSync10(paths.registryDb)) return { running: false };
|
|
27053
|
-
const registry = new
|
|
27053
|
+
const registry = new KxmRuntimeRegistry(paths.registryDb);
|
|
27054
27054
|
try {
|
|
27055
27055
|
const record2 = registry.supervisor();
|
|
27056
27056
|
if (!record2) return { running: false };
|
|
@@ -27085,7 +27085,7 @@ async function probeSupervisor(port, expectedRuntimeId, token, timeoutMs = 750)
|
|
|
27085
27085
|
const response = await fetch(`http://127.0.0.1:${port}/healthz?nonce=${nonce}`, { signal: controller.signal });
|
|
27086
27086
|
if (!response.ok) return false;
|
|
27087
27087
|
const payload = await response.json();
|
|
27088
|
-
const expectedProof =
|
|
27088
|
+
const expectedProof = hashKxmTokenProof(token, nonce);
|
|
27089
27089
|
return payload.runtimeId === expectedRuntimeId && payload.tokenProof === expectedProof;
|
|
27090
27090
|
} catch {
|
|
27091
27091
|
return false;
|
|
@@ -27093,15 +27093,15 @@ async function probeSupervisor(port, expectedRuntimeId, token, timeoutMs = 750)
|
|
|
27093
27093
|
clearTimeout(timeout);
|
|
27094
27094
|
}
|
|
27095
27095
|
}
|
|
27096
|
-
function
|
|
27096
|
+
function hashKxmTokenProof(token, nonce) {
|
|
27097
27097
|
return createHmac("sha256", token).update(`kxm-runtime-token-proof\0${nonce}`, "utf8").digest("hex");
|
|
27098
27098
|
}
|
|
27099
|
-
async function
|
|
27100
|
-
const paths =
|
|
27101
|
-
const status =
|
|
27099
|
+
async function ensureKxmSupervisor(options = {}) {
|
|
27100
|
+
const paths = kxmRuntimePaths(options.stateRoot !== void 0 ? { stateRoot: options.stateRoot } : { ...options.env ? { env: options.env } : {} });
|
|
27101
|
+
const status = kxmSupervisorStatus(paths);
|
|
27102
27102
|
if (status.running && status.port) {
|
|
27103
27103
|
for (let attempt = 0; attempt < 3; attempt += 1) {
|
|
27104
|
-
const token =
|
|
27104
|
+
const token = readKxmSupervisorToken(paths);
|
|
27105
27105
|
if (token && await probeSupervisorWithRetry(status.port, status.runtimeId, token)) {
|
|
27106
27106
|
return { runtimeId: status.runtimeId, port: status.port, token, started: false };
|
|
27107
27107
|
}
|
|
@@ -27129,9 +27129,9 @@ async function ensureVnextSupervisor(options = {}) {
|
|
|
27129
27129
|
const deadline = Date.now() + 1e4;
|
|
27130
27130
|
while (Date.now() < deadline) {
|
|
27131
27131
|
await new Promise((resolveWait) => setTimeout(resolveWait, 100));
|
|
27132
|
-
const next =
|
|
27132
|
+
const next = kxmSupervisorStatus(paths);
|
|
27133
27133
|
if (next.running && next.port) {
|
|
27134
|
-
const token =
|
|
27134
|
+
const token = readKxmSupervisorToken(paths);
|
|
27135
27135
|
if (token && await probeSupervisor(next.port, next.runtimeId, token)) {
|
|
27136
27136
|
return { runtimeId: next.runtimeId, port: next.port, token, started: true };
|
|
27137
27137
|
}
|
|
@@ -27165,7 +27165,7 @@ async function readJsonBody(request, limit = 64 * 1024) {
|
|
|
27165
27165
|
}
|
|
27166
27166
|
return parsed;
|
|
27167
27167
|
} catch (error) {
|
|
27168
|
-
if (error instanceof
|
|
27168
|
+
if (error instanceof KxmConfigError) throw error;
|
|
27169
27169
|
throw runtimeError("runtime_request_invalid", request.url ?? "<request>", "request body is not valid JSON");
|
|
27170
27170
|
}
|
|
27171
27171
|
}
|
|
@@ -27217,24 +27217,24 @@ async function driveSessionStillPending(settled) {
|
|
|
27217
27217
|
await Promise.resolve();
|
|
27218
27218
|
return pending;
|
|
27219
27219
|
}
|
|
27220
|
-
async function
|
|
27220
|
+
async function startKxmRuntimeSupervisor(options = {}) {
|
|
27221
27221
|
const now = options.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
|
|
27222
|
-
const paths =
|
|
27222
|
+
const paths = kxmRuntimePaths(options.stateRoot !== void 0 ? { stateRoot: options.stateRoot } : {});
|
|
27223
27223
|
try {
|
|
27224
|
-
return await
|
|
27224
|
+
return await startKxmRuntimeSupervisorInner(paths, options.port, now);
|
|
27225
27225
|
} catch (error) {
|
|
27226
|
-
if (!(error instanceof
|
|
27226
|
+
if (!(error instanceof KxmConfigError && error.issues.some((issue3) => issue3.code === "runtime_supervisor_conflict"))) {
|
|
27227
27227
|
recordSupervisorError(paths, error.message);
|
|
27228
27228
|
}
|
|
27229
27229
|
throw error;
|
|
27230
27230
|
}
|
|
27231
27231
|
}
|
|
27232
|
-
async function
|
|
27232
|
+
async function startKxmRuntimeSupervisorInner(paths, requestedPortOption, now) {
|
|
27233
27233
|
mkdirSync4(paths.runtimeDir, { recursive: true, mode: 448 });
|
|
27234
27234
|
mkdirSync4(paths.projectsDir, { recursive: true, mode: 448 });
|
|
27235
27235
|
const token = randomBytes3(32).toString("hex");
|
|
27236
|
-
const tokenHash =
|
|
27237
|
-
const registry = new
|
|
27236
|
+
const tokenHash = hashKxmSupervisorToken(token);
|
|
27237
|
+
const registry = new KxmRuntimeRegistry(paths.registryDb);
|
|
27238
27238
|
const runtimeId = `rtm_${createHash12("sha256").update(`${paths.stateRoot}\0${process.pid}\0${now()}\0${randomBytes3(16).toString("hex")}`, "utf8").digest("hex").slice(0, 24)}`;
|
|
27239
27239
|
const requestedPort = requestedPortOption ?? 0;
|
|
27240
27240
|
let activeRuntimeId = runtimeId;
|
|
@@ -27246,14 +27246,14 @@ async function startVnextRuntimeSupervisorInner(paths, requestedPortOption, now)
|
|
|
27246
27246
|
const key = projectRuntimeKey(projectRoot);
|
|
27247
27247
|
const existing = contexts.get(key);
|
|
27248
27248
|
if (existing) return existing;
|
|
27249
|
-
const context =
|
|
27249
|
+
const context = openKxmRuntimeContext(projectRoot, { homeRuntimeId: activeRuntimeId, stateRoot: paths.stateRoot });
|
|
27250
27250
|
contexts.set(key, context);
|
|
27251
27251
|
return context;
|
|
27252
27252
|
};
|
|
27253
27253
|
const requireAuth = (request) => {
|
|
27254
27254
|
const header = request.headers.authorization ?? "";
|
|
27255
27255
|
const presented = header.startsWith("Bearer ") ? header.slice("Bearer ".length) : "";
|
|
27256
|
-
const presentedHash = presented.length > 0 ? Buffer.from(
|
|
27256
|
+
const presentedHash = presented.length > 0 ? Buffer.from(hashKxmSupervisorToken(presented), "utf8") : Buffer.alloc(0);
|
|
27257
27257
|
const expectedHash = Buffer.from(tokenHash, "utf8");
|
|
27258
27258
|
if (presentedHash.length !== expectedHash.length || !timingSafeEqual2(presentedHash, expectedHash)) {
|
|
27259
27259
|
throw runtimeError("runtime_auth_failed", request.url ?? "<request>", "missing or invalid supervisor token");
|
|
@@ -27271,7 +27271,7 @@ async function startVnextRuntimeSupervisorInner(paths, requestedPortOption, now)
|
|
|
27271
27271
|
state: "running",
|
|
27272
27272
|
// Proof of token knowledge: an impostor that merely binds the
|
|
27273
27273
|
// stale port cannot answer the keyed challenge.
|
|
27274
|
-
tokenProof: nonce.length > 0 ?
|
|
27274
|
+
tokenProof: nonce.length > 0 ? hashKxmTokenProof(token, nonce) : void 0
|
|
27275
27275
|
});
|
|
27276
27276
|
return;
|
|
27277
27277
|
}
|
|
@@ -27293,8 +27293,8 @@ async function startVnextRuntimeSupervisorInner(paths, requestedPortOption, now)
|
|
|
27293
27293
|
return;
|
|
27294
27294
|
}
|
|
27295
27295
|
const context = contextFor(projectRoot);
|
|
27296
|
-
const bundle =
|
|
27297
|
-
const acceptance =
|
|
27296
|
+
const bundle = loadKxmProject(projectRoot, {});
|
|
27297
|
+
const acceptance = acceptKxmRun(context, bundle, {
|
|
27298
27298
|
...typeof body.commandId === "string" && body.commandId.length > 0 ? { commandId: body.commandId } : {},
|
|
27299
27299
|
workflowId,
|
|
27300
27300
|
prompt
|
|
@@ -27317,11 +27317,11 @@ async function startVnextRuntimeSupervisorInner(paths, requestedPortOption, now)
|
|
|
27317
27317
|
return;
|
|
27318
27318
|
}
|
|
27319
27319
|
const context = contextFor(projectRoot);
|
|
27320
|
-
const bundle =
|
|
27320
|
+
const bundle = loadKxmProject(projectRoot, {});
|
|
27321
27321
|
if (request.method === "GET" && !sub) {
|
|
27322
|
-
const projected =
|
|
27323
|
-
const folded =
|
|
27324
|
-
const drive =
|
|
27322
|
+
const projected = projectKxmRunReadOnly(context, runId);
|
|
27323
|
+
const folded = foldStoredKxmRun(context, projected);
|
|
27324
|
+
const drive = kxmDrivePollProjection(context, runId, folded);
|
|
27325
27325
|
sendJson(response, 200, { ok: true, run: projected, ...drive !== void 0 ? { drive } : {} });
|
|
27326
27326
|
return;
|
|
27327
27327
|
}
|
|
@@ -27334,7 +27334,7 @@ async function startVnextRuntimeSupervisorInner(paths, requestedPortOption, now)
|
|
|
27334
27334
|
const run = context.eventStore.run(runId);
|
|
27335
27335
|
if (!run) throw runtimeError("run_unknown", runId, "run not found");
|
|
27336
27336
|
const delayMs = typeof body.delayMs === "number" && body.delayMs > 0 ? body.delayMs : 0;
|
|
27337
|
-
const createProducer = () => body.mode === "live" ?
|
|
27337
|
+
const createProducer = () => body.mode === "live" ? createKxmOneShotProducer({
|
|
27338
27338
|
projectRoot,
|
|
27339
27339
|
defaultHarness: String(bundle.project.value.defaultHarness ?? "pi"),
|
|
27340
27340
|
resolveHarness: (agentId) => {
|
|
@@ -27353,7 +27353,7 @@ async function startVnextRuntimeSupervisorInner(paths, requestedPortOption, now)
|
|
|
27353
27353
|
}
|
|
27354
27354
|
return { provider, model: modelName };
|
|
27355
27355
|
}
|
|
27356
|
-
}) :
|
|
27356
|
+
}) : createKxmSimulatedProducer(async () => {
|
|
27357
27357
|
if (delayMs > 0) {
|
|
27358
27358
|
await new Promise((r) => setTimeout(r, delayMs));
|
|
27359
27359
|
}
|
|
@@ -27362,7 +27362,7 @@ async function startVnextRuntimeSupervisorInner(paths, requestedPortOption, now)
|
|
|
27362
27362
|
let session;
|
|
27363
27363
|
let earlyError;
|
|
27364
27364
|
try {
|
|
27365
|
-
const scheduler =
|
|
27365
|
+
const scheduler = KxmRunScheduler.for(context, bundle);
|
|
27366
27366
|
const opening = scheduler.openDriveSession(runId, {
|
|
27367
27367
|
mode: body.mode,
|
|
27368
27368
|
allowLimits: false,
|
|
@@ -27411,7 +27411,7 @@ async function startVnextRuntimeSupervisorInner(paths, requestedPortOption, now)
|
|
|
27411
27411
|
if (request.method === "GET" && sub === "drive") {
|
|
27412
27412
|
const run = context.eventStore.run(runId);
|
|
27413
27413
|
if (!run) throw runtimeError("run_unknown", runId, "run not found");
|
|
27414
|
-
const activeSession =
|
|
27414
|
+
const activeSession = kxmDriveSession(context.eventStore.path, runId);
|
|
27415
27415
|
const session = activeSession ? {
|
|
27416
27416
|
driveId: activeSession.driveId,
|
|
27417
27417
|
mode: activeSession.mode,
|
|
@@ -27424,7 +27424,7 @@ async function startVnextRuntimeSupervisorInner(paths, requestedPortOption, now)
|
|
|
27424
27424
|
}
|
|
27425
27425
|
if (request.method === "POST" && sub === "cancel") {
|
|
27426
27426
|
const body = await readJsonBody(request);
|
|
27427
|
-
const result =
|
|
27427
|
+
const result = cancelKxmRun(context, runId, {
|
|
27428
27428
|
...typeof body.commandId === "string" && body.commandId.length > 0 ? { commandId: body.commandId } : {}
|
|
27429
27429
|
});
|
|
27430
27430
|
sendJson(response, 200, { ok: true, idempotent: result.idempotent, run: result.run, events: result.events });
|
|
@@ -27434,11 +27434,11 @@ async function startVnextRuntimeSupervisorInner(paths, requestedPortOption, now)
|
|
|
27434
27434
|
const body = await readJsonBody(request);
|
|
27435
27435
|
const run = context.eventStore.run(runId);
|
|
27436
27436
|
if (!run) throw runtimeError("run_unknown", runId, "run not found");
|
|
27437
|
-
const state =
|
|
27437
|
+
const state = foldStoredKxmRun(context, run);
|
|
27438
27438
|
let unblocked = false;
|
|
27439
27439
|
if (state.status === "blocked_uncertain" || state.status === "cancelling" || state.currentStep?.effectState === "blocked_uncertain") {
|
|
27440
27440
|
const action = body.action === "cancel" || body.action === "fail" || body.action === "retry" || body.action === "unblock" ? body.action : "unblock";
|
|
27441
|
-
const rec =
|
|
27441
|
+
const rec = recoverKxmRun(context, runId, {
|
|
27442
27442
|
action,
|
|
27443
27443
|
reason: typeof body.summary === "string" ? body.summary : `signal_${body.signalKey ?? "callback"}`
|
|
27444
27444
|
});
|
|
@@ -27481,9 +27481,9 @@ async function startVnextRuntimeSupervisorInner(paths, requestedPortOption, now)
|
|
|
27481
27481
|
sendJson(response, 200, { ok: true, receipt, verified: false, divergence: "run missing" });
|
|
27482
27482
|
return;
|
|
27483
27483
|
}
|
|
27484
|
-
const state =
|
|
27484
|
+
const state = foldStoredKxmRun(context, stored);
|
|
27485
27485
|
const events = context.eventStore.events(runId, 0, 1e6);
|
|
27486
|
-
const checked =
|
|
27486
|
+
const checked = verifyKxmDriveReceipt(receipt, events, state.status, { runId, driveId });
|
|
27487
27487
|
sendJson(response, 200, {
|
|
27488
27488
|
ok: true,
|
|
27489
27489
|
receipt,
|
|
@@ -27511,7 +27511,7 @@ async function startVnextRuntimeSupervisorInner(paths, requestedPortOption, now)
|
|
|
27511
27511
|
}
|
|
27512
27512
|
sendJson(response, 404, { ok: false, error: "runtime_not_found" });
|
|
27513
27513
|
} catch (error) {
|
|
27514
|
-
if (error instanceof
|
|
27514
|
+
if (error instanceof KxmConfigError) {
|
|
27515
27515
|
const code = error.issues[0]?.code ?? "runtime_error";
|
|
27516
27516
|
const status = code === "runtime_auth_failed" ? 401 : code === "run_unknown" ? 404 : 400;
|
|
27517
27517
|
sendJson(response, status, { ok: false, error: code, issues: error.issues });
|
|
@@ -27552,7 +27552,7 @@ async function startVnextRuntimeSupervisorInner(paths, requestedPortOption, now)
|
|
|
27552
27552
|
}
|
|
27553
27553
|
}
|
|
27554
27554
|
try {
|
|
27555
|
-
|
|
27555
|
+
publishKxmSupervisorToken(paths, token);
|
|
27556
27556
|
clearSupervisorError(paths);
|
|
27557
27557
|
} catch (error) {
|
|
27558
27558
|
registry.close();
|
|
@@ -27578,10 +27578,10 @@ async function startVnextRuntimeSupervisorInner(paths, requestedPortOption, now)
|
|
|
27578
27578
|
registry.markStopping(process.pid, now());
|
|
27579
27579
|
} catch {
|
|
27580
27580
|
}
|
|
27581
|
-
const openSessions = [...contexts.values()].flatMap((context) =>
|
|
27581
|
+
const openSessions = [...contexts.values()].flatMap((context) => kxmOpenDriveSessions(context.eventStore.path).map((session) => ({ context, session })));
|
|
27582
27582
|
for (const { context, session } of openSessions) {
|
|
27583
27583
|
try {
|
|
27584
|
-
|
|
27584
|
+
cancelKxmRun(context, session.runId, { reason: "runtime_shutdown" });
|
|
27585
27585
|
} catch {
|
|
27586
27586
|
}
|
|
27587
27587
|
try {
|
|
@@ -27599,7 +27599,7 @@ async function startVnextRuntimeSupervisorInner(paths, requestedPortOption, now)
|
|
|
27599
27599
|
producerClosed: false
|
|
27600
27600
|
});
|
|
27601
27601
|
}
|
|
27602
|
-
for (const context of contexts.values())
|
|
27602
|
+
for (const context of contexts.values()) closeKxmRuntimeContext(context);
|
|
27603
27603
|
contexts.clear();
|
|
27604
27604
|
const closed = new Promise((resolveStop) => server.close(() => resolveStop()));
|
|
27605
27605
|
server.closeIdleConnections?.();
|
|
@@ -27618,7 +27618,7 @@ async function startVnextRuntimeSupervisorInner(paths, requestedPortOption, now)
|
|
|
27618
27618
|
});
|
|
27619
27619
|
return { server, port, runtimeId: activeRuntimeId, stop };
|
|
27620
27620
|
}
|
|
27621
|
-
async function
|
|
27621
|
+
async function kxmRuntimeRequest(handle, method, path, body) {
|
|
27622
27622
|
const response = await fetch(`http://127.0.0.1:${handle.port}${path}`, {
|
|
27623
27623
|
method,
|
|
27624
27624
|
headers: {
|
|
@@ -27636,7 +27636,7 @@ async function vnextRuntimeRequest(handle, method, path, body) {
|
|
|
27636
27636
|
return payload;
|
|
27637
27637
|
}
|
|
27638
27638
|
|
|
27639
|
-
// plugins/kxm/src/
|
|
27639
|
+
// plugins/kxm/src/pi-producer.ts
|
|
27640
27640
|
import { spawn as spawn4 } from "node:child_process";
|
|
27641
27641
|
import { join as join14 } from "node:path";
|
|
27642
27642
|
import { StringDecoder } from "node:string_decoder";
|
|
@@ -27911,7 +27911,7 @@ var PiSession = class {
|
|
|
27911
27911
|
}
|
|
27912
27912
|
}
|
|
27913
27913
|
};
|
|
27914
|
-
function
|
|
27914
|
+
function createKxmPiProducer(options = {}) {
|
|
27915
27915
|
const sessions = /* @__PURE__ */ new Map();
|
|
27916
27916
|
const defaultModel = options.defaultModel ?? "xai/grok-4.6";
|
|
27917
27917
|
const defaultProvider = options.defaultProvider ?? "xai";
|
|
@@ -29932,6 +29932,13 @@ export {
|
|
|
29932
29932
|
DRIVE_RECEIPT_MAX_BYTES,
|
|
29933
29933
|
IMPROVEMENT_REPORT_SCHEMA,
|
|
29934
29934
|
IMPROVEMENT_REPORT_V1_SCHEMA,
|
|
29935
|
+
KXM_ABSENT_MEMORY_REVISION,
|
|
29936
|
+
KXM_DRIVE_RECEIPT_SCHEMA,
|
|
29937
|
+
KXM_EVENT_STORE_SCHEMA_VERSION,
|
|
29938
|
+
KXM_REGISTRY_SCHEMA_VERSION,
|
|
29939
|
+
KXM_RUN_EVENT_SCHEMA,
|
|
29940
|
+
KxmRunEventStore,
|
|
29941
|
+
KxmRuntimeRegistry,
|
|
29935
29942
|
LOG_LEVEL_PRIORITY,
|
|
29936
29943
|
MAX_RUNTIME_STOP_GRACE_MS,
|
|
29937
29944
|
MAX_SSH_OUTPUT_BYTES,
|
|
@@ -29945,22 +29952,15 @@ export {
|
|
|
29945
29952
|
SteelClient,
|
|
29946
29953
|
SubagentManager,
|
|
29947
29954
|
VIEWPORT_PRESETS,
|
|
29948
|
-
VNEXT_ABSENT_MEMORY_REVISION,
|
|
29949
|
-
VNEXT_DRIVE_RECEIPT_SCHEMA,
|
|
29950
|
-
VNEXT_EVENT_STORE_SCHEMA_VERSION,
|
|
29951
|
-
VNEXT_REGISTRY_SCHEMA_VERSION,
|
|
29952
|
-
VNEXT_RUN_EVENT_SCHEMA,
|
|
29953
|
-
VnextRunEventStore,
|
|
29954
|
-
VnextRuntimeRegistry,
|
|
29955
29955
|
WIN_NPM_INNER_EXE,
|
|
29956
|
-
|
|
29956
|
+
acceptKxmRun,
|
|
29957
29957
|
assertClosedGateObservation,
|
|
29958
|
-
|
|
29958
|
+
assertKxmConfigError,
|
|
29959
29959
|
backupDatabaseFile,
|
|
29960
29960
|
buildImprovementReport,
|
|
29961
29961
|
buildSshArgs,
|
|
29962
29962
|
calculatePromptFootprint,
|
|
29963
|
-
|
|
29963
|
+
cancelKxmRun,
|
|
29964
29964
|
checkControlSocket,
|
|
29965
29965
|
checkIntegrity,
|
|
29966
29966
|
checkMemoryRevisionDrift,
|
|
@@ -29968,27 +29968,27 @@ export {
|
|
|
29968
29968
|
checkpointWal,
|
|
29969
29969
|
classifyCandidateKind,
|
|
29970
29970
|
closeControlSocket,
|
|
29971
|
-
|
|
29971
|
+
closeKxmRuntimeContext,
|
|
29972
29972
|
computeGateEvidenceOutcome,
|
|
29973
|
-
|
|
29973
|
+
computeKxmMemoryRevision,
|
|
29974
29974
|
createAnnotationFeedback,
|
|
29975
29975
|
createBackup,
|
|
29976
|
+
createKxmOneShotProducer,
|
|
29977
|
+
createKxmPiProducer,
|
|
29976
29978
|
createLogger,
|
|
29977
|
-
createVnextOneShotProducer,
|
|
29978
|
-
createVnextPiProducer,
|
|
29979
29979
|
databaseError,
|
|
29980
29980
|
defaultSpawn,
|
|
29981
29981
|
discoverProjectStores,
|
|
29982
29982
|
eligibleHarnesses,
|
|
29983
|
+
ensureKxmSupervisor,
|
|
29983
29984
|
ensureSocketDir,
|
|
29984
|
-
ensureVnextSupervisor,
|
|
29985
29985
|
ensureWalJournalMode,
|
|
29986
29986
|
estimateTokens,
|
|
29987
29987
|
evaluatePromotionPolicy,
|
|
29988
29988
|
executeSshRun,
|
|
29989
29989
|
fileSha256,
|
|
29990
29990
|
findWinNpmInnerExe,
|
|
29991
|
-
|
|
29991
|
+
foldStoredKxmRun,
|
|
29992
29992
|
formatAnnotationFeedbackPrompt,
|
|
29993
29993
|
formatCDPEndpoint,
|
|
29994
29994
|
formatHarnessInventory,
|
|
@@ -30001,25 +30001,39 @@ export {
|
|
|
30001
30001
|
groupRoutingRecords,
|
|
30002
30002
|
harnessCommandCandidates,
|
|
30003
30003
|
harnessSpawnUsesShell,
|
|
30004
|
-
|
|
30005
|
-
|
|
30006
|
-
|
|
30004
|
+
hashKxmDriveLog,
|
|
30005
|
+
hashKxmSupervisorToken,
|
|
30006
|
+
hashKxmTokenProof,
|
|
30007
30007
|
isKnownHarnessId,
|
|
30008
|
-
|
|
30008
|
+
isKxmRuntimeContextClosed,
|
|
30009
30009
|
isWindowsHarnessShim,
|
|
30010
|
+
kxmDeclaredExecutorIds,
|
|
30011
|
+
kxmDeclaredRepositoryIds,
|
|
30012
|
+
kxmEventBase,
|
|
30013
|
+
kxmExecutorPolicyRevision,
|
|
30014
|
+
kxmIncrementMonotonicNs,
|
|
30015
|
+
kxmMonotonicNs,
|
|
30016
|
+
kxmPolicyRevisions,
|
|
30017
|
+
kxmProjectAdmissionLimits,
|
|
30018
|
+
kxmRunRevisionDrift,
|
|
30019
|
+
kxmRuntimePaths,
|
|
30020
|
+
kxmRuntimeRequest,
|
|
30021
|
+
kxmSupervisorStatus,
|
|
30022
|
+
kxmSupervisorTokenFile,
|
|
30023
|
+
kxmToolPolicyRevision,
|
|
30010
30024
|
loadModesConfig,
|
|
30011
30025
|
narrowSubagentTools,
|
|
30012
|
-
|
|
30013
|
-
|
|
30014
|
-
|
|
30015
|
-
|
|
30016
|
-
|
|
30017
|
-
|
|
30018
|
-
|
|
30019
|
-
|
|
30026
|
+
newKxmAssignmentId,
|
|
30027
|
+
newKxmAttemptId,
|
|
30028
|
+
newKxmCommandId,
|
|
30029
|
+
newKxmEffectId,
|
|
30030
|
+
newKxmEventId,
|
|
30031
|
+
newKxmEvidenceId,
|
|
30032
|
+
newKxmObservationId,
|
|
30033
|
+
newKxmRunId,
|
|
30020
30034
|
oneShotReadOnlyArgs,
|
|
30021
30035
|
openDatabase,
|
|
30022
|
-
|
|
30036
|
+
openKxmRuntimeContext,
|
|
30023
30037
|
parseAgyOneShotUsage,
|
|
30024
30038
|
parseClaudeOneShotUsage,
|
|
30025
30039
|
parseCodexOneShotUsage,
|
|
@@ -30027,7 +30041,7 @@ export {
|
|
|
30027
30041
|
parseGrokOneShotUsage,
|
|
30028
30042
|
parseKimiOneShotUsage,
|
|
30029
30043
|
parseSshConfig,
|
|
30030
|
-
|
|
30044
|
+
persistKxmRunState,
|
|
30031
30045
|
planHarnessUpdate,
|
|
30032
30046
|
probeHarnessAssignment,
|
|
30033
30047
|
probeHarnessAssignmentAsync,
|
|
@@ -30035,14 +30049,14 @@ export {
|
|
|
30035
30049
|
probeHarnessesAsync,
|
|
30036
30050
|
probeHarnessesForModel,
|
|
30037
30051
|
probeHarnessesForModelAsync,
|
|
30052
|
+
projectKxmRunReadOnly,
|
|
30038
30053
|
projectRuntimeKey,
|
|
30039
|
-
projectVnextRunReadOnly,
|
|
30040
30054
|
pruneSocketDir,
|
|
30041
|
-
|
|
30042
|
-
|
|
30043
|
-
|
|
30055
|
+
readKxmRunStatus,
|
|
30056
|
+
readKxmSupervisorToken,
|
|
30057
|
+
rebuildKxmRunProjection,
|
|
30044
30058
|
redactLogValue,
|
|
30045
|
-
|
|
30059
|
+
registerKxmRuntimeCloseHook,
|
|
30046
30060
|
resolveActiveMode,
|
|
30047
30061
|
resolveDispatchStatus,
|
|
30048
30062
|
resolvePassCliApiKey,
|
|
@@ -30056,27 +30070,13 @@ export {
|
|
|
30056
30070
|
runtimeError,
|
|
30057
30071
|
runtimeStopGraceMs,
|
|
30058
30072
|
sanitizeLogOutput,
|
|
30059
|
-
|
|
30073
|
+
startKxmRuntimeSupervisor,
|
|
30060
30074
|
tableColumns,
|
|
30061
30075
|
truncateSshOutput,
|
|
30062
30076
|
userTables,
|
|
30063
30077
|
validateHarnessModelPair,
|
|
30064
30078
|
verifyExpectedTables,
|
|
30065
|
-
|
|
30066
|
-
vnextDeclaredExecutorIds,
|
|
30067
|
-
vnextDeclaredRepositoryIds,
|
|
30068
|
-
vnextEventBase,
|
|
30069
|
-
vnextExecutorPolicyRevision,
|
|
30070
|
-
vnextIncrementMonotonicNs,
|
|
30071
|
-
vnextMonotonicNs,
|
|
30072
|
-
vnextPolicyRevisions,
|
|
30073
|
-
vnextProjectAdmissionLimits,
|
|
30074
|
-
vnextRunRevisionDrift,
|
|
30075
|
-
vnextRuntimePaths,
|
|
30076
|
-
vnextRuntimeRequest,
|
|
30077
|
-
vnextSupervisorStatus,
|
|
30078
|
-
vnextSupervisorTokenFile,
|
|
30079
|
-
vnextToolPolicyRevision,
|
|
30079
|
+
verifyKxmDriveReceipt,
|
|
30080
30080
|
withDatabaseTransaction,
|
|
30081
30081
|
writeImprovementReport
|
|
30082
30082
|
};
|