@kontextmind/kxm 0.7.104 → 0.7.106

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.104",
14
+ "version": "0.7.106",
15
15
  "category": "development",
16
16
  "tags": ["kxm", "multi-agent", "workflows", "mcp"]
17
17
  }
package/CHANGELOG.md CHANGED
@@ -6,6 +6,18 @@ All notable user-facing changes are documented here. The project follows [Semant
6
6
 
7
7
  ### Added
8
8
 
9
+ - **Claude-only workflow recommendations now fail honestly when execution is unavailable.**
10
+ `suggest` honors explicit harness constraints, uses flat installable IDs and verified
11
+ capability-appropriate routes, refuses unchecked existing definitions, and never substitutes a
12
+ different writer. `workflow add` validates IDs and runner-compatible YAML before
13
+ writing; picked/imported dry runs leave configuration untouched. `gate validate
14
+ --file` accepts local YAML without changing webhook environment-source validation.
15
+ Run output distinguishes creation from execution and names live prerequisites and
16
+ `runs drive/status/receipt`; incompatible `task run` requests leave tasks unchanged.
17
+ Harness inventory reflects the project default, and initialization explains the
18
+ generic Pi/npm starter settings. Claude's one-shot profile remains read-only; Pi/Grok
19
+ writer recommendations require audited writer admission. See the [CLI reference](docs/reference/cli-reference.md#kxm-suggest).
20
+
9
21
  - **`kxm workflow add --template <name>` writes a valid first workflow.**
10
22
  `implement-and-verify` (the `implementer` agent, then the project's `test` gate; a
11
23
  failing gate sends the work back to `implement` at most twice), `dual-critic-review` (two
@@ -333,6 +345,17 @@ All notable user-facing changes are documented here. The project follows [Semant
333
345
  picking a global definition wrote the one-step scaffold under its id and reported
334
346
  success. It now writes the global definition's content, with `--description` replacing
335
347
  its description, and the loader check refuses one the project cannot load.
348
+ - **`kxm role add --pick <global-id>` copies the global role.** In local scope, picking a
349
+ global role wrote an empty `Role <id>` with no skills or roster under its ID. It now
350
+ writes the global role's content, with `--description`, `--skills` and `--model`
351
+ replacing those fields the way they do for a built-in template.
352
+ - **`kxm role add` no longer leaves a project that refuses to load.** A local add now needs
353
+ a KXM project (`project_not_found` otherwise, and no stray `.kxm/` that would make
354
+ `kxm init` refuse), writes under the project root from any subdirectory, and is checked
355
+ by the project loader first with the new role in place of any file of that ID. A
356
+ `writer` role whose roster leaves out the `implementer` agent's model, including the
357
+ built-in `writer` template for such a project, is refused with `role_invalid`, exit 2,
358
+ and nothing is written, also under `--dry-run`.
336
359
  - **Live `kxm runs drive` can author on an audited writer profile.** A write-repository
337
360
  step on pi (`-a`, with extensions, skills, and the session off) or grok
338
361
  (`--always-approve`, with subagents and web search off) runs against the checkout.
@@ -60,10 +60,15 @@ to run one file is in [Develop KXM](development.md#run-one-file-or-one-test).
60
60
  | Settlement from a structured result only; prose outcomes and undeclared outcomes end as `outcome_unknown` | `pi-producer.test.ts`, `engine.test.ts` |
61
61
  | Routing records carry `workflowId`, `askSha256`, `objectiveSha256` and `stepWrites`, and settle only `blocked` or `failed` | `route-admission.test.ts` |
62
62
  | Dispatch context: only committed, pinned memory and hash-verified promoted skills reach an agent; the rest is a `dispatch_context_*` gap | `engine.test.ts` ("dispatch context: agents receive only committed, pinned memory and verified skills; anything else is withheld with a gap and the step still completes") |
63
- | `kxm run` prints the simulated drive command for the new run | `cli.test.ts` ("kxm run prints the simulated drive command for the created run") |
63
+ | Run creation reports no execution and concrete live prerequisites; task refusal leaves task/Runtime unchanged; project harness default is honored | `cli.test.ts`, `engine.test.ts`, `harness.test.ts` |
64
64
  | `kxm workflow add --template` writes workflows that validate and plan; an impossible gate outcome is refused | `cli-experience.test.ts` ("workflow add templates validate and plan a run, and a gate outcome the step can never produce is refused") |
65
+ | Flat workflow IDs and schema/compiler validation precede mutations; imported/picked local/global dry runs write nothing | `role-and-workflow-manager.test.ts`, `cli-experience.test.ts` |
66
+ | Claude-only suggestions honor detected/authenticated routes, require audited writer profiles, refuse existing unchecked definitions, and quote shell arguments literally | `suggest.test.ts`, `cli-experience.test.ts` |
67
+ | Explicit local YAML validates with runner schema/transitions; webhook environment sources retain JSON/secret checks | `gate-validation.test.ts` |
65
68
  | `kxm workflow add` writes a local workflow only where the loader reads it and only if the project still loads; outside a project it refuses | `role-and-workflow-manager.test.ts` ("workflow add writes only what the project loader accepts, at the project root, and loadKxmProject still loads") |
66
69
  | `kxm workflow add --pick <global-id>` copies the global definition into the project, not the scaffold, and the loader check refuses one that does not fit | `role-and-workflow-manager.test.ts` ("workflow add --pick <global-id> copies that global definition into the project, and refuses one the project loader rejects") |
70
+ | `kxm role add --pick <global-id>` copies the global role into the project, not an empty role, with `--description`, `--skills` and `--model` applied over it | `role-and-workflow-manager.test.ts` ("role add --pick <global-id> copies that global role into the project, with --description, --skills and --model applied over it") |
71
+ | `kxm role add` writes a local role only at the project root and only if the project still loads, so a `writer` roster without the implementer's model is refused; outside a project it refuses | `role-and-workflow-manager.test.ts` ("role add writes a local role only at the project root, and only if the project loader accepts it") |
67
72
  | `default.yaml` and the 13-step `fix.yaml` compile deterministically; back edges need budgets | `engine-compile.test.ts` |
68
73
  | Artifact gate: non-empty regular files pass; missing, empty, non-file and escaping paths fail | `artifacts-exist.test.ts` |
69
74
  | Vision gate: strict verdicts, admitted routes only, unreadable images fail closed | `vision-gate.test.ts` |
@@ -91,7 +91,7 @@ kxm -V
91
91
  - The `command` field is not always the words you typed: `hub stop` and `session stop` report `stop`, `session token` reports `auth token`, `routes admit` and `routes disable` report `routes admitted` and `routes disabled`, `models inventory-refresh` reports `models inventory refresh`, `workflow export` reports `retrospective export`, `gate degrade` reports `workflow degrade`, `gate signal` and `workflow signal` report `signal`, `gate github watch` reports `github watch`, `agent worker` reports `worker`, and `improve report` reports `improve`.
92
92
  - A result with `ok: false` is written to stderr in both text and JSON mode; everything else goes to stdout. `runtime status` is the exception: when the supervisor is down it prints `ok: true, running: false` on stdout and exits 1.
93
93
  - `peer` subcommands and `workflow checkpoint|record|wait` print the hub's result object as returned, tagged with `schema` but without `ok` or `command`. Their failures print `{"ok":false,"error":"command_failed","detail":"..."}`. Text mode prints the same JSON.
94
- - Several error paths ignore `--json` and print one plain line on stderr: argument checks in `agent worker`, `session start`, `workflow start`, `gate degrade`, `gate signal`, and `gate github watch`; every error from `config`, `role`, `workflow definitions|add|remove|modify` (except the `workflow add` refusals listed under it, which honor `--json`), `goal`, `task`, `memory`, `skills` (other than `skills create --dry-run`), `suggest`, `studio`, and `completion`. Check the exit code before parsing stdout.
94
+ - Several error paths ignore `--json` and print one plain line on stderr: argument checks in `agent worker`, `session start`, `workflow start`, `gate degrade`, `gate signal`, and `gate github watch`; errors from `config`, `role`, `workflow definitions|remove|modify`, `goal`, `task` outside run admission, `memory`, `skills` (other than `skills create --dry-run`), `studio`, and `completion`. `suggest` and `workflow add` failures honor `--json`. Check the exit code before parsing stdout.
95
95
  - Every `context` subcommand exits 1 with a Node.js stack trace and no JSON when the hub cannot be reached.
96
96
  - Output is redacted. Values of environment variables whose names contain `TOKEN`, `SECRET`, `KEY`, or `PASSWORD` are replaced with `[redacted]`, and 64-character hex strings are replaced unless they appear in a known digest field such as `configRevision` or `sha256`. `session brief` and `auth token` print the session token itself; treat their output as a credential.
97
97
 
@@ -173,6 +173,8 @@ kxm init [--name <name>] [--project-id <id>] [--repository <id=absolute-path>]..
173
173
 
174
174
  Creates, validates, repairs, resumes, or joins a KXM project at the Git root that contains the current directory. A new project gets a minimal configuration: one coordinator agent, one implementer agent, a `test` command gate, and a `default` plan-implement-verify workflow. An existing project is validated without rewriting. Conflict-free template updates to non-authority fields are applied; authority changes, overlapping edits, and provenance-free or legacy state stay planning-only. `init` does not start a hub or the Runtime.
175
175
 
176
+ The starter `defaultHarness: pi` and `npm test` gate are generic settings, not repository detection. Creation and create-planning output include `guidance`: for Claude, set `defaultHarness: claude` in `.kxm/project.yaml`, update any explicit `harness` overrides in `.kxm/agents/*.yaml`, and configure compatible agent models; for .NET or other non-npm repositories, set `.kxm/gates.yaml` → `gates.test.argv` to the repository's actual test command. Preflight reports an actionable prerequisite for `npm test` without a readable `package.json` test script; `task run` refuses it before creating a run.
177
+
176
178
  | Option | Argument | Default | Description |
177
179
  |---|---|---|---|
178
180
  | `--name` | `<name>` | Git root directory name | Project display name for a new project |
@@ -184,7 +186,7 @@ Creates, validates, repairs, resumes, or joins a KXM project at the Git root tha
184
186
  - Needs a Git repository. Does not need a hub or the Runtime.
185
187
  - Writes `.kxm/project.yaml`, `.kxm/agents/coordinator.yaml`, `.kxm/agents/implementer.yaml`, `.kxm/gates.yaml`, `.kxm/repo/repo.yaml`, `.kxm/workflows/default.yaml`, and `.kxm/template-provenance.yaml`, using a `.kxm-init-transaction` directory at the Git root while a create or repair is in flight. Repository bindings are written under the user state root, never into Git. `--dry-run` writes nothing.
186
188
  - On an interactive terminal without `--json` or `--dry-run`, a successful create or join offers to install shell completion (suppress with `KXM_SKIP_COMPLETION_PROMPT=1`) and to write workflow-guide agents (suppress with `KXM_SKIP_GUIDE_SETUP_PROMPT=1`). Guided setup keeps a role only when one of its guide candidates is on a fixed map of reviewed harness/model pairs and that harness is authenticated; it writes the agent and workflow files, appends those selectors to `.kxm/routes.yaml`, and skips every other candidate. Google candidates are not on the map and are always skipped, because the Runtime's Pi one-shot cannot reach Google's `antigravity` Pi provider yet (see [Harness routing](harness-routing.md#google-through-the-antigravity-pi-provider)).
187
- - JSON keys: `action` (`planned`, `created`, `joined`, `repaired`, `resumed`, or `validated`), `mode`, `inspectedFrom`, `projectRoot`, `changesRequired`, `legacyInputs`, `issues`, `configRevision`, `files`, `plannedOnly`, and, when relevant, `localBindingFile`, `bindingsChanged`, `repairPlan`, `resumePending`, `transactionKind`.
189
+ - JSON keys: `action` (`planned`, `created`, `joined`, `repaired`, `resumed`, or `validated`), `mode`, `inspectedFrom`, `projectRoot`, `changesRequired`, `legacyInputs`, `issues`, `configRevision`, `files`, `plannedOnly`, and, when relevant, `guidance`, `localBindingFile`, `bindingsChanged`, `repairPlan`, `resumePending`, `transactionKind`.
188
190
  - Exit 0 for every completed action and every dry-run plan. Exit 1 when the result is planning-only (legacy state, blocked repair, partial state without provenance) or for `initialization_failed` (with `issues`) and `initialization_io_failed`. A planning-only text result prints the reason and then one `<file>: <code>: <message>` line per validation issue, for example `.kxm/workflows/first.yaml: gate_outcome_impossible: ...`.
189
191
 
190
192
  Preview what a new project would contain:
@@ -882,8 +884,9 @@ Probes the built-in harness catalog (`pi`, `claude`, `kimi`, `codex`, `deepseek`
882
884
 
883
885
  No command-specific options.
884
886
 
885
- - Reads only. No hub needed. Always exits 0.
887
+ - Reads only. No hub needed. In a KXM project, `defaultHarness` and the inventory's default marker reflect `.kxm/project.yaml`; outside a project they default to Pi. Invalid project configuration must be repaired before the project default can be resolved.
886
888
  - JSON keys: `defaultHarness`, `harnesses` (each with `id`, `label`, `default`, `mode`, `detected`, `authenticated`, `dispatch` (`status`, `supported`, `reason`), `canUpdate` (`self`, `extensions`, `models`), `issues`).
889
+ - Errors: `harness_list_failed` with configuration `issues`, or `harness_list_io_failed` (exit 1); both honor `--json` and write to stderr without claiming a fallback project default.
887
890
  - `dispatch` is `yes` only when the harness is detected, has an audited read-only one-shot profile, and is authenticated. Otherwise the first failing check gives the reason: `not_detected`, `no_headless_mode`, `permission_profile_unaudited` (a detected `deepseek`), `not_authenticated`, or the auth issue when login state is unknown (`auth_context_required` for Pi, `auth_unknown`, `auth_unparsed`, or another `auth_*` code).
888
891
 
889
892
  Captured with no harness CLIs on `PATH`:
@@ -893,7 +896,7 @@ kxm harness list
893
896
  ```
894
897
 
895
898
  ```text
896
- default harness: pi (omit agent harness: to use headless Pi)
899
+ default harness: pi (used when an agent omits harness:)
897
900
  enable/disable = Git YAML (.kxm/agents, .kxm/models) or the harness's own plugin CLI
898
901
  governed kxm skills are not auto-updated
899
902
  id default detected auth dispatch updates
@@ -1194,7 +1197,7 @@ Not run with a configured role; in a fresh project it exits 1 with `kxm: role 'w
1194
1197
  kxm role add [roleId] [--file <path>] [--description <text>] [--skills <skills>] [--harness <harness>] [--model <model>] [--scope global|local] [--overwrite] [--pick [selection]]
1195
1198
  ```
1196
1199
 
1197
- Adds a role definition. Without a role ID, or with `--pick`, you choose from the built-in templates (`writer`, `planner`, `critic-arch`, `critic-cli`, `verifier`) and, for local scope, existing global roles. With `--file`, the YAML file is used and its `id` is replaced by the role ID.
1200
+ Adds a role definition. Without a role ID, or with `--pick`, you choose from the built-in templates (`writer`, `planner`, `critic-arch`, `critic-cli`, `verifier`) and, for local scope, existing global roles; a global role with a template's ID is not offered. The choice is written under its own ID with its content: the template, or a copy of the global role's file, with `--description`, `--skills`, and `--model` (with `--harness`) replacing its description, skills, and roster. With `--file`, the YAML file is used and its `id` is replaced by the role ID. Otherwise a role with only the given options is written.
1198
1201
 
1199
1202
  | Option | Argument | Default | Description |
1200
1203
  |---|---|---|---|
@@ -1208,6 +1211,8 @@ Adds a role definition. Without a role ID, or with `--pick`, you choose from the
1208
1211
  | `--pick` | `[selection]` | none | Pick from available role templates (index or id) |
1209
1212
 
1210
1213
  - Writes `<scope dir>/roles/<id>.yaml`. `--dry-run` plans the write and writes nothing.
1214
+ - Local scope belongs to a KXM project: the file lands in the project root's `.kxm/roles/` from any subdirectory, and outside a project the command refuses with `project_not_found` and creates nothing. Before writing, the project loader checks the project with the new role in place of any file of that ID. The loader reads only `writer.yaml`, whose enabled roster must include the `implementer` agent's model (see [Roles](config-reference.md#kxmrolesroleyaml-kxmrolev1)). If the project would not load, the command refuses with `role_invalid`, lists each issue and writes nothing, also under `--dry-run`, and `--overwrite` replaces a `writer.yaml` the loader refuses. Global scope is not checked, because no loader reads it.
1215
+ - Refusals exit 2 and honor `--json`: `project_not_found` and `role_invalid` (with `issues`, each `{phase, code, file, message}`). An existing role without `--overwrite` exits 1 with a plain `role add failed: role_already_exists: ...` line, also under `--dry-run`.
1211
1216
  - JSON keys: `roleId`, `id`, `filePath`, `scope`.
1212
1217
 
1213
1218
  > [!WARNING]
@@ -1383,12 +1388,12 @@ dry run: resume workflow run wf_dry_run (stage: review)
1383
1388
  kxm run <workflow> [prompt...]
1384
1389
  ```
1385
1390
 
1386
- Create a KXM run (offline-first; `kxm runs drive <runId> --simulated` executes it model-free). The run is immutable and pins the project's `homeRuntimeId`, config revision, and executor and tool policy revisions. Run events record only the SHA-256 of the prompt; the full prompt text is kept in a local sidecar file, `run-events.db.run-prompts.json`, next to the project's Runtime event store and written with mode 0600, and a dispatch refuses the run (`run_prompt_mismatch`) if that text no longer matches the hash. The Runtime supervisor is started first if it is not running. No steps execute until the run is driven (see [`kxm runs drive`](#kxm-runs-drive)); the text output's second line prints the command that drives the new run model-free and the one that cancels it.
1391
+ Create a KXM run without executing steps. The run pins the project's `homeRuntimeId`, config revision, and executor and tool policy revisions. Events store the prompt's SHA-256; its full text is kept in a local mode-0600 sidecar, `run-events.db.run-prompts.json`, and dispatch refuses a hash mismatch (`run_prompt_mismatch`). The Runtime supervisor starts if needed. Output explicitly reports no execution, live prerequisites, and separate drive/status/receipt commands. Use `kxm runs drive <runId> --wait` for supported live one-shot calls; no hub or Pi worker is required. `--simulated` is a model-free experiment, not evidence that implementation ran. Local runs are inspected with `kxm runs`, not the webhook-only `kxm workflow get`.
1387
1392
 
1388
1393
  - Arguments: `<workflow>`, Workflow id to run (a file under `.kxm/workflows/`); `[prompt...]`, Run prompt (events keep its hash; the full text is kept in a local 0600 sidecar file).
1389
1394
  - No command-specific options. Refuses `--workspace` (exit 2).
1390
1395
  - Needs a KXM project. Starts and uses the Runtime; no hub needed. Honors `--dry-run`, which validates the project and prints the plan without starting the supervisor.
1391
- - JSON keys: `phase`, `idempotent`, `run` (`runId`, `homeRuntimeId`, `status`, `configRevision`), `supervisor` (`runtimeId`, `port`, `started`). Dry run: `projectRoot`, `workflowId`, `configRevision`. The JSON result does not carry the drive command.
1396
+ - JSON keys: `idempotent`, `run` (`runId`, `homeRuntimeId`, `status`, `configRevision`), `supervisor` (`runtimeId`, `port`, `started`), and `execution` (`status: not_started`, `mode: live`, `defaultHarness`, `authentication: not_checked`, `prerequisites`, `nextSteps`). Dry run: `projectRoot`, `workflowId`, `configRevision`, `defaultHarness`, `prerequisites`. The obsolete `phase: pre-3a` field is no longer returned.
1392
1397
  - Errors: `workflow_required` (exit 2), `project_required`, `run_workflow_unknown`, `run_failed` with `issues` (any invalid file in the project fails the load, for example `gate_outcome_impossible`), `run_io_failed` (exit 1).
1393
1398
  - The `default` workflow that `kxm init` writes does not set `limits.maxAgentTimeMs`, so it can be driven. A workflow that sets that limit is created, but `kxm runs drive` refuses it with `run_handoff_required` (`limit_unsupported`); projects from older `kxm init` templates carry it on `default`.
1394
1399
 
@@ -1416,7 +1421,12 @@ kxm run default "Fix the flaky login test"
1416
1421
 
1417
1422
  ```text
1418
1423
  run created: run_a80e84c98f514299b82f0157f4537ea3 (home rtm_1a42e069…, config sha256:b45f8f51a506…)
1419
- drive it model-free: kxm runs drive run_a80e84c98f514299b82f0157f4537ea3 --simulated --wait (or cancel: kxm runs cancel run_a80e84c98f514299b82f0157f4537ea3)
1424
+ No steps executed. Project default harness: pi; per-agent harness settings take precedence.
1425
+ Live prerequisite (...): ...
1426
+ Live execution uses one-shot harness calls; no hub or Pi worker is required. Check installation/authentication with kxm harness list.
1427
+ Resolve the prerequisites above, then execute: kxm runs drive run_a80e84c98f514299b82f0157f4537ea3 --wait
1428
+ Inspect: kxm runs status run_a80e84c98f514299b82f0157f4537ea3 --json; receipt: kxm runs receipt run_a80e84c98f514299b82f0157f4537ea3 --json; cancel: kxm runs cancel run_a80e84c98f514299b82f0157f4537ea3
1429
+ These are local Runtime runs, not webhook workflows; use kxm runs, not kxm workflow get.
1420
1430
  ```
1421
1431
 
1422
1432
  ## `kxm runs`
@@ -1965,6 +1975,8 @@ kxm workflow add [workflowId] [--template <name> | --file <path> | --pick [selec
1965
1975
 
1966
1976
  Add a workflow definition to global or local configuration. With `--template <name>`, the named built-in template is written under the workflow ID. Without a workflow ID, or with `--pick`, you choose from the built-in templates and, for local scope, existing global definitions; a global definition with a template's ID is not offered. The choice is written under its own ID with its content: the template, or a copy of the global definition's file, with `--description` replacing its description. With `--file`, the YAML file is copied as-is once it passes the local check below. Otherwise a one-step scaffold is written: one `implementer` agent step with write access to `control` that ends the run `completed` on `passed` and `failed` on `failed`.
1967
1977
 
1978
+ IDs are flat, portable lowercase slugs, at most 64 characters: use `bug-fix`, not `software-engineering/bug-fix`. Paths, traversal, and reserved platform names fail before writing. Imported definitions must use `kxm.workflow.v1`, with `agent` rather than legacy `role` steps and no top-level `id`; installation validates the runner's restricted YAML, schema, and transitions before creating directories or replacing a file. `--pick` copies a selected global definition, honors `--description`, and preserves an explicit destination ID. A global definition is not silently replaced with a scaffold.
1979
+
1968
1980
  | Option | Argument | Default | Description |
1969
1981
  |---|---|---|---|
1970
1982
  | `--file` | `<path>` | none | Path to YAML workflow definition file |
@@ -1977,8 +1989,8 @@ Add a workflow definition to global or local configuration. With `--template <na
1977
1989
  - Templates: `implement-and-verify` runs the `implementer` agent, then the project's `test` gate, and a failing gate (`implementation-failure`) sends the work back to `implement` at most twice. `dual-critic-review` adds two review steps between them, both run as the `coordinator` agent with read access; point `review-arch` and `review-cli` at your own agents for independent critics. `spec-and-plan` plans and then reviews the plan, both as `coordinator`, reading the repository only.
1978
1990
  - The templates and the scaffold are valid `kxm.workflow.v1` definitions that use only what `kxm init` creates: the `coordinator` and `implementer` agents, the `control` repository, and the `test` gate. Each was checked with `kxm init --json` and `kxm run <id> --dry-run` for this page. A new file under `.kxm/workflows/` is a permission expansion that `kxm trust check` asks you to review before you commit it.
1979
1991
  - Writes `<scope dir>/workflows/<id>.yaml`. `kxm run` loads only `.kxm/workflows/`, so a `--scope global` definition is not runnable until it is copied into a project. `--dry-run` plans the write and writes nothing.
1980
- - Local scope belongs to a KXM project: the file lands in the project root's `.kxm/workflows/` from any subdirectory, and outside a project the command refuses with `project_not_found` and creates nothing. Before writing, the project loader checks the project with the new document in place of any file of that ID, using the parser, schema and bundle rules `kxm run` uses. If the project would not load, the command refuses with `workflow_invalid`, lists each issue and writes nothing, also under `--dry-run`. So `--file` or a picked global definition with a top-level `id` or a `role:` step, the shape `workflow add` wrote through 0.7.92, is refused, and `--overwrite` replaces a file left in that shape. Global scope is not checked, because no loader reads it.
1981
- - Refusals exit 2 and honor `--json`: `workflow_template_unknown` (the text names the three templates), `workflow_id_required` (no workflow ID), `workflow_add_conflict` (`--template` combined with `--file` or `--pick`), `project_not_found`, and `workflow_invalid` (with `issues`, each `{phase, code, file, message}`). An existing definition without `--overwrite` exits 1 with a plain `workflow add failed: workflow_already_exists: ...` line, also under `--dry-run`.
1992
+ - Local scope belongs to a KXM project: the file lands in the project root's `.kxm/workflows/` from any subdirectory, and outside a project the command refuses with `project_not_found` and creates nothing. Before writing, the project loader checks the project with the new document in place of any file of that ID, using the parser, schema and bundle rules `kxm run` uses. If the project would not load, the command refuses with `workflow_invalid`, lists each issue and writes nothing, also under `--dry-run`. So `--file` or a picked global definition with a top-level `id` or a `role:` step, the shape `workflow add` wrote through 0.7.92, is refused, and `--overwrite` replaces a file left in that shape. Global definitions receive ID, schema and transition checks, but have no project references to validate.
1993
+ - Refusals exit 2 and honor `--json`: `workflow_template_unknown` (the text names the three templates), `workflow_id_required` (no workflow ID), `workflow_add_conflict` (`--template` combined with `--file` or `--pick`), `project_not_found`, and `workflow_invalid` (with `issues`, each `{phase, code, file, message}`). Other input, file and overwrite failures exit 1 with `workflow_add_failed` and `message`. No failure writes the destination, and dry runs do not create missing local, global, or runtime directories.
1982
1994
  - JSON keys: `workflowId`, `id`, `filePath`, `scope`.
1983
1995
 
1984
1996
  Start a first workflow from a template:
@@ -2071,17 +2083,23 @@ Validates workflow definitions and operates evidence gates. The group has exactl
2071
2083
  kxm gate validate [--file <path>]
2072
2084
  ```
2073
2085
 
2074
- Parse workflow definitions without printing secrets, using the same single source the hub loads: `--file`, else `KXM_WEBHOOK_WORKFLOWS_FILE`, else inline `KXM_WEBHOOK_WORKFLOWS`.
2086
+ Validate workflow definitions without printing secrets. An explicit `--file` accepts a local `kxm.workflow.v1` YAML/JSON mapping or a webhook JSON array. Local mappings use the runner's restricted YAML parser, schema, and transition compiler; use `kxm init --dry-run` to also validate project references. Without `--file`, `KXM_WEBHOOK_WORKFLOWS_FILE` or inline `KXM_WEBHOOK_WORKFLOWS` remain webhook-only JSON sources, exactly as the hub loads them.
2075
2087
 
2076
2088
  | Option | Argument | Default | Description |
2077
2089
  |---|---|---|---|
2078
2090
  | `--file` | `<path>` | configured source | Workflow definition file |
2079
2091
 
2080
- - Each definition's `secretEnv` must name a set variable holding at least 16 characters (likewise `signalSecretEnv` when declared); otherwise parsing fails, for example with `workflow.secret must be a string`.
2092
+ - For webhook definitions, each `secretEnv` must name a set variable holding at least 16 characters (likewise `signalSecretEnv` when declared); otherwise parsing fails.
2081
2093
  - Reads definitions; appends telemetry. No hub needed.
2082
- - JSON keys: `source`, `file`, `workflows` (`id`, `secretConfigured`, `signalSecretConfigured`), `warnings`; `outcome` is `warning` when warnings exist.
2094
+ - JSON keys: `source`, `file`, `workflows`, `warnings`; local entries contain `id` and `schema`, while webhook entries contain `id`, `secretConfigured`, and `signalSecretConfigured`. `outcome` is `warning` when warnings exist.
2083
2095
  - Exit 2 for `workflow_source_required` or `ambiguous_workflow_source` (both variables set); exit 1 for `file_not_found` or a parse error.
2084
2096
 
2097
+ Validate an installed local template:
2098
+
2099
+ ```bash
2100
+ kxm gate validate --file .kxm/workflows/bug-fix.yaml
2101
+ ```
2102
+
2085
2103
  ```bash
2086
2104
  KXM_WORKFLOW_SECRET="$SECRET" kxm gate validate --file workflows.json
2087
2105
  ```
@@ -2523,19 +2541,20 @@ Workflow: default
2523
2541
  kxm task run <taskId>
2524
2542
  ```
2525
2543
 
2526
- Launch a workflow run driven by this task: runs `kxm run <workflow> <objective>` with the task's assigned workflow (default `default`), then sets the task status to `in_progress` when that succeeds.
2544
+ Prepare a local run from a task's objective and assigned workflow, or the project's `defaultWorkflow` when none is assigned. Read-only live preflight reports unsupported steps, limits, gates, harnesses, or model routes before creating a run. Unsupported work exits 1 with `run_execution_unavailable`, `defaultHarness`, and `execution.prerequisites`; neither the task nor Runtime is mutated. In particular, Claude-only writer work receives the read-only harness limitation instead of a dead-end created run.
2527
2545
 
2528
- - Output, requirements, and errors are those of [`kxm run`](#kxm-run), including the `--workspace` refusal.
2529
- - Mutates the task file. `--dry-run` validates the project and the workflow as `kxm run --dry-run` does, then plans the run request and the task file write without making either; the status stays unchanged. Dry-run JSON keys: `taskId`, `projectRoot`, `workflowId`, `configRevision`, `status` (the status it would set), `dryRun`, `planned`.
2546
+ - On compatible configuration, output is that of [`kxm run`](#kxm-run): creation only, `execution.status: not_started`, and explicit live drive/status/receipt commands. Authentication is checked on dispatch, not certified by creation. Task status is not changed to `in_progress` merely because a run exists.
2547
+ - `--dry-run` applies the same live preflight and plans only the run request, with no task write or process start. JSON includes `taskId`, the unchanged task `status`, `projectRoot`, `workflowId`, `configRevision`, `defaultHarness`, `prerequisites`, `execution`, `dryRun`, and `planned`.
2548
+
2549
+ For a task assigned a configured, supported read-only workflow, a dry-run excerpt is:
2530
2550
 
2531
2551
  ```bash
2532
2552
  kxm task run task_4f79c0833e41 --dry-run
2533
2553
  ```
2534
2554
 
2535
2555
  ```text
2536
- dry run: run workflow default for task task_4f79c0833e41, then mark it in_progress
2556
+ dry run: create workflow architecture-spike for task task_4f79c0833e41; task status stays todo until work actually starts
2537
2557
  would request POST kxm-runtime /v1/runs (starts the Runtime supervisor if it is not running)
2538
- would write /work/proj/.kxm/tasks/task_4f79c0833e41.yaml
2539
2558
  ```
2540
2559
 
2541
2560
  ### `kxm task sync`
@@ -2617,30 +2636,20 @@ kxm goal list
2617
2636
  kxm suggest <prompt...>
2618
2637
  ```
2619
2638
 
2620
- Recommends a workflow, area, roles, and skills for a prompt or issue description using keyword matching and the detected harnesses. The suggested workflow ID comes from a built-in catalog and may not exist in your project; check with `kxm workflow definitions` before running the suggested command.
2639
+ Recommends a flat workflow ID backed by a shipped template, with category metadata and explicit execution prerequisites. The install command creates a definition only; it does not create or drive a run.
2621
2640
 
2622
- - Arguments: `<prompt...>`, the task description.
2623
- - No command-specific options. Probes harnesses as `harness list` does; reads nothing else. No hub needed.
2624
- - Suggested skills are always KXM command skills shipped in `plugins/kxm/skills` (for example `kxm-workflow`, `kxm-runs`, `kxm-peer`, `kxm-context-memory`), never the KontextMind knowledge-plane skills.
2625
- - JSON keys: `prompt`, `workflowId`, `area`, `confidence`, `reasons`, `suggestedSkills`, `roles` (`planner`, `writer`, `critics`, `verifier`), `suggestedCommand`.
2641
+ - Explicit `Claude only`, `Claude-only`, or `only Claude Code` constraints exclude other harnesses. A missing, unauthenticated, or unsupported required harness produces `harness_unavailable`; KXM never silently substitutes Grok or Codex.
2642
+ - A write workflow requires an audited writer profile for the selected harness. Only Pi and Grok currently have one; Claude-only bug fixes produce `live_write_unsupported` with direct-Claude implementation guidance, never a Grok substitution. No misleading create/drive command is emitted for an unsupported profile.
2643
+ - For supported work, every suggested agent binding uses the selected detected, authenticated, dispatch-ready harness. Configure its compatible admitted model, install the exact template, validate project configuration, then use the separate create/live-drive/status/receipt commands. Writers also require single-assignment/single-run admission, any configured developer-roster writer approval, and the repository's actual verification gate. An already-present recommended workflow ID produces `workflow_already_exists`; KXM will not assume its agents or permissions match the template.
2644
+ - Arguments: `<prompt...>`; no command-specific options. No hub needed. `--dry-run` skips native authentication probes to avoid their side effects and does not claim verified availability.
2645
+ - JSON keys: `prompt`, `workflowId`, `template`, `area`, `confidence`, `reasons`, `suggestedSkills`, `roles` (an array of `{agent, harness, role}`), `suggestedCommand` (installation only), and `execution`. Supported execution includes `prerequisites`, `shell`, `createCommand`, `driveCommand`, `statusCommand`, and `receiptCommand`; refusal includes `error`, `reason`, and `nextSteps`, sets `ok: false`, and exits 1.
2626
2646
 
2627
2647
  ```bash
2628
- kxm suggest "Add retry with backoff to the payment webhook handler"
2648
+ kxm suggest "Fix a bug in an isolated worktree using Claude only" --json
2629
2649
  ```
2630
2650
 
2631
2651
  ```text
2632
- Suggested Workflow: software-engineering/feature-implementation (software-engineering)
2633
- Confidence: 65%
2634
- Reasons: Matched keywords: add
2635
- Suggested Skills: kxm-workflow, kxm-peer, kxm-context-memory
2636
- Roles:
2637
- Planner: claude (fable)
2638
- Writer: grok (grok-4.6)
2639
- Critics: claude:fable, codex:gpt-5.6-sol
2640
- Verifier: npm run verify
2641
-
2642
- Execute with:
2643
- kxm run software-engineering/feature-implementation "Add retry with backoff to the payment webhook handler"
2652
+ {"ok":false,"workflowId":"bug-fix","template":"implement-and-verify","roles":[],"suggestedCommand":"kxm workflow add bug-fix --template implement-and-verify","error":"live_write_unsupported",...}
2644
2653
  ```
2645
2654
 
2646
2655
  ## `kxm explain`
@@ -965,7 +965,7 @@ read different fields:
965
965
  |---|---|---|---|
966
966
  | Project loader (`validateBundle`) | `.kxm/roles/writer.yaml` only | `roster[].model`, `roster[].enabled` | Cross-checks the writer roster against the `implementer` agent's model (see below). Parsed as restricted YAML. |
967
967
  | Runtime route check (`listRoleBindings` in `plugins/kxm/src/routes.ts`) | `.kxm/roles/<role>.yaml`, role = agent ID, `writer` for `implementer` | `roster[].model` | The agent's `provider/model` must appear exactly. `enabled` is ignored, so a disabled entry still admits. The role name comes from the filename. |
968
- | `kxm role` commands (`plugins/kxm/src/role.ts`) | `.kxm/roles/*.yaml` and `~/.config/kxm/roles/*.yaml` | Everything below | Listing and editing only. A file without `schema: kxm.role.v1` is silently skipped. A local file overrides a global one with the same ID. |
968
+ | `kxm role` commands (`plugins/kxm/src/role.ts`) | `.kxm/roles/*.yaml` and `~/.config/kxm/roles/*.yaml` | Everything below | Listing and editing only. A file without `schema: kxm.role.v1` is silently skipped. A local file overrides a global one with the same ID. A local `kxm role add` runs the project loader check above first and refuses with `role_invalid` a role the loader would reject. |
969
969
 
970
970
  The loader check applies when the agent `implementer` (or else `writer`)
971
971
  declares a model and the roster has at least one enabled entry. One enabled
@@ -1,6 +1,6 @@
1
1
  # Workflow definition reference
2
2
 
3
- KXM has two kinds of workflow definition. A **webhook workflow definition** is JSON that the [hub](../glossary.md#hub) loads; a signed webhook starts a run, and one coordinator agent works through its ordered **stages**. A **Runtime workflow** is a `kxm.workflow.v1` YAML file in your project; `kxm run` starts it, and the local Runtime executes its **steps**. This page compares the two, documents every field of the JSON format, and summarizes the YAML format with links to its full reference.
3
+ KXM has two kinds of workflow definition. A **webhook workflow definition** is JSON that the [hub](../glossary.md#hub) loads; a signed webhook starts a run, and one coordinator agent works through its ordered **stages**. A **Runtime workflow** is a `kxm.workflow.v1` YAML file in your project; `kxm run` creates a run, and `kxm runs drive` executes supported **steps**. This page compares the two, documents every field of the JSON format, and summarizes the YAML format with links to its full reference.
4
4
 
5
5
  ## Two workflow systems
6
6
 
@@ -10,12 +10,12 @@ KXM has two kinds of workflow definition. A **webhook workflow definition** is J
10
10
  | Location | Any JSON file named by `KXM_WEBHOOK_WORKFLOWS_FILE`, or inline in `KXM_WEBHOOK_WORKFLOWS` | `.kxm/workflows/<id>.yaml`, tracked in Git |
11
11
  | Loaded by | The hub, once at start | Every project load (`kxm init`, `kxm run`) |
12
12
  | Units | Stages, in order | Steps, connected by typed transitions |
13
- | Started by | A signed `POST /v1/webhooks/<id>`, or `kxm workflow start` | `kxm run <workflow> [prompt]` |
13
+ | Started by | A signed `POST /v1/webhooks/<id>`, or `kxm workflow start` | Create with `kxm run <workflow> [prompt]`, execute with `kxm runs drive <runId> --wait` |
14
14
  | Who does the work | One coordinator agent, prompted with every stage, using the [workflow tools](tools.md#workflow-tools) | The Runtime: agent steps through a model producer, gate steps by running `.kxm/gates.yaml` commands |
15
15
  | Evidence | Keyed strings plus verified peer replies | Gate evidence the Runtime records itself |
16
16
  | External results | `kxm_workflow_wait`, then a signed signal | Recovery signals only; `wait` steps compile but are not matched yet |
17
17
  | Inspect with | `kxm_workflow_get`, `kxm workflow get`, `kxm dash` | `kxm runs status`, `kxm runs list` |
18
- | Validate with | `kxm gate validate` | `kxm init --dry-run`, `kxm run --dry-run` |
18
+ | Validate with | `kxm gate validate` | `kxm gate validate --file <yaml>` (schema/transitions), `kxm init --dry-run` (project references), `kxm run --dry-run` (run prerequisites) |
19
19
 
20
20
  Both kinds of run have IDs of the form `run_<32 hex>`. The journal, checkpoints and waits belong to webhook runs only.
21
21
 
@@ -274,7 +274,7 @@ A Runtime workflow is a YAML file whose name is its ID. The [configuration file
274
274
  | Agent steps | The model returns a JSON `outcome` from the step's declared keys; anything else becomes `failed`, so declare `failed` | [Transitions and outcomes](config-reference.md#transitions-and-outcomes) |
275
275
  | Not executed yet | Some valid fields make the Runtime hand the run off (`step_unsupported`, `gate_unsupported`, `limit_unsupported`) instead of executing | [Steps the Runtime does not execute yet](config-reference.md#steps-the-runtime-does-not-execute-yet) |
276
276
 
277
- `kxm workflow add --template <name>` writes a valid starting file from a built-in template (`implement-and-verify`, `dual-critic-review` or `spec-and-plan`). `kxm run <workflow>` creates a run and prints the commands that drive it with the model-free simulation (`kxm runs drive <runId> --simulated --wait`) or cancel it. See [`kxm run`](cli-reference.md#kxm-run) and [`kxm runs`](cli-reference.md#kxm-runs).
277
+ `kxm workflow add bug-fix --template implement-and-verify` writes a valid starting file; `dual-critic-review` and `spec-and-plan` are also available. IDs are flat filename-derived slugs, not catalog paths such as `software-engineering/bug-fix`. Installation validates YAML/schema/transitions before writing, including under `--dry-run`. `kxm run <workflow>` creates a run and reports live prerequisites and separate `runs drive/status/receipt` commands. Current live one-shot profiles are read-only, so a writer template can validate but cannot execute live; `task run` refuses incompatible work before creating a run or changing the task. Simulation remains explicitly available and is not proof of implementation. See [`kxm run`](cli-reference.md#kxm-run) and [`kxm runs`](cli-reference.md#kxm-runs).
278
278
 
279
279
  ## Related
280
280
 
@@ -153,13 +153,17 @@ The hash is the project's configuration revision, the same one `kxm trust diff`
153
153
  kxm run first "Plan a hello script"
154
154
  ```
155
155
 
156
- Expected output:
156
+ Creation output includes:
157
157
 
158
158
  ```text
159
159
  run created: run_<id> (home rtm_<id>…, config sha256:<revision>…)
160
- drive it model-free: kxm runs drive run_<id> --simulated --wait (or cancel: kxm runs cancel run_<id>)
160
+ No steps executed. Project default harness: pi; per-agent harness settings take precedence.
161
161
  ```
162
162
 
163
+ The remaining output lists live prerequisites and the commands for `runs drive`,
164
+ `runs status`, and `runs receipt`. A created run is not an executed workflow;
165
+ the deliberate simulation below does not require a live authenticated model.
166
+
163
167
  `kxm run` starts the Runtime supervisor if it is not running. Check the new run, using the run ID from the output:
164
168
 
165
169
  ```bash
@@ -38,6 +38,16 @@ In an interactive terminal, `kxm init` then offers shell completion and workflow
38
38
 
39
39
  > [!TIP]
40
40
  > If your tests do not run with `npm test`, change `gates.test.argv` in `.kxm/gates.yaml` now, before you commit.
41
+ >
42
+ > The starter settings are not repository detection. For a Claude project, set
43
+ > `defaultHarness: claude` in `.kxm/project.yaml`, update any explicit `harness` overrides
44
+ > in `.kxm/agents/*.yaml`, and configure compatible agent models;
45
+ > `kxm harness list` reports that project default. Claude's Runtime one-shot profile is
46
+ > read-only: a Claude-only bug-fix suggestion or incompatible `task run`
47
+ > refuses with prerequisites rather than substituting another writer. Implement
48
+ > directly in Claude Code, or use a genuinely read-only Runtime workflow. A local
49
+ > `kxm run` only creates a run; execute supported work with `kxm runs drive <runId>
50
+ > --wait` and inspect it with `kxm runs status`, not `kxm workflow get`.
41
51
 
42
52
  ### 2. Ignore runtime state and commit `.kxm/`
43
53
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kontextmind/kxm",
3
- "version": "0.7.104",
3
+ "version": "0.7.106",
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.104",
5
+ "version": "0.7.106",
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",