@kontextmind/kxm 0.7.61 → 0.7.64

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.
@@ -11,7 +11,7 @@
11
11
  "name": "kxm",
12
12
  "source": "./plugins/kxm",
13
13
  "description": "Durable workflows, peer agents, and kxm tui",
14
- "version": "0.7.61",
14
+ "version": "0.7.64",
15
15
  "category": "development",
16
16
  "tags": ["kxm", "multi-agent", "workflows", "mcp"]
17
17
  }
@@ -100,7 +100,7 @@ created → accepted → dispatched → executing → result_recorded → termin
100
100
  | `dispatched` | Attempt identity and dispatch intent persisted before process start |
101
101
  | `executing` | Invocation admitted and the attempt capability is usable. This slice is in-process (no OS process identity yet); later recovery still requires exact process/session proof |
102
102
  | `reattaching` | Runtime is verifying the same process/session and event cursor |
103
- | `result_recorded` | Structured attempt result and referenced receipts are durably stored |
103
+ | `result_recorded` | Structured attempt result and referenced receipts are durably stored. When a producer **refused** (`resultClass: producer_rejected`), the payload may carry `producerError`: a **machine code only** (lowercase-underscore identifier, ≤64 chars, schema-enforced; capability material is redacted before extraction, and anything unclassifiable — including prose — records as `producer_error`). The routing record names the producer that actually ran: a live drive that fails authentication must never read in the log as a simulation |
104
104
  | `retry_pending` | Policy permits another physical attempt after the prior attempt became terminal |
105
105
  | `blocked_uncertain` | A dependent effect cannot be reconciled safely |
106
106
  | `terminal` | The logical assignment outcome is final and immutable: passed, failed, or cancelled |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kontextmind/kxm",
3
- "version": "0.7.61",
3
+ "version": "0.7.64",
4
4
  "description": "KXM local-first multi-agent orchestration and operator dashboard",
5
5
  "type": "module",
6
6
  "author": "KontextMind",
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
3
3
  "name": "kxm",
4
4
  "displayName": "KXM",
5
- "version": "0.7.61",
5
+ "version": "0.7.64",
6
6
  "description": "Headless multi-agent orchestration, durable workflows, and a live operator dashboard for Pi and Claude Code",
7
7
  "author": {
8
8
  "name": "KontextMind",
@@ -17121,7 +17121,7 @@ async function deliverInboxNotification(messageId, delivered, notify) {
17121
17121
  }
17122
17122
 
17123
17123
  // plugins/kxm/src/mcp-server.ts
17124
- var VERSION = "0.7.61";
17124
+ var VERSION = "0.7.64";
17125
17125
  var inbox = /* @__PURE__ */ new Map();
17126
17126
  var notifiedInbox = /* @__PURE__ */ new Set();
17127
17127
  var meshClient;
@@ -16102,8 +16102,9 @@ function probeHarnessAssignment(options) {
16102
16102
  };
16103
16103
  }
16104
16104
  const authArgs = ["auth", "check"];
16105
- if (options.model) {
16106
- authArgs.push("--model", options.model);
16105
+ const qualifiedModel = options.model ? options.provider && options.model.startsWith(`${options.provider}/`) ? options.model : options.provider ? `${options.provider}/${options.model}` : options.model : void 0;
16106
+ if (qualifiedModel) {
16107
+ authArgs.push("--model", qualifiedModel);
16107
16108
  } else if (options.provider) {
16108
16109
  authArgs.push("--provider", options.provider);
16109
16110
  }
@@ -24601,15 +24602,29 @@ var KxmRunScheduler = class _KxmRunScheduler {
24601
24602
  }
24602
24603
  };
