@kontextmind/kxm 0.7.128 → 0.7.131

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 (65) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.kxm/README.md +4 -1
  3. package/.kxm/agents/coordinator.yaml +1 -0
  4. package/.kxm/agents/critic-arch.yaml +1 -4
  5. package/.kxm/agents/critic-cli.yaml +1 -4
  6. package/.kxm/agents/implementer.yaml +1 -4
  7. package/.kxm/workflows/implement-only.yaml +1 -1
  8. package/.kxm/workflows/review-arch-only.yaml +1 -1
  9. package/.kxm/workflows/review-cli-only.yaml +1 -1
  10. package/CHANGELOG.md +42 -1
  11. package/docs/architecture/inventory.md +1 -1
  12. package/docs/concepts/architecture.md +1 -1
  13. package/docs/concepts/data-and-storage.md +1 -1
  14. package/docs/contracts/README.md +1 -1
  15. package/docs/contracts/migration.md +12 -8
  16. package/docs/contracts/routing.md +3 -3
  17. package/docs/contributing/assignment-runner.md +14 -15
  18. package/docs/contributing/development.md +22 -6
  19. package/docs/contributing/harness-routing-internals.md +8 -8
  20. package/docs/glossary.md +1 -1
  21. package/docs/guides/agent-skills.md +1 -1
  22. package/docs/operations/backup-and-restore.md +7 -7
  23. package/docs/operations/upgrade.md +2 -2
  24. package/docs/reference/cli-reference.md +37 -14
  25. package/docs/reference/config-reference.md +81 -155
  26. package/docs/reference/harness-routing.md +29 -21
  27. package/docs/reference/workflow-catalog.md +4 -4
  28. package/docs/start/first-workflow.md +1 -1
  29. package/examples/project/.kxm/agents/coordinator.yaml +1 -2
  30. package/examples/project/.kxm/agents/critic-1.yaml +1 -3
  31. package/examples/project/.kxm/agents/critic-2.yaml +1 -2
  32. package/examples/project/.kxm/agents/critic-3.yaml +2 -3
  33. package/examples/project/.kxm/agents/implementer.yaml +1 -2
  34. package/examples/project/.kxm/agents/planner.yaml +1 -2
  35. package/examples/project/.kxm/agents/reproducer.yaml +1 -2
  36. package/examples/project/.kxm/agents/reviewer.yaml +1 -2
  37. package/examples/project/.kxm/workflows/fix.yaml +0 -12
  38. package/package.json +8 -8
  39. package/plugins/kxm/.claude-plugin/plugin.json +1 -1
  40. package/plugins/kxm/dist/cli.js +2565 -465
  41. package/plugins/kxm/dist/mcp-server.js +1 -1
  42. package/plugins/kxm/dist/runtime-supervisor.js +683 -348
  43. package/plugins/kxm/dist/runtime.js +694 -358
  44. package/plugins/kxm/dist/server.js +17 -14
  45. package/plugins/kxm/package.json +1 -1
  46. package/plugins/kxm/skills/kxm/SKILL.md +1 -1
  47. package/plugins/kxm/skills/kxm-definitions/SKILL.md +8 -0
  48. package/plugins/kxm/src/cli/lanes.ts +109 -4
  49. package/plugins/kxm/src/cli/project.ts +6 -6
  50. package/plugins/kxm/src/database.ts +25 -19
  51. package/plugins/kxm/src/engine.ts +168 -163
  52. package/plugins/kxm/src/init-guide-setup.ts +75 -15
  53. package/plugins/kxm/src/mcp-server.ts +1 -1
  54. package/plugins/kxm/src/oneshot-producer.ts +3 -15
  55. package/plugins/kxm/src/project-config.ts +83 -70
  56. package/plugins/kxm/src/routes.ts +26 -18
  57. package/plugins/kxm/src/runtime-service.ts +1 -0
  58. package/plugins/kxm/src/runtime-store.ts +390 -77
  59. package/plugins/kxm/src/runtime-supervisor.ts +87 -21
  60. package/plugins/kxm/src/suggest.ts +2 -2
  61. package/plugins/kxm/src/template.ts +2 -14
  62. package/schemas/agent.schema.json +8 -0
  63. package/scripts/roster-policy.d.mts +2 -1
  64. package/scripts/roster-policy.mjs +119 -22
  65. package/scripts/run-bounded.mjs +53 -0
@@ -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.128",
14
+ "version": "0.7.131",
15
15
  "category": "development",
16
16
  "tags": ["kxm", "multi-agent", "workflows", "mcp"]
17
17
  }
package/.kxm/README.md CHANGED
@@ -15,7 +15,6 @@ a `default` workflow, `gates.yaml` and `template-provenance.yaml`.
15
15
  | `agents/`, `models/`, `workflows/` | Agents, model profiles and workflows, one YAML file each | Tracked |
16
16
  | `gates.yaml` | The executable gate registry | Tracked |
17
17
  | `roles/`, `routes.yaml`, `prices.yaml` | Role rosters, admitted model routes, dated list prices | Tracked |
18
- | `roster.yaml` | The developer assignment roster for this repository | Tracked, and must be committed |
19
18
  | `template-provenance.yaml` | Hashes of the template `kxm init` used | Tracked |
20
19
  | `models/inventory.yaml` | The discovered model catalog | Generated; track it for a reviewed snapshot |
21
20
  | `config.yaml` | Shared personalization settings | Tracked if the project shares them |
@@ -26,6 +25,10 @@ a `default` workflow, `gates.yaml` and `template-provenance.yaml`.
26
25
  | `state/` | The hub database `kxm.db`, Pi sessions and restart state | Ignored |
27
26
  | `run/` | SSH control sockets from `kxm ssh` | Ignored |
28
27
 
