@kontextmind/kxm 0.7.189 → 0.7.191
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.
- package/.claude-plugin/marketplace.json +1 -1
- package/docs/README.md +1 -0
- package/docs/evals/planner-bakeoff-2026-10/judge/argon.json +18 -0
- package/docs/evals/planner-bakeoff-2026-10/judge/journal.json +18 -0
- package/docs/evals/planner-bakeoff-2026-10/judge/reviewer.json +18 -0
- package/docs/evals/planner-bakeoff-2026-10/judge/weekly.json +18 -0
- package/docs/evals/planner-bakeoff-2026-10/judge/wiki.json +18 -0
- package/docs/evals/planner-bakeoff-2026-10/judge/writer2.json +18 -0
- package/docs/evals/planner-bakeoff-2026-10/prompts/argon.txt +30 -0
- package/docs/evals/planner-bakeoff-2026-10/prompts/journal.txt +22 -0
- package/docs/evals/planner-bakeoff-2026-10/prompts/reviewer.txt +28 -0
- package/docs/evals/planner-bakeoff-2026-10/prompts/shared.txt +20 -0
- package/docs/evals/planner-bakeoff-2026-10/prompts/weekly.txt +23 -0
- package/docs/evals/planner-bakeoff-2026-10/prompts/wiki.txt +27 -0
- package/docs/evals/planner-bakeoff-2026-10/prompts/writer2.txt +40 -0
- package/docs/evals/planner-bakeoff-2026-10/raw/argon-fable.txt +68 -0
- package/docs/evals/planner-bakeoff-2026-10/raw/argon-sonnet.txt +69 -0
- package/docs/evals/planner-bakeoff-2026-10/raw/journal-fable.txt +60 -0
- package/docs/evals/planner-bakeoff-2026-10/raw/journal-sonnet.txt +79 -0
- package/docs/evals/planner-bakeoff-2026-10/raw/reviewer-fable.txt +74 -0
- package/docs/evals/planner-bakeoff-2026-10/raw/reviewer-sonnet.txt +95 -0
- package/docs/evals/planner-bakeoff-2026-10/raw/weekly-fable.txt +63 -0
- package/docs/evals/planner-bakeoff-2026-10/raw/weekly-sonnet.txt +66 -0
- package/docs/evals/planner-bakeoff-2026-10/raw/wiki-fable.txt +72 -0
- package/docs/evals/planner-bakeoff-2026-10/raw/wiki-sonnet.txt +79 -0
- package/docs/evals/planner-bakeoff-2026-10/raw/writer2-fable.txt +73 -0
- package/docs/evals/planner-bakeoff-2026-10/raw/writer2-sonnet.txt +79 -0
- package/docs/evals/planner-bakeoff-2026-10/score.py +304 -0
- package/docs/evals/planner-bakeoff-2026-10.md +164 -0
- package/package.json +1 -1
- package/plugins/kxm/.claude-plugin/plugin.json +1 -1
- package/plugins/kxm/dist/mcp-server.js +1 -1
- package/plugins/kxm/package.json +1 -1
- package/plugins/kxm/src/mcp-server.ts +1 -1
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
## Outcome
|
|
2
|
+
|
|
3
|
+
- `reviewer-cli` roster, permission read-only, becomes:
|
|
4
|
+
1. `codex-gpt-6-1-sol`, effort low — primary required CLI critic. Native harness `codex`, model `gpt-6.1-sol`, vendor openai, selector `openai/gpt-6.1-sol`.
|
|
5
|
+
2. `pi-qwen3-8-flash-openrouter`, effort low — different-vendor fallback (unchanged).
|
|
6
|
+
3. `codex-gpt-5-6-sol`, effort low — kept admitted as last fallback, not deleted.
|
|
7
|
+
- `gpt-6.1-sol` exists in inventory (`kxm.model.v2`) before the routes change; `kxm routes admit` accepts it.
|
|
8
|
+
- `.kxm/prices.yaml` gains one dated, re-pinned row for `gpt-6.1-sol` with `openai/gpt-6.1-sol-pro` as an alias on that row, not a second model.
|
|
9
|
+
- Cost recording: ChatGPT `authMethod` → `costBasis: unmetered`, `priceRef: subscription:codex`; API-key login → `unknown`.
|
|
10
|
+
- Architecture review stays `claude-fable` then a different-vendor Pi fallback. Two critics still required for acceptance.
|
|
11
|
+
|
|
12
|
+
## Files
|
|
13
|
+
|
|
14
|
+
- Model inventory file for `gpt-6.1-sol` (schema `kxm.model.v2`): id `gpt-6.1-sol`, vendor openai, harness `codex`, selector `openai/gpt-6.1-sol`, reasoning efforts `low|medium|high|xhigh|max`, ceiling `reviewer-cli`. No `pro` effort value.
|
|
15
|
+
- `.kxm/routes.yaml` (`kxm.routes.v2`): add route `codex-gpt-6-1-sol`; reorder `reviewer-cli` roster as above; move the "required CLI critic" comment to the new primary; writer, planner, reviewer-arch rosters untouched.
|
|
16
|
+
- `.kxm/prices.yaml`: add `gpt-6.1-sol` row — $2 in / $10 out per 1M through 272000 prompt tokens, then $4 / $15; cache read $0.10, cache write $2.50 both tiers; alias `openai/gpt-6.1-sol-pro`; update date and sha256 pin.
|
|
17
|
+
- Any harness-run script hardcoding `gpt-5.6-sol` / `codex-gpt-5-6-sol` as the critic model: switch to the new id (locate by grep; names unknown from packet).
|
|
18
|
+
- Roster policy tests (see below).
|
|
19
|
+
|
|
20
|
+
## Tests
|
|
21
|
+
|
|
22
|
+
- Roster policy test: `reviewer-cli` primary is `codex-gpt-6-1-sol`, effort low, permission read-only; `codex-gpt-5-6-sol` still admitted and last; position 2 is a non-openai vendor.
|
|
23
|
+
- Route id derivation: `codex` + `gpt-6.1-sol` → `codex-gpt-6-1-sol` (dots → dashes).
|
|
24
|
+
- Native-vendor brake: `openai-codex/gpt-6.1-sol` (Pi) and `openrouter openai/gpt-6.1-sol` and `openai/gpt-6.1-sol-pro` via OpenRouter are refused.
|
|
25
|
+
- Ceiling: admitting `gpt-6.1-sol` to `reviewer-arch` fails; `reviewer-arch` primary remains `claude-fable`.
|
|
26
|
+
- Effort validation: `pro` is rejected for the role; `low` accepted; one-shot shape resolves to `codex exec --json` with an effort flag.
|
|
27
|
+
- Prices loader: new row loads with pinned hash; hash mismatch refuses; `openai/gpt-6.1-sol-pro` resolves to the same row/price; tier boundary at 272000 prompt tokens.
|
|
28
|
+
- Cost basis: ChatGPT auth → `unmetered` + `subscription:codex`; API-key → `unknown`.
|
|
29
|
+
- Acceptance gate: still requires both critics; single-critic result is triage only.
|
|
30
|
+
- `kxm routes admit` ordering: refuses when the model is absent from inventory.
|
|
31
|
+
- Docs brake test: no remaining `gpt-5.6-sol` described as "primary" CLI critic.
|
|
32
|
+
|
|
33
|
+
## Docs
|
|
34
|
+
|
|
35
|
+
Same change: `AGENTS.md` role table (Review row → "Codex gpt-6.1-sol"), `docs/reference/harness-routing.md`, `docs/reference/config-reference.md`, `docs/reference/cli-reference.md`, `docs/contributing/assignment-runner.md`, `docs/contributing/harness-routing-internals.md`, `CHANGELOG.md`, `plans/implementation-plan.md` Tracking → Decided (new admission, 5.6 demoted to last fallback, pro alias note, refused routes).
|
|
36
|
+
|
|
37
|
+
## Risks and guards
|
|
38
|
+
|
|
39
|
+
- Billing OpenAI through Pi (`openai-codex`) or OpenRouter: native-vendor brake stays fail-closed; test it.
|
|
40
|
+
- Price hash mismatch silently underquoting: loader refuses mismatch; re-pin exactly once with the date.
|
|
41
|
+
- Adding `gpt-6.1-sol-pro` as a second model: refuse; alias only.
|
|
42
|
+
- Reasoning `pro` leaking into role effort: schema rejects it.
|
|
43
|
+
- Codex logged out or API-key login: no fallback to Pi same vendor; next eligible is the different-vendor Qwen route; cost recorded `unknown` for API key, never `unmetered`.
|
|
44
|
+
- Dropping or weakening the architecture critic: refuse; acceptance keeps both PASS records.
|
|
45
|
+
- Deleting `codex-gpt-5-6-sol`: refuse; demote only.
|
|
46
|
+
- Harness preferences overlay: refuse.
|
|
47
|
+
- Order of operations: inventory before `kxm routes admit`, or admit fails.
|
|
48
|
+
|
|
49
|
+
## Sequence
|
|
50
|
+
|
|
51
|
+
1. Add `gpt-6.1-sol` to model inventory; verify with `kxm harness list` / `pi auth check` not needed (native codex).
|
|
52
|
+
2. Add price row + alias; update date and sha256; run loader test.
|
|
53
|
+
3. Add route via `kxm routes admit`; reorder `reviewer-cli`; keep 5.6 last.
|
|
54
|
+
4. Update hardcoded critic model in harness-run scripts.
|
|
55
|
+
5. Update roster policy tests and add new tests above.
|
|
56
|
+
6. Update all listed docs, CHANGELOG, Tracking.
|
|
57
|
+
7. `npm run verify`; confirm dist matches if CLI changed.
|
|
58
|
+
8. Record admission decision in Tracking → Decided.
|
|
59
|
+
|
|
60
|
+
## Non-goals
|
|
61
|
+
|
|
62
|
+
- No change to writer, planner, or `reviewer-arch` rosters.
|
|
63
|
+
- No pro architecture-review route; no `gpt-6.1-sol` on `reviewer-arch`.
|
|
64
|
+
- No new model entry for pro; no OpenRouter/Pi OpenAI routes.
|
|
65
|
+
- No effort change (stays low); no preferences overlay; no third verify gate.
|
|
66
|
+
- No deletion of GPT-5.6 Sol.
|
|
67
|
+
|
|
68
|
+
## Open questions
|
|
69
|
+
|
|
70
|
+
- Exact filename/path of the model inventory file for `kxm.model.v2`.
|
|
71
|
+
- Which harness-run script(s) hardcode the critic model.
|
|
72
|
+
- Exact codex `exec` effort flag name (packet gives values, not the flag).
|
|
73
|
+
- Whether `kxm routes admit` reorders rosters or ordering must be hand-edited in `routes.yaml`.
|
|
74
|
+
- Whether `plans/kxm-roadmap/state.json` needs a row for this admission.
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
## Outcome
|
|
2
|
+
- `codex-gpt-6-1-sol` (harness `codex`, model `gpt-6.1-sol`, vendor `openai`, effort `low`, read-only) becomes the reviewer-cli primary.
|
|
3
|
+
- `codex-gpt-5-6-sol` stays admitted as the last fallback. It is not deleted.
|
|
4
|
+
- The Pi different-vendor fallback stays in the middle. It must remain a non-OpenAI vendor.
|
|
5
|
+
- Final reviewer-cli roster:
|
|
6
|
+
1. `codex-gpt-6-1-sol`, low
|
|
7
|
+
2. `pi-qwen3-8-flash-openrouter`, low
|
|
8
|
+
3. `codex-gpt-5-6-sol`, low
|
|
9
|
+
- The architecture reviewer, writer and planner rosters do not change.
|
|
10
|
+
- GPT-6.1 Sol does not go onto `reviewer-arch`.
|
|
11
|
+
|
|
12
|
+
## Files
|
|
13
|
+
- Model inventory entry for `gpt-6.1-sol` (schema `kxm.model.v2`). It must exist before admission, and the selector is `openai/gpt-6.1-sol`.
|
|
14
|
+
- `.kxm/routes.yaml` (schema `kxm.routes.v2`): admit the `codex-gpt-6-1-sol` route using `kxm routes admit`. Don't hand-edit if the command can do it.
|
|
15
|
+
- `.kxm/prices.yaml`:
|
|
16
|
+
- Add the price row for `gpt-6.1-sol`.
|
|
17
|
+
- Use the list prices from the packet: $2 input and $10 output per 1M tokens through 272000 prompt tokens, then $4 and $15. Cache read is $0.10 and cache write is $2.50 on both tiers.
|
|
18
|
+
- Alias the pro id on the same row. Do not add a second model.
|
|
19
|
+
- Update the date and the sha256 pin together.
|
|
20
|
+
- Reviewer-cli role definition (roster order and the "required CLI critic" comment).
|
|
21
|
+
- Any harness-run script that hardcodes the critic model. Find it with a search for `gpt-5.6-sol` and `codex-gpt-5-6-sol`, then read the role roster instead of a literal if the script allows it.
|
|
22
|
+
- Roster policy tests.
|
|
23
|
+
|
|
24
|
+
## Tests
|
|
25
|
+
- Roster policy test:
|
|
26
|
+
- Primary is `codex-gpt-6-1-sol`.
|
|
27
|
+
- The read-only permission is unchanged.
|
|
28
|
+
- Effort is `low`.
|
|
29
|
+
- Roster order is as above.
|
|
30
|
+
- A different-vendor Pi fallback is still present.
|
|
31
|
+
- `codex-gpt-5-6-sol` is still admitted as the last fallback.
|
|
32
|
+
- Test that `reviewer-arch` contains no `gpt-6.1-sol` route, and that `claude-fable` is still its primary.
|
|
33
|
+
- Admission brakes:
|
|
34
|
+
- `kxm routes admit` is refused when the model is absent from inventory.
|
|
35
|
+
- `openai-codex` Pi provider routes and `openrouter/openai/gpt-6.1-sol` are refused by the native-vendor brake.
|
|
36
|
+
- The pro mode is not accepted as a role effort value.
|
|
37
|
+
- Prices:
|
|
38
|
+
- A hash mismatch is refused.
|
|
39
|
+
- The pro alias resolves to the same row.
|
|
40
|
+
- The tier boundary at 272000 prompt tokens prices correctly.
|
|
41
|
+
- Cost basis:
|
|
42
|
+
- ChatGPT auth records `unmetered` with `priceRef` `subscription:codex`.
|
|
43
|
+
- API-key auth records `unknown`.
|
|
44
|
+
- Codex one-shot command shape: `codex exec --json` with a mandatory effort, rejecting an empty or invalid value.
|
|
45
|
+
- Docs lint and the version check. Finish with `npm run verify`.
|
|
46
|
+
|
|
47
|
+
## Docs
|
|
48
|
+
Update these in the same change:
|
|
49
|
+
- `AGENTS.md` role table
|
|
50
|
+
- `docs/reference/harness-routing.md`
|
|
51
|
+
- `docs/reference/config-reference.md`
|
|
52
|
+
- `docs/reference/cli-reference.md`
|
|
53
|
+
- `docs/contributing/assignment-runner.md`
|
|
54
|
+
- `docs/contributing/harness-routing-internals.md`
|
|
55
|
+
- `CHANGELOG.md`
|
|
56
|
+
- The `plans/implementation-plan.md` Tracking section (Decided entry for the admission, and the new primary)
|
|
57
|
+
|
|
58
|
+
Wording must keep the rule that both critics are required for acceptance and a single critic is triage only.
|
|
59
|
+
|
|
60
|
+
## Risks and guards
|
|
61
|
+
- Billing through Pi or OpenRouter is refused. Keep the native-vendor brake and add the tests above.
|
|
62
|
+
- A stale price hash must fail the loader. Never edit the row without re-pinning.
|
|
63
|
+
- Pro is a reasoning mode, not a model and not a role effort. Refuse `pro` as an effort and refuse a separate pro route in the codex ceiling.
|
|
64
|
+
- The codex ceiling is reviewer-cli only. Do not widen it.
|
|
65
|
+
- An API-key login must not be recorded as unmetered.
|
|
66
|
+
- Don't leave stale `gpt-5.6-sol` literals in scripts or docs that call it the primary.
|
|
67
|
+
- Don't create dual naming or compatibility aliases for the old route.
|
|
68
|
+
- Refuse to add a harness preferences overlay.
|
|
69
|
+
- Refuse to drop or weaken the architecture critic.
|
|
70
|
+
|
|
71
|
+
## Sequence
|
|
72
|
+
1. Confirm `gpt-6.1-sol` is in inventory. If it isn't, refresh the inventory through the supported updater.
|
|
73
|
+
2. Add the price row and alias, then re-pin the hash.
|
|
74
|
+
3. Run `kxm routes admit` for the new route.
|
|
75
|
+
4. Reorder the reviewer-cli roster.
|
|
76
|
+
5. Update scripts that hardcode the critic.
|
|
77
|
+
6. Write the tests first or alongside, and confirm they fail against the old roster.
|
|
78
|
+
7. Update the docs, CHANGELOG and Tracking.
|
|
79
|
+
8. Run `npm run verify`.
|
|
80
|
+
9. Run the fixed witness, then get both critic PASS records before acceptance.
|
|
81
|
+
|
|
82
|
+
## Non-goals
|
|
83
|
+
- No change to the writer, planner or `reviewer-arch` rosters.
|
|
84
|
+
- No pro architecture-review route.
|
|
85
|
+
- No Pi or OpenRouter OpenAI route.
|
|
86
|
+
- No effort change above `low` for this role.
|
|
87
|
+
- No overlay, and no new schema fields.
|
|
88
|
+
- No hosting or provider migration.
|
|
89
|
+
|
|
90
|
+
## Open questions
|
|
91
|
+
- Is the `gpt-6.1-sol` inventory entry already present, and which updater supplies it?
|
|
92
|
+
- Does the Pi fallback stay second in the roster, or should the order between the Pi fallback and `codex-gpt-5-6-sol` be flipped? I assumed the Pi fallback stays second.
|
|
93
|
+
- Are the packet's list prices complete enough to pin, or does the price feed need a dated source?
|
|
94
|
+
- Which harness-run scripts hardcode the critic? The packet doesn't name them.
|
|
95
|
+
- Is the model's comment text ("required CLI critic") carried over verbatim to the new primary?
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
## Outcome
|
|
2
|
+
|
|
3
|
+
A weekly GitHub Actions job refreshes `.kxm/models/inventory.yaml` and `.kxm/prices.yaml` from the public OpenRouter models API (plus the Nous catalog the existing refresh already reads), and opens exactly one pull request only when the catalog bytes changed. The PR body lists added, removed, and repriced model ids. A human reviews and merges. The job never touches `.kxm/routes.yaml`, never admits or disables routes, never drops CLI-only inventory rows, and never changes writer/planner/reviewer rosters.
|
|
4
|
+
|
|
5
|
+
## Files
|
|
6
|
+
|
|
7
|
+
- `.github/workflows/catalog-refresh.yml` (new): weekly `schedule` plus `workflow_dispatch`; no secrets; `permissions: contents: write, pull-requests: write` only.
|
|
8
|
+
- A deterministic refresh entry point reused by CI and locally, in the existing `kxm models` command module (exact path per repo layout): adds a `prices` refresh step beside `inventory-refresh`, computes the diff, and writes a PR-body markdown file.
|
|
9
|
+
- A small diff/PR-body module (new, same package as the prices loader): compares old vs new `prices.yaml` and `inventory.yaml`, emits `added`, `removed`, `repriced` lists, and a boolean `changed`.
|
|
10
|
+
- `.kxm/prices.yaml`, `.kxm/models/inventory.yaml`: changed only by the PR the job opens, never by the workflow definition itself.
|
|
11
|
+
- `docs/reference/harness-routing.md`, the contributing CI page under `docs/contributing/`, `CHANGELOG.md`.
|
|
12
|
+
- `plans/implementation-plan.md` Tracking: one line noting the weekly job exists and that it is not a route-admission path.
|
|
13
|
+
|
|
14
|
+
## Tests
|
|
15
|
+
|
|
16
|
+
Unit tests next to the existing prices-loader and inventory-refresh tests (same test runner, no network: fixture JSON for the OpenRouter response):
|
|
17
|
+
|
|
18
|
+
- Unchanged catalog: refresh produces identical bytes, `changed=false`, `date` and `sha256` untouched, no PR body written.
|
|
19
|
+
- Changed catalog: `date` and `sha256` both update, and only together; a test that mutates one without the other is rejected by the loader.
|
|
20
|
+
- PR body names added ids and removed ids verbatim and lists repriced ids with old/new values; body contains no `OPENROUTER_API_KEY`-style strings (assert against a fixture environment with a planted fake secret).
|
|
21
|
+
- CLI-only rows preserved: run the merge with `pi`, `grok`, and `agy` absent from `PATH`; assert those inventory rows survive byte-for-byte. A refresh that drops them must throw, not warn.
|
|
22
|
+
- routes.yaml refusal: the refresh step is handed a fake filesystem; assert `.kxm/routes.yaml` is never opened for write and no roster field changes.
|
|
23
|
+
- Token guard: if the OpenRouter response is 401/403 or demands auth, the step exits non-zero with a message that says a token would be required, rather than retrying with any env var.
|
|
24
|
+
- Workflow lint: a test or docs-lint rule asserting the workflow file contains no `secrets.` reference other than the default `GITHUB_TOKEN` and no model-calling step.
|
|
25
|
+
|
|
26
|
+
## Docs
|
|
27
|
+
|
|
28
|
+
- `docs/reference/harness-routing.md`: new subsection "Weekly catalog refresh": what changes, what does not (routes, rosters), that stale prices still show in the routing report so operators check `date`, and how to run the same refresh locally with `--dry-run`.
|
|
29
|
+
- Contributing CI page: add the job to the workflow table; state it is not a required status check and does not call a model; name the schedule as an operator choice.
|
|
30
|
+
- `CHANGELOG.md`: one entry under unreleased.
|
|
31
|
+
|
|
32
|
+
## Risks and guards
|
|
33
|
+
|
|
34
|
+
- **Silent underquote**: if fetch fails or is partial, write nothing and exit non-zero; never write a `prices.yaml` with today's `date` over stale models.
|
|
35
|
+
- **Hash drift**: compute `sha256` over the canonical serialized `models` block, then write `date` and hash in one atomic write; the loader already refuses mismatch.
|
|
36
|
+
- **CLI-only row loss**: merge, do not replace; refuse if the post-merge inventory lacks any row that existed and is not sourced from OpenRouter/Nous.
|
|
37
|
+
- **Accidental admission**: the job's write allowlist is exactly two files; any other diff fails the step.
|
|
38
|
+
- **Token creep**: no `secrets.*` beyond `GITHUB_TOKEN`; fail closed with a clear message if the API ever requires auth.
|
|
39
|
+
- **PR spam**: open one PR on a fixed branch name and update it if it already exists; no PR when `changed=false`.
|
|
40
|
+
- **Auto-merge**: no `gh pr merge`, no `--auto`, no auto-approve.
|
|
41
|
+
- I would refuse to: add a token to work around an auth wall, make the job a required check, let it edit `routes.yaml`, or widen rosters.
|
|
42
|
+
|
|
43
|
+
## Sequence
|
|
44
|
+
|
|
45
|
+
1. Diff module and PR-body renderer, with fixtures and tests.
|
|
46
|
+
2. Prices refresh step with atomic date+hash write and CLI-only row preservation guard; tests.
|
|
47
|
+
3. Workflow file; schedule choice: Monday 06:00 UTC (a choice, not a discovered fact); dry-run locally against fixtures.
|
|
48
|
+
4. Docs and CHANGELOG; Tracking line.
|
|
49
|
+
5. `npm run verify`; commit; push; one manual `workflow_dispatch` to confirm "no PR when unchanged".
|
|
50
|
+
|
|
51
|
+
## Non-goals
|
|
52
|
+
|
|
53
|
+
- Admitting, disabling, or ranking routes; editing rosters.
|
|
54
|
+
- Nous Portal price fetching if it requires auth (inventory ids only, as today).
|
|
55
|
+
- Changing the routing report's stale-price behavior.
|
|
56
|
+
- Any model call in CI.
|
|
57
|
+
|
|
58
|
+
## Open questions
|
|
59
|
+
|
|
60
|
+
- Does the public OpenRouter models endpoint return pricing without a key for all models the inventory lists? If not, which are excluded and how is that surfaced in the PR body?
|
|
61
|
+
- Exact field names in `prices.yaml` `models` entries for repricing comparison.
|
|
62
|
+
- Whether PR creation should use `GITHUB_TOKEN` directly or an existing repo convention; `GITHUB_TOKEN`-opened PRs do not trigger PR CI, so the reviewer may need to re-run checks.
|
|
63
|
+
- Whether the existing `inventory-refresh` already preserves CLI-only rows, or that guard must be added there too.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
## Outcome
|
|
2
|
+
A scheduled GitHub Actions workflow runs weekly. It fetches the public OpenRouter models API, refreshes the price catalog and the model inventory, and opens one pull request only when the bytes changed. A human reviews and merges it. The job never edits `routes.yaml`, never admits or disables routes, and never touches rosters.
|
|
3
|
+
|
|
4
|
+
## Files
|
|
5
|
+
- `.github/workflows/catalog-refresh.yml` (new).
|
|
6
|
+
- Triggers: `schedule` and `workflow_dispatch`.
|
|
7
|
+
- Schedule is a **choice, not a discovered fact**: Monday 06:00 UTC (`0 6 * * 1`).
|
|
8
|
+
- Permissions: `contents: write` and `pull-requests: write` only.
|
|
9
|
+
- Steps: checkout, install with `npm ci`, run the refresh script, and open a PR only if the diff is non-empty. There is no token for the OpenRouter fetch. The default `GITHUB_TOKEN` is used only for the PR.
|
|
10
|
+
- It must not be a required status check and must not call a model.
|
|
11
|
+
- `scripts/catalog-refresh.*` (new). It is a deterministic orchestrator that does the following.
|
|
12
|
+
1. Fetch the public models endpoint. A 401 or 403 is a hard failure with the message "token required; refusing to proceed".
|
|
13
|
+
2. Build the new prices file, with the date and sha256 recomputed only when the model bytes differ.
|
|
14
|
+
3. Run `kxm models inventory-refresh --json`. Use the `--dry-run` result to compute the diff.
|
|
15
|
+
4. Run the guards.
|
|
16
|
+
5. Write the PR body from the diff.
|
|
17
|
+
- `.kxm/prices.yaml` and `.kxm/models/inventory.yaml` are the only outputs the job may change.
|
|
18
|
+
- A small, testable module for diffing (added, removed, repriced) and for rendering the PR body, so the logic is not buried in YAML.
|
|
19
|
+
|
|
20
|
+
## Tests
|
|
21
|
+
Put these under the Node unit suite (`npm test`) so existing PR CI picks them up. They use fixtures, not the network.
|
|
22
|
+
- **Unchanged:** identical API fixture produces an empty diff, so no PR is requested and prices.yaml is byte-identical (date and sha unchanged).
|
|
23
|
+
- **PR body:** added and removed ids appear by name, repriced ids show old and new values, and the body contains no env or secret values.
|
|
24
|
+
- **CLI-only rows:** run with no `pi`, `grok`, or `agy` on PATH. Rows that came from those binaries must survive. Any deletion fails the run.
|
|
25
|
+
- **Routes:** the job fails if `.kxm/routes.yaml` has any diff, and the script never invokes `routes admit` or `routes disable`.
|
|
26
|
+
- **Price hash:** date and sha256 change together or not at all, and the loader still refuses a mismatch.
|
|
27
|
+
- **Auth failure:** a 401 or 403 fixture fails closed.
|
|
28
|
+
- **Workflow lint:** a test asserts the workflow has no secrets reference for the fetch, minimal permissions, and no model-calling step.
|
|
29
|
+
|
|
30
|
+
## Docs
|
|
31
|
+
- `docs/reference/harness-routing.md`: describe the weekly job, the stale-price behavior (`priceCatalogStale`), and that admission stays an operator action.
|
|
32
|
+
- The contributing CI page: add the new workflow, its schedule marked as a choice, and a note that it is not required.
|
|
33
|
+
- `CHANGELOG.md`: add an entry.
|
|
34
|
+
- Run docs lint, because the repo has a docs brake.
|
|
35
|
+
|
|
36
|
+
## Risks and guards
|
|
37
|
+
- **CLI-only row loss:** the runner has no local harness binaries. Guard: the script merges refreshed OpenRouter and Nous rows into the existing file and never rewrites absent-source rows. Abort if the row count by source drops without a matching removal in the diff.
|
|
38
|
+
- **Route drift:** after the refresh, assert that `routes.yaml` is unchanged. A new inventory id does not imply a route.
|
|
39
|
+
- **Silent underquoting:** if the fetch fails or returns a suspiciously empty or short list, fail without writing. Never write a partial catalog.
|
|
40
|
+
- **Duplicate PRs:** use a fixed branch name and update the existing PR instead of opening a second one.
|
|
41
|
+
- **Secrets:** the PR body is built from ids and numbers only.
|
|
42
|
+
- **Generated `dist`:** if any CLI source changes, `npm run verify` must stay green.
|
|
43
|
+
- **Refuse to:** add a token, call a model, edit routes or rosters, auto-merge, or add a required check.
|
|
44
|
+
|
|
45
|
+
## Sequence
|
|
46
|
+
1. Write the diff and body module and its fixture tests first, and see them fail.
|
|
47
|
+
2. Write the orchestrator with the guards.
|
|
48
|
+
3. Add the workflow.
|
|
49
|
+
4. Add the workflow lint test.
|
|
50
|
+
5. Update the docs and the changelog.
|
|
51
|
+
6. Run `npm run verify`, then do a `workflow_dispatch` dry run.
|
|
52
|
+
|
|
53
|
+
## Non-goals
|
|
54
|
+
- Auto-admission of routes, roster changes, or auto-merge.
|
|
55
|
+
- Nous price fetching beyond what `inventory-refresh` already does.
|
|
56
|
+
- A model-based review of the diff.
|
|
57
|
+
- Changing the loader semantics or the schema.
|
|
58
|
+
- Backfilling CLI harness discovery.
|
|
59
|
+
|
|
60
|
+
## Open questions
|
|
61
|
+
- Does `kxm models inventory-refresh` already preserve rows by source, or does the script need to enforce that?
|
|
62
|
+
- Which Nous endpoint does the refresh use, and is it public?
|
|
63
|
+
- Is `--dry-run` output stable enough to diff?
|
|
64
|
+
- What is the exact shape of the OpenRouter price fields (units), and how does the `models` map in `prices.yaml` store them?
|
|
65
|
+
- Does the repo's branch-protection setup let `GITHUB_TOKEN`-created PRs trigger CI? If not, a different mechanism is needed.
|
|
66
|
+
- Where do the sha256 inputs come from: the canonical bytes, or the models block only?
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
## Outcome
|
|
2
|
+
|
|
3
|
+
A small, hand-authored Markdown knowledge wiki under `.kxm/knowledge/` that operators can read for current architecture, routing decisions, glossary pointers, CI/release patterns, and a few runbooks. It is explicitly authored, not compiled; it does not select wiki ingest or compile, touches no hub schema, routes, rosters, prices, npm scripts, or CI jobs, and passes markdownlint. Four existing docs gain one link line each.
|
|
4
|
+
|
|
5
|
+
## Files
|
|
6
|
+
|
|
7
|
+
New (all under `.kxm/knowledge/handbook/` to avoid colliding with the compiler's `.kxm/knowledge/wiki/` output):
|
|
8
|
+
|
|
9
|
+
- `index.md` — table of contents; a header note stating these pages are authored by hand, not generated, and not the authoritative store.
|
|
10
|
+
- `architecture-overview.md` — hub, local Runtime, SQLite at `.kxm/state/kxm.db`, single node, at-least-once.
|
|
11
|
+
- `decisions/native-harness-wins.md` — Fable plans and reviews architecture; Grok writes; Codex reviews CLI/docs; Pi only for vendors without an authenticated native harness; Google route per Tracking (see open questions); fail closed when logged out.
|
|
12
|
+
- `glossary.md` — short summary of key terms, each linking to `docs/glossary.md`; no new definitions.
|
|
13
|
+
- `patterns/ci.md` — PRs run docs lint, typecheck, Node unit tests, Python control-plane suite; `CI / required` aggregates.
|
|
14
|
+
- `runbooks/release.md` — npm package `@kontextmind/kxm`, changelog update, existing verify/CI gates; no new command.
|
|
15
|
+
- `runbooks/failed-release.md` — high level: stop, inspect CI, do not re-tag, fix forward via normal PR loop.
|
|
16
|
+
- `runbooks/model-routes.md` — `kxm routes list`; admit/disable are reviewed actions; `prices.yaml` hash must match or the route fails closed.
|
|
17
|
+
- `runbooks/browser.md` — Obscura is the default Playwright browser; Steel is for human takeover, MFA, live viewer only; no flags beyond `KXM_BROWSER=steel`, which the packet supports.
|
|
18
|
+
|
|
19
|
+
Edited (one line each):
|
|
20
|
+
|
|
21
|
+
- `docs/README.md`
|
|
22
|
+
- the architecture index under `docs/` (exact filename to confirm)
|
|
23
|
+
- the context-and-memory guide
|
|
24
|
+
- the config reference
|
|
25
|
+
|
|
26
|
+
## Tests
|
|
27
|
+
|
|
28
|
+
- No new test files. Run existing `npm run verify` (includes `lint:docs` / markdownlint and the docs brake for product names).
|
|
29
|
+
- If the docs lint has a link checker, the four new relative links must resolve; the handbook's own relative links to `docs/glossary.md` must resolve from `.kxm/knowledge/handbook/`.
|
|
30
|
+
- Manually confirm no page is picked up by anything that would treat it as compiled output (it lives outside `wiki/`).
|
|
31
|
+
|
|
32
|
+
## Docs
|
|
33
|
+
|
|
34
|
+
- The four link lines read, for example: "Hand-authored operator handbook: `.kxm/knowledge/handbook/index.md` (not generated)."
|
|
35
|
+
- Sentence-case titles, relative links, product name KXM only. No "Mesh".
|
|
36
|
+
- No links from `docs/` into `plans/`; the handbook also avoids linking into `plans/`.
|
|
37
|
+
- Context-and-memory guide line must restate: wiki compile/ingest remain unselected; the handbook is not compiler output.
|
|
38
|
+
|
|
39
|
+
## Risks and guards
|
|
40
|
+
|
|
41
|
+
- **Authority confusion**: a reader may treat handbook pages as compiled truth. Guard: index banner plus a one-line footer on each page ("authored; verify against code and Tracking").
|
|
42
|
+
- **Collision with compiler**: writing into `.kxm/knowledge/wiki/` would be overwritten or mistaken for generated. Guard: use `handbook/` subdirectory.
|
|
43
|
+
- **Glossary fork**: duplicating definitions creates drift. Guard: summarize and link only; refuse to define new terms.
|
|
44
|
+
- **Stale admissions**: listing admitted routes would repeat the drift AGENTS.md already suffered. Guard: the decision page names the rotation shape and points to Tracking → Decided and `kxm harness list` for current admissions.
|
|
45
|
+
- **Invented facts**: refuse to add prices, model ids, release commands, or browser flags not in the packet.
|
|
46
|
+
- **Secrets/hosts**: refuse hostnames, tokens, private box names.
|
|
47
|
+
- **Scope creep**: refuse to fix the three known compiler gaps, add npm scripts, CI jobs, schema, or route changes.
|
|
48
|
+
- markdownlint failure blocks commit; fix the Markdown, not the lint config.
|
|
49
|
+
|
|
50
|
+
## Sequence
|
|
51
|
+
|
|
52
|
+
1. Confirm exact filenames of the architecture index, context-and-memory guide, and config reference.
|
|
53
|
+
2. Create `handbook/index.md` with authority banner.
|
|
54
|
+
3. Write architecture, decision, glossary, CI pages.
|
|
55
|
+
4. Write the four runbooks.
|
|
56
|
+
5. Add the four one-line links.
|
|
57
|
+
6. Run `npm run verify`; fix lint.
|
|
58
|
+
7. Commit as `docs: seed hand-authored knowledge handbook`; push; PR via normal loop.
|
|
59
|
+
|
|
60
|
+
## Non-goals
|
|
61
|
+
|
|
62
|
+
- Running `kxm context wiki-compile` or `wiki-lint`; selecting ingest.
|
|
63
|
+
- Fixing the `.kxm/memory` lookup path, unreviewed-journal inclusion, or temporal-state index link.
|
|
64
|
+
- Editing routes, rosters, `prices.yaml`, hub schema, npm scripts, CI.
|
|
65
|
+
- A second glossary or any Phase 4/11 router content.
|
|
66
|
+
|
|
67
|
+
## Open questions
|
|
68
|
+
|
|
69
|
+
- Exact filenames of the architecture index, context-and-memory guide, and config reference.
|
|
70
|
+
- Google route wording: the packet says "agy, not OpenRouter"; current Tracking → Decided may phrase it as the `antigravity` Pi provider with `agy` as a catalog helper. Writer must copy the Tracking text verbatim rather than choose.
|
|
71
|
+
- Whether `.kxm/` is excluded by `.gitignore` or markdownlint config, which would require an explicit include.
|
|
72
|
+
- Whether docs lint resolves links in files outside `docs/`.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
## Outcome
|
|
2
|
+
|
|
3
|
+
A small hand-written wiki lives under `.kxm/knowledge/`. It has an `index.md` and about eight short pages. The pages cover architecture, the routing decision, a glossary pointer, the CI pattern, release and failed-release runbooks, a model-route runbook, and a browser runbook. Each page opens with one line saying it is authored Markdown, a reviewable operator view, and not generated or authoritative. Pages link to the authoritative docs. Nothing selects wiki-compile or ingest, and there are no schema, CLI, script, CI, route, roster, or price changes.
|
|
4
|
+
|
|
5
|
+
## Files
|
|
6
|
+
|
|
7
|
+
New, under `.kxm/knowledge/`:
|
|
8
|
+
- `index.md`: lists the pages in a table with a one-line purpose each. It states the authored status and that wiki-compile and wiki-lint are unselected.
|
|
9
|
+
- `architecture-overview.md`: hub, local Runtime, SQLite at `.kxm/state/kxm.db`, single node, at-least-once delivery.
|
|
10
|
+
- `decision-native-harness.md`:
|
|
11
|
+
- A provider's native harness wins when it is installed and logged in.
|
|
12
|
+
- Claude Fable plans and does architecture review.
|
|
13
|
+
- Grok writes.
|
|
14
|
+
- Codex reviews CLI and docs.
|
|
15
|
+
- Google goes through agy, not OpenRouter.
|
|
16
|
+
- Pi is for vendors with no native harness.
|
|
17
|
+
- Admissions live in Tracking and `kxm harness list`, not in this page.
|
|
18
|
+
- `glossary-pointer.md`: a short summary of the key terms plus a link to `docs/glossary.md`. No new definitions.
|
|
19
|
+
- `pattern-ci.md`: pull requests run docs lint, typecheck, Node unit tests, and the Python control-plane suite. `CI / required` is the aggregate check.
|
|
20
|
+
- `runbook-release.md`: npm package `@kontextmind/kxm`, changelog, and pointers to existing release docs.
|
|
21
|
+
- `runbook-failed-release.md`: triage steps at a high level, with no new commands.
|
|
22
|
+
- `runbook-model-routes.md`: `kxm routes list`; admit and disable are reviewed; the `prices.yaml` hash must match.
|
|
23
|
+
- `runbook-browser.md`: Obscura is the default Playwright browser. Steel is only for human takeover. No flags.
|
|
24
|
+
|
|
25
|
+
Edited, one line each:
|
|
26
|
+
- `docs/README.md`
|
|
27
|
+
- the architecture index in docs
|
|
28
|
+
- the context-and-memory guide
|
|
29
|
+
- the config reference
|
|
30
|
+
|
|
31
|
+
## Tests
|
|
32
|
+
|
|
33
|
+
- No new tests. Run `npm run verify`, which includes `lint:docs`, the markdownlint gate.
|
|
34
|
+
- Check that every relative link resolves. Run the existing docs link check if there is one.
|
|
35
|
+
- Confirm the four doc links point only to `.kxm/knowledge/` and that nothing under `docs/` links into `plans/`.
|
|
36
|
+
- Confirm that `.kxm/knowledge/` is not gitignored. Then confirm that markdownlint covers or deliberately excludes it, and that the docs brake against Mesh names passes on it.
|
|
37
|
+
- Run a grep over the new pages for secrets, tokens, private hostnames, and "Mesh".
|
|
38
|
+
|
|
39
|
+
## Docs
|
|
40
|
+
|
|
41
|
+
- The four one-line links are the only edits to existing docs.
|
|
42
|
+
- Add a changelog entry only if the changelog convention covers docs-only changes.
|
|
43
|
+
- Do not edit `plans/implementation-plan.md`, since no phase gate changes.
|
|
44
|
+
|
|
45
|
+
## Risks and guards
|
|
46
|
+
|
|
47
|
+
- **Authority confusion:** a banner on every page and in the index says the pages are authored and non-authoritative. Link to the source docs rather than restating them.
|
|
48
|
+
- **Drift:** the routing page must not list current admissions. It points to Tracking → Decided and `kxm harness list`, as AGENTS.md does.
|
|
49
|
+
- **Wiki-compile collision:** the compiler writes to `.kxm/knowledge/wiki/`. Keep authored pages at the `.kxm/knowledge/` top level, not in `wiki/`, so a compile run cannot overwrite them. Also check whether any tool treats `.kxm/knowledge/` as generated output or cleans it.
|
|
50
|
+
- **Glossary fork:** summarize only, and use glossary terms exactly.
|
|
51
|
+
- **KontextMind confusion:** never describe the wiki as a KontextMind mind or km_ surface.
|
|
52
|
+
- Refuse to add flags, commands, prices, model ids, or hostnames that are not in the packet or existing docs. Refuse to add `.kxm/memory` files or touch the compiler gaps.
|
|
53
|
+
- Refuse to add dual or legacy product names.
|
|
54
|
+
|
|
55
|
+
## Sequence
|
|
56
|
+
|
|
57
|
+
1. Confirm that `.kxm/knowledge/` is tracked and that markdownlint, link checks, and the docs brake cover it. Record the answer.
|
|
58
|
+
2. Write `index.md` and the architecture and glossary pages.
|
|
59
|
+
3. Write the decision and CI pages.
|
|
60
|
+
4. Write the four runbooks, taking details only from existing docs.
|
|
61
|
+
5. Add the four one-line links.
|
|
62
|
+
6. Run the secret and name grep, then `npm run verify`.
|
|
63
|
+
7. Commit.
|
|
64
|
+
|
|
65
|
+
## Non-goals
|
|
66
|
+
|
|
67
|
+
- Running or fixing wiki-compile or wiki-lint.
|
|
68
|
+
- Fixing the `.kxm/memory` lookup, the unreviewed-entry inclusion, or the temporal-state index path.
|
|
69
|
+
- Wiki ingest or any hub schema change.
|
|
70
|
+
- New npm scripts, CI jobs, or a release command.
|
|
71
|
+
- Edits to routes, rosters, or prices.
|
|
72
|
+
- Links from docs into plans.
|
|
73
|
+
|
|
74
|
+
## Open questions
|
|
75
|
+
|
|
76
|
+
- Are the `.kxm/` paths ignored by git, or by the markdownlint config? If so, which exception is needed?
|
|
77
|
+
- Which existing doc is the architecture index, and which doc is the canonical release source?
|
|
78
|
+
- Does the changelog require entries for docs-only changes?
|
|
79
|
+
- Does the existing release doc have a failed-release procedure to link to, or must the page stay at the level of "stop and escalate to the operator"?
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
## Outcome
|
|
2
|
+
|
|
3
|
+
- Writer #2 becomes `pi-qwen3-coder-next-openrouter` (model `openrouter/qwen/qwen3-coder-next`, vendor alibaba, harness pi, permission edit, effort medium). Alias `qwen-openrouter-pi` moves to the new route.
|
|
4
|
+
- Why this candidate: it is the direct successor to the retired coder route, the cheapest in the packet (0.12 / 0.80), Qwen is explicitly allowed through OpenRouter, and its 262144 context has no long-context premium tier to misquote. `qwen3.7-plus` is rejected for the 256000-token price step and higher base price; `qwen3-coder-flash` is the fallback if coder-next fails the tool-support check (see Open questions).
|
|
5
|
+
- `pi-qwen3-coder-plus-openrouter` is retired, not deleted: off the admitted list and roster, price row kept, inventory and routes carry a retired comment.
|
|
6
|
+
- Writer #1 and routes 3–6 unchanged, same order.
|
|
7
|
+
|
|
8
|
+
## Files
|
|
9
|
+
|
|
10
|
+
- New model file, `kxm.model.v2`, for `pi-qwen3-coder-next-openrouter` (same directory as the existing `pi-qwen3-coder-plus-openrouter` model file).
|
|
11
|
+
- Inventory: add the new id; mark the old id `retired` with a dated comment (404 on 2026-10-17).
|
|
12
|
+
- Routes / admitted list: remove old id, add new id with permission edit; retired comment on the old entry.
|
|
13
|
+
- Writer roster, effort medium: replace position 2 only.
|
|
14
|
+
- `.kxm/prices.yaml`: keep `qwen/qwen3-coder-plus` row at last list price with a retired note; add `qwen/qwen3-coder-next` 0.12 / 0.80, context 262144; bump date to 2026-10-17 and recompute sha256 in the same change.
|
|
15
|
+
- `plans/evidence/` new note: OpenRouter 404 for the old slug, candidate table, price source date, selection rationale, tool-support verification result.
|
|
16
|
+
- `plans/implementation-plan.md` Tracking → Decided: record the writer #2 swap and the brake reasoning.
|
|
17
|
+
- Docs: harness-routing, config reference, CLI reference, assignment runner, glossary (only if it names the route), changelog.
|
|
18
|
+
- `dist/`: regenerate only if a test or grep shows the old route id or slug embedded in a bundle.
|
|
19
|
+
|
|
20
|
+
## Tests
|
|
21
|
+
|
|
22
|
+
- Roster-policy tests: writer #2 expectations switch to the new id; assert the old id is absent from admitted and roster but present in inventory as retired.
|
|
23
|
+
- Prices loader test: fixture with the new date/hash passes; a mismatched sha256 is refused.
|
|
24
|
+
- Inventory-before-admit test: admitting an id not in inventory fails closed.
|
|
25
|
+
- Brake test: `openrouter/moonshotai/...` as a writer is refused with the native-harness reason; a meta slug is refused as unadmitted.
|
|
26
|
+
- Model-file schema test for the new file (v2, harness pi, vendor alibaba, edit present).
|
|
27
|
+
- Docs brake / lint:docs: no doc still names `qwen3-coder-plus` as a live writer.
|
|
28
|
+
- `npm run verify` after `npm ci`.
|
|
29
|
+
|
|
30
|
+
## Docs
|
|
31
|
+
|
|
32
|
+
- harness-routing: roster table row 2, retired-route note, pricing tier note (none for coder-next).
|
|
33
|
+
- Config reference: prices.yaml example rows and the date/sha pin rule.
|
|
34
|
+
- CLI reference: any example output showing writer #2.
|
|
35
|
+
- Assignment runner: default writer rotation example.
|
|
36
|
+
- Glossary: alias `qwen-openrouter-pi` target, if listed.
|
|
37
|
+
- Changelog: "writer #2 replaced; old route retired, price history kept."
|
|
38
|
+
|
|
39
|
+
## Risks and guards
|
|
40
|
+
|
|
41
|
+
- Tool support unverified from this packet. Guard: the writer must run a real `pi auth check --provider openrouter` and a one-shot edit smoke on the new model before admitting; if the model cannot call tools, do not admit, fall back to `qwen3-coder-flash` under the same check.
|
|
42
|
+
- Moonshot via OpenRouter is refused: kimi has a native harness, so this is the native-vendor-through-Pi case the brake exists for. Not selected.
|
|
43
|
+
- Meta via OpenRouter is an admission question, not in scope; not selected.
|
|
44
|
+
- prices.yaml hash drift: date and sha256 updated in the same commit; loader refuses mismatch, so verify runs it.
|
|
45
|
+
- Ordering: inventory edit lands before routes admit, in the same change, so no intermediate state admits an unknown id.
|
|
46
|
+
- History: no deletion of the old price row or inventory entry.
|
|
47
|
+
- Refuse: editing writer #1, planner, reviewer-cli, reviewer-arch; reordering Argon/Flash; adding a harness preferences overlay; inventing supported_parameters or prices.
|
|
48
|
+
|
|
49
|
+
## Sequence
|
|
50
|
+
|
|
51
|
+
1. Evidence note under `plans/evidence/` with the 404 and candidate table.
|
|
52
|
+
2. New model file; inventory add + retire old.
|
|
53
|
+
3. prices.yaml rows, date, sha256.
|
|
54
|
+
4. Routes/admitted + roster swap; alias move.
|
|
55
|
+
5. Tests (roster, loader, brake, inventory, schema).
|
|
56
|
+
6. Docs and changelog; Tracking entry.
|
|
57
|
+
7. Tool-support smoke on the new route; fail closed if it cannot edit.
|
|
58
|
+
8. `npm ci && npm run verify`; regenerate `dist` only if embedded strings changed.
|
|
59
|
+
9. One commit per logical change (evidence/model, prices, routes+tests, docs).
|
|
60
|
+
|
|
61
|
+
## Non-goals
|
|
62
|
+
|
|
63
|
+
- No change to writer #1, critics, or Gemini positions.
|
|
64
|
+
- No Meta or Moonshot admission.
|
|
65
|
+
- No catalog feed, price refresh tooling, or routing report changes.
|
|
66
|
+
- No alias compatibility shim for the old route id; it brakes.
|
|
67
|
+
|
|
68
|
+
## Open questions
|
|
69
|
+
|
|
70
|
+
- Does `qwen/qwen3-coder-next` advertise tool calling on OpenRouter (`supported_parameters` absent from packet)? Assumption labeled: yes; blocking if false.
|
|
71
|
+
- Exact directory names for model files, inventory, routes, and roster-policy tests in this repo.
|
|
72
|
+
- Does `dist` embed the roster or route ids?
|
|
73
|
+
- Should the alias `qwen-openrouter-pi` follow the new route or be retired with the old one? Assumed: follows.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
## Outcome
|
|
2
|
+
Replace writer #2 `pi-qwen3-coder-plus-openrouter` with `pi-qwen3-coder-next-openrouter` (model `openrouter/qwen/qwen3-coder-next`, vendor alibaba, permission edit, harness pi). Writer #1 and #3–#6 stay in their current order. The old route is retired, not deleted.
|
|
3
|
+
|
|
4
|
+
**Why qwen3-coder-next:**
|
|
5
|
+
- It is a Qwen model, so the OpenRouter route is allowed. Qwen has no native harness.
|
|
6
|
+
- It is the closest successor to a coder-specialised model.
|
|
7
|
+
- At 0.12 / 0.80 it is the cheapest candidate.
|
|
8
|
+
- It has a flat price, so there is no long-context premium like qwen3.7-plus's 0.96 / 3.84 tier at 256000 tokens and above.
|
|
9
|
+
- Its 262144 context is smaller than the alternatives. That is acceptable for edit-sized writer prompts.
|
|
10
|
+
|
|
11
|
+
**Tool-support assumption (labeled):** the packet does not show `supported_parameters`. I assume `qwen3-coder-next` supports tools because it is a coder model. The writer must verify this against the live OpenRouter models API before admitting the route (see Risks and guards).
|
|
12
|
+
|
|
13
|
+
**Fallback if tool support is not shown:** `qwen/qwen3.7-plus` is the second choice. It would need the same check, and the premium tier must be recorded.
|
|
14
|
+
|
|
15
|
+
## Files
|
|
16
|
+
- `.kxm/models/pi-qwen3-coder-next-openrouter.yaml`: schema `kxm.model.v2`, harness pi, vendor alibaba, permissions include edit. Add alias `qwen-next-openrouter-pi`.
|
|
17
|
+
- Model inventory file: add the new id. This must come before the routes change.
|
|
18
|
+
- Routes file: add the new route as admitted. Mark `pi-qwen3-coder-plus-openrouter` retired in a comment, remove it from the admitted list, and remove it from the writer roster so #2 is the new route. Keep the old alias out of the active lists.
|
|
19
|
+
- Inventory: keep the old id with a retired comment. Do not reuse its alias.
|
|
20
|
+
- `.kxm/prices.yaml`: add the `qwen/qwen3-coder-next` row at 0.12 / 0.80. Keep the `qwen/qwen3-coder-plus` row at its last list price. Update the date and sha256 together.
|
|
21
|
+
- Writer roster definition (assignment runner): swap #2 only.
|
|
22
|
+
- `plans/evidence/<date>-writer-2-qwen3-coder-next.md`: evidence note.
|
|
23
|
+
|
|
24
|
+
## Tests
|
|
25
|
+
- Roster-policy tests: update the hardcoded #2 id. Assert that #1 and #3–#6 are unchanged and in order (Argon high, Argon medium, Flash medium, Flash high).
|
|
26
|
+
- Add a test that the retired route is not admitted and not on the roster.
|
|
27
|
+
- Add a test that the new id exists in inventory before routes admit it. This should fail if the order is wrong.
|
|
28
|
+
- Prices loader test: the sha256 and date match, and the old row is still present.
|
|
29
|
+
- Brake test: no `moonshotai/*` route through Pi/OpenRouter.
|
|
30
|
+
- Model file schema test: `kxm.model.v2`, vendor alibaba, edit permission.
|
|
31
|
+
- Run `npm run verify`.
|
|
32
|
+
|
|
33
|
+
## Docs
|
|
34
|
+
Update every place that names writer #2 or `qwen3-coder-plus`:
|
|
35
|
+
- harness-routing
|
|
36
|
+
- config reference
|
|
37
|
+
- CLI reference
|
|
38
|
+
- assignment runner doc
|
|
39
|
+
- glossary, only if it names the route
|
|
40
|
+
- changelog
|
|
41
|
+
- `plans/implementation-plan.md` Tracking (Decided and the relevant slice)
|
|
42
|
+
- generated `dist`, only if a grep shows the string embedded. If it is, regenerate rather than hand-edit.
|
|
43
|
+
|
|
44
|
+
Do not rewrite historical evidence or changelog entries that describe the old route as it was.
|
|
45
|
+
|
|
46
|
+
## Risks and guards
|
|
47
|
+
- **Tool support is unproven in the packet.** Before admission, the writer must check `supported_parameters` for tools in the live models API. If it is absent, do not admit. Fall back to the next candidate that shows tools, or leave #2 vacant with the gap recorded. Never admit on assumption alone.
|
|
48
|
+
- **Moonshot `kimi-k2.7-code` is refused.** Moonshot has a native kimi harness, and billing a native vendor through Pi/OpenRouter is the brake case. It is the only candidate that falls under the brake.
|
|
49
|
+
- **Meta `muse-spark-open` is not auto-admitted.** It is an admission question, and it is also the most expensive per token.
|
|
50
|
+
- **Price pin:** the loader refuses a date or sha256 mismatch. Update both in the same commit and recompute the hash after the final edit.
|
|
51
|
+
- **Order dependency:** inventory must contain the id before routes admit it.
|
|
52
|
+
- **404 risk repeats:** record the verification date, 2026-10-17, in the evidence note.
|
|
53
|
+
- **No dual names or alias for the retired route.** Old names fail closed.
|
|
54
|
+
|
|
55
|
+
## Sequence
|
|
56
|
+
1. Verify `qwen3-coder-next` live and tool-capable. Record the result in the evidence note.
|
|
57
|
+
2. Add the model file.
|
|
58
|
+
3. Add the inventory entry, with the retired comment on the old id.
|
|
59
|
+
4. Add the prices row, then update the date and recompute the sha256.
|
|
60
|
+
5. Update routes: admit the new route, retire the old one, update the roster.
|
|
61
|
+
6. Update the tests.
|
|
62
|
+
7. Update the docs, changelog and Tracking.
|
|
63
|
+
8. Regenerate `dist` if needed.
|
|
64
|
+
9. Run `npm run verify`.
|
|
65
|
+
|
|
66
|
+
## Non-goals
|
|
67
|
+
- Do not change writer #1, the planner, `reviewer-cli`, or `reviewer-arch`.
|
|
68
|
+
- Do not reorder Argon or Flash.
|
|
69
|
+
- Do not add a harness preferences overlay.
|
|
70
|
+
- Do not delete the old price row.
|
|
71
|
+
- Do not add a compatibility alias.
|
|
72
|
+
- Do not run a side-by-side model comparison.
|
|
73
|
+
|
|
74
|
+
## Open questions
|
|
75
|
+
- Does `qwen/qwen3-coder-next` list tool support? The packet does not show `supported_parameters` for any candidate.
|
|
76
|
+
- What is the exact evidence-note filename convention, and where do the inventory and routes files live?
|
|
77
|
+
- What is the last list price of `qwen3-coder-plus`? It is not in the packet, so keep the row as it is.
|
|
78
|
+
- Does effort stay medium for the new route? I assume yes.
|
|
79
|
+
- Is a 262144 context enough for assignment prompts? This is unmeasured.
|