@kontextmind/kxm 0.7.185 → 0.7.187

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 (39) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.kxm/README.md +1 -1
  3. package/.kxm/roles/writer.yaml +1 -1
  4. package/CHANGELOG.md +18 -0
  5. package/docs/contributing/assignment-runner.md +2 -2
  6. package/docs/contributing/ci-and-release.md +2 -1
  7. package/docs/contributing/development.md +22 -0
  8. package/docs/contributing/harness-routing-internals.md +12 -12
  9. package/docs/glossary.md +1 -1
  10. package/docs/guides/governed-skills.md +1 -1
  11. package/docs/guides/pi-workers.md +2 -2
  12. package/docs/guides/provenance-gates.md +1 -1
  13. package/docs/operations/troubleshooting.md +1 -1
  14. package/docs/reference/cli-reference.md +11 -11
  15. package/docs/reference/config-reference.md +44 -10
  16. package/docs/reference/configuration.md +2 -2
  17. package/docs/reference/harness-routing.md +27 -12
  18. package/package.json +1 -1
  19. package/packages/core/tui/dist/index.js +1 -1
  20. package/packages/core/tui/src/tui/optimizer.ts +1 -1
  21. package/plugins/kxm/.claude-plugin/plugin.json +1 -1
  22. package/plugins/kxm/dist/cli.js +47 -28
  23. package/plugins/kxm/dist/mcp-server.js +1 -1
  24. package/plugins/kxm/dist/runtime-supervisor.js +6 -2
  25. package/plugins/kxm/dist/runtime.js +7 -3
  26. package/plugins/kxm/dist/server.js +0 -1
  27. package/plugins/kxm/package.json +1 -1
  28. package/plugins/kxm/src/cli/system.ts +1 -1
  29. package/plugins/kxm/src/init-guide-setup.ts +9 -9
  30. package/plugins/kxm/src/mcp-server.ts +1 -1
  31. package/plugins/kxm/src/model-catalog-refresh.ts +572 -0
  32. package/plugins/kxm/src/model-inventory.ts +42 -15
  33. package/plugins/kxm/src/oneshot-producer.ts +2 -2
  34. package/plugins/kxm/src/pi-producer.ts +1 -1
  35. package/plugins/kxm/src/subagent-control.ts +1 -1
  36. package/plugins/kxm/src/workforce-names.mjs +12 -4
  37. package/scripts/harness-run.d.mts +1 -1
  38. package/scripts/harness-run.mjs +2 -2
  39. package/scripts/refresh-model-catalog.mjs +67 -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.185",
14
+ "version": "0.7.187",
15
15
  "category": "development",
16
16
  "tags": ["kxm", "multi-agent", "workflows", "mcp"]
17
17
  }
package/.kxm/README.md CHANGED
@@ -37,7 +37,7 @@ Ids in this checkout follow one convention per kind:
37
37
  |---|---|---|
38
38
  | Role | The purpose: `planner`, `writer`, `reviewer-arch`, `reviewer-cli` | Unchanged |
39
39
  | Agent | The same id as its `role` | `planner`, `writer`, `reviewer-arch`, `reviewer-cli` |
40
- | Route | `<harness>-<model-slug>[-<provider>]`, with `.` written as `-` | `grok-grok-4-7`, `claude-fable`, `pi-qwen3-coder-plus-openrouter` |
40
+ | Route | `<harness>-<model-slug>[-<provider>]`, with `.` written as `-` | `grok-grok-4-7`, `claude-fable`, `pi-qwen3-7-plus-openrouter` |
41
41
  | Workflow | `default`, `land`, or `<role>-only` | `default`, `land`, `writer-only`, `reviewer-arch-only`, `reviewer-cli-only` |
42
42
  | Agent step | The agent's role id | `writer`, `reviewer-arch`, `reviewer-cli` |
43
43
 
@@ -10,7 +10,7 @@ description: Primary implementation agent.
10
10
  roster:
11
11
  - route: grok-grok-4-7
12
12
  effort: medium
13
- - route: pi-qwen3-coder-plus-openrouter
13
+ - route: pi-qwen3-7-plus-openrouter
14
14
  effort: medium
15
15
  - route: agy-gemini-4-argon-high
16
16
  effort: medium