28
+ The role files under `.kxm/roles/` and the model files under `.kxm/models/`
29
+ carry the developer policy. The assignment runner reads them at
30
+ `refs/remotes/origin/main`.
31
+
29
32
  The [configuration reference](../docs/reference/config-reference.md#workspace-layout-tracked-ignored-and-state)
30
33
  describes every file, the ignore rules to add, and the state KXM keeps outside
31
34
  the project.
@@ -1,5 +1,6 @@
1
1
  schema: kxm.agent.v1
2
2
  purpose: Coordinate the pinned workflow and emit schema-validated commands.
3
+ role: planner
3
4
  tools:
4
5
  preset: coordinator
5
6
  defaultRepositoryAccess: read
@@ -1,9 +1,6 @@
1
1
  schema: kxm.agent.v1
2
2
  purpose: Architecture critic for the approved workflow change.
3
- harness: claude
4
- model:
5
- provider: anthropic
6
- model: fable
3
+ role: reviewer-arch
7
4
  tools:
8
5
  preset: read-only
9
6
  defaultRepositoryAccess: read
@@ -1,9 +1,6 @@
1
1
  schema: kxm.agent.v1
2
2
  purpose: CLI and verification critic for the approved workflow change.
3
- harness: codex
4
- model:
5
- provider: openai
6
- model: gpt-5.6-sol
3
+ role: reviewer-cli
7
4
  tools:
8
5
  preset: read-only
9
6
  defaultRepositoryAccess: read
@@ -1,9 +1,6 @@
1
1
  schema: kxm.agent.v1
2
2
  purpose: Implement the approved change within the declared repository scope.
3
- harness: grok
4
- model:
5
- provider: xai
6
- model: grok-4.7
3
+ role: writer
7
4
  tools:
8
5
  preset: workspace-writer
9
6
  defaultRepositoryAccess: none
@@ -1,5 +1,5 @@
1
1
  schema: kxm.workflow.v1
2
- description: One implementer step with a drive receipt. Replaces just impl.
2
+ description: One implementer step with a drive receipt.
3
3
  coordinator: coordinator
4
4
  limits:
5
5
  maxTransitions: 2
@@ -1,5 +1,5 @@
1
1
  schema: kxm.workflow.v1
2
- description: One read-only architecture critic step. Replaces just review-arch.
2
+ description: One read-only architecture critic step.
3
3
  coordinator: coordinator
4
4
  limits:
5
5
  maxTransitions: 2
@@ -1,5 +1,5 @@
1
1
  schema: kxm.workflow.v1
2
- description: One read-only CLI critic step. Replaces just review-cli.
2
+ description: One read-only CLI critic step.
3
3
  coordinator: coordinator
4
4
  limits:
5
5
  maxTransitions: 2
package/CHANGELOG.md CHANGED
@@ -138,6 +138,17 @@ All notable user-facing changes are documented here. The project follows [Semant
138
138
 
139
139
  ### Changed
140
140
 
141
+ - **Dispatch reads role and model files, and agents bind a role.**
142
+ `scripts/roster-policy.mjs` builds the developer policy from
143
+ `.kxm/models/*.yaml` and `.kxm/roles/*.yaml` at `refs/remotes/origin/main`.
144
+ The engine resolves harness, model, and effort from the agent's `role`
145
+ and that role's roster. A step `model` does not override that route.
146
+ `kxm routes` prints `policy` (`admitted`, `disabled`) and `membership`
147
+ from the role files. `.kxm/routes.yaml` keeps admitted and disabled
148
+ selectors. `reviewer-arch` resolves to `fable-claude`. `opus-claude` is
149
+ admitted and named by no roster, so it is absent from `routes` and the
150
+ lineups. `gemini-agy` is in the writer lineup. An agent `tools.preset`
151
+ may only narrow its role preset; that rule is recorded and enforced in P3.
141
152
  - **Role and model files are live `kxm.role.v2` and `kxm.model.v2`.**
142
153
  `schemas/role.schema.json` and `schemas/model.schema.json` are the files
143
154
  `kxm config` validates. Each admitted roster route is a
@@ -153,7 +164,9 @@ All notable user-facing changes are documented here. The project follows [Semant
153
164
  in the developer ceilings or the harness inventory can dispatch them:
154
165
  `zai-coding-cn/glm-5.3-flash`, `qwen-token-plan/qwen3.8-flash`,
155
166
  `qwen-token-plan/qwen3.8-max`, and `zai-coding-cn/glm-5.3`.
156
- Dispatch still reads `.kxm/roster.yaml` until P2.
167
+ Dispatch resolves harness, provider, model, and effort from the role roster.
168
+ A live request with no harness is refused. A roster entry with no effort
169
+ leaves thinking unset.
157
170
 
158
171
  - **Usage errors under `--json` print a `usage_error` envelope and exit 2.**
159
172
  A missing required option, unknown command, or other Commander usage error
@@ -418,6 +431,14 @@ All notable user-facing changes are documented here. The project follows [Semant
418
431
 
419
432
  ### Removed
420
433
 
434
+ - **The developer roster file and the transport just recipes.**
435
+ The single roster document and the `impl`, `plan`, `review-arch`,
436
+ `review-cli`, `impl-bg`, and `dispatch` recipes are gone. One-step
437
+ workflows are the transport: `kxm lane run <unit> --brief <file> --workflow implement-only`,
438
+ and the same command with `review-arch-only` or `review-cli-only`.
439
+ Transfer policy from `.kxm/roster.yaml` to the role and model files and
440
+ delete the retired roster before running KXM. KXM refuses a leftover
441
+ `.kxm/roster.yaml`.
421
442
  - **`.kxm/template-provenance.yaml` was removed from this project, a repository
422
443
  change rather than a product change,** because the installed kxm no longer
423
444
  recognizes its recorded revision and a project without the file validates as
@@ -425,6 +446,26 @@ All notable user-facing changes are documented here. The project follows [Semant
425
446
 
426
447
  ### Fixed
427
448
 
449
+ - **The test suite no longer passes `--test-timeout`.** Under `node --test` that flag bounds each file, so coverage on CI timed out `test/core/engine.test.ts` at three minutes. The wall clock in `scripts/run-bounded.mjs` still bounds each script.
450
+ - **A git worktree lane registers under its project.** The Runtime registry
451
+ keeps the home row and adds the lane as its own control root and event
452
+ store, with the same project id and home runtime (`lane_of` on the lane
453
+ row). A foreign clone with that id is still `project_home_conflict`. A
454
+ registered root whose directory is gone is replaced, and that replacement
455
+ logs one `project_registration_replaced` event. `kxm lane drop` unregisters
456
+ the lane root when the Runtime is running, and still drops the worktree
457
+ when the Runtime is stopped. `kxm runs status` and `kxm lane status` print
458
+ the root they read. On the first read-write open, the registry table is
459
+ rebuilt and the registry advances from schema 1 to 2, copying every row
460
+ forward with `lane_of` empty. `kxm lane drop` refuses `lane_run_open` and names every
461
+ unsettled run in that lane's event store unless `--force` is set. Unregister
462
+ answers 409 `runtime_project_busy` or `runtime_project_has_lanes` unless the
463
+ body sets `force`.
464
+ - **`npm test` exits when the suite finishes.** The script passes
465
+ `--test-force-exit`, so a green run does not sit in the event loop and a
466
+ red run still prints its failures. Two full runs of the suite without the
467
+ flag also exited once the files finished; the handle that kept an earlier
468
+ run alive was not reproduced in this tree.
428
469
  - **`kxm land` names the pull request from the first commit subject and matches the Release run by time.**
429
470
  `--title` sets the title; otherwise the subject of the first commit on the
430
471
  branch is used, and a missing subject refuses `land_pr_title_missing`. The
@@ -13,7 +13,7 @@ Read from `plugins/kxm/src/cli.ts`, `scripts/kxm-hub.mjs`, `plugins/kxm/src/hub.
13
13
  | Hub | `kxm hub start` via `scripts/kxm-hub.mjs` | `127.0.0.1:7331` | `.kxm/state/kxm.db` under the workspace state dir | `plugins/kxm/src/hub.ts` |
14
14
  | Hub credentials | written when the hub starts | `hub-env.json` under the user state root | that JSON file, not SQLite | `plugins/kxm/src/hub-env.ts` |
15
15
  | Runtime supervisor | `kxm runtime` / `scripts/kxm-runtime-supervisor.mjs` | `127.0.0.1` and the requested port, or ephemeral | registry and event stores below | `plugins/kxm/src/runtime-supervisor.ts` |
16
- | Runtime registry | opened by the supervisor | `runtime/registry.db` under the user state root | `registry.db` | `plugins/kxm/src/runtime-paths.ts` |
16
+ | Runtime registry | opened by the supervisor | `runtime/registry.db` under the user state root | `registry.db`. A lane worktree registers under its project: same project id, its own control root, `lane_of` set. A registering root is the primary worktree when its git common dir is `<root>/.git`; if that primary registers while the live home row is not primary, the primary becomes the home row and every other live row of that repository becomes its lane. | `plugins/kxm/src/runtime-paths.ts` |
17
17
  | Runtime event store | opened by the supervisor | `runtime/projects/<key>/run-events.db` | `run-events.db` | `plugins/kxm/src/runtime-paths.ts` |
18
18
  | MCP server | Claude plugin or stdio launch | stdio | none | `plugins/kxm/src/mcp-server.ts` |
19
19
  | One-shot harness | supervisor producer | child process, no listener | none | `plugins/kxm/src/oneshot-producer.ts` |
@@ -211,7 +211,7 @@ The package ships a directory of `SKILL.md` suites that Pi and Claude Code both
211
211
  Project behavior lives in Git under `.kxm/`: `project.yaml`, `agents/`, `models/`, `workflows/`, `gates.yaml`, `roles/`, `routes.yaml`, `memory/`, and `skills/`. The project bundle (`project.yaml`, `agents/`, `models/`, `workflows/`, and `gates.yaml`) is restricted YAML checked against a JSON Schema. `routes.yaml`, `roles/`, and the front matter in `memory/` and `skills/` are parsed as ordinary YAML with their own checks, and a live drive re-reads an agent file the same way to resolve its route. Git review is the activation boundary:
212
212
 
213
213
  - Every run pins revision hashes of the project bundle, memory, executor policy, and tool policy. An edit affects only later runs, and a run whose pinned revisions drift is refused.
214
- - `kxm trust diff` prints a structured permission diff against a base revision (default `HEAD`). `kxm trust check` exits non-zero when the change expands permissions. Neither covers `routes.yaml`, `roles/`, `roster.yaml`, or `prices.yaml`, so admitting a route is not flagged.
214
+ - `kxm trust diff` prints a structured permission diff against a base revision (default `HEAD`). `kxm trust check` exits non-zero when the change expands permissions. Neither covers `routes.yaml`, `roles/`, `the role files`, or `prices.yaml`, so admitting a route is not flagged.
215
215
  - Legacy `.kxm/config/*.json` files are refused, never converted.
216
216
 
217
217
  Webhook workflow definitions are separate JSON that the hub loads at start, with secrets named by environment variable. Personal settings merge built-in defaults, then `~/.config/kxm/config.yaml`, then the project's `.kxm/config.yaml`. See the [configuration file reference](../reference/config-reference.md) and [Configuration](../reference/configuration.md).
@@ -162,7 +162,7 @@ Each database records its schema version in SQLite's `user_version`. When a proc
162
162
  - an older store fails with `runtime_schema_outdated`;
163
163
  - a store with tables but no version fails with `runtime_schema_shape_invalid`.
164
164
 
165
- KXM never upgrades a store in place, because the code would otherwise have to keep working against schema shapes it no longer tests. To cross a store version, stop the owner, back up if you need the history, delete the store with its `-wal` and `-shm` files, and let the owner recreate it: `kxm hub start` for `kxm.db`, and the Runtime for the registry and event stores. `kxm init` rebuilds no database. Legacy `.kxm/config/*.json` files are refused the same way.
165
+ KXM does not upgrade hub stores or Runtime event stores in place, because the code would otherwise have to keep working against schema shapes it no longer tests. To cross one of those versions, stop the owner, back up if you need the history, delete the store with its `-wal` and `-shm` files, and let the owner recreate it: `kxm hub start` for `kxm.db`, and the Runtime for event stores. The Runtime registry is the exception: schema 1 opens as schema 2, and each existing row keeps its root with `lane_of` left empty. `kxm init` rebuilds no database. Legacy `.kxm/config/*.json` files are refused the same way.
166
166
 
167
167
  Every store opens in WAL mode with a 5-second busy timeout, `synchronous=NORMAL`, and foreign keys on. A database or sidecar that is a symbolic link is refused. [ADR-0003](../adr/ADR-0003-sqlite-only-store.md) records why SQLite is the only store.
168
168
 
@@ -17,7 +17,7 @@
17
17
  | [Synchronization](synchronization.md) | Implemented for the default policy; custom policies and on-demand content transfer are not |
18
18
  | [Routing](routing.md) | Implemented: routing records, the dated price catalog, `kxm routing report` and `kxm improve` |
19
19
  | [Validation](validation.md) | Largely implemented: the restricted YAML loader, schema, reference and semantic checks, and permission diffs |
20
- | [Migration](migration.md) | Decided: there is no migration path and no `kxm migrate` command; legacy state is refused |
20
+ | [Migration](migration.md) | Decided: no `kxm migrate` command; legacy state is refused. The Runtime registry schema 1 to 2 copy is the one in-place step |
21
21
 
22
22
  KXM is a convention-over-configuration, local-first orchestration and
23
23
  context platform. One local Runtime owns execution; an optional multi-project
@@ -14,7 +14,7 @@ one re-adds a compatibility lane by inference.
14
14
  | Project tree with legacy `.kxm/config` JSON | `loadKxmProject` fails closed with `legacy_state_unsupported`, one issue per legacy file. No receipt, plan, flag, or environment variable unlocks it. |
15
15
  | `kxm init` on such a tree | Reports `mode: "legacy"`, lists `legacyInputs`, performs **no writes**. Recovery is a fresh project directory plus the YAML definitions worth keeping. |
16
16
  | `kxm migrate` | Unknown command. It existed as `plan` / `apply` / `verify` for pre-KXM JSON and was deleted with this decision. |
17
- | SQLite store stamped with an older `user_version` | Refused with `runtime_schema_outdated`; the refusal never advances `user_version`, so the store stays identifiably old. Delete the state file and let the process that owns it recreate the store (`kxm hub start` for hub state, the Runtime for registry/event stores). `kxm init` is **project-only** and rebuilds no database. Forward-only stamping is prohibited — it turns a clean failure into a later query against a column that does not exist. |
17
+ | SQLite store stamped with an older `user_version` | Hub stores and Runtime event stores are refused with `runtime_schema_outdated`. That refusal never advances `user_version`. Delete the state file and let the process that owns it recreate the store (`kxm hub start` for hub state, the Runtime for event stores). `kxm init` is **project-only** and rebuilds no database. The Runtime registry is the exception: schema 1 is copied to schema 2 in place, existing rows stay, and `lane_of` is null on those rows. Forward-only stamping of any other store is prohibited, because it turns a clean failure into a later query against a column that does not exist. |
18
18
  | Retired product and command names | Rejected by fail-closed brakes (lint + readiness tests), not aliased. |
19
19
  | Shared/off-scope Pi history | Never imported into a narrower run scope. A new physical session starts clean; durable facts come from Git, workflow evidence, artifacts, or promoted context. |
20
20
  | Historical run records | Never fabricated. Events whose real ordering was not observed stay absent rather than reconstructed into a finer-grained model. |
@@ -31,15 +31,19 @@ does exist:
31
31
  [Back up and restore KXM](../operations/backup-and-restore.md); a single `kxm.db`
32
32
  copy is not a backup.
33
33
  - **Out-of-range versions refuse without touching the file.** The stamp is read
34
- before anything that can modify the store, so a database this build refuses —
35
- older or newer — comes back byte-identical: neither its schema nor its
34
+ before anything that can modify the store, so a database this build refuses,
35
+ older or newer, comes back byte-identical: neither its schema nor its
36
36
  `user_version` changes, and it is not converted to WAL as a side effect of being
37
- rejected. A store ahead of this build is refused without downgrade.
38
- - **Schema changes are additive-and-replace, not in-place.** Land the new
37
+ rejected. A store ahead of this build is refused without downgrade. The
38
+ registry schema 1 to 2 copy is not a refusal: that file is rewritten, and
39
+ every other older store is still refused untouched.
40
+ - **Schema changes are additive-and-replace, not in-place,** except the
41
+ Runtime registry's `lane_of` column. For every other store, land the new
39
42
  definition, delete the local state, and let the process that owns each store
40
- recreate it — `kxm hub start` for hub state, the Runtime for registry and
41
- event stores. `kxm init` is project-only and rebuilds no database.
42
- Nothing in the runtime may rewrite an existing store's shape.
43
+ recreate it. `kxm hub start` recreates hub state. The Runtime recreates event
44
+ stores. `kxm init` is project-only and rebuilds no database. Nothing else in
45
+ the runtime may rewrite an existing store's shape. Opening a schema 1
46
+ registry copies its rows into schema 2 and leaves `lane_of` null.
43
47
 
44
48
  ## If this ever changes
45
49
 
@@ -130,11 +130,11 @@ just accept /abs/task-dir <commit> /abs/writer-record /abs/arch-review /abs/cli-
130
130
  # optional observed PR/CI (direct script; the five-argument just recipe cannot forward them):
131
131
  # node scripts/assignment-run.mjs accept --task-dir /abs/task --commit <sha> --record-dir /abs/writer --critic /abs/arch --critic /abs/cli [--observed-pr <id>] [--observed-ci <id>]
132
132
 
133
- just plan-current /abs/task-dir /abs/plan.md <sha256> <base-commit> <expected-generation>
133
+ kxm assign plan-current --task-dir /abs/task-dir --plan /abs/plan.md --sha256 <sha256> --base-commit <base-commit> --expected-generation <expected-generation>
134
134
  just change-report /abs/task-dir
135
135
  ```
136
136
 
137
- `just impl|plan|review-arch|review-cli` remain harness transport. They do not
137
+ `kxm lane run` remain harness transport. They do not
138
138
  create assignment identity, witness receipts, or `accepted.json`.
139
139
 
140
140
  Distinctions the report and docs must keep:
@@ -161,7 +161,7 @@ learned policy and not a catalog feed. Phase 9 may use this report to
161
161
  Per-candidate acceptance requires an actual native writer, the fixed witness,
162
162
  and both designated native reviews. PR/CI/merge complete issue 127. This
163
163
  document does not assert those gates have passed. Low-level
164
- `just impl|plan|review-arch|review-cli` recipes remain harness transport.
164
+ `kxm lane run` recipes remain harness transport.
165
165
 
166
166
  ## Implemented: v2 record
167
167
 
@@ -16,24 +16,25 @@ a KXM product feature.
16
16
  ## Before you begin
17
17
 
18
18
  - A clean control checkout of this repository whose `HEAD` is an ancestor of
19
- `origin/main`. The runner loads `.kxm/roster.yaml` only from there.
19
+ `origin/main`. The runner loads `.kxm/roles/*.yaml` and `.kxm/models/*.yaml`
20
+ only from there.
20
21
  - A separate worktree for the writer. `kxm lane create <unit>` creates one from
21
22
  `origin/main`.
22
23
  - The harness CLIs the roster admits, installed and logged in.
23
24
  `node scripts/kxm.mjs harness list` shows which are. The loop below is
24
- `kxm assign`. `just` still runs the transport recipes.
25
+ `kxm assign`. Transport is `kxm lane run <unit> --brief <file> --workflow implement-only`,
26
+ or the same command with `review-arch-only` or `review-cli-only`.
25
27
  - A task directory whose final path segment equals the task ID. Every path you
26
28
  pass to the runner must be absolute.
27
29
 
28
30
  ## Roles and routes
29
31
 
30
- The trusted roster policy in [`.kxm/roster.yaml`](../../.kxm/roster.yaml)
31
- (`kxm.developer-roster.v1`) admits each route for specific roles and
32
- permissions:
32
+ The trusted roster policy in `.kxm/roles/*.yaml` and `.kxm/models/*.yaml`
33
+ admits each route for specific roles and permissions:
33
34
 
34
35
  | Role | Admitted route (harness / model) | Vendor | Permission |
35
36
  |---|---|---|---|
36
- | `writer` | `grok` / `grok-4.7`; relief: `pi` / `openrouter/qwen/qwen3-coder-plus` | `xai`; `alibaba` | `edit` |
37
+ | `writer` | `grok` / `grok-4.7`; relief: `pi` / `openrouter/qwen/qwen3-coder-plus`; `agy` / `gemini-3.8-flash-high` | `xai`; `alibaba`; `google` | `edit` |
37
38
  | `planner` | `claude` / `fable` | `anthropic` | `read-only` |
38
39
  | `reviewer-arch` | `claude` / `fable` | `anthropic` | `read-only` |
39
40
  | `reviewer-cli` | `codex` / `gpt-5.6-sol` | `openai` | `read-only` |
@@ -85,7 +86,7 @@ Use this slim loop for daily work and for docs. The 13-step `fix` workflow in
85
86
  > runner validates anything. The process environment is passed through as it
86
87
  > is. Export any variable you need before the command.
87
88
 
88
- The seven `just` assignment recipes remain available and will be removed after one real unit has been accepted through `kxm assign`; until then both forms are equivalent because both call `scripts/assignment-run.mjs` unchanged.
89
+ Transport is `kxm lane run <unit> --brief <file> --workflow implement-only`, or the same command with `review-arch-only` or `review-cli-only`. The transport recipes are deleted.
89
90
 
90
91
  ### 1. Pin the current plan
91
92
 
@@ -314,17 +315,15 @@ It writes `recording-resolved.json` in the record directory. It never changes
314
315
  ## Transport-only recipes
315
316
 
316
317
  Drive a one-step workflow in a lane. Each command writes a drive receipt and
317
- the checkout fingerprint. `just impl`, `just plan`, `just review-arch`,
318
- `just review-cli`, and `just impl-bg` are retired in favor of these. The
319
- recipes stay in the justfile until one real unit has been driven this way.
318
+ the checkout fingerprint.
320
319
 
321
320
  ```bash
322
- kxm lane run <unit> --workflow implement-only --brief <file>
323
- kxm lane run <unit> --workflow review-arch-only --brief <file>
324
- kxm lane run <unit> --workflow review-cli-only --brief <file>
321
+ kxm lane run <unit> --brief <file> --workflow implement-only
322
+ kxm lane run <unit> --brief <file> --workflow review-arch-only
323
+ kxm lane run <unit> --brief <file> --workflow review-cli-only
325
324
  ```
326
325
 
327
- `just dispatch` still sends one `kxm.harness-request.v1` envelope through
326
+ `scripts/harness-run.mjs` still accepts one `kxm.harness-request.v1` envelope through
328
327
  `scripts/harness-run.mjs` and prints a `kxm.harness-result.v2` envelope. It
329
328
  mints no assignment, witness or acceptance proof, so its output cannot be
330
329
  accepted. The retired recipes did the same.
@@ -430,4 +429,4 @@ gate-only workflows are supported. See the
430
429
  - [Develop KXM](development.md): the commit gate the witness runs
431
430
  - [CI and release](ci-and-release.md): what runs after you push
432
431
  - [Harness routing](../reference/harness-routing.md): harness and model pairing
433
- - [Configuration reference](../reference/config-reference.md#kxmrosteryaml-kxmdeveloper-rosterv1): the roster file
432
+ - [Configuration reference](../reference/config-reference.md#developer-assignment-policy): the developer assignment policy
@@ -13,8 +13,16 @@ extension, the Claude Code plugin, or the bundled skills.
13
13
  - Optional tools, needed only for the matching task:
14
14
  - [Pi](https://pi.dev) to load the extension from source.
15
15
  - The Claude Code CLI to validate the plugin manifests locally.
16
- - [`just`](https://github.com/casey/just) for the
17
- [assignment runner](assignment-runner.md).
16
+ - [`just`](https://github.com/casey/just) for the remaining
17
+ [assignment runner](assignment-runner.md) recipes only:
18
+ `assign`, `witness`, `accept`, `observe-cost`, `attribute`,
19
+ `change-report`, and `plan-current`. Those recipes are harness
20
+ transport for the issue 127 runner. They are not how a unit is
21
+ dispatched. Do not rename or delete them.
22
+ - `kxm lane run` to dispatch a unit. A writer unit uses
23
+ `kxm lane run <unit> --brief <file> --workflow implement-only`.
24
+ The read-only critic workflows on the same command are
25
+ `review-arch-only` and `review-cli-only`.
18
26
  - Docker for the clean-container install smoke.
19
27
 
20
28
  ## Set up a checkout
@@ -116,7 +124,7 @@ excluded from the npm package.
116
124
  ├── .github/ CI, release, issue and PR templates (not shipped)
117
125
  ├── .claude/ Developer harness notes and commands (not shipped)
118
126
  ├── plans/ Internal planning and tracking (not shipped)
119
- ├── justfile Developer recipes for the assignment runner
127
+ ├── justfile Remaining issue 127 recipes (assign, witness, accept, observe-cost, attribute, change-report, plan-current)
120
128
  └── AGENTS.md, CLAUDE.md, GEMINI.md Agent instructions with generated blocks
121
129
  ```
122
130
 
@@ -196,8 +204,14 @@ For what each skill covers, see [Agent skills](../guides/agent-skills.md).
196
204
  8. Push and open a pull request. The template asks for the slice issue and the
197
205
  `npm run verify` result.
198
206
 
199
- Maintainers who delegate work to coding agents use the
200
- [assignment runner](assignment-runner.md) for steps 2 to 7.
207
+ Maintainers who delegate a unit dispatch it with
208
+ `kxm lane run <unit> --brief <file> --workflow implement-only`.
209
+ Read-only critics use the same command with `review-arch-only` or
210
+ `review-cli-only`. The [assignment runner](assignment-runner.md)
211
+ recipes (`assign`, `witness`, `accept`, `observe-cost`, `attribute`,
212
+ `change-report`, `plan-current`) stay on `just`. They are harness
213
+ transport for the issue 127 runner, not the unit transport, and they
214
+ cover steps 2 to 7 after a lane run.
201
215
 
202
216
  ## Generated artifacts
203
217
 
@@ -235,10 +249,12 @@ It runs three scripts in order:
235
249
 
236
250
  | Step | Script | What it checks |
237
251
  |---|---|---|
238
- | 1 | `npm test` | Build, then `test/core/*.test.ts` and `packages/core/*/tests/unit/*.test.ts` |
252
+ | 1 | `npm test` | Build, then `test/core/*.test.ts` and `packages/core/*/tests/unit/*.test.ts`. The script passes `--test-force-exit` so a finished run leaves the process even if a handle is still open; a failing test is still reported before that exit |
239
253
  | 2 | `npm run check` | `tsc --noEmit`, `markdownlint-cli2`, and version surfaces |
240
254
  | 3 | `npm run check:generated` | Generated artifacts are tracked and match the staged copy |
241
255
 
256
+ Every suite script passes `--test-force-exit`, and `scripts/run-bounded.mjs` stops the run if the suite is still going after its wall-clock limit (20 minutes, or 40 for the complete and coverage suites). The bound is that wall clock per script. A per-test timeout is not used because under `node --test` each file is itself a test, so a per-test timeout also bounds each file.
257
+
242
258
  Other scripts you will use:
243
259
 
244
260
  | Script | Use it for |
@@ -3,7 +3,7 @@
3
3
  This page records how the KXM repository applies [harness routing](../reference/harness-routing.md) to its own work: the routes this checkout admits, its writer roster, its price catalog, and the developer roster policy that `just assign` and the dev helper enforce. It is maintainer material. The snapshots were captured on 2026-09-23 on one operator machine, from a source checkout where `node scripts/kxm.mjs` is the same program as `kxm`; they change whenever an admission changes.
4
4
 
5
5
  > [!IMPORTANT]
6
- > The files are the authority, not this page: `.kxm/routes.yaml`, `.kxm/roles/`, `.kxm/roster.yaml` and `.kxm/prices.yaml`. Product routing decisions are recorded under Tracking → Decided in `plans/implementation-plan.md`.
6
+ > The files are the authority, not this page: `.kxm/routes.yaml`, `.kxm/roles/*.yaml`, `.kxm/models/*.yaml`, and `.kxm/prices.yaml`. Product routing decisions are recorded under Tracking → Decided in `plans/implementation-plan.md`.
7
7
 
8
8
  ## This checkout's routes and roster
9
9
 
@@ -59,9 +59,9 @@ On the capture machine, `kxm harness list` showed `claude` detected but logged o
59
59
 
60
60
  `.kxm/prices.yaml` is dated `2026-09-16`, so every current run records `providerMetadata.priceCatalogStale: true` and no list estimate. The list prices below come from `.kxm/models/inventory.yaml`, fetched `2026-09-16T14:54:53Z`, in USD per 1M tokens. The checkout has no routing records yet, so none of the examples has recorded latency; for latency, run a bounded side-by-side experiment and compare p50 and p95 in `kxm routing report`.
61
61
 
62
- ## The developer roster (`.kxm/roster.yaml`)
62
+ ## The developer roster
63
63
 
64
- The issue-127 runner (`just assign`, see the [assignment runner](assignment-runner.md)) uses its own policy file, [`kxm.developer-roster.v1`](../reference/config-reference.md#kxmrosteryaml-kxmdeveloper-rosterv1). Routes there name the harness, the model and the vendor explicitly:
64
+ The issue-127 runner (`kxm assign`, see the [assignment runner](assignment-runner.md)) reads `.kxm/roles/*.yaml` and `.kxm/models/*.yaml` at `refs/remotes/origin/main`. See [Developer assignment policy](../reference/config-reference.md#developer-assignment-policy). Routes there name the harness, the model and the vendor explicitly:
65
65
 
66
66
  ```yaml
67
67
  grok-native:
@@ -100,7 +100,7 @@ The product brake, the dev helper and the roster policy now agree on the vendor
100
100
 
101
101
  ## Worked examples on this checkout
102
102
 
103
- These extend the generic examples on the reference page with this checkout's admissions, developer-roster routes, readiness on the capture machine, and inventory prices.
103
+ These extend the generic examples on the reference page with this checkout's admissions, developer policy routes, readiness on the capture machine, and inventory prices.
104
104
 
105
105
  ### Grok 4.6
106
106
 
@@ -174,19 +174,19 @@ The developer runner is stricter. Its only Pi writer is `openrouter/qwen/qwen3-c
174
174
 
175
175
  | Symptom | Cause | Fix |
176
176
  |---|---|---|
177
- | `pi brake: xai has a native harness; refusing Pi impersonation` | A dev-helper request routed a native vendor through Pi. | Use the native harness recipe instead: `just impl`, `just plan`, `just review-arch` or `just review-cli`. |
178
- | `Roster policy refused: native vendor cannot use Pi` | A `.kxm/roster.yaml` Pi route names a native vendor, as in `openrouter/x-ai/…` or `nous-portal/anthropic/…`. | Remove the route. Only a native harness route is valid for that vendor. |
177
+ | `pi brake: xai has a native harness; refusing Pi impersonation` | A dev-helper request routed a native vendor through Pi. | Use the native harness through `kxm lane run <unit> --brief <file> --workflow review-arch-only`. |
178
+ | `Roster policy refused: native vendor cannot use Pi` | A Pi route in `.kxm/models/*.yaml` names a native vendor, as in `openrouter/x-ai/…` or `nous-portal/anthropic/…`. | Remove the route. Only a native harness route is valid for that vendor. |
179
179
  | The dev helper refuses a codex route. | `codex` is logged in with an API key. | Run `codex login` with the ChatGPT flow. |
180
180
 
181
181
  For example, the native writer recipe:
182
182
 
183
183
  ```bash
184
- just impl brief.md
184
+ kxm lane run <unit> --brief <file> --workflow implement-only
185
185
  ```
186
186
 
187
187
  ## Related
188
188
 
189
189
  - [Harness routing](../reference/harness-routing.md): the rules, the decision procedure and the generic examples
190
190
  - [Assignment runner](assignment-runner.md): the loop that enforces the developer roster
191
- - [Configuration file reference](../reference/config-reference.md#kxmrosteryaml-kxmdeveloper-rosterv1): the `kxm.developer-roster.v1` fields
191
+ - [Configuration file reference](../reference/config-reference.md#developer-assignment-policy): the developer assignment policy fields
192
192
  - [Routing and cost telemetry contract](../contracts/routing.md): the routing record, cost basis and dev-helper telemetry
package/docs/glossary.md CHANGED
@@ -423,7 +423,7 @@ A `kxm.role.v2` definition in `.kxm/roles/`, managed with `kxm role`, that descr
423
423
 
424
424
  ### Roster
425
425
 
426
- A list of allowed models. It means either a [role](#role)'s roster, or the developer roster `.kxm/roster.yaml` that the [assignment runner](contributing/assignment-runner.md) trusts to choose writers and critics. Neither one admits a route; see [admission](#admission).
426
+ A list of allowed models. It means either a [role](#role)'s roster, or the developer roster in `.kxm/roles/*.yaml` and `.kxm/models/*.yaml` that the [assignment runner](contributing/assignment-runner.md) trusts to choose writers and critics. Neither one admits a route; see [admission](#admission).
427
427
 
428
428
  ### Route
429
429
 
@@ -1,6 +1,6 @@
1
1
  # Agent skills
2
2
 
3
- KXM ships a suite of Agent Skills that teach a coding agent how to use the `kxm` CLI and the `kxm_*` tools safely: which command owns a task, which verbs exist, and which steps belong to a person. This page is for anyone running KXM from Claude Code, Pi or Codex, and for contributors who edit the skills. Skills document the CLI; they grant no permission, admit no writer and replace no trusted `.kxm/roster.yaml` policy.
3
+ KXM ships a suite of Agent Skills that teach a coding agent how to use the `kxm` CLI and the `kxm_*` tools safely: which command owns a task, which verbs exist, and which steps belong to a person. This page is for anyone running KXM from Claude Code, Pi or Codex, and for contributors who edit the skills. Skills document the CLI; they grant no permission, admit no writer and replace no trusted policy in `.kxm/roles/*.yaml` and `.kxm/models/*.yaml`.
4
4
 
5
5
  Governed skills that your own runs produce are a separate lifecycle; see [Governed skills](governed-skills.md).
6
6
 
@@ -15,7 +15,7 @@ KXM spreads state over six roots. Some of them move with environment variables,
15
15
  ```mermaid
16
16
  flowchart TB
17
17
  subgraph R["$R checkout root: the Git checkout, never moves"]
18
- R1["Project definition: .kxm/project.yaml, config.yaml, agents/, models/, workflows/, gates.yaml, roles/, roles, routes.yaml, roster.yaml, prices.yaml, repo/, project/env.yaml"]
18
+ R1["Project definition: .kxm/project.yaml, config.yaml, agents/, workflows/, gates.yaml, .kxm/roles/, .kxm/models/, routes.yaml, prices.yaml, repo/, project/env.yaml"]
19
19
  R2["Durable records: .kxm/memory/, skills/, goals/, tasks/, candidates/"]
20
20
  end
21
21
  subgraph D["$D workspace: KXM_WORKSPACE_DIR or --workspace, default $R/.kxm"]
@@ -31,7 +31,7 @@ flowchart TB
31
31
  S2["hub-env.json, hub-binding.json, update.yaml, projects/HASH/repository-bindings.json"]
32
32
  end
33
33
  subgraph C["$C user config: KXM_USER_CONFIG_DIR, default ~/.config/kxm"]
34
- C1["config.yaml, roles/, workflows/, roles, session.token"]
34
+ C1["config.yaml, workflows/, session.token. Checkout routing lives in .kxm/roles/ and .kxm/models/"]
35
35
  end
36
36
  subgraph T["$T federated telemetry: XDG_CONFIG_HOME/kxm/telemetry"]
37
37
  T1["model-metrics.jsonl, not written by any command today"]
@@ -71,13 +71,13 @@ The Runtime registry and the other projects' event stores are shared by every pr
71
71
  | `$S/runtime/registry.db` | Runtime registry: projects, their roots and home Runtime, the supervisor identity and claim | Only with `--all-projects` (`registry`) |
72
72
  | `$S/projects/<hash>/repository-bindings.json`, `$S/update.yaml` | Member repository paths; updater settings | No |
73
73
  | `$S/hub-env.json`, `$S/hub-binding.json`, `$C/session.token` | Credentials and the machine's hub binding | No; prefer regenerating secrets to copying them |
74
- | `$R/.kxm/` definition files and durable records | Project, roles, routes, prices, roster, memory, skills, goals, tasks, candidates | No; commit them to Git or copy the checkout |
74
+ | `$R/.kxm/` definition files and durable records | Project, `.kxm/roles/`, `.kxm/models/`, routes, prices, memory, skills, goals, tasks, candidates | No; commit them to Git or copy the checkout |
75
75
  | Each member repository's `.kxm/repo/*.yaml` | Member definition and environment | No; they live in the member's own checkout |
76
76
  | `$W/worker-*.json`, `$W/pi-sessions/` | Worker routing and recovery manifests; Pi model history | No; manifests are required for resumable workers, Pi history is optional |
77
77
  | `$D/assets/`, `$D/logs/` | Retrospectives and evidence; logs and local usage accounting (`telemetry.jsonl`) | No |
78
78
  | `$C` | User-level roles, workflows and settings | No |
79
79
 
80
- A restore without `roster.yaml`, `routes.yaml` or `prices.yaml` comes back healthy but with different admission and cost behavior, so treat them as part of the backup even though they are plain files. `kxm improve report --out-dir` can write candidates outside `$R/.kxm/candidates/`; include that directory if you use it.
80
+ A restore without `.kxm/roles/`, `.kxm/models/`, `routes.yaml`, or `prices.yaml` comes back healthy but with different admission and cost behavior, so treat them as part of the backup even though they are plain files. `kxm improve report --out-dir` can write candidates outside `$R/.kxm/candidates/`; include that directory if you use it.
81
81
 
82
82
  These files are disposable and need no backup: `hub.pid`, `hub.stop`, `worker-*.pid`, `session-brief.json`, `update-check.json`, `runtime/supervisor.token`, `runtime/supervisor.error`.
83
83
 
@@ -237,14 +237,14 @@ It restores the registry and every project's event store and sidecar. Every chec
237
237
 
238
238
  ### Restore ceilings
239
239
 
240
- A backup newer than this build is refused with `runtime_schema_newer` before any file changes. KXM has no migrations: an older backup restores, but its store then refuses to open with `runtime_schema_outdated`. Restore an older backup with the release that wrote it; see [Upgrade KXM](upgrade.md#understand-schema-changes).
240
+ A backup newer than this build is refused with `runtime_schema_newer` before any file changes. Hub and event stores are not migrated: an older backup of those restores, then the store refuses to open with `runtime_schema_outdated`. A registry backup at schema 1 opens in place: existing rows stay, and each gains an empty `lane_of` column. Restore any other older backup with the release that wrote it; see [Upgrade KXM](upgrade.md#understand-schema-changes).
241
241
 
242
242
  The ceilings come from `KXM_BACKUP_CEILINGS` in `plugins/kxm/src/database.ts` and match each store's own schema version:
243
243
 
244
244
  | Store id | Highest schema version restored |
245
245
  |---|---|
246
246
  | `hub-store` | 5 |
247
- | `registry` | 1 |
247
+ | `registry` | 2 |
248
248
  | `events:<key>` | 7 |
249
249
  | `binding-store` | 1 (no current store uses it) |
250
250
 
@@ -280,7 +280,7 @@ Test a full restore on a spare machine before you rely on it, and repeat the tes
280
280
  | `backup_no_stores` | No `.kxm/state/kxm.db` under the checkout (or it was moved with `KXM_STATE_DIR` or `KXM_DATA_PATH`) and no event store for this checkout under the user state root | Run inside the checkout; copy a relocated database with the stopped-state procedure |
281
281
  | `Backup is incomplete (<n> omitted); not ok:`, exit 1 | A store or sidecar could not be copied, or appeared while the backup ran | Fix the source named after `omitted`, then run `kxm backup` again |
282
282
  | `restore_incomplete` | The manifest records `complete: false` | Restore a complete backup; the partial one is not restorable |
283
- | Runs are missing, or the Runtime refuses the project with `project_home_conflict`, after a restore | The checkout moved to another absolute path, and the registry still binds the project to the old one | Keep the checkout at its original path and restore there |
283
+ | Runs are missing, or the Runtime refuses the project with `project_home_conflict`, after a restore | The checkout moved, and a live registration still points at the old directory. A missing directory is replaced on the next registration. A second live checkout that is not a worktree of the registered repository is still refused | Keep a live checkout at its original path. A worktree of that repository registers as a lane |
284
284
  | `restore_requires_all_projects` | The backup holds the Runtime registry or another project's event store: it was taken with `--all-projects`, or by a build from before backups were scoped | Pass `--all-projects` if rolling back every project is what you want; otherwise restore a backup taken without it |
285
285
  | `restore_runtime_running` | The Runtime supervisor is running | Run `kxm runtime stop`, pause whatever restarts it, then restore |
286
286
  | `restore_runtime_unverified` | `$S/runtime/registry.db` cannot be read, so restore cannot tell whether the supervisor is running | Stop the Runtime, move the registry aside, then restore; an `--all-projects` backup brings the registry back |
@@ -84,7 +84,7 @@ kxm update pi --models # refresh Pi model catalogs
84
84
 
85
85
  ## Understand schema changes
86
86
 
87
- Each store records a schema version, and KXM never upgrades a store in place.
87
+ Each store records a schema version. Hub stores and Runtime event stores are never upgraded in place. The Runtime registry copies schema 1 forward to schema 2 and keeps every existing row.
88
88
 
89
89
  | Store | Location | Created by |
90
90
  |---|---|---|
@@ -93,7 +93,7 @@ Each store records a schema version, and KXM never upgrades a store in place.
93
93
  | Run event store | `runtime/projects/<key>/run-events.db` under the user state root | The Runtime supervisor |
94
94
 
95
95
  - A store **newer** than the running release refuses to open (`runtime_schema_newer`). Do not delete it; run the release that created it, or upgrade.
96
- - A store **older** than the running release also refuses to open (`runtime_schema_outdated`), and the error names the store. There is no migration.
96
+ - A hub store or event store **older** than the running release also refuses to open (`runtime_schema_outdated`), and the error names the store. There is no migration for those stores. A registry at schema 1 opens, and its rows stay.
97
97
 
98
98
  When a release changes a schema, either stay on the old release, or accept a fresh store: stop the owner, move the old file aside (keep it with your backup), and start the owner, which re-creates it. `kxm init` rebuilds no database. A fresh hub store loses message and workflow history; a fresh Runtime store loses local run history. Check the changelog for schema changes before you upgrade.
99
99