@kontextmind/kxm 0.7.29 → 0.7.30

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.29",
14
+ "version": "0.7.30",
15
15
  "category": "development",
16
16
  "tags": ["kxm", "multi-agent", "workflows", "mcp"]
17
17
  }
@@ -3,7 +3,7 @@
3
3
  This document describes the bundled KXM Agent Skills suite: focused skills
4
4
  that cover current KXM top-level command groups. The suite documents the
5
5
  existing CLI. It does **not** land unified YAML role/project/workflow
6
- authority, admit new writers, or replace trusted `.kxm/roster.json` policy.
6
+ authority, admit new writers, or replace trusted `.kxm/roster.yaml` policy.
7
7
 
8
8
  ## Feature-to-Skill Matrix
9
9
 
@@ -16,7 +16,7 @@ policy.
16
16
  ## 1. Overview and role rotation
17
17
 
18
18
  Developer orchestration on this runner uses a role-based rotation backed by
19
- trusted policy in [`.kxm/roster.json`](../.kxm/roster.json). Roles, harnesses,
19
+ trusted policy in [`.kxm/roster.yaml`](../.kxm/roster.yaml). Roles, harnesses,
20
20
  and models are admitted with strict permission and vendor boundaries:
21
21
 
22
22
  | Role | Admitted route | Vendor | Permission | Purpose |
@@ -36,7 +36,7 @@ and models are admitted with strict permission and vendor boundaries:
36
36
  exceed the admitted ceiling (e.g. attempting to give edit permissions to a
37
37
  read-only reviewer).
38
38
  - **Trusted roster policy:** Dispatch (`assign` / `run`) and accept load
39
- `.kxm/roster.json` through the trusted control Git loader
39
+ `.kxm/roster.yaml` through the trusted control Git loader
40
40
  (`loadTrustedRosterPolicy`). Loader errors, missing/empty policy, and
41
41
  malformed policy fail closed with `route_invalid`. There is no raw working-tree
42
42
  JSON fallback and no null-policy acceptance. Tests may inject an explicit
