@kontextmind/kxm 0.7.97 → 0.7.98

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.kxm/workflows/default.yaml +2 -0
  3. package/CHANGELOG.md +39 -2
  4. package/docs/concepts/architecture.md +1 -1
  5. package/docs/concepts/data-and-storage.md +1 -1
  6. package/docs/contracts/routing.md +1 -1
  7. package/docs/contributing/test-matrix.md +6 -5
  8. package/docs/operations/backup-and-restore.md +43 -24
  9. package/docs/operations/deploy.md +1 -1
  10. package/docs/reference/cli-reference.md +59 -24
  11. package/docs/reference/config-reference.md +24 -13
  12. package/docs/reference/harness-routing.md +3 -3
  13. package/docs/reference/http-api.md +1 -1
  14. package/docs/start/first-workflow.md +4 -4
  15. package/docs/start/quickstart-claude-code.md +2 -2
  16. package/package.json +1 -1
  17. package/plugins/kxm/.claude-plugin/plugin.json +1 -1
  18. package/plugins/kxm/dist/cli.js +393 -154
  19. package/plugins/kxm/dist/core.js +5 -2
  20. package/plugins/kxm/dist/mcp-server.js +1 -1
  21. package/plugins/kxm/dist/runtime-supervisor.js +231 -48
  22. package/plugins/kxm/dist/runtime.js +415 -92
  23. package/plugins/kxm/dist/server.js +7 -0
  24. package/plugins/kxm/package.json +1 -1
  25. package/plugins/kxm/skills/kxm-hub-ops/SKILL.md +4 -3
  26. package/plugins/kxm/skills/kxm-project-setup/SKILL.md +3 -2
  27. package/plugins/kxm/skills/kxm-routing-improve/SKILL.md +3 -0
  28. package/plugins/kxm/skills/kxm-runs/SKILL.md +8 -7
  29. package/plugins/kxm/src/cli/project.ts +22 -13
  30. package/plugins/kxm/src/cli/system.ts +22 -1
  31. package/plugins/kxm/src/cli.ts +11 -3
  32. package/plugins/kxm/src/database.ts +210 -36
  33. package/plugins/kxm/src/engine.ts +117 -2
  34. package/plugins/kxm/src/harness.ts +29 -0
  35. package/plugins/kxm/src/init-guide-setup.ts +43 -28
  36. package/plugins/kxm/src/mcp-server.ts +1 -1
  37. package/plugins/kxm/src/oneshot-producer.ts +16 -8
  38. package/plugins/kxm/src/prices.ts +33 -2
  39. package/plugins/kxm/src/routing.ts +13 -7
  40. package/plugins/kxm/src/studio-layout.ts +5 -4
  41. package/plugins/kxm/src/template.ts +31 -0
  42. package/plugins/kxm/src/worktree-witness.ts +71 -0
  43. package/schemas/backup-manifest.schema.json +33 -0
@@ -340,11 +340,15 @@ reference. Schema: `schemas/agent.schema.json`; semantic checks in
340
340
  | `session.maxIdleMs` | Integer, 0 to 31,536,000,000 | Optional | Not read by any code path yet |
341
341
 
342
342
  Tool presets are names checked against a registered list. The live one-shot
