@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
|
@@ -1,46 +1,46 @@
|
|
|
1
|
-
import { gateDefinitionHash } from "./
|
|
2
|
-
import {
|
|
3
|
-
import type {
|
|
4
|
-
import {
|
|
1
|
+
import { gateDefinitionHash } from "./gate-hash.ts";
|
|
2
|
+
import { mintKxmCapabilitySecret, kxmTransitionBudgetFailure } from "./engine.ts";
|
|
3
|
+
import type { KxmRunPlanEnvelope } from "./engine-plan.ts";
|
|
4
|
+
import { kxmCanonicalJson, type JsonValue } from "./project-config.ts";
|
|
5
5
|
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
type
|
|
12
|
-
} from "./
|
|
6
|
+
foldStoredKxmRun,
|
|
7
|
+
persistKxmRunState,
|
|
8
|
+
kxmEventBase,
|
|
9
|
+
kxmIncrementMonotonicNs,
|
|
10
|
+
kxmMonotonicNs,
|
|
11
|
+
type KxmRuntimeContext,
|
|
12
|
+
} from "./runtime-service.ts";
|
|
13
13
|
import {
|
|
14
14
|
assertClosedGateObservation,
|
|
15
15
|
computeGateEvidenceOutcome,
|
|
16
16
|
gateRowContentHash,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
newKxmAssignmentId,
|
|
18
|
+
newKxmAttemptId,
|
|
19
|
+
newKxmEffectId,
|
|
20
|
+
newKxmEventId,
|
|
21
|
+
newKxmEvidenceId,
|
|
22
|
+
newKxmObservationId,
|
|
23
23
|
runtimeError,
|
|
24
|
-
type
|
|
25
|
-
type
|
|
26
|
-
type
|
|
27
|
-
type
|
|
28
|
-
type
|
|
29
|
-
type
|
|
30
|
-
type
|
|
31
|
-
} from "./
|
|
24
|
+
type KxmGateErrorClass,
|
|
25
|
+
type KxmGateEvidenceOutcome,
|
|
26
|
+
type KxmGateEvidenceRow,
|
|
27
|
+
type KxmGateObservationRow,
|
|
28
|
+
type KxmGateStopCause,
|
|
29
|
+
type KxmRunEvent,
|
|
30
|
+
type KxmRunRecord,
|
|
31
|
+
} from "./runtime-store.ts";
|
|
32
32
|
|
|
33
|
-
export interface
|
|
34
|
-
completeness:
|
|
33
|
+
export interface KxmGateObservationInput {
|
|
34
|
+
completeness: KxmGateObservationRow["completeness"];
|
|
35
35
|
spawned: 0 | 1;
|
|
36
36
|
pid: number | null;
|
|
37
37
|
exitCode: number | null;
|
|
38
38
|
signal: string | null;
|
|
39
39
|
exitObserved: 0 | 1;
|
|
40
40
|
closeObserved: 0 | 1;
|
|
41
|
-
stopCause:
|
|
42
|
-
signalsAttempted:
|
|
43
|
-
errorClass:
|
|
41
|
+
stopCause: KxmGateStopCause;
|
|
42
|
+
signalsAttempted: KxmGateObservationRow["signalsAttempted"];
|
|
43
|
+
errorClass: KxmGateErrorClass | null;
|
|
44
44
|
stdoutSha256: string | null;
|
|
45
45
|
stdoutBytes: number | null;
|
|
46
46
|
stdoutComplete: 0 | 1 | null;
|
|
@@ -54,23 +54,23 @@ export interface VnextGateObservationInput {
|
|
|
54
54
|
finishedAt: string | null;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
export function recordGateIntent(context:
|
|
57
|
+
export function recordGateIntent(context: KxmRuntimeContext, run: KxmRunRecord, envelope: KxmRunPlanEnvelope, stepId: string) {
|
|
58
58
|
return context.eventStore.transaction(() => recordGateIntentInTransaction(context, run, envelope, stepId));
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
export function recordGateIntentInTransaction(context:
|
|
61
|
+
export function recordGateIntentInTransaction(context: KxmRuntimeContext, run: KxmRunRecord, envelope: KxmRunPlanEnvelope, stepId: string) {
|
|
62
62
|
const step = requireGateStep(envelope, stepId, run.runId);
|
|
63
63
|
const definition = envelope.gates.definitions[step.gate];
|
|
64
64
|
if (!definition || definition.kind === "reserved") {
|
|
65
65
|
throw runtimeError("gate_row_invalid", run.runId, "reserved gates cannot record intent in this slice");
|
|
66
66
|
}
|
|
67
|
-
const folded =
|
|
67
|
+
const folded = foldStoredKxmRun(context, run);
|
|
68
68
|
const used = folded.stepAttempts[stepId] ?? 0;
|
|
69
69
|
const stepAttempt = used + 1;
|
|
70
|
-
const assignmentId =
|
|
71
|
-
const attemptId =
|
|
72
|
-
const effectId =
|
|
73
|
-
const minted =
|
|
70
|
+
const assignmentId = newKxmAssignmentId();
|
|
71
|
+
const attemptId = newKxmAttemptId();
|
|
72
|
+
const effectId = newKxmEffectId();
|
|
73
|
+
const minted = mintKxmCapabilitySecret();
|
|
74
74
|
const now = new Date().toISOString();
|
|
75
75
|
const seq = sequencer(context, run, now);
|
|
76
76
|
seq.push("step.entered", { stepId, stepAttempt, status: "pending" });
|
|
@@ -126,11 +126,11 @@ export function recordGateIntentInTransaction(context: VnextRuntimeContext, run:
|
|
|
126
126
|
return persist(context, run, now, seq.events.at(-1)!.sequence);
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
-
export function recordGateSpawned(context:
|
|
129
|
+
export function recordGateSpawned(context: KxmRuntimeContext, run: KxmRunRecord, envelope: KxmRunPlanEnvelope, stepId: string) {
|
|
130
130
|
return context.eventStore.transaction(() => recordGateSpawnedInTransaction(context, run, envelope, stepId));
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
export function recordGateSpawnedInTransaction(context:
|
|
133
|
+
export function recordGateSpawnedInTransaction(context: KxmRuntimeContext, run: KxmRunRecord, envelope: KxmRunPlanEnvelope, stepId: string) {
|
|
134
134
|
const ids = requireIntent(context, run, envelope, stepId);
|
|
135
135
|
if (ids.gateKind !== "command") throw runtimeError("gate_row_invalid", run.runId, "effect.dispatched is command-only");
|
|
136
136
|
const now = new Date().toISOString();
|
|
@@ -149,21 +149,21 @@ export function recordGateSpawnedInTransaction(context: VnextRuntimeContext, run
|
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
export function recordGateSettlement(
|
|
152
|
-
context:
|
|
153
|
-
run:
|
|
154
|
-
envelope:
|
|
152
|
+
context: KxmRuntimeContext,
|
|
153
|
+
run: KxmRunRecord,
|
|
154
|
+
envelope: KxmRunPlanEnvelope,
|
|
155
155
|
stepId: string,
|
|
156
|
-
observation:
|
|
156
|
+
observation: KxmGateObservationInput,
|
|
157
157
|
) {
|
|
158
158
|
return context.eventStore.transaction(() => recordGateSettlementInTransaction(context, run, envelope, stepId, observation));
|
|
159
159
|
}
|
|
160
160
|
|
|
161
161
|
export function recordGateSettlementInTransaction(
|
|
162
|
-
context:
|
|
163
|
-
run:
|
|
164
|
-
envelope:
|
|
162
|
+
context: KxmRuntimeContext,
|
|
163
|
+
run: KxmRunRecord,
|
|
164
|
+
envelope: KxmRunPlanEnvelope,
|
|
165
165
|
stepId: string,
|
|
166
|
-
observation:
|
|
166
|
+
observation: KxmGateObservationInput,
|
|
167
167
|
) {
|
|
168
168
|
const ids = requireIntent(context, run, envelope, stepId);
|
|
169
169
|
assertClosedGateObservation(ids.gateKind, observation);
|
|
@@ -182,7 +182,7 @@ export function recordGateSettlementInTransaction(
|
|
|
182
182
|
});
|
|
183
183
|
}
|
|
184
184
|
seq.push("attempt.status_changed", { attemptId: ids.attemptId, assignmentId: ids.assignmentId, stepId, stepAttempt: ids.stepAttempt, status: "settling" });
|
|
185
|
-
const observationId =
|
|
185
|
+
const observationId = newKxmObservationId();
|
|
186
186
|
const observed = seq.push("effect.observed", {
|
|
187
187
|
effect: { id: ids.effectId, policy: { class: ids.gateKind === "artifacts-exist" ? "read-only" : "unknown", sharedMutable: false } },
|
|
188
188
|
stepId,
|
|
@@ -193,8 +193,8 @@ export function recordGateSettlementInTransaction(
|
|
|
193
193
|
});
|
|
194
194
|
const observationRow = buildObservation(ids, observation, observationId, observed.eventId);
|
|
195
195
|
patchReceipt(observed, observationRow);
|
|
196
|
-
const evidenceId =
|
|
197
|
-
const evidenceDraft:
|
|
196
|
+
const evidenceId = newKxmEvidenceId();
|
|
197
|
+
const evidenceDraft: KxmGateEvidenceRow = {
|
|
198
198
|
evidenceId,
|
|
199
199
|
attemptId: ids.attemptId,
|
|
200
200
|
observationId,
|
|
@@ -233,21 +233,21 @@ export function recordGateSettlementInTransaction(
|
|
|
233
233
|
}
|
|
234
234
|
|
|
235
235
|
export function recordGateNoStart(
|
|
236
|
-
context:
|
|
237
|
-
run:
|
|
238
|
-
envelope:
|
|
236
|
+
context: KxmRuntimeContext,
|
|
237
|
+
run: KxmRunRecord,
|
|
238
|
+
envelope: KxmRunPlanEnvelope,
|
|
239
239
|
stepId: string,
|
|
240
|
-
observation:
|
|
240
|
+
observation: KxmGateObservationInput,
|
|
241
241
|
) {
|
|
242
242
|
return context.eventStore.transaction(() => recordGateNoStartInTransaction(context, run, envelope, stepId, observation));
|
|
243
243
|
}
|
|
244
244
|
|
|
245
245
|
export function recordGateNoStartInTransaction(
|
|
246
|
-
context:
|
|
247
|
-
run:
|
|
248
|
-
envelope:
|
|
246
|
+
context: KxmRuntimeContext,
|
|
247
|
+
run: KxmRunRecord,
|
|
248
|
+
envelope: KxmRunPlanEnvelope,
|
|
249
249
|
stepId: string,
|
|
250
|
-
observation:
|
|
250
|
+
observation: KxmGateObservationInput,
|
|
251
251
|
) {
|
|
252
252
|
const ids = requireIntent(context, run, envelope, stepId);
|
|
253
253
|
assertClosedGateObservation(ids.gateKind, observation);
|
|
@@ -258,7 +258,7 @@ export function recordGateNoStartInTransaction(
|
|
|
258
258
|
const now = new Date().toISOString();
|
|
259
259
|
const seq = sequencer(context, run, now);
|
|
260
260
|
const cancelReason = cancelled ? ensureOperatorCancel(seq, ids.state, run, context) : undefined;
|
|
261
|
-
const observationId =
|
|
261
|
+
const observationId = newKxmObservationId();
|
|
262
262
|
const observed = seq.push("effect.observed", {
|
|
263
263
|
effect: { id: ids.effectId, policy: { class: ids.gateKind === "artifacts-exist" ? "read-only" : "unknown", sharedMutable: false } },
|
|
264
264
|
stepId,
|
|
@@ -304,23 +304,23 @@ export function recordGateNoStartInTransaction(
|
|
|
304
304
|
}
|
|
305
305
|
|
|
306
306
|
export function recordGateUncertain(
|
|
307
|
-
context:
|
|
308
|
-
run:
|
|
309
|
-
envelope:
|
|
307
|
+
context: KxmRuntimeContext,
|
|
308
|
+
run: KxmRunRecord,
|
|
309
|
+
envelope: KxmRunPlanEnvelope,
|
|
310
310
|
stepId: string,
|
|
311
311
|
reason: string,
|
|
312
|
-
observation:
|
|
312
|
+
observation: KxmGateObservationInput,
|
|
313
313
|
) {
|
|
314
314
|
return context.eventStore.transaction(() => recordGateUncertainInTransaction(context, run, envelope, stepId, reason, observation));
|
|
315
315
|
}
|
|
316
316
|
|
|
317
317
|
export function recordGateUncertainInTransaction(
|
|
318
|
-
context:
|
|
319
|
-
run:
|
|
320
|
-
envelope:
|
|
318
|
+
context: KxmRuntimeContext,
|
|
319
|
+
run: KxmRunRecord,
|
|
320
|
+
envelope: KxmRunPlanEnvelope,
|
|
321
321
|
stepId: string,
|
|
322
322
|
reason: string,
|
|
323
|
-
observation:
|
|
323
|
+
observation: KxmGateObservationInput,
|
|
324
324
|
) {
|
|
325
325
|
const ids = requireIntent(context, run, envelope, stepId);
|
|
326
326
|
if (observation.completeness !== "incomplete") {
|
|
@@ -341,7 +341,7 @@ export function recordGateUncertainInTransaction(
|
|
|
341
341
|
}
|
|
342
342
|
const now = new Date().toISOString();
|
|
343
343
|
const seq = sequencer(context, run, now);
|
|
344
|
-
const observationId =
|
|
344
|
+
const observationId = newKxmObservationId();
|
|
345
345
|
const blocked = seq.push("effect.blocked_uncertain", {
|
|
346
346
|
effect: { id: ids.effectId, policy: { class: ids.gateKind === "artifacts-exist" ? "read-only" : "unknown", sharedMutable: false } },
|
|
347
347
|
stepId,
|
|
@@ -359,21 +359,21 @@ export function recordGateUncertainInTransaction(
|
|
|
359
359
|
}
|
|
360
360
|
|
|
361
361
|
export function recordGateCancelObserved(
|
|
362
|
-
context:
|
|
363
|
-
run:
|
|
364
|
-
envelope:
|
|
362
|
+
context: KxmRuntimeContext,
|
|
363
|
+
run: KxmRunRecord,
|
|
364
|
+
envelope: KxmRunPlanEnvelope,
|
|
365
365
|
stepId: string,
|
|
366
|
-
observation:
|
|
366
|
+
observation: KxmGateObservationInput,
|
|
367
367
|
) {
|
|
368
368
|
return context.eventStore.transaction(() => recordGateCancelObservedInTransaction(context, run, envelope, stepId, observation));
|
|
369
369
|
}
|
|
370
370
|
|
|
371
371
|
export function recordGateCancelObservedInTransaction(
|
|
372
|
-
context:
|
|
373
|
-
run:
|
|
374
|
-
envelope:
|
|
372
|
+
context: KxmRuntimeContext,
|
|
373
|
+
run: KxmRunRecord,
|
|
374
|
+
envelope: KxmRunPlanEnvelope,
|
|
375
375
|
stepId: string,
|
|
376
|
-
observation:
|
|
376
|
+
observation: KxmGateObservationInput,
|
|
377
377
|
) {
|
|
378
378
|
const ids = requireIntent(context, run, envelope, stepId);
|
|
379
379
|
assertClosedGateObservation(ids.gateKind, observation);
|
|
@@ -398,7 +398,7 @@ export function recordGateCancelObservedInTransaction(
|
|
|
398
398
|
});
|
|
399
399
|
}
|
|
400
400
|
seq.push("attempt.status_changed", { attemptId: ids.attemptId, assignmentId: ids.assignmentId, stepId, stepAttempt: ids.stepAttempt, status: "settling" });
|
|
401
|
-
const observationId =
|
|
401
|
+
const observationId = newKxmObservationId();
|
|
402
402
|
const policyClass = ids.gateKind === "artifacts-exist" ? "read-only" : "unknown";
|
|
403
403
|
const observed = seq.push("effect.observed", {
|
|
404
404
|
effect: { id: ids.effectId, policy: { class: policyClass, sharedMutable: false } },
|
|
@@ -437,10 +437,10 @@ export function recordGateCancelObservedInTransaction(
|
|
|
437
437
|
|
|
438
438
|
function appendEvaluatedTail(
|
|
439
439
|
seq: ReturnType<typeof sequencer>,
|
|
440
|
-
envelope:
|
|
440
|
+
envelope: KxmRunPlanEnvelope,
|
|
441
441
|
ids: ReturnType<typeof requireIntent>,
|
|
442
442
|
stepId: string,
|
|
443
|
-
outcome:
|
|
443
|
+
outcome: KxmGateEvidenceOutcome,
|
|
444
444
|
) {
|
|
445
445
|
const mapped = outcome === "passed" ? "passed" : outcome === "repro-missing" ? "failed" : "failed";
|
|
446
446
|
seq.push("assignment.result_recorded", { assignmentId: ids.assignmentId, resultClass: "outcome", outcome, status: "result_recorded" });
|
|
@@ -453,7 +453,7 @@ function appendEvaluatedTail(
|
|
|
453
453
|
seq.push("run.status_changed", { status: "failed", reason: "outcome_unknown", stepId, outcome });
|
|
454
454
|
return;
|
|
455
455
|
}
|
|
456
|
-
const budget =
|
|
456
|
+
const budget = kxmTransitionBudgetFailure(envelope.plan, ids.state, stepId, outcome);
|
|
457
457
|
if (budget) {
|
|
458
458
|
seq.push("run.status_changed", { status: "failed", reason: budget, stepId, outcome });
|
|
459
459
|
return;
|
|
@@ -466,7 +466,7 @@ function appendEvaluatedTail(
|
|
|
466
466
|
}
|
|
467
467
|
}
|
|
468
468
|
|
|
469
|
-
function evidenceKeyFor(envelope:
|
|
469
|
+
function evidenceKeyFor(envelope: KxmRunPlanEnvelope, stepId: string): string | null {
|
|
470
470
|
const required = envelope.plan.steps[stepId]?.requiredEvidence.filter((item) => item.kind === "gate") ?? [];
|
|
471
471
|
return required.length === 1 ? required[0]!.key : null;
|
|
472
472
|
}
|
|
@@ -481,18 +481,18 @@ function placeholderReceipt(observationId: string, kind: string, now: string) {
|
|
|
481
481
|
};
|
|
482
482
|
}
|
|
483
483
|
|
|
484
|
-
function patchReceipt(event:
|
|
484
|
+
function patchReceipt(event: KxmRunEvent, row: KxmGateObservationRow): void {
|
|
485
485
|
const receipt = event.payload.receipt as { hash: string };
|
|
486
486
|
receipt.hash = row.contentHash;
|
|
487
487
|
}
|
|
488
488
|
|
|
489
489
|
function buildObservation(
|
|
490
490
|
ids: ReturnType<typeof requireIntent>,
|
|
491
|
-
observation:
|
|
491
|
+
observation: KxmGateObservationInput,
|
|
492
492
|
observationId: string,
|
|
493
493
|
recordedEventId: string,
|
|
494
|
-
):
|
|
495
|
-
const row:
|
|
494
|
+
): KxmGateObservationRow {
|
|
495
|
+
const row: KxmGateObservationRow = {
|
|
496
496
|
observationId,
|
|
497
497
|
attemptId: ids.attemptId,
|
|
498
498
|
runId: ids.runId,
|
|
@@ -509,15 +509,15 @@ function buildObservation(
|
|
|
509
509
|
return { ...row, contentHash: gateRowContentHash("gate_observations", { ...row, contentHash: "" }) };
|
|
510
510
|
}
|
|
511
511
|
|
|
512
|
-
function requireGateStep(envelope:
|
|
512
|
+
function requireGateStep(envelope: KxmRunPlanEnvelope, stepId: string, runId: string) {
|
|
513
513
|
const step = envelope.plan.steps[stepId];
|
|
514
514
|
if (!step || step.kind !== "gate") throw runtimeError("run_events_illegal", runId, `step ${stepId} is not a gate`);
|
|
515
515
|
return step;
|
|
516
516
|
}
|
|
517
517
|
|
|
518
|
-
function requireIntent(context:
|
|
518
|
+
function requireIntent(context: KxmRuntimeContext, run: KxmRunRecord, envelope: KxmRunPlanEnvelope, stepId: string) {
|
|
519
519
|
const step = requireGateStep(envelope, stepId, run.runId);
|
|
520
|
-
const folded =
|
|
520
|
+
const folded = foldStoredKxmRun(context, run);
|
|
521
521
|
const attemptId = folded.currentStep?.attemptId;
|
|
522
522
|
if (!attemptId || folded.currentStep?.stepId !== stepId) {
|
|
523
523
|
throw runtimeError("run_events_illegal", run.runId, "gate intent has not been recorded");
|
|
@@ -534,9 +534,9 @@ function requireIntent(context: VnextRuntimeContext, run: VnextRunRecord, envelo
|
|
|
534
534
|
|
|
535
535
|
function ensureOperatorCancel(
|
|
536
536
|
seq: ReturnType<typeof sequencer>,
|
|
537
|
-
state: ReturnType<typeof
|
|
538
|
-
run:
|
|
539
|
-
context:
|
|
537
|
+
state: ReturnType<typeof foldStoredKxmRun>,
|
|
538
|
+
run: KxmRunRecord,
|
|
539
|
+
context: KxmRuntimeContext,
|
|
540
540
|
): string {
|
|
541
541
|
if (state.status === "cancelling") return cancelReasonFromLog(context, run.runId);
|
|
542
542
|
if (state.status !== "running") {
|
|
@@ -550,7 +550,7 @@ function ensureOperatorCancel(
|
|
|
550
550
|
return "operator_cancel";
|
|
551
551
|
}
|
|
552
552
|
|
|
553
|
-
function cancelReasonFromLog(context:
|
|
553
|
+
function cancelReasonFromLog(context: KxmRuntimeContext, runId: string): string {
|
|
554
554
|
const events = context.eventStore.events(runId, 0, 1_000_000);
|
|
555
555
|
for (let index = events.length - 1; index >= 0; index -= 1) {
|
|
556
556
|
const event = events[index]!;
|
|
@@ -561,36 +561,36 @@ function cancelReasonFromLog(context: VnextRuntimeContext, runId: string): strin
|
|
|
561
561
|
return "operator_cancel";
|
|
562
562
|
}
|
|
563
563
|
|
|
564
|
-
function sequencer(context:
|
|
564
|
+
function sequencer(context: KxmRuntimeContext, run: KxmRunRecord, now: string) {
|
|
565
565
|
let sequence = context.eventStore.nextSequence(run.runId);
|
|
566
|
-
let mono =
|
|
567
|
-
const events:
|
|
566
|
+
let mono = kxmMonotonicNs();
|
|
567
|
+
const events: KxmRunEvent[] = [];
|
|
568
568
|
return {
|
|
569
569
|
events,
|
|
570
|
-
push(eventType: string, payload: Record<string, unknown>):
|
|
571
|
-
const event:
|
|
572
|
-
...
|
|
573
|
-
eventId:
|
|
570
|
+
push(eventType: string, payload: Record<string, unknown>): KxmRunEvent {
|
|
571
|
+
const event: KxmRunEvent = {
|
|
572
|
+
...kxmEventBase(context, run, now, mono),
|
|
573
|
+
eventId: newKxmEventId(),
|
|
574
574
|
eventType,
|
|
575
575
|
sequence: sequence++,
|
|
576
576
|
payload,
|
|
577
577
|
};
|
|
578
|
-
mono =
|
|
578
|
+
mono = kxmIncrementMonotonicNs(mono);
|
|
579
579
|
events.push(event);
|
|
580
580
|
return event;
|
|
581
581
|
},
|
|
582
582
|
};
|
|
583
583
|
}
|
|
584
584
|
|
|
585
|
-
function persist(context:
|
|
586
|
-
const next =
|
|
587
|
-
|
|
585
|
+
function persist(context: KxmRuntimeContext, run: KxmRunRecord, now: string, lastSequence: number) {
|
|
586
|
+
const next = foldStoredKxmRun(context, run);
|
|
587
|
+
persistKxmRunState(context, run.runId, next, lastSequence);
|
|
588
588
|
context.eventStore.updateRunStatus(run.runId, next.status, now);
|
|
589
589
|
return { state: next, run: { ...run, status: next.status, updatedAt: now } };
|
|
590
590
|
}
|
|
591
591
|
|
|
592
|
-
function hashFromStore(context:
|
|
592
|
+
function hashFromStore(context: KxmRuntimeContext, runId: string): string {
|
|
593
593
|
return context.eventStore.runPlan(runId)!.runPlanHash;
|
|
594
594
|
}
|
|
595
595
|
|
|
596
|
-
void
|
|
596
|
+
void kxmCanonicalJson;
|