24603
24604
  function invokeProducer(producer, request) {
24605
+ const reason = (error) => {
24606
+ try {
24607
+ const raw = error instanceof Error ? error.message : error;
24608
+ const message = typeof raw === "string" ? raw : "";
24609
+ let text = message;
24610
+ if (request.capability) text = text.split(request.capability).join("[redacted]");
24611
+ text = text.replace(/kxmcap_[A-Za-z0-9_-]+/g, "[redacted]");
24612
+ const match = /^[a-z][a-z0-9]*(?:_[a-z0-9]+){1,3}/.exec(text);
24613
+ const code = match?.[0] ?? "";
24614
+ return code.length > 0 && code.length <= 64 ? code : "producer_error";
24615
+ } catch {
24616
+ return "producer_error";
24617
+ }
24618
+ };
24604
24619
  let pending;
24605
24620
  try {
24606
24621
  pending = Promise.resolve(producer.produce(request));
24607
- } catch {
24608
- return Promise.resolve({ error: true });
24622
+ } catch (error) {
24623
+ return Promise.resolve({ error: true, errorCode: reason(error) });
24609
24624
  }
24610
24625
  return pending.then(
24611
24626
  (result) => ({ result, error: false }),
24612
- () => ({ error: true })
24627
+ (error) => ({ error: true, errorCode: reason(error) })
24613
24628
  );
24614
24629
  }
24615
24630
  var kxmGateDispatchSeams = {};
@@ -25428,7 +25443,7 @@ async function drivePanel(context, panel, producer) {
25428
25443
  if (kxmPanelDispatchSeams.failSettleMember?.(member)) {
25429
25444
  throw runtimeError("run_events_illegal", runId, "member settlement write failed");
25430
25445
  }
25431
- settleMember(context, member, produced.result, produced.error);
25446
+ settleMember(context, member, produced.result, produced.error, produced.errorCode);
25432
25447
  });
25433
25448
  return true;
25434
25449
  } catch (err) {
@@ -25583,7 +25598,7 @@ function producerRoutingRecord(context, dispatch, result, now) {
25583
25598
  }
25584
25599
  return parseRoutingRecordV2(record2);
25585
25600
  }