343
- producer launches every harness with a fixed read-only argument set
344
- (`READ_ONLY_ONESHOT_ARGS` in `plugins/kxm/src/harness.ts`); it does not
345
- translate `tools` into harness flags. The Runtime refuses live steps that
346
- request `write` access until the writer sandbox is in place, so a step that
347
- writes a repository runs today only under the simulated producer.
343
+ producer launches each harness with a fixed argument set and does not
344
+ translate `tools` into harness flags. A read-only step uses the read-only set
345
+ (`READ_ONLY_ONESHOT_ARGS` in `plugins/kxm/src/harness.ts`). A step with `write`
346
+ access uses the audited writer set (`WRITER_ONESHOT_ARGS`), which exists only
347
+ for `pi` (`-a` with extensions, skills, prompt templates and sessions off) and
348
+ `grok` (`--always-approve` with subagents and web search off). Both approve
349
+ every tool call, shell commands included, and neither confines the process to
350
+ the checkout. A live write step on any other harness is handed off; see
351
+ [Steps the Runtime does not execute yet](#steps-the-runtime-does-not-execute-yet).
348
352
 
349
353
  ### Model selectors
350
354
 
@@ -451,9 +455,11 @@ Error codes: `executor_unknown`, `harness_unknown`, `tool_preset_unknown`,
451
455
  [Rules shared by the project bundle](#rules-shared-by-the-project-bundle), and
452
456
  `role_roster_conflicts_with_agent` (see [Roles](#kxmrolesroleyaml-kxmrolev1)).
453
457
 
454
- Commands: `kxm init` creates `coordinator` and `implementer`; an interactive
455
- `kxm init` can add workflow-guide agents for authenticated harnesses; `kxm run`
456
- and the Runtime read them; `kxm trust` diffs them.
458
+ Commands: `kxm init` creates `coordinator` (`claude`, `anthropic/fable`) and
459
+ `implementer` (`grok`, `xai/grok-4.6`) and admits both selectors in
460
+ `.kxm/routes.yaml`; an interactive `kxm init` can add workflow-guide agents for
461
+ reviewed harness/model pairs whose harness is authenticated, and admits their
462
+ selectors too; `kxm run` and the Runtime read them; `kxm trust` diffs them.
457
463
 
458
464
  ## `.kxm/models/<id>.yaml` (`kxm.model.v1`)
459
465
 
@@ -672,16 +678,21 @@ these, the run is handed off (`step_unsupported`, `gate_unsupported`, or
672
678
  `limit_unsupported`) instead of executing, and `kxm runs drive` reports
673
679
  `run_handoff_required`:
674
680
 
675
- - `limits.maxAgentTimeMs` in the workflow or project. The built-in template
676
- sets it, so the `default` workflow that `kxm init` writes cannot be driven
677
- as generated.
681
+ - `limits.maxAgentTimeMs` in the workflow or project. The current `kxm init`
682
+ template leaves it out; older templates set it on `default`.
678
683
  - `tools`, `secrets`, or `safeSpeculation: true` on any step.
679
684
  - `join.strategy` other than `all` or `all-settled`, `join.minimumPassed` with
680
685
  `all`, and `join.cancelRemaining`.
681
686
  - `assignments.maxAttemptsPerAssignment` above 2,
682
687
  `assignments.maxWriteRepositories` above 1, and `distinctBy` other than
683
688
  `provider`.
684
- - A live (non-simulated) step with `write` access to any repository.
689
+ - A live (non-simulated) step with `write` access to any repository when its
690
+ agent's harness has no audited writer profile (only `pi` and `grok` have
691
+ one), when `assignments.maximum` is above 1, when the project's
692
+ `limits.maxConcurrentRuns` is above 1, or when `.kxm/roster.yaml` exists and
693
+ is not a `kxm.developer-roster.v1` whose writer lineup admits that harness
694
+ and model with `edit` permission. The checkout witness can attribute a
695
+ change only to one writer at a time.
685
696
  - Gate steps with `assignments.allowedAgents`, any assignment count or
686
697
  `maxAttemptsPerAssignment` other than 1, `distinctBy`,
687
698
  `maxWriteRepositories`, a join other than plain `all`, a `model`, no
@@ -1716,7 +1727,7 @@ Everything under `.kxm/` at the project root falls into one of three groups.
1716
1727
  | `logs/` | Ignored runtime logs | The hub and workers |
1717
1728
  | `state/` | Ignored restart state: the hub database `kxm.db`, Pi sessions, worker manifests | The hub and workers |
1718
1729
  | `run/` | Ignored sockets (`run/ssh-sockets/`) | `kxm ssh` |
1719
- | `backups/` | Ignored; each `backup-<time>/` holds a copy of the hub database and `manifest.json` | `kxm backup` (without `--out`) |
1730
+ | `backups/` | Ignored; each `backup-<time>/` holds copies of the hub database, the Runtime stores and their prompt sidecars, and `manifest.json` | `kxm backup` (without `--out`) |
1720
1731
  | `config/` | Legacy: its JSON files make the project unloadable | Nothing current |
1721
1732
  | `.kxm-init-transaction/` (sibling of `.kxm/` at the Git root) | Ignored; interrupted `kxm init` state | `kxm init` |
1722
1733
 
@@ -278,7 +278,7 @@ No product producer writes `metered` today. Subscription runs are `unmetered` be
278
278
  - The catalog `date` is today.
279
279
  - The harness is `claude` and the token counts are complete. The Runtime runs every harness, Pi included, through the one-shot producer, which estimates only for `claude`. The package also ships a long-lived Pi producer that estimates for any provider, but nothing in the Runtime calls it today.
280
280
 
281
- `kxm routing report` groups records by harness, model, effort and role. It ranks routes by quality first (Pass%, then Rwk%), then by cost per accepted attempt. Among routes of equal quality, a route with any unknown-cost attempt ranks after every route without one, because its cost is only a lower bound. Its `$/Acc` still shows only what was priced, so a route that mixes unmetered and unknown-cost attempts can read `$0.0000`; the `*` in the `Unk` column marks it. Read `Unm` and `Unk` before you trust `$/Acc`.
281
+ `kxm routing report` groups records by harness, model, effort and role. It ranks routes by quality first (Pass%, then Rwk%), then by cost per accepted attempt. Among routes of equal quality, a route with any unknown-cost attempt ranks after every route without one, because its cost is unknown. Its `$/Acc` prints `-` instead of a partial sum, and the `*` in the `Unk` column marks it. Read `Unm` and `Unk` before you trust `$/Acc`.
282
282
 
283
283
  The `Quota` column counts attempts whose metadata looks quota-exhausted. Nothing fails over on it. The report has no provider column, so the `Harness` column is what tells you native from Pi.
284
284
 
@@ -407,7 +407,7 @@ The code today limits where that route can run:
407
407
  - The KXM Pi extension registers the `antigravity` provider. The Runtime's Pi one-shot runs with `--no-extensions`, so it cannot reach `antigravity/…`.
408
408
  - Only an interactive Pi with KXM loaded, or a long-lived Pi worker, can use it.
409
409
 
410
- Admit an `antigravity/…` route only through a reviewed admission decision. Whether Google work should use `agy` or `antigravity` today is still an operator decision; see [Where the code is looser than the rules](#where-the-code-is-looser-than-the-rules).
410
+ Admit an `antigravity/…` route only through a reviewed admission decision. The guided setup in `kxm init` maps Google guide candidates to `antigravity/gemini-3.8-flash-high` on Pi and admits that selector, but a Runtime drive of such an agent still cannot reach the provider. Whether Google work should use `agy` or `antigravity` today is still an operator decision; see [Where the code is looser than the rules](#where-the-code-is-looser-than-the-rules).
411
411
 
412
412
  ### Claude bridge: experiment only
413
413
 
@@ -493,7 +493,7 @@ These are places where the code decides less than the [routing rules](#routing-r
493
493
  - **Reseller ids without a vendor segment.** Pi also serves native vendors' models under a reseller's own provider id, for example `github-copilot/claude-…`, `amazon-bedrock/anthropic.…` or `azure-openai-responses/gpt-…`. The brake reads the provider and the vendor segment, not the model name, so it accepts these ids. Keep them out of `.kxm/routes.yaml`.
494
494
  - **Open-weight models on a third-party plan.** A DeepSeek model billed through Alibaba's plan, such as `qwen-token-plan/deepseek-v4.1-flash`, passes the brake although DeepSeek is a braked vendor. The reverse also happens: an open-weight model filed under a native vendor's namespace, such as `groq/openai/gpt-oss-120b`, is refused. Whether a third-party plan bill counts as billing the vendor is not decided.
495
495
  - **Selectors the brake cannot see.** A worker started without `--model` runs Pi's default model, and a bare model id lets Pi choose the provider. Neither names a vendor, so neither is checked. A model that a person selects inside an interactive Pi session is not checked either.
496
- - **The Google route.** The rules name the `antigravity` Pi provider as Google's route, but the code sends Google through `agy`: the guided setup in `kxm init` maps Google candidates to `agy`, and the Runtime's Pi one-shot cannot reach `antigravity/…` (section 4).
496
+ - **The Google route.** The rules name the `antigravity` Pi provider as Google's route, and the guided setup in `kxm init` now writes Google roles on Pi with `antigravity/gemini-3.8-flash-high` and admits that selector. The Runtime's Pi one-shot runs with `--no-extensions`, so it cannot reach `antigravity/…` and a live drive of those roles fails at dispatch (section 4). A `google/gemini-…` selector still runs only through `agy`.
497
497
  - **Two Pi provider allowlists.** `PI_ALLOWED_PROVIDERS` in `plugins/kxm/src/harness.ts` is exported but gates nothing; on the product path, the brake and admission in `.kxm/routes.yaml` decide. The developer helper keeps a different list of its own.
498
498
  - **`limits.maxModelCost` cannot trip on a live run.** The engine counts only `metered` cost toward the cap, and no producer records `metered` today (section 2). The Runtime caps `unmetered` and `unknown` attempts at 100 per run instead; see [Cost basis and staleness](config-reference.md#cost-basis-and-staleness).
499
499
  - **Config load checks harness/model pairs only for agents that declare `harness:` and select their model through a profile or tag.** An agent with a direct `{provider, model}` selector, or one that omits `harness:` and names `provider: xai`, passes `kxm init --dry-run` and fails only at dispatch.
@@ -191,7 +191,7 @@ A bad token is `runtime_auth_failed`; a missing parameter is `runtime_request_in
191
191
 
192
192
  ## Web Studio server
193
193
 
194
- `kxm studio serve` runs a separate local server, on `127.0.0.1:4242` by default, with `/`, `/health`, `GET /api/layout` and `POST /api/mutate`. It answers every route with `Access-Control-Allow-Origin: *`, so any web page in a local browser can read the layout. The mutate route requires a bearer session token only when one resolves; with none it accepts any caller. It accepts an allowlisted command name but executes nothing. See [`kxm studio serve`](cli-reference.md#kxm-studio-serve).
194
+ `kxm studio serve` runs a separate local server, on `127.0.0.1:4242` by default, with `/`, `/health`, `GET /api/layout` and `POST /api/mutate`. It answers every route with `Access-Control-Allow-Origin: *`, so any web page in a local browser can read the layout. The mutate route requires a bearer session token only when one resolves; with none it accepts any caller. It answers an allowlisted command name with HTTP 501 and `error: "mutation_handler_missing"`, and executes nothing. See [`kxm studio serve`](cli-reference.md#kxm-studio-serve).
195
195
 
196
196
  ## Related
197
197
 
@@ -250,11 +250,11 @@ The file is a `kxm.workflow.v1` definition. `coordinator` names the agent that o
250
250
  | Cost | None | Model usage on your accounts |
251
251
 
252
252
  > [!WARNING]
253
- > Without `--simulated`, `kxm runs drive` calls live harnesses. An agent whose model is not an admitted route fails with `producer_route_not_admitted`. Read [Harness routing](../reference/harness-routing.md) before your first live drive. A live drive hands off any agent, panel, approval or wait step with `write` access; gate steps are exempt, and the read-only `spec-and-plan` template avoids the refusal.
253
+ > Without `--simulated`, `kxm runs drive` calls live harnesses. An agent whose model is not an admitted route fails with `producer_route_not_admitted`. Read [Harness routing](../reference/harness-routing.md) before your first live drive. A live step with `write` access runs only on a harness with an audited writer profile (`pi` or `grok`), as a single assignment, in a project whose `limits.maxConcurrentRuns` is 1, and, when `.kxm/roster.yaml` exists, only on a route in its writer lineup; any other live write step is handed off. A live write step settles `passed` only when the checkout changed, and a read-only step that changes the checkout settles `failed`. Gate steps are exempt. The read-only `spec-and-plan` template needs none of this.
254
254
 
255
- ### Why not the `default` workflow
255
+ ### Why start with `first` and not `default`
256
256
 
257
- `kxm init` also writes a `default` workflow that plans, implements and runs the test gate. It declares `limits.maxAgentTimeMs`, an agent-time budget the Runtime cannot enforce yet. A drive of it is refused with HTTP 409 `run_handoff_required` (reason `limit_unsupported`), and the run stays `preparing` until you cancel it with `kxm runs cancel <run-id>`. [Steps the Runtime does not execute yet](../reference/config-reference.md#steps-the-runtime-does-not-execute-yet) lists every setting that causes a handoff.
257
+ `kxm init` also writes a `default` workflow. Its coordinator plans on `claude` / `anthropic/fable`, its implementer writes the checkout on `grok` / `xai/grok-4.6`, and a `test` gate runs `npm test`; `kxm init` admits exactly those two models in `.kxm/routes.yaml`. You can drive it, but even a simulated drive runs `npm test` in your checkout, and a live drive spends both subscriptions and passes the implement step only when Grok changes the checkout. `first` calls no model and runs no command, so it is the safer first run. [Steps the Runtime does not execute yet](../reference/config-reference.md#steps-the-runtime-does-not-execute-yet) lists every setting that makes a drive hand the run off.
258
258
 
259
259
  ### Two kinds of runs
260
260
 
@@ -264,7 +264,7 @@ The file is a `kxm.workflow.v1` definition. `coordinator` names the agent that o
264
264
 
265
265
  | Message or symptom | Cause | Fix |
266
266
  |---|---|---|
267
- | `run_handoff_required` naming `limits.maxAgentTimeMs` | You drove the `default` workflow | Cancel the run and use `first` |
267
+ | `run_handoff_required` naming `limits.maxAgentTimeMs` | The workflow declares an agent-time budget, which the Runtime does not enforce; a project from an older `kxm init` template has one on `default` | Cancel the run, remove the limit or use `first` |
268
268
  | `trust check failed: review every expansion above before merging` | The workflow is not committed | Review it, then commit it |
269
269
  | `workflow <id> does not exist in this project` | The ID is not a local workflow | Use an ID from `kxm workflow definitions` marked `[local]` |
270
270
  | `gate_outcome_impossible` from `kxm init` | A gate step routes failure on `failed` | Declare `implementation-failure` on the gate step |
@@ -320,7 +320,7 @@ Continue with [step 4](#4-bind-this-machine-and-check-the-hub) through [step 7](
320
320
 
321
321
  ### Before you update
322
322
 
323
- From the directory the hub runs in, back up its database, then stop the hub and the Runtime:
323
+ From the directory the hub runs in, back up its database and the Runtime stores, then stop the hub and the Runtime:
324
324
 
325
325
  ```bash
326
326
  kxm backup
@@ -331,7 +331,7 @@ kxm runtime stop
331
331
  `kxm backup` writes a verified copy and a hashed manifest to `.kxm/backups/backup-<timestamp>/`.
332
332
 
333
333
  > [!WARNING]
334
- > `kxm backup` copies the hub store only. It does not find the Runtime's registry and run event stores under the user state root. Copy those while the Runtime is stopped, as [Back up everything else](../operations/backup-and-restore.md#back-up-everything-else) describes.
334
+ > `kxm backup` copies the hub store and the Runtime's registry and run event stores, and those Runtime stores belong to every project on this machine. A later `kxm restore` rolls all of them back. It does not copy bindings, `update.yaml` or the other state roots; [Back up everything else](../operations/backup-and-restore.md#back-up-everything-else) covers those.
335
335
 
336
336
  [Back up and restore KXM](../operations/backup-and-restore.md) and [Upgrade KXM](../operations/upgrade.md) cover restores and rollback.
337
337
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kontextmind/kxm",
3
- "version": "0.7.97",
3
+ "version": "0.7.98",
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.97",
5
+ "version": "0.7.98",
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",