package/CHANGELOG.md CHANGED
@@ -6,6 +6,15 @@ All notable user-facing changes are documented here. The project follows [Semant
6
6
 
7
7
  ### Added
8
8
 
9
+ - **OpenRouter model prices and the inventory refresh weekly.**
10
+ `.github/workflows/refresh-models.yml` runs Monday at 13:00 UTC, or on
11
+ demand, and opens one pull request on `automation/model-refresh` when
12
+ `.kxm/prices.yaml` or the OpenRouter slice of `.kxm/models/inventory.yaml`
13
+ changes. A model still named by `.kxm/routes.yaml` or a roster is kept when
14
+ it leaves the catalog, and the `model-catalog-guard` check fails until a
15
+ human decides. Run it locally with
16
+ `node --disable-warning=ExperimentalWarning --experimental-strip-types scripts/refresh-model-catalog.mjs`.
17
+
9
18
  - **The witnessed MG1 Python control-plane foundation is now reproducible from this repository.**
10
19
  `python/kxm-control` provides the pinned Python 3.13 uv workspace, fixed
11
20
  `kxmd` Postgres/Temporal caller, Authentik user and runner verification
@@ -216,6 +225,15 @@ All notable user-facing changes are documented here. The project follows [Semant
216
225
 
217
226
  ### Changed
218
227
 
228
+ - **Writer #2 is OpenRouter Qwen3.7 Plus.** `pi-qwen3-7-plus-openrouter`
229
+ (`openrouter/qwen/qwen3.7-plus`) replaces `pi-qwen3-coder-plus-openrouter`.
230
+ OpenRouter no longer lists `qwen/qwen3-coder-plus`. The live catalog on
231
+ 2026-10-17 prices Qwen3.7 Plus at $0.32 input and $1.28 output per 1M
232
+ tokens, with a 1,000,000-token context and tool support. The old model
233
+ file stays `status: retired`, off every roster, and `qwen-openrouter-pi`
234
+ no longer resolves. `.kxm/prices.yaml` keeps the last Coder Plus row and
235
+ adds the Qwen3.7 Plus base tier. The dev helper's only Pi writer is
236
+ `openrouter/qwen/qwen3.7-plus`.
219
237
  - **The CLI critic is Codex GPT-6.1 Sol.** `codex-gpt-6-1-sol` is the
220
238
  `reviewer-cli` primary (`codex` / `gpt-6.1-sol`, effort `low`).
221
239
  `pi-qwen3-8-flash-openrouter` stays the other-vendor fallback, and
@@ -34,7 +34,7 @@ admits each route for specific roles and permissions:
34
34
 
35
35
  | Role | Admitted route (harness / model) | Vendor | Permission |
36
36
  |---|---|---|---|
37
- | `writer` | `grok` / `grok-4.7`; relief: `pi` / `openrouter/qwen/qwen3-coder-plus`; `agy` / `gemini-4-argon-high`, then `gemini-4-argon-medium`, then `gemini-3.8-flash-medium`, then `gemini-3.8-flash-high` | `xai`; `alibaba`; `google` | `edit` |
37
+ | `writer` | `grok` / `grok-4.7`; relief: `pi` / `openrouter/qwen/qwen3.7-plus`; `agy` / `gemini-4-argon-high`, then `gemini-4-argon-medium`, then `gemini-3.8-flash-medium`, then `gemini-3.8-flash-high` | `xai`; `alibaba`; `google` | `edit` |
38
38
  | `planner` | `claude` / `fable` | `anthropic` | `read-only` |
39
39
  | `reviewer-arch` | `claude` / `fable` | `anthropic` | `read-only` |
40
40
  | `reviewer-cli` | `codex` / `gpt-6.1-sol`; fallback `pi` / `openrouter/qwen/qwen3.8-flash`, then `codex` / `gpt-5.6-sol` | `openai`; `alibaba`; `openai` | `read-only` |
@@ -347,7 +347,7 @@ and exits with status 2. It refuses when:
347
347
  segment must not be a braked native vendor (`x-ai`, `moonshotai` and
348
348
  `google-ai` count as `xai`, `moonshot` and `google`);
349
349
  - a Pi `edit` request comes from a role other than `experiment` or `writer`, or
350
- a Pi writer asks for anything but `openrouter/qwen/qwen3-coder-plus` with
350
+ a Pi writer asks for anything but `openrouter/qwen/qwen3.7-plus` with
351
351
  `edit`;
352
352
  - the request asks for hooks or skills, sets `max_cost_usd` for a harness other
353
353
  than Claude, or sets `max_turns` for a harness other than Grok;
@@ -46,6 +46,7 @@ together.
46
46
  | Push to `main`, or manual | `ci.yml` (Validate matrix) | `validate:pr` on Linux and Windows for Node 22.19.0 and Node 24; not on a pull request |
47
47
  | Code pull request and code push | `ci.yml` (Plugin validation) | `claude plugin validate --strict` on the marketplace and the plugin |
48
48
  | Daily at 04:00 UTC, or manual | `nightly.yml` | `test:coverage:complete`, `check`, `check:generated`, `npm pack --dry-run` |
49
+ | Monday at 13:00 UTC, or manual | `refresh-models.yml` | Fetches the public OpenRouter catalog, and opens or updates one pull request on `automation/model-refresh` when `.kxm/prices.yaml` or `.kxm/models/inventory.yaml` changes. Uses `GITHUB_TOKEN` only, then dispatches `ci.yml` on that branch |
49
50
  | Merged pull request | `auto-release.yml` | Tags the merge commit and dispatches `release.yml` |
50
51
  | Tag push or dispatch | `release.yml` | Verifies, packs and publishes (see [Release flow](#release-flow)) |
51
52
  | Manual only | `smoke.yml` | Real Pi smoke, currently disabled (see [Smoke tests](#smoke-tests)) |
@@ -269,7 +270,7 @@ The real Pi smoke calls paid models, so it never runs by default. Its workflow,
269
270
  `KXM_SMOKE_RUNNER` names a runner with Pi credentials. Both smoke models run as
270
271
  long-lived Pi workers, so each must pass the Pi native-vendor brake: pick two
271
272
  non-native routes such as
272
- `openrouter/qwen/qwen3-coder-plus,openrouter/z-ai/glm-5.3-flash`, never `xai/…`
273
+ `openrouter/qwen/qwen3.7-plus,openrouter/z-ai/glm-5.3-flash`, never `xai/…`
273
274
  or `anthropic/…`. The container smoke needs
274
275
  Docker, a `pass-cli` session and a local Pi model store. It keeps secrets in a
275
276
  mode-600 file inside a temporary directory; set `KXM_SMOKE_VAULT` to read keys
@@ -400,6 +400,28 @@ authentication are the protocol. A change to any of them needs:
400
400
  Prefer additive changes. KXM does not keep backward-compatible aliases for
401
401
  retired names: an old name fails closed instead.
402
402
 
403
+ ## Refresh model prices and inventory
404
+
405
+ OpenRouter list prices and the model inventory are refreshed by
406
+ `.github/workflows/refresh-models.yml` every Monday at 13:00 UTC. To run the
407
+ same refresh before that, from the repository root:
408
+
409
+ ```bash
410
+ node --disable-warning=ExperimentalWarning --experimental-strip-types scripts/refresh-model-catalog.mjs --dry-run
411
+ ```
412
+
413
+ `--dry-run` prints models added, removed, and repriced, and writes nothing.
414
+ Drop `--dry-run` to update `.kxm/prices.yaml` and `.kxm/models/inventory.yaml`.
415
+ Exit 2 means a model named by `.kxm/routes.yaml` or a roster left the OpenRouter
416
+ catalog; the refresh keeps that inventory row and sets `missingUpstream: true`.
417
+ Review the diff and commit it yourself, or wait for the Monday pull request on
418
+ `automation/model-refresh`. The field reference is
419
+ [Weekly OpenRouter refresh](../reference/config-reference.md#weekly-openrouter-refresh).
420
+
421
+ `kxm models inventory-refresh` still rewrites the whole inventory from Pi, Grok,
422
+ agy, OpenRouter, and Nous, including a new `fetchedAt` timestamp. The weekly
423
+ script does not call those local CLIs.
424
+
403
425
  ## Troubleshooting
404
426
 
405
427
  | Symptom | Cause | Fix |
@@ -9,7 +9,7 @@ This page records how the KXM repository applies [harness routing](../reference/
9
9
 
10
10
  The files use one id shape per kind. A route id is `<harness>-<model-slug>[-<provider>]`, with `.` written as `-`. An agent id equals its role. A workflow id is `default`, `land`, or `<role>-only`. An agent step id equals that role.
11
11
 
12
- This checkout's routes are `grok-grok-4-7`, `pi-qwen3-coder-plus-openrouter`, `agy-gemini-4-argon-high`, `agy-gemini-4-argon-medium`, `agy-gemini-3-8-flash-medium`, `agy-gemini-3-8-flash-high`, `claude-fable`, `codex-gpt-6-1-sol`, `codex-gpt-5-6-sol`, `pi-qwen3-8-flash-openrouter`, and `pi-glm-5-3-flash-openrouter`. Agents are `planner`, `writer`, `reviewer-arch`, and `reviewer-cli`. `opus-claude` was removed because `opus` is not an admitted selector. `qwen-token-plan/*` and `zai-coding-cn/*` left the admitted list because those harnesses are not allowlisted; their `prices.yaml` rows stay. Old ids resolve as aliases. Every roster entry names an effort. `reviewer-arch` dispatches `claude-fable`. #343's architecture critic ran on opus because the justfile recipe review-arch hardcoded that model; the role file on that commit listed only `fable-claude`. The helper now refuses `opus`.
12
+ This checkout's admitted routes are `grok-grok-4-7`, `pi-qwen3-7-plus-openrouter`, `agy-gemini-4-argon-high`, `agy-gemini-4-argon-medium`, `agy-gemini-3-8-flash-medium`, `agy-gemini-3-8-flash-high`, `claude-fable`, `codex-gpt-6-1-sol`, `codex-gpt-5-6-sol`, `pi-qwen3-8-flash-openrouter`, and `pi-glm-5-3-flash-openrouter`. `pi-qwen3-coder-plus-openrouter` stays on disk with `status: retired` because OpenRouter removed `qwen/qwen3-coder-plus` (catalog 404); it is not admitted and not on a roster, and `qwen-openrouter-pi` does not resolve. Agents are `planner`, `writer`, `reviewer-arch`, and `reviewer-cli`. `opus-claude` was removed because `opus` is not an admitted selector. `qwen-token-plan/*` and `zai-coding-cn/*` left the admitted list because those harnesses are not allowlisted; their `prices.yaml` rows stay. Other old ids resolve as aliases. Every roster entry names an effort. `reviewer-arch` dispatches `claude-fable`. #343's architecture critic ran on opus because the justfile recipe review-arch hardcoded that model; the role file on that commit listed only `fable-claude`. The helper now refuses `opus`.
13
13
 
14
14
  ## This checkout's routes and roster
15
15
 
@@ -25,7 +25,7 @@ skills: []
25
25
  roster:
26
26
  - route: grok-grok-4-7
27
27
  effort: medium
28
- - route: pi-qwen3-coder-plus-openrouter
28
+ - route: pi-qwen3-7-plus-openrouter
29
29
  effort: medium
30
30
  - route: agy-gemini-4-argon-high
31
31
  effort: medium
@@ -37,7 +37,7 @@ roster:
37
37
  effort: medium
38
38
  ```
39
39
 
40
- The writer role lists route ids, in order: `grok-grok-4-7`, then `pi-qwen3-coder-plus-openrouter`, then `agy-gemini-4-argon-high`, `agy-gemini-4-argon-medium`, `agy-gemini-3-8-flash-medium`, and `agy-gemini-3-8-flash-high`. `grok-grok-4-7` is harness `grok`, model `grok-4.7`, vendor `xai`. An agent file does not declare `harness:`. Argon is writer #3 and #4. Flash medium is the safety net because Argon needs a paid Google AI Pro, Ultra, or Enterprise plan and `agy -p` exits when the pinned model is missing. Flash high stays on the roster so that admitted model file is still used. The planner primary stays `claude-fable`. The CLI critic primary is `codex-gpt-6-1-sol`, then `pi-qwen3-8-flash-openrouter`, then `codex-gpt-5-6-sol`. The architecture critic primary stays `claude-fable`, then `pi-glm-5-3-flash-openrouter`. Argon can serve as a planner or architecture-review fallback; it is not on those rosters. GPT-6.1 Sol Pro is the same model with reasoning mode `pro`. The route id does not carry a reasoning mode, role effort has no `pro` value, and codex is limited to `reviewer-cli`, so that mode is not an architecture fallback.
40
+ The writer role lists route ids, in order: `grok-grok-4-7`, then `pi-qwen3-7-plus-openrouter`, then `agy-gemini-4-argon-high`, `agy-gemini-4-argon-medium`, `agy-gemini-3-8-flash-medium`, and `agy-gemini-3-8-flash-high`. `grok-grok-4-7` is harness `grok`, model `grok-4.7`, vendor `xai`. An agent file does not declare `harness:`. Argon is writer #3 and #4. Flash medium is the safety net because Argon needs a paid Google AI Pro, Ultra, or Enterprise plan and `agy -p` exits when the pinned model is missing. Flash high stays on the roster so that admitted model file is still used. The planner primary stays `claude-fable`. The CLI critic primary is `codex-gpt-6-1-sol`, then `pi-qwen3-8-flash-openrouter`, then `codex-gpt-5-6-sol`. The architecture critic primary stays `claude-fable`, then `pi-glm-5-3-flash-openrouter`. Argon can serve as a planner or architecture-review fallback; it is not on those rosters. GPT-6.1 Sol Pro is the same model with reasoning mode `pro`. The route id does not carry a reasoning mode, role effort has no `pro` value, and codex is limited to `reviewer-cli`, so that mode is not an architecture fallback.
41
41
 
42
42
  `node scripts/kxm.mjs routes list`:
43
43
 
@@ -49,7 +49,7 @@ admitted google/gemini-4-argon-high
49
49
  admitted google/gemini-4-argon-medium
50
50
  admitted openai/gpt-5.6-sol
51
51
  admitted openai/gpt-6.1-sol
52
- admitted openrouter/qwen/qwen3-coder-plus
52
+ admitted openrouter/qwen/qwen3.7-plus
53
53
  admitted openrouter/qwen/qwen3.8-flash
54
54
  admitted openrouter/z-ai/glm-5.3-flash
55
55
  admitted xai/grok-4.7
@@ -61,14 +61,14 @@ reviewer-cli codex-gpt-6-1-sol
61
61
  reviewer-cli pi-qwen3-8-flash-openrouter
62
62
  reviewer-cli codex-gpt-5-6-sol
63
63
  writer grok-grok-4-7
64
- writer pi-qwen3-coder-plus-openrouter
64
+ writer pi-qwen3-7-plus-openrouter
65
65
  writer agy-gemini-4-argon-high
66
66
  writer agy-gemini-4-argon-medium
67
67
  writer agy-gemini-3-8-flash-medium
68
68
  writer agy-gemini-3-8-flash-high
69
69
  ```
70
70
 
71
- `routes admit --model openrouter/qwen/qwen3-coder-plus --dry-run` exits 2 with `select a model from the refreshed inventory` even though that selector is already admitted, because the inventory never carries `openrouter/…` selectors. Selectors like these are admitted by a Git-reviewed edit of `.kxm/routes.yaml`.
71
+ `routes admit --model openrouter/qwen/qwen3.7-plus --dry-run` exits 2 with `select a model from the refreshed inventory` even though that selector is already admitted, because the inventory never carries `openrouter/…` selectors. Selectors like these are admitted by a Git-reviewed edit of `.kxm/routes.yaml`.
72
72
 
73
73
  On the capture machine, `kxm harness list` showed `claude` detected but logged out (`dispatch no (not_authenticated)`), `deepseek` not installed, and `grok`, `codex`, `kimi` and `agy` ready.
74
74
 
@@ -85,9 +85,9 @@ The issue-127 runner (`kxm assign`, see the [assignment runner](assignment-runne
85
85
  harness: grok
86
86
  model: grok-4.7
87
87
  vendor: xai
88
- pi-qwen3-coder-plus-openrouter:
88
+ pi-qwen3-7-plus-openrouter:
89
89
  harness: pi
90
- model: openrouter/qwen/qwen3-coder-plus
90
+ model: openrouter/qwen/qwen3.7-plus
91
91
  vendor: alibaba
92
92
  ```
93
93
 
@@ -108,7 +108,7 @@ The product layers are in [What the brake refuses](../reference/harness-routing.
108
108
 
109
109
  | Layer | Where | What it refuses | What you see |
110
110
  |---|---|---|---|
111
- | Dev helper | `scripts/harness-run.mjs` | A braked Pi provider, a Pi provider outside the allowlist, a Pi writer other than `openrouter/qwen/qwen3-coder-plus`, or an aggregator id whose vendor segment is a native vendor | `pi brake: xai has a native harness; refusing Pi impersonation`, or `… refusing to bill it through openrouter` |
111
+ | Dev helper | `scripts/harness-run.mjs` | A braked Pi provider, a Pi provider outside the allowlist, a Pi writer other than `openrouter/qwen/qwen3.7-plus`, or an aggregator id whose vendor segment is a native vendor | `pi brake: xai has a native harness; refusing Pi impersonation`, or `… refusing to bill it through openrouter` |
112
112
  | Developer roster | `scripts/roster-policy.mjs` | An aggregator route whose vendor segment is a native vendor | `Roster policy refused: native vendor cannot use Pi` |
113
113
 
114
114
  The dev helper's allowlist (`openrouter`, `nous-portal`, `antigravity`) is a different list from `PI_ALLOWED_PROVIDERS` in `plugins/kxm/src/harness.ts`, which gates nothing. Which of the two should govern is an open decision (Tracking → Still open). Edit permission exists only in the dev helper, and only for admitted writer or experiment routes. The helper accepts only a ChatGPT login for codex, not an API key.
@@ -129,7 +129,7 @@ These extend the generic examples on the reference page with this checkout's adm
129
129
  | Billing | grok.com subscription (OAuth) | $2.00 input, $6.00 output, $0.50 cached input |
130
130
  | Context | 500,000 (`x-ai/grok-4.7` in the refreshed inventory) | 500,000 |
131
131
 
132
- Pi's own `xai` provider reported `ready` (OAuth) on the capture machine. When the grok quota runs out, the next writer in the lineup is `pi-qwen3-coder-plus-openrouter`, a different vendor.
132
+ Pi's own `xai` provider reported `ready` (OAuth) on the capture machine. When the grok quota runs out, the next writer in the lineup is `pi-qwen3-7-plus-openrouter`, a different vendor.
133
133
 
134
134
  ### GPT-6.1 Sol
135
135
 
@@ -177,11 +177,11 @@ The code differs from that decision: `.kxm/routes.yaml` admits `google/gemini-3.
177
177
  | Model | Vendor-plan route | OpenRouter route | Notes |
178
178
  |---|---|---|---|
179
179
  | Qwen3.8 Flash | `qwen-token-plan/qwen3.8-flash`: removed from the admitted list on 2026-09-27; `qwen-token-plan` is not allowlisted | `openrouter/qwen/qwen3.8-flash`: admitted, route `pi-qwen3-8-flash-openrouter`, read-only fallback for planner and reviewer-cli | `prices.yaml` keeps both rows. |
180
- | Qwen3 Coder Plus | none | `openrouter/qwen/qwen3-coder-plus`: route `pi-qwen3-coder-plus-openrouter` | The only admitted Pi writer: exact model, `edit` permission. |
180
+ | Qwen3.7 Plus | none | `openrouter/qwen/qwen3.7-plus`: route `pi-qwen3-7-plus-openrouter`, writer #2 | The only admitted Pi writer: exact model, `edit` permission. OpenRouter list on 2026-10-17 is $0.32 input and $1.28 output per 1M tokens, 1,000,000 context, tools supported. |
181
181
  | GLM 5.3 and 5.3 Flash | `zai-coding-cn/glm-5.3` and `…/glm-5.3-flash`: removed from the admitted list on 2026-09-27; `zai-coding-cn` is not allowlisted | `openrouter/z-ai/glm-5.3-flash`: admitted, route `pi-glm-5-3-flash-openrouter`, read-only fallback for reviewer-arch | Z.ai has no native harness. |
182
182
  | DeepSeek V4.1 Flash | `qwen-token-plan/deepseek-v4.1-flash`: removed from the admitted list on 2026-09-27 | `deepseek/deepseek-v4.1-flash` in the OpenRouter feed | Bills a DeepSeek model through Alibaba's plan. `deepseek` is a native-vendor Pi brake, so this is not a route. |
183
183
 
184
- The developer runner is stricter. Its only Pi writer is `openrouter/qwen/qwen3-coder-plus`, and it does not allowlist `qwen-token-plan` or `zai-coding-cn`. Today OpenRouter is the right answer here for Qwen3 Coder Plus, Qwen3.8 Flash and GLM 5.3 Flash.
184
+ The developer runner is stricter. Its only Pi writer is `openrouter/qwen/qwen3.7-plus`, and it does not allowlist `qwen-token-plan` or `zai-coding-cn`. Today OpenRouter is the right answer here for Qwen3.7 Plus, Qwen3.8 Flash and GLM 5.3 Flash. `qwen/qwen3-coder-plus` is retired.
185
185
 
186
186
  ### Nous
187
187
 
package/docs/glossary.md CHANGED
@@ -427,7 +427,7 @@ A list of allowed models. It means either a [role](#role)'s roster, or the devel
427
427
 
428
428
  ### Route
429
429
 
430
- A model selector, such as `xai/grok-4.6` or `openrouter/qwen/qwen3-coder-plus`, that a step can run on. The harness that runs it comes from the agent or the project default. See [Harness routing](reference/harness-routing.md).
430
+ A model selector, such as `xai/grok-4.6` or `openrouter/qwen/qwen3.7-plus`, that a step can run on. The harness that runs it comes from the agent or the project default. See [Harness routing](reference/harness-routing.md).
431
431
 
432
432
  ### Session
433
433
 
@@ -61,7 +61,7 @@ Write the procedure as a Markdown file. KXM adds `name` and `description` front
61
61
  ```bash
62
62
  kxm skills create --file flaky.md --name "Triage flaky test" \
63
63
  --description "Isolate and classify a flaky test before changing code" \
64
- --created-by agent-a --harness pi --models openrouter/qwen/qwen3-coder-plus \
64
+ --created-by agent-a --harness pi --models openrouter/qwen/qwen3.7-plus \
65
65
  --journal journal_abc
66
66
  ```
67
67
 
@@ -82,7 +82,7 @@ When no unused fallback remains, the worker waits `KXM_WORKER_PROVIDER_RETRY_MS`
82
82
  > [!IMPORTANT]
83
83
  > A worker refuses to start on a model whose vendor has its own native harness. Before Pi starts, the worker runs `--model` and every `--fallback-models` entry through the Pi native-vendor brake, and exits 1 with `pi_native_impersonation_blocked` on the first one it refuses: a native provider (`xai/…`), that vendor's own Pi provider (`openai-codex/…`, `kimi-coding/…`), or an aggregator path to it (`openrouter/x-ai/…`). `--dry-run` does not run this check.
84
84
 
85
- Pick every model with [Harness routing](../reference/harness-routing.md), for example `openrouter/qwen/qwen3-coder-plus` with the fallback `openrouter/z-ai/glm-5.3-flash`. The brake cannot check a worker started without `--model`, which runs Pi's default model, or a bare model id that lets Pi choose the provider, so name the provider.
85
+ Pick every model with [Harness routing](../reference/harness-routing.md), for example `openrouter/qwen/qwen3.7-plus` with the fallback `openrouter/z-ai/glm-5.3-flash`. The brake cannot check a worker started without `--model`, which runs Pi's default model, or a bare model id that lets Pi choose the provider, so name the provider.
86
86
 
87
87
  An agent name is only a label. To use a native-harness model as a peer, connect that harness to the hub under the agent name instead, for example the Claude Code plugin with the name `reviewer-claude`.
88
88
 
@@ -203,7 +203,7 @@ kxm hub stop
203
203
  | `KXM worker <project>/<name> is already managed by PID <pid>` | A supervisor for this agent is already running. | Use the running worker, or stop it first. |
204
204
  | The worker exits with `worker requires --name and --project` | Name or project missing. | Pass `--name` and `--project`, or set `KXM_AGENT_NAME` and `KXM_PROJECT`. |
205
205
  | `KXM_WORKER_FALLBACK_MODELS requires KXM_WORKER_MODEL` | Fallbacks without a primary model. | Add `--model`. |
206
- | The worker exits 1 with `pi_native_impersonation_blocked: …` | `--model` or a fallback is a model whose vendor has its own harness. | Run that model in its native harness, or use an admitted Pi route such as `openrouter/qwen/qwen3-coder-plus`. |
206
+ | The worker exits 1 with `pi_native_impersonation_blocked: …` | `--model` or a fallback is a model whose vendor has its own harness. | Run that model in its native harness, or use an admitted Pi route such as `openrouter/qwen/qwen3.7-plus`. |
207
207
  | `kxm connection failed` in the Pi log, or Pi shows `hub:off` | Wrong URL, token, or project, or the name is live elsewhere (`duplicate_agent_name`). | Compare `KXM_SERVER_URL`, `KXM_AUTH_TOKEN`, and `KXM_PROJECT` with the hub; check `kxm peer list`. |
208
208
  | Workflow runs share one conversation | Isolation is `off`, the default. | Restart with `--session-isolation workflow`. |
209
209
  | A request stays `delivered` | A turn, tool, or provider call is still running, or the watchdogs are recovering it. | Read the lifecycle log. Do not send a duplicate. |
@@ -173,7 +173,7 @@ kxm agent worker --name reviewer-grok --project provenance-demo --model <reviewe
173
173
  </details>
174
174
 
175
175
  > [!IMPORTANT]
176
- > The reviewer names are labels. Choose every Pi model with [Harness routing](../reference/harness-routing.md), for example `openrouter/qwen/qwen3-coder-plus` and `openrouter/z-ai/glm-5.3-flash` for two reviewers from different vendors. A worker refuses a model whose vendor has its own native harness, such as Anthropic or xAI, with `pi_native_impersonation_blocked`. To use such a model as a reviewer, connect its native harness under the same agent name instead, for example the Claude Code plugin as `reviewer-claude`.
176
+ > The reviewer names are labels. Choose every Pi model with [Harness routing](../reference/harness-routing.md), for example `openrouter/qwen/qwen3.7-plus` and `openrouter/z-ai/glm-5.3-flash` for two reviewers from different vendors. A worker refuses a model whose vendor has its own native harness, such as Anthropic or xAI, with `pi_native_impersonation_blocked`. To use such a model as a reviewer, connect its native harness under the same agent name instead, for example the Claude Code plugin as `reviewer-claude`.
177
177
 
178
178
  In an operator terminal, supply the workflow-start secret, validate the definition, and create a run:
179
179
 
@@ -134,7 +134,7 @@ The [plugin troubleshooting guide](../../plugins/kxm/README.md#troubleshooting)
134
134
  | The heartbeat is healthy but one tool never finishes | A tool exceeded `KXM_WORKER_TOOL_TIMEOUT_MS` (31 minutes by default, above the 30-minute fanout wait) | The worker logs `worker_tool_timeout` and restarts the child; raise the limit only above the longest legitimate call |
135
135
  | A long-lived worker keeps restarting | Pi is missing from the service `PATH`, the working directory is gone, or model credentials are missing | Read `worker_process_error` and `worker_exited`; set `KXM_PI_COMMAND` to an explicit path |
136
136
  | A read-only reviewer edits files | Prompt wording does not remove tools | Set `KXM_WORKER_TOOLS=read,grep,find,ls` |
137
- | The worker exits at once with `pi_native_impersonation_blocked` | `--model` or a `--fallback-models` entry is a model whose vendor has its own harness, such as `xai/…`, `openai-codex/…` or `openrouter/x-ai/…` | Run that model in its native harness, or pick an admitted Pi route such as `openrouter/qwen/qwen3-coder-plus`; see [Harness routing](../reference/harness-routing.md#what-the-brake-refuses) |
137
+ | The worker exits at once with `pi_native_impersonation_blocked` | `--model` or a `--fallback-models` entry is a model whose vendor has its own harness, such as `xai/…`, `openai-codex/…` or `openrouter/x-ai/…` | Run that model in its native harness, or pick an admitted Pi route such as `openrouter/qwen/qwen3.7-plus`; see [Harness routing](../reference/harness-routing.md#what-the-brake-refuses) |
138
138
 
139
139
  Use `--fresh-start`, not `--no-continue`, when only the first launch must avoid old session state.
140
140
 
@@ -1157,7 +1157,7 @@ admitted google/gemini-4-argon-high
1157
1157
  admitted google/gemini-4-argon-medium
1158
1158
  admitted openai/gpt-5.6-sol
1159
1159
  admitted openai/gpt-6.1-sol
1160
- admitted openrouter/qwen/qwen3-coder-plus
1160
+ admitted openrouter/qwen/qwen3.7-plus
1161
1161
  admitted openrouter/qwen/qwen3.8-flash
1162
1162
  admitted openrouter/z-ai/glm-5.3-flash
1163
1163
  admitted xai/grok-4.7
@@ -1169,7 +1169,7 @@ reviewer-cli codex-gpt-6-1-sol
1169
1169
  reviewer-cli pi-qwen3-8-flash-openrouter
1170
1170
  reviewer-cli codex-gpt-5-6-sol
1171
1171
  writer grok-grok-4-7
1172
- writer pi-qwen3-coder-plus-openrouter
1172
+ writer pi-qwen3-7-plus-openrouter
1173
1173
  writer agy-gemini-4-argon-high
1174
1174
  writer agy-gemini-4-argon-medium
1175
1175
  writer agy-gemini-3-8-flash-medium
@@ -1181,7 +1181,7 @@ kxm routes list --json
1181
1181
  ```
1182
1182
 
1183
1183
  ```text
1184
- {"schema":"kxm.cli-result.v1","ok":true,"command":"routes list","policy":{"schema":"kxm.routes.v2","updatedAt":"2026-10-17T14:30:00.000Z","admitted":["anthropic/fable","google/gemini-3.8-flash-high","google/gemini-3.8-flash-medium","google/gemini-4-argon-high","google/gemini-4-argon-medium","openai/gpt-5.6-sol","openai/gpt-6.1-sol","openrouter/qwen/qwen3-coder-plus","openrouter/qwen/qwen3.8-flash","openrouter/z-ai/glm-5.3-flash","xai/grok-4.7"],"disabled":[]},"membership":["planner claude-fable","planner pi-qwen3-8-flash-openrouter","reviewer-arch claude-fable","reviewer-arch pi-glm-5-3-flash-openrouter","reviewer-cli codex-gpt-6-1-sol","reviewer-cli pi-qwen3-8-flash-openrouter","reviewer-cli codex-gpt-5-6-sol","writer grok-grok-4-7","writer pi-qwen3-coder-plus-openrouter","writer agy-gemini-4-argon-high","writer agy-gemini-4-argon-medium","writer agy-gemini-3-8-flash-medium","writer agy-gemini-3-8-flash-high"]}
1184
+ {"schema":"kxm.cli-result.v1","ok":true,"command":"routes list","policy":{"schema":"kxm.routes.v2","updatedAt":"2026-10-17T14:30:00.000Z","admitted":["anthropic/fable","google/gemini-3.8-flash-high","google/gemini-3.8-flash-medium","google/gemini-4-argon-high","google/gemini-4-argon-medium","openai/gpt-5.6-sol","openai/gpt-6.1-sol","openrouter/qwen/qwen3.7-plus","openrouter/qwen/qwen3.8-flash","openrouter/z-ai/glm-5.3-flash","xai/grok-4.7"],"disabled":[]},"membership":["planner claude-fable","planner pi-qwen3-8-flash-openrouter","reviewer-arch claude-fable","reviewer-arch pi-glm-5-3-flash-openrouter","reviewer-cli codex-gpt-6-1-sol","reviewer-cli pi-qwen3-8-flash-openrouter","reviewer-cli codex-gpt-5-6-sol","writer grok-grok-4-7","writer pi-qwen3-7-plus-openrouter","writer agy-gemini-4-argon-high","writer agy-gemini-4-argon-medium","writer agy-gemini-3-8-flash-medium","writer agy-gemini-3-8-flash-high"]}
1185
1185
  ```
1186
1186
 
1187
1187
  ### `kxm routes count`
@@ -1386,7 +1386,7 @@ kxm role get writer --json
1386
1386
  ```
1387
1387
 
1388
1388
  ```text
1389
- {"schema":"kxm.cli-result.v1","ok":true,"command":"role get","roleId":"writer","scope":"local","filePath":"/work/kxm/.kxm/roles/writer.yaml","role":{"schema":"kxm.role.v2","id":"writer","purpose":"writer","permission":"edit","description":"Primary implementation agent.","skills":[],"roster":[{"route":"grok-grok-4-7","effort":"medium"},{"route":"pi-qwen3-coder-plus-openrouter","effort":"medium"},{"route":"agy-gemini-4-argon-high","effort":"medium"},{"route":"agy-gemini-4-argon-medium","effort":"medium"},{"route":"agy-gemini-3-8-flash-medium","effort":"medium"},{"route":"agy-gemini-3-8-flash-high","effort":"medium"}]}}
1389
+ {"schema":"kxm.cli-result.v1","ok":true,"command":"role get","roleId":"writer","scope":"local","filePath":"/work/kxm/.kxm/roles/writer.yaml","role":{"schema":"kxm.role.v2","id":"writer","purpose":"writer","permission":"edit","description":"Primary implementation agent.","skills":[],"roster":[{"route":"grok-grok-4-7","effort":"medium"},{"route":"pi-qwen3-7-plus-openrouter","effort":"medium"},{"route":"agy-gemini-4-argon-high","effort":"medium"},{"route":"agy-gemini-4-argon-medium","effort":"medium"},{"route":"agy-gemini-3-8-flash-medium","effort":"medium"},{"route":"agy-gemini-3-8-flash-high","effort":"medium"}]}}
1390
1390
  ```
1391
1391
 
1392
1392
  Captured from this checkout with `node scripts/kxm.mjs role get writer --json`. The path is shortened to `/work/kxm`.
@@ -1396,7 +1396,7 @@ kxm role modify writer --add-skill kxm --dry-run --json
1396
1396
  ```
1397
1397
 
1398
1398
  ```text
1399
- {"schema":"kxm.cli-result.v1","ok":true,"command":"role modify","roleId":"writer","id":"writer","role":{"schema":"kxm.role.v2","id":"writer","purpose":"writer","permission":"edit","description":"Primary implementation agent.","skills":["kxm"],"roster":[{"route":"grok-grok-4-7","effort":"medium"},{"route":"pi-qwen3-coder-plus-openrouter","effort":"medium"},{"route":"agy-gemini-4-argon-high","effort":"medium"},{"route":"agy-gemini-4-argon-medium","effort":"medium"},{"route":"agy-gemini-3-8-flash-medium","effort":"medium"},{"route":"agy-gemini-3-8-flash-high","effort":"medium"}]},"filePath":"/work/kxm/.kxm/roles/writer.yaml","scope":"local","dryRun":true,"planned":[{"action":"write","target":"/work/kxm/.kxm/roles/writer.yaml"}]}
1399
+ {"schema":"kxm.cli-result.v1","ok":true,"command":"role modify","roleId":"writer","id":"writer","role":{"schema":"kxm.role.v2","id":"writer","purpose":"writer","permission":"edit","description":"Primary implementation agent.","skills":["kxm"],"roster":[{"route":"grok-grok-4-7","effort":"medium"},{"route":"pi-qwen3-7-plus-openrouter","effort":"medium"},{"route":"agy-gemini-4-argon-high","effort":"medium"},{"route":"agy-gemini-4-argon-medium","effort":"medium"},{"route":"agy-gemini-3-8-flash-medium","effort":"medium"},{"route":"agy-gemini-3-8-flash-high","effort":"medium"}]},"filePath":"/work/kxm/.kxm/roles/writer.yaml","scope":"local","dryRun":true,"planned":[{"action":"write","target":"/work/kxm/.kxm/roles/writer.yaml"}]}
1400
1400
  ```
1401
1401
 
1402
1402
  Add an existing route to a role's roster (Not run):
@@ -2014,11 +2014,11 @@ Starts a long-lived, supervised Pi RPC worker in the foreground through `scripts
2014
2014
  - Needs Pi and a reachable hub. Runs until stopped (`kxm hub stop` stops managed workers too). The exit code is the worker's.
2015
2015
  - A name and project are required (exit 2 otherwise); an invalid isolation mode exits 2.
2016
2016
  - `--dry-run` prints a `kxm.worker-result.v1` envelope with `workspace`, `name`, `project`, `model`, `fallbackModels`, `tools`, `sessionIsolation`, `continue`, `freshStart`.
2017
- - Before Pi starts, the worker runs `--model` and every `--fallback-models` entry through the Pi native-vendor brake. A model whose vendor has its own harness (for example `xai/…`, `openai-codex/…`, `openrouter/x-ai/…` or `antigravity/claude-…`) exits 1 with `pi_native_impersonation_blocked: <message>` on stderr; use the native harness, or an admitted Pi route such as `openrouter/qwen/qwen3-coder-plus`. `--dry-run` does not run this check. See [Harness routing](harness-routing.md#what-the-brake-refuses).
2017
+ - Before Pi starts, the worker runs `--model` and every `--fallback-models` entry through the Pi native-vendor brake. A model whose vendor has its own harness (for example `xai/…`, `openai-codex/…`, `openrouter/x-ai/…` or `antigravity/claude-…`) exits 1 with `pi_native_impersonation_blocked: <message>` on stderr; use the native harness, or an admitted Pi route such as `openrouter/qwen/qwen3.7-plus`. `--dry-run` does not run this check. See [Harness routing](harness-routing.md#what-the-brake-refuses).
2018
2018
  - The remaining worker variables are described in [Long-lived worker settings](configuration.md#long-lived-worker-settings).
2019
2019
 
2020
2020
  ```bash
2021
- kxm agent worker --name reviewer --project demo --model openrouter/qwen/qwen3-coder-plus --tools read,grep,find,ls --session-isolation workflow --fresh-start --dry-run
2021
+ kxm agent worker --name reviewer --project demo --model openrouter/qwen/qwen3.7-plus --tools read,grep,find,ls --session-isolation workflow --fresh-start --dry-run
2022
2022
  ```
2023
2023
 
2024
2024
  ```text
@@ -2026,7 +2026,7 @@ would start worker
2026
2026
  ```
2027
2027
 
2028
2028
  ```bash
2029
- kxm agent worker --name coordinator --project demo --model openrouter/qwen/qwen3-coder-plus --session-isolation workflow
2029
+ kxm agent worker --name coordinator --project demo --model openrouter/qwen/qwen3.7-plus --session-isolation workflow
2030
2030
  ```
2031
2031
 
2032
2032
  Not run: starts a long-lived Pi worker.
@@ -3362,7 +3362,7 @@ Submit a skill candidate from verified episodes.
3362
3362
  - Writes a candidate. Honors `--dry-run`. JSON keys: `metadata` (or `name` for a dry run).
3363
3363
 
3364
3364
  ```bash
3365
- kxm skills create --file SKILL.md --name retry-backoff --created-by alice --harness pi --models openrouter/qwen/qwen3-coder-plus --run wf_123 --dry-run --json
3365
+ kxm skills create --file SKILL.md --name retry-backoff --created-by alice --harness pi --models openrouter/qwen/qwen3.7-plus --run wf_123 --dry-run --json
3366
3366
  ```
3367
3367
 
3368
3368
  ```text
@@ -3627,7 +3627,7 @@ Dedicated offline benchmark for side-by-side model comparison (Decision Q12). To
3627
3627
  | Option | Argument | Default | Description |
3628
3628
  |---|---|---|---|
3629
3629
  | `--task` | `<fixture>` | `Deterministic benchmark task` | Task prompt or fixture path for benchmark comparison |
3630
- | `--arms` | `<models>` | `grok/grok-4.6,claude/fable,pi/qwen3-coder-plus` | Comma-separated model routes to benchmark (e.g. grok/grok-4.6,claude/fable) |
3630
+ | `--arms` | `<models>` | `grok/grok-4.6,claude/fable,pi/qwen3.7-plus` | Comma-separated model routes to benchmark (e.g. grok/grok-4.6,claude/fable) |
3631
3631
  | `--runs` | `<count>` | `1` | Benchmark runs per arm |
3632
3632
 
3633
3633
  - Reads nothing. JSON keys: `task`, `runs`, `timestamp`, `arms` (`harness`, `model`, `latencyMs`, `tokensIn`, `tokensOut`, `costUsd`, `outcome`).
@@ -3641,7 +3641,7 @@ Routing Benchmark Results (task: Deterministic benchmark task, runs: 1)
3641
3641
  Harness Model Latency(ms) TokensIn TokensOut Cost($) Outcome
3642
3642
  grok grok-4.6 420 1200 450 $0.17 passed
3643
3643
  claude fable 680 1200 450 $0.45 passed
3644
- pi qwen3-coder-plus 560 1200 450 $0.12 passed
3644
+ pi qwen3.7-plus 560 1200 450 $0.12 passed
3645
3645
  ```
3646
3646
 
3647
3647
  ## `kxm prices`
@@ -963,7 +963,7 @@ description: Primary implementation agent.
963
963
  roster:
964
964
  - route: grok-grok-4-7
965
965
  effort: medium
966
- - route: pi-qwen3-coder-plus-openrouter
966
+ - route: pi-qwen3-7-plus-openrouter
967
967
  effort: medium
968
968
  ```
969
969
 
@@ -991,7 +991,7 @@ unknown keys are ignored).
991
991
 
992
992
  A route string is derived from the selected model file's `vendor` and
993
993
  `model`, joined by a slash: `xai/grok-4.6`, `anthropic/fable`,
994
- `openrouter/qwen/qwen3-coder-plus`. When the file is missing, nothing is
994
+ `openrouter/qwen/qwen3.7-plus`. When the file is missing, nothing is
995
995
  admitted and every live attempt is refused (`producer_route_unsupported`, or
996
996
  `producer_route_not_admitted` from the live producer). A leftover
997
997
  `.kxm/producers.yaml` makes every reader fail with `retired
@@ -1002,7 +1002,7 @@ admitted and every live attempt is refused (`producer_route_unsupported`, or
1002
1002
  `model_selection_required`. Inventory IDs come in several shapes (bare
1003
1003
  `grok-4.6` from `grok models`, `vendor/model` from OpenRouter,
1004
1004
  `provider/model` from `pi --list-models`), so a route such as
1005
- `openrouter/qwen/qwen3-coder-plus` or `anthropic/fable` usually has to be
1005
+ `openrouter/qwen/qwen3.7-plus` or `anthropic/fable` usually has to be
1006
1006
  added by editing the file.
1007
1007
 
1008
1008
  ```yaml
@@ -1013,7 +1013,7 @@ admitted:
1013
1013
  - openai/gpt-5.6-sol
1014
1014
  - openai/gpt-6.1-sol
1015
1015
  - xai/grok-4.6
1016
- - openrouter/qwen/qwen3-coder-plus
1016
+ - openrouter/qwen/qwen3.7-plus
1017
1017
  disabled: []
1018
1018
  ```
1019
1019
 
@@ -1068,9 +1068,9 @@ routes:
1068
1068
  roles: [writer]
1069
1069
  permissions: [edit]
1070
1070
  status: admitted # admitted | retired
1071
- pi-qwen3-coder-plus-openrouter:
1071
+ pi-qwen3-7-plus-openrouter:
1072
1072
  harness: pi
1073
- model: openrouter/qwen/qwen3-coder-plus # Pi: allowed provider prefix + vendor/model
1073
+ model: openrouter/qwen/qwen3.7-plus # Pi: allowed provider prefix + vendor/model
1074
1074
  vendor: alibaba
1075
1075
  roles: [writer]
1076
1076
  permissions: [edit]
@@ -1097,7 +1097,7 @@ routes:
1097
1097
  permissions: [read-only]
1098
1098
  status: admitted
1099
1099
  lineup: # routes admitted for each role, preference order
1100
- writer: [grok-grok-4-7, pi-qwen3-coder-plus-openrouter, agy-gemini-4-argon-high, agy-gemini-4-argon-medium, agy-gemini-3-8-flash-medium, agy-gemini-3-8-flash-high]
1100
+ writer: [grok-grok-4-7, pi-qwen3-7-plus-openrouter, agy-gemini-4-argon-high, agy-gemini-4-argon-medium, agy-gemini-3-8-flash-medium, agy-gemini-3-8-flash-high]
1101
1101
  planner: [claude-fable, pi-qwen3-8-flash-openrouter]
1102
1102
  reviewer-arch: [claude-fable, pi-glm-5-3-flash-openrouter]
1103
1103
  reviewer-cli: [codex-gpt-6-1-sol, pi-qwen3-8-flash-openrouter, codex-gpt-5-6-sol]
@@ -1105,11 +1105,11 @@ required_critics:
1105
1105
  review-arch: claude-fable
1106
1106
  review-cli: codex-gpt-6-1-sol
1107
1107
  model_origins: # required for every Pi route model
1108
- openrouter/qwen/qwen3-coder-plus:
1108
+ openrouter/qwen/qwen3.7-plus:
1109
1109
  vendor: alibaba
1110
1110
  evidence:
1111
- source: plans/evidence/route-qwen-openrouter-pi.md
1112
- sha256: b15f8a54adc398b33e75609e959076eee310bf4ff6623d0b8470ea3da95e6c54
1111
+ source: plans/evidence/route-pi-qwen3-7-plus-openrouter.md
1112
+ sha256: 10e11cfa572ef4891e514d229fa8b7f0f355b31e6481315a6dd763bbe44244a1
1113
1113
  ```
1114
1114
 
1115
1115
  Validated with `validateRosterDocument` from `scripts/roster-policy.mjs`,
@@ -1264,10 +1264,44 @@ file even when a source fails, and exits 1 if any source failed.
1264
1264
  | `models[].sources` | Which sources listed the model |
1265
1265
  | `models[].standard` | OpenRouter per-million rates: `inputPerMillion`, `outputPerMillion`, `cacheReadPerMillion`, `cacheWritePerMillion` |
1266
1266
  | `models[].discount` | Nous per-million rates, same fields |
1267
+ | `models[].missingUpstream` | `true` when the weekly refresh kept a row that OpenRouter no longer lists because a route or roster still names it |
1267
1268
 
1268
1269
  The inventory is discovery data, not admission. Admitting a route is a
1269
1270
  separate, reviewed change to `.kxm/routes.yaml`.
1270
1271
 
1272
+ ### Weekly OpenRouter refresh
1273
+
1274
+ `.github/workflows/refresh-models.yml` runs every Monday at 13:00 UTC and on
1275
+ `workflow_dispatch`. It fetches `https://openrouter.ai/api/v1/models` and
1276
+ updates the OpenRouter `standard` rates in this inventory, plus the matching
1277
+ single-tier rows in `.kxm/prices.yaml`. Nous `discount` rates and the `pi`,
1278
+ `grok`, and `agy` source blocks stay as the last `kxm models inventory-refresh`
1279
+ left them. Output is sorted by model id. `prices.yaml` `date` and the
1280
+ inventory `fetchedAt` (midnight UTC of that date) change only when the catalog
1281
+ content changes, so an unchanged week does not open a pull request.
1282
+
1283
+ A model named by `.kxm/routes.yaml` (`admitted` or `disabled`) or by a roster
1284
+ entry in `.kxm/roles/*.yaml` is not deleted when it leaves OpenRouter. The
1285
+ refresh keeps the previous inventory row, sets `missingUpstream: true`, and
1286
+ the workflow's `model-catalog-guard` check fails. The pull request lists that
1287
+ model, and any referenced model whose input or output rate moved by more than
1288
+ 20 percent, at the top. A multi-tier price row is left unchanged and called
1289
+ out the same way. `anthropic/fable` is matched through its aliases; when those
1290
+ OpenRouter rows disagree, the price row is left unchanged.
1291
+
1292
+ Run the same refresh from a checkout:
1293
+
1294
+ ```bash
1295
+ node --disable-warning=ExperimentalWarning --experimental-strip-types scripts/refresh-model-catalog.mjs --dry-run
1296
+ node --disable-warning=ExperimentalWarning --experimental-strip-types scripts/refresh-model-catalog.mjs
1297
+ ```
1298
+
1299
+ `--dry-run` prints the summary and writes nothing. Exit 2 means a referenced
1300
+ model would be kept after leaving the catalog. The workflow pushes a non-empty
1301
+ diff to `automation/model-refresh` and opens or updates one pull request with
1302
+ `GITHUB_TOKEN`. It then dispatches `ci.yml` on that branch, because a push
1303
+ made with `GITHUB_TOKEN` does not start CI by itself.
1304
+
1271
1305
  ## Personalization settings (`kxm.config.v1`)
1272
1306
 
1273
1307
  Personal and workflow preferences, merged in three layers: built-in defaults
@@ -166,14 +166,14 @@ For example, a review-only worker that cannot edit the checkout:
166
166
 
167
167
  ```bash
168
168
  export KXM_WORKER_TOOLS="read,grep,find,ls,kxm_list,kxm_get,kxm_reply"
169
- kxm agent worker --name reviewer --project <project> --model openrouter/qwen/qwen3-coder-plus
169
+ kxm agent worker --name reviewer --project <project> --model openrouter/qwen/qwen3.7-plus
170
170
  ```
171
171
 
172
172
  <details><summary>PowerShell</summary>
173
173
 
174
174
  ```powershell
175
175
  $env:KXM_WORKER_TOOLS = "read,grep,find,ls,kxm_list,kxm_get,kxm_reply"
176
- kxm agent worker --name reviewer --project <project> --model openrouter/qwen/qwen3-coder-plus
176
+ kxm agent worker --name reviewer --project <project> --model openrouter/qwen/qwen3.7-plus
177
177
  ```
178
178
 
179
179
  </details>