@@ -96,7 +96,7 @@ node scripts/assignment-run.mjs run --manifest /absolute/path/to/manifest.json
96
96
  ```
97
97
 
98
98
  - Manifest validation asserts worktree cleanliness and validates the route
99
- against `.kxm/roster.json`.
99
+ against `.kxm/roster.yaml`.
100
100
  - Headless execution dispatches to the native harness (or OpenRouter via Pi for
101
101
  admitted relief).
102
102
  - Successful runs write `completion.json`, candidate snapshot metadata, and
@@ -219,7 +219,7 @@ The runner fails closed with bounded error codes defined in `RUNNER_CODES`:
219
219
 
220
220
  | Code | Trigger condition | Remedy |
221
221
  |---|---|---|
222
- | `route_invalid` | Harness/model not admitted in lineup for the requested role, permission exceeds route ceiling, or trusted roster policy cannot be loaded/validated. | Use a trusted clean control checkout; do not dispatch from a dirty implementation branch. Check `.kxm/roster.json` lineup and permissions for the role. |
222
+ | `route_invalid` | Harness/model not admitted in lineup for the requested role, permission exceeds route ceiling, or trusted roster policy cannot be loaded/validated. | Use a trusted clean control checkout; do not dispatch from a dirty implementation branch. Check `.kxm/roster.yaml` lineup and permissions for the role. |
223
223
  | `critic_invalid` | Missing required critic role, duplicate roles, wrong model, or vendor collision between writer and critics. | Ensure independent critics (Fable + Sol) from distinct providers. |
224
224
  | `critic_block` | An unresolved `BLOCK` verdict exists for the target tree. | Rework the changes, address findings, and pass review with a `rework_of` link. |
225
225
  | `commit_tree_mismatch` | Git commit tree does not equal the witnessed tree. | Commit the exact candidate tree verified by the witness before running accept. |
@@ -77,7 +77,7 @@ too). kxm resolves each role's first guide candidate whose harness is
77
77
  authenticated and writes only current vNext project resources —
78
78
  `.kxm/agents/<role>.yaml` (`kxm.agent.v1`) and `.kxm/workflows/<slug>.yaml`
79
79
  (`kxm.workflow.v1`). It never writes retired legacy authority (`.kxm/config`,
80
- `.kxm/roster.json`). Roles whose candidates have no authenticated harness are
80
+ retired `.kxm/roster.json`) or the trusted `.kxm/roster.yaml` policy. Roles whose candidates have no authenticated harness are
81
81
  reported as skipped, not silently downgraded. Guide candidates are dated
82
82
  research — verify them before dispatch. Declining is safe: set
83
83
  `KXM_SKIP_GUIDE_SETUP_PROMPT=1` to suppress the offer.
@@ -74,7 +74,7 @@ pull request (five CI jobs: 2 Linux validate, classify, docs, plugin)
74
74
 
75
75
  **Runner loop invariants:**
76
76
 
77
- - **Roles and rotation:** The runner strictly maps assignments to authenticated roster roles (`AGENTS.md` and `.kxm/roster.json`):
77
+ - **Roles and rotation:** The runner strictly maps assignments to authenticated roster roles (`AGENTS.md` and `.kxm/roster.yaml`):
78
78
  - **Implement / write code (`writer`):** **Grok** (`grok --model grok-4.6`, headless). Currently admitted native writer on this runner. Failover follows attempts-and-relief: after an empty or failed attempt, immediately fail over to the next eligible authenticated writer in the roster (**Qwen** `openrouter/qwen/qwen3-coder-plus` via Pi).
79
79
  - **Plan (`planner`):** **Claude Fable** (`claude --model fable`), read-only architecture and permissions planning.
80
80
  - **Review architecture (`reviewer-arch`):** **Claude Fable** (`claude --model fable`), designated architecture and permissions critic.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kontextmind/kxm",
3
- "version": "0.7.29",
3
+ "version": "0.7.30",
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.29",
5
+ "version": "0.7.30",
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.29";
17124
+ var VERSION = "0.7.30";
17125
17125
  var inbox = /* @__PURE__ */ new Map();
17126
17126
  var notifiedInbox = /* @__PURE__ */ new Set();
17127
17127
  var meshClient;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kxm-claude-plugin",
3
- "version": "0.7.29",
3
+ "version": "0.7.30",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "engines": {
@@ -8,7 +8,7 @@ description: Select the right suite skill; state universal safety rules and port
8
8
  This skill routes to the appropriate specialized skill for each KXM command category. Use this skill to determine which specific skill handles the command you need.
9
9
 
10
10
  These bundled skills document the current CLI. They do not switch runtime YAML
11
- authority, admit writers, or replace `.kxm/roster.json` trusted policy.
11
+ authority, admit writers, or replace `.kxm/roster.yaml` trusted policy.
12
12
 
13
13
  ## Command Routing Guide
14
14
 
@@ -10,7 +10,8 @@
10
10
  * This module writes only current vNext project resources:
11
11
  * - `.kxm/agents/<role-slug>.yaml` (kxm.agent.v1)
12
12
  * - `.kxm/workflows/<slug>.yaml` (kxm.workflow.v1)
13
- * It never writes retired legacy authority (`.kxm/config`, `.kxm/roster.json`)
13
+ * It never writes retired legacy authority (`.kxm/config`, retired
14
+ * `.kxm/roster.json`) or the trusted `.kxm/roster.yaml` policy
14
15
  * and does not use the kxm.role.v1 subsystem.
15
16
  */
16
17
 
@@ -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.29";
11
+ const VERSION = "0.7.30";
12
12
  const inbox = new Map<string, MessageRecord>();
13
13
  const notifiedInbox = new Set<string>();
14
14
  let meshClient: HubClient | undefined;
@@ -5,7 +5,7 @@ operator settings, live registry identities, or admission.
5
5
 
6
6
  - Live project models remain `kxm.model.v1` under `schemas/vnext/`.
7
7
  - Live CLI roles remain `kxm.role.v1`.
8
- - Runner admission remains `.kxm/roster.json` via the trusted control Git loader.
8
+ - Runner admission remains `.kxm/roster.yaml` via the trusted control Git loader.
9
9
  - This directory is not discovered as a vNext project resource.
10
10
 
11
11
  Pure validation lives in `plugins/kxm/src/policy-draft.mjs`
@@ -1,13 +1,15 @@
1
1
  /** Unwired developer policy foundation. No dispatch or acceptance authority. */
2
2
  import { execFileSync } from 'node:child_process';
3
3
  import { createHash } from 'node:crypto';
4
- import { lstatSync, readFileSync, realpathSync } from 'node:fs';
4
+ import { existsSync, lstatSync, readFileSync, realpathSync } from 'node:fs';
5
5
  import path from 'node:path';
6
6
  import { fileURLToPath } from 'node:url';
7
+ import YAML from 'yaml';
7
8
  import { NATIVE_PI_BRAKE_PROVIDERS, PI_ALLOWED_PROVIDERS, PI_ANTIGRAVITY_MODEL_ID, PI_NATIVE_VENDOR_PROVIDERS, ROUTES } from './harness-run.mjs';
8
9
 
9
10
  const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
10
- const POLICY = '.kxm/roster.json';
11
+ const POLICY = '.kxm/roster.yaml';
12
+ const RETIRED_POLICY = '.kxm/roster.json';
11
13
  const TRUSTED = 'refs/remotes/origin/main';
12
14
  const ROLES = ['writer', 'planner', 'reviewer-arch', 'reviewer-cli', 'experiment'];
13
15
  const ALIASES = Object.freeze({ 'x-ai': 'xai', moonshotai: 'moonshot', 'google-ai': 'google', qwen: 'alibaba' });
@@ -54,6 +56,7 @@ function frozen(value) {
54
56
  return value;
55
57
  }
56
58
  function control() {
59
+ if (existsSync(path.join(ROOT, RETIRED_POLICY))) refuse(`retired ${RETIRED_POLICY} present; use ${POLICY}`);
57
60
  if (realpathSync(gitText('rev-parse', '--show-toplevel')) !== realpathSync(ROOT)) refuse('module is outside its control repository');
58
61
  const head = gitText('rev-parse', '--verify', 'HEAD^{commit}');
59
62
  const trusted = gitText('rev-parse', '--verify', `${TRUSTED}^{commit}`);
@@ -159,7 +162,8 @@ export function validateRosterDocument(policy, readBlob) {
159
162
  }
160
163
  function validate(bytes, commit) {
161
164
  let policy;
162
- try { policy = JSON.parse(bytes.toString('utf8')); } catch { refuse('invalid policy JSON'); }
165
+ try { policy = YAML.parse(bytes.toString('utf8')); } catch { refuse('invalid policy YAML'); }
166
+ if (policy === undefined || policy === null || typeof policy !== 'object' || Array.isArray(policy)) refuse('invalid policy YAML');
163
167
  return validateRosterDocument(policy, source => blobAt(commit, source).bytes);
164
168
  }
165
169
  export function loadTrustedRosterPolicy() {