25586
- function settleMember(context, dispatch, result, produceError) {
25601
+ function settleMember(context, dispatch, result, produceError, produceErrorCode) {
25587
25602
  const run = requireRun(context, dispatch.run.runId);
25588
25603
  const state = foldStoredKxmRun(context, run);
25589
25604
  const capability = context.eventStore.capabilityByAttempt(dispatch.attemptId);
@@ -25634,7 +25649,10 @@ function settleMember(context, dispatch, result, produceError) {
25634
25649
  stepId: dispatch.stepId,
25635
25650
  assignmentId: dispatch.assignmentId,
25636
25651
  attemptId: dispatch.attemptId,
25637
- harness: result?.harness ?? (dispatch.producerId === "pi" ? "pi" : "driver-simulated"),
25652
+ // Label the producer that actually ran: the old fallback printed "driver-simulated"
25653
+ // for every producer that was not literally "pi", so a live oneshot drive that
25654
+ // failed authentication read in the log as a simulation.
25655
+ harness: result?.harness ?? dispatch.producerId,
25638
25656
  provider: result?.provider ?? "simulated",
25639
25657
  requestedModel: result?.requestedModel ?? "simulated",
25640
25658
  effectiveModel: result?.effectiveModel ?? result?.requestedModel ?? "simulated",
@@ -25648,7 +25666,8 @@ function settleMember(context, dispatch, result, produceError) {
25648
25666
  push("assignment.result_recorded", {
25649
25667
  assignmentId: dispatch.assignmentId,
25650
25668
  resultClass: "producer_rejected",
25651
- status: "result_recorded"
25669
+ status: "result_recorded",
25670
+ ...produceErrorCode !== void 0 ? { producerError: produceErrorCode } : {}
25652
25671
  });
25653
25672
  push("attempt.status_changed", { attemptId: dispatch.attemptId, status: "terminal" });
25654
25673
  push("assignment.terminal", { assignmentId: dispatch.assignmentId, outcome: "failed", status: "terminal" });
@@ -16125,8 +16125,9 @@ function probeHarnessAssignment(options) {
16125
16125
  };
16126
16126
  }
16127
16127
  const authArgs = ["auth", "check"];
16128
- if (options.model) {
16129
- authArgs.push("--model", options.model);
16128
+ const qualifiedModel = options.model ? options.provider && options.model.startsWith(`${options.provider}/`) ? options.model : options.provider ? `${options.provider}/${options.model}` : options.model : void 0;
16129
+ if (qualifiedModel) {
16130
+ authArgs.push("--model", qualifiedModel);
16130
16131
  } else if (options.provider) {
16131
16132
  authArgs.push("--provider", options.provider);
16132
16133
  }
@@ -25113,15 +25114,29 @@ var KxmRunScheduler = class _KxmRunScheduler {
25113
25114
  }
25114
25115
  };
25115
25116
  function invokeProducer(producer, request) {
25117
+ const reason = (error) => {
25118
+ try {
25119
+ const raw = error instanceof Error ? error.message : error;
25120
+ const message = typeof raw === "string" ? raw : "";
25121
+ let text = message;
25122
+ if (request.capability) text = text.split(request.capability).join("[redacted]");
25123
+ text = text.replace(/kxmcap_[A-Za-z0-9_-]+/g, "[redacted]");
25124
+ const match = /^[a-z][a-z0-9]*(?:_[a-z0-9]+){1,3}/.exec(text);
25125
+ const code = match?.[0] ?? "";
25126
+ return code.length > 0 && code.length <= 64 ? code : "producer_error";
25127
+ } catch {
25128
+ return "producer_error";
25129
+ }
25130
+ };
25116
25131
  let pending;
25117
25132
  try {
25118
25133
  pending = Promise.resolve(producer.produce(request));
25119
- } catch {
25120
- return Promise.resolve({ error: true });
25134
+ } catch (error) {
25135
+ return Promise.resolve({ error: true, errorCode: reason(error) });
25121
25136
  }
25122
25137
  return pending.then(
25123
25138
  (result) => ({ result, error: false }),
25124
- () => ({ error: true })
25139
+ (error) => ({ error: true, errorCode: reason(error) })
25125
25140
  );
25126
25141
  }
25127
25142
  var kxmGateDispatchSeams = {};
@@ -25940,7 +25955,7 @@ async function drivePanel(context, panel, producer) {
25940
25955
  if (kxmPanelDispatchSeams.failSettleMember?.(member)) {
25941
25956
  throw runtimeError("run_events_illegal", runId, "member settlement write failed");
25942
25957
  }
25943
- settleMember(context, member, produced.result, produced.error);
25958
+ settleMember(context, member, produced.result, produced.error, produced.errorCode);
25944
25959
  });
25945
25960
  return true;
25946
25961
  } catch (err) {
@@ -26095,7 +26110,7 @@ function producerRoutingRecord(context, dispatch, result, now) {
26095
26110
  }
26096
26111
  return parseRoutingRecordV2(record2);
26097
26112
  }
26098
- function settleMember(context, dispatch, result, produceError) {
26113
+ function settleMember(context, dispatch, result, produceError, produceErrorCode) {
26099
26114
  const run = requireRun(context, dispatch.run.runId);
26100
26115
  const state = foldStoredKxmRun(context, run);
26101
26116
  const capability = context.eventStore.capabilityByAttempt(dispatch.attemptId);
@@ -26146,7 +26161,10 @@ function settleMember(context, dispatch, result, produceError) {
26146
26161
  stepId: dispatch.stepId,
26147
26162
  assignmentId: dispatch.assignmentId,
26148
26163
  attemptId: dispatch.attemptId,
26149
- harness: result?.harness ?? (dispatch.producerId === "pi" ? "pi" : "driver-simulated"),
26164
+ // Label the producer that actually ran: the old fallback printed "driver-simulated"
26165
+ // for every producer that was not literally "pi", so a live oneshot drive that
26166
+ // failed authentication read in the log as a simulation.
26167
+ harness: result?.harness ?? dispatch.producerId,
26150
26168
  provider: result?.provider ?? "simulated",
26151
26169
  requestedModel: result?.requestedModel ?? "simulated",
26152
26170
  effectiveModel: result?.effectiveModel ?? result?.requestedModel ?? "simulated",
@@ -26160,7 +26178,8 @@ function settleMember(context, dispatch, result, produceError) {
26160
26178
  push("assignment.result_recorded", {
26161
26179
  assignmentId: dispatch.assignmentId,
26162
26180
  resultClass: "producer_rejected",
26163
- status: "result_recorded"
26181
+ status: "result_recorded",
26182
+ ...produceErrorCode !== void 0 ? { producerError: produceErrorCode } : {}
26164
26183
  });
26165
26184
  push("attempt.status_changed", { attemptId: dispatch.attemptId, status: "terminal" });
26166
26185
  push("assignment.terminal", { assignmentId: dispatch.assignmentId, outcome: "failed", status: "terminal" });
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-plugin",
3
- "version": "0.7.61",
3
+ "version": "0.7.64",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "engines": {
@@ -854,15 +854,41 @@ function invokeProducer(
854
854
  producer: KxmProducer,
855
855
  request: KxmProducerRequest,
856
856
  ): Promise<{ result?: KxmProducerResult; error: boolean; errorCode?: string }> {
857
+ // The reason a producer refused is the single most useful fact about a failed attempt,
858
+ // and it used to be discarded here: a live drive that could not authenticate read in the
859
+ // event log exactly like a simulation that ran fine. But the message is producer-
860
+ // controlled text and must never reach durable records as-is — a producer that throws
861
+ // its capability (the hygiene contract tests exactly that) would persist the secret.
862
+ // So: redact the attempt capability and anything capability-shaped, then keep only a
863
+ // leading machine-code identifier (lowercase segments joined by underscores). Anything
864
+ // else — prose, free text, a redacted-to-empty message — records as producer_error.
865
+ const reason = (error: unknown): string => {
866
+ // Never throw while classifying a throw: a producer can reject with anything
867
+ // (Object.create(null) defeats String(), an Error whose message is not a string
868
+ // defeats split()), and a throwing classifier would reroute a producer_rejected
869
+ // settle into the execution-error path — the exact invisibility this exists to fix.
870
+ try {
871
+ const raw = error instanceof Error ? error.message : error;
872
+ const message = typeof raw === "string" ? raw : "";
873
+ let text = message;
874
+ if (request.capability) text = text.split(request.capability).join("[redacted]");
875
+ text = text.replace(/kxmcap_[A-Za-z0-9_-]+/g, "[redacted]");
876
+ const match = /^[a-z][a-z0-9]*(?:_[a-z0-9]+){1,3}/.exec(text);
877
+ const code = match?.[0] ?? "";
878
+ return code.length > 0 && code.length <= 64 ? code : "producer_error";
879
+ } catch {
880
+ return "producer_error";
881
+ }
882
+ };
857
883
  let pending: Promise<KxmProducerResult>;
858
884
  try {
859
885
  pending = Promise.resolve(producer.produce(request));
860
- } catch {
861
- return Promise.resolve({ error: true });
886
+ } catch (error) {
887
+ return Promise.resolve({ error: true, errorCode: reason(error) });
862
888
  }
863
889
  return pending.then(
864
890
  (result) => ({ result, error: false }),
865
- () => ({ error: true }),
891
+ (error) => ({ error: true, errorCode: reason(error) }),
866
892
  );
867
893
  }
868
894
 
@@ -1778,7 +1804,7 @@ function appendExecuting(context: KxmRuntimeContext, dispatch: PreparedDispatch)
1778
1804
  }
1779
1805
 
1780
1806
  type MemberWork =
1781
- | { attemptId: string; invoked: true; produced: { result?: KxmProducerResult; error: boolean } }
1807
+ | { attemptId: string; invoked: true; produced: { result?: KxmProducerResult; error: boolean; errorCode?: string } }
1782
1808
  | { attemptId: string; invoked: false; skipped: true }
1783
1809
  | { attemptId: string; invoked: false; appendFailed: true; error: unknown };
1784
1810
 
@@ -1919,7 +1945,7 @@ async function drivePanel(
1919
1945
  });
1920
1946
  };
1921
1947
 
1922
- const settleInvoked = (member: PreparedDispatch, produced: { result?: KxmProducerResult; error: boolean }): boolean => {
1948
+ const settleInvoked = (member: PreparedDispatch, produced: { result?: KxmProducerResult; error: boolean; errorCode?: string }): boolean => {
1923
1949
  if (produced.result?.effectUncertain) {
1924
1950
  settlementFailed = true;
1925
1951
  stopBirths = true;
@@ -1930,7 +1956,7 @@ async function drivePanel(
1930
1956
  if (kxmPanelDispatchSeams.failSettleMember?.(member)) {
1931
1957
  throw runtimeError("run_events_illegal", runId, "member settlement write failed");
1932
1958
  }
1933
- settleMember(context, member, produced.result, produced.error);
1959
+ settleMember(context, member, produced.result, produced.error, produced.errorCode);
1934
1960
  });
1935
1961
  return true;
1936
1962
  } catch (err) {
@@ -2092,6 +2118,7 @@ function settleMember(
2092
2118
  dispatch: PreparedDispatch,
2093
2119
  result: KxmProducerResult | undefined,
2094
2120
  produceError: boolean,
2121
+ produceErrorCode?: string,
2095
2122
  ): void {
2096
2123
  const run = requireRun(context, dispatch.run.runId);
2097
2124
  const state = foldStoredKxmRun(context, run);
@@ -2146,7 +2173,10 @@ function settleMember(
2146
2173
  stepId: dispatch.stepId,
2147
2174
  assignmentId: dispatch.assignmentId,
2148
2175
  attemptId: dispatch.attemptId,
2149
- harness: result?.harness ?? (dispatch.producerId === "pi" ? "pi" : "driver-simulated"),
2176
+ // Label the producer that actually ran: the old fallback printed "driver-simulated"
2177
+ // for every producer that was not literally "pi", so a live oneshot drive that
2178
+ // failed authentication read in the log as a simulation.
2179
+ harness: result?.harness ?? dispatch.producerId,
2150
2180
  provider: result?.provider ?? "simulated",
2151
2181
  requestedModel: result?.requestedModel ?? "simulated",
2152
2182
  effectiveModel: result?.effectiveModel ?? result?.requestedModel ?? "simulated",
@@ -2162,6 +2192,7 @@ function settleMember(
2162
2192
  assignmentId: dispatch.assignmentId,
2163
2193
  resultClass: "producer_rejected",
2164
2194
  status: "result_recorded",
2195
+ ...(produceErrorCode !== undefined ? { producerError: produceErrorCode } : {}),
2165
2196
  });
2166
2197
  push("attempt.status_changed", { attemptId: dispatch.attemptId, status: "terminal" });
2167
2198
  push("assignment.terminal", { assignmentId: dispatch.assignmentId, outcome: "failed", status: "terminal" });
@@ -1118,8 +1118,17 @@ export function probeHarnessAssignment(options: HarnessAssignmentProbeOptions):
1118
1118
  }
1119
1119
 
1120
1120
  const authArgs = ["auth", "check"];
1121
- if (options.model) {
1122
- authArgs.push("--model", options.model);
1121
+ // `pi auth check --model` requires a provider-qualified id: a bare model answers
1122
+ // status "invalid", which reads as not_authenticated and hides the real state. When
1123
+ // the caller holds provider and bare model separately (the engine's request shape),
1124
+ // qualify the id; a model that already carries its namespace goes through as-is.
1125
+ const qualifiedModel = options.model
1126
+ ? (options.provider && options.model.startsWith(`${options.provider}/`)
1127
+ ? options.model
1128
+ : options.provider ? `${options.provider}/${options.model}` : options.model)
1129
+ : undefined;
1130
+ if (qualifiedModel) {
1131
+ authArgs.push("--model", qualifiedModel);
1123
1132
  } else if (options.provider) {
1124
1133
  authArgs.push("--provider", options.provider);
1125
1134
  }
@@ -8,7 +8,7 @@ import { AGENT_COMMANDS_MAP, enforceToolPolicy, getMcpTools, reconcileInbox } fr
8
8
  import { deliverInboxNotification } from "./inbox.ts";
9
9
  import type { HubEvent, MessageRecord } from "./protocol.ts";
10
10
 
11
- const VERSION = "0.7.61";
11
+ const VERSION = "0.7.64";
12
12
  const inbox = new Map<string, MessageRecord>();
13
13
  const notifiedInbox = new Set<string>();
14
14
  let meshClient: HubClient | undefined;
@@ -364,6 +364,7 @@
364
364
  "runPlanHash": { "$ref": "common.schema.json#/$defs/sha256" },
365
365
  "capabilityHash": { "$ref": "common.schema.json#/$defs/sha256" },
366
366
  "resultClass": { "enum": ["outcome", "outcome_unknown", "producer_rejected", "cancelled"] },
367
+ "producerError": { "type": "string", "pattern": "^[a-z][a-z0-9]*(?:_[a-z0-9]+){1,3}$", "maxLength": 64, "description": "Machine-code reason a producer refused (produce threw), present only for resultClass producer_rejected. Capability material is redacted before extraction; anything unclassifiable records as producer_error." },
367
368
  "status": { "$ref": "common.schema.json#/$defs/lifecycleStatus" },
368
369
  "previousStatus": { "$ref": "common.schema.json#/$defs/lifecycleStatus" },
369
370
  "outcome": { "$ref": "common.schema.json#/$defs/identifier" },