@kontextmind/kxm 0.7.165 → 0.7.167
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/CHANGELOG.md +16 -0
- package/docs/README.md +1 -0
- package/docs/architecture/hosted-direction.md +9 -4
- package/docs/architecture/inventory.md +1 -0
- package/docs/concepts/trust-model.md +1 -1
- package/docs/contributing/decisions.md +153 -0
- package/docs/contributing/learnings.md +54 -53
- package/docs/contributing/operating-rules.md +19 -6
- package/docs/glossary.md +2 -2
- package/docs/operations/troubleshooting.md +2 -2
- package/docs/operations.md +62 -8
- package/docs/reference/cli-reference.md +11 -11
- package/docs/reference/config-reference.md +36 -11
- package/docs/reference/configuration.md +2 -2
- package/docs/reference/tools.md +1 -1
- package/docs/start/quickstart-claude-code.md +2 -2
- package/package.json +1 -1
- package/plugins/kxm/.claude-plugin/plugin.json +1 -1
- package/plugins/kxm/README.md +3 -3
- package/plugins/kxm/dist/claude-hook.js +417 -66
- package/plugins/kxm/dist/cli.js +1399 -900
- package/plugins/kxm/dist/extension.js +399 -64
- package/plugins/kxm/dist/mcp-server.js +622 -135
- package/plugins/kxm/dist/runtime-supervisor.js +668 -166
- package/plugins/kxm/dist/runtime.js +713 -211
- package/plugins/kxm/dist/server.js +466 -58
- package/plugins/kxm/package.json +1 -1
- package/plugins/kxm/skills/kxm-hub-ops/SKILL.md +15 -7
- package/plugins/kxm/src/cli/hub.ts +80 -21
- package/plugins/kxm/src/cli/types.ts +8 -1
- package/plugins/kxm/src/cli.ts +41 -7
- package/plugins/kxm/src/config.ts +246 -3
- package/plugins/kxm/src/extension.ts +8 -7
- package/plugins/kxm/src/hub-autostart.ts +20 -0
- package/plugins/kxm/src/hub-env.ts +83 -31
- package/plugins/kxm/src/hub-identity.ts +337 -0
- package/plugins/kxm/src/mcp-server.ts +17 -15
- package/plugins/kxm/src/project-name.ts +6 -47
- package/plugins/kxm/src/server.ts +22 -4
- package/scripts/kxm-hub.mjs +5 -0
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,22 @@ All notable user-facing changes are documented here. The project follows [Semant
|
|
|
6
6
|
|
|
7
7
|
### Added
|
|
8
8
|
|
|
9
|
+
- **Hub project identity and its access key live in `.kxm/config.yaml`.**
|
|
10
|
+
`hub.local` and `hub.cloud` hold the URL, the project id to present, and a
|
|
11
|
+
key reference (`key.op` is an `op://` reference, `key.env` is an environment
|
|
12
|
+
variable name). A literal token is refused. `op read` runs at use time and
|
|
13
|
+
the resolved value is not saved. The same order is used everywhere: flag,
|
|
14
|
+
`KXM_PROJECT`, the active mode's config project, `.kxm/project.yaml`, the
|
|
15
|
+
package name, then the directory name. `kxm hub bind` and
|
|
16
|
+
`kxm hub bind --cloud` write the non-secret fields, and `kxm hub view`
|
|
17
|
+
prints the mode, URL, project id, and key source. The hub's
|
|
18
|
+
`hub.projects` map uses the same references. `KXM_PROJECT_TOKENS` still
|
|
19
|
+
replaces that map. Setups whose hub map is keyed by the package name should
|
|
20
|
+
set `hub.local.project` or `hub.cloud.project` to that name, or keep passing
|
|
21
|
+
`KXM_PROJECT`: a checkout with `.kxm/project.yaml` otherwise sends that id
|
|
22
|
+
and gets `project_token_missing`. See
|
|
23
|
+
[Operate a KXM hub](docs/operations.md#hub-identity-in-config).
|
|
24
|
+
|
|
9
25
|
- **`kxm hub bind --cloud` attaches a client to a remote hub reached through a loopback forward.**
|
|
10
26
|
The binding records `--token-env` and/or `--token-command` and never the token.
|
|
11
27
|
Later commands, including the environment for a Pi worker, use that source and
|
package/docs/README.md
CHANGED
|
@@ -117,6 +117,7 @@ KXM connects coding agents through a durable, authenticated [hub](glossary.md#hu
|
|
|
117
117
|
| [KXM terminal components](contributing/tui-components.md) | Maintainers, integrators | The panel kit behind `kxm dash` |
|
|
118
118
|
| [Repository work delivery skill](contributing/repo-work-delivery.md) | Contributors | The repository-local skill for delivering a change |
|
|
119
119
|
| [Operating rules](contributing/operating-rules.md) | Agents, maintainers | The operator's standing instructions, dated, and where each is enforced |
|
|
120
|
+
| [Decisions](contributing/decisions.md) | Agents, maintainers | Medium-or-higher decisions from automated work, with weights and evidence |
|
|
120
121
|
| [Learnings](contributing/learnings.md) | Agents, maintainers | Durable lessons from running the writer, landing, and docs loops |
|
|
121
122
|
| [Artifact templates](templates/README.md) | Workflow authors | Document templates and where workflows use them |
|
|
122
123
|
|
|
@@ -2,8 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
Target. This page is a direction, not a live deployment.
|
|
4
4
|
|
|
5
|
-
Read from `plans/plan-per-tenant-hosting.md`.
|
|
6
|
-
is
|
|
5
|
+
Read from `plans/plan-per-tenant-hosting.md`.
|
|
6
|
+
`plans/plan-greenfield-infra.md` is in this checkout as a `kxm.doc.v1`
|
|
7
|
+
stub (status draft, authority instruction): the long-form proposal was
|
|
8
|
+
never committed, and the canonical facts below come from the
|
|
9
|
+
implementation-plan greenfield bullets.
|
|
7
10
|
|
|
8
11
|
```mermaid
|
|
9
12
|
flowchart LR
|
|
@@ -44,8 +47,10 @@ roadmap question. The tracker wins.
|
|
|
44
47
|
|
|
45
48
|
## Greenfield infra plan
|
|
46
49
|
|
|
47
|
-
`plans/plan-greenfield-infra.md` is
|
|
48
|
-
`
|
|
50
|
+
`plans/plan-greenfield-infra.md` is observed from this checkout as a
|
|
51
|
+
`kxm.doc.v1` stub (status draft, authority instruction, updated
|
|
52
|
+
2026-09-28). Its delivery position is unchanged: none of the delivery is
|
|
53
|
+
scheduled there.
|
|
49
54
|
|
|
50
55
|
The tracker names that file. The sentences that can be repeated without a
|
|
51
56
|
hostname, an account name, or a secret are: a first move is recorded as
|
|
@@ -12,6 +12,7 @@ Read from `plugins/kxm/src/cli.ts`, `scripts/kxm-hub.mjs`, `plugins/kxm/src/hub.
|
|
|
12
12
|
| `kxm` CLI | `node scripts/kxm.mjs` or the installed bin | no listener | none | `plugins/kxm/src/cli.ts` |
|
|
13
13
|
| Hub | `kxm hub start` via `scripts/kxm-hub.mjs` | `127.0.0.1:7331` | `.kxm/state/kxm.db` under the workspace state dir | `plugins/kxm/src/hub.ts` |
|
|
14
14
|
| Hub credentials | written when the hub starts | `hub-env.json` under the user state root | that JSON file, not SQLite | `plugins/kxm/src/hub-env.ts` |
|
|
15
|
+
| Hub cloud binding | `kxm hub bind <url> --cloud --token-env/--token-command` | no listener; writes the binding record and never stores the token | binding record; token stays in the named env or command | `plugins/kxm/src/cli/hub.ts` |
|
|
15
16
|
| Runtime supervisor | `kxm runtime` / `scripts/kxm-runtime-supervisor.mjs` | `127.0.0.1` and the requested port, or ephemeral | registry and event stores below | `plugins/kxm/src/runtime-supervisor.ts` |
|
|
16
17
|
| Runtime registry | opened by the supervisor | `runtime/registry.db` under the user state root | `registry.db`. A lane worktree registers under its project: same project id, its own control root, `lane_of` set. A registering root is the primary worktree when its git common dir is `<root>/.git`; if that primary registers while the live home row is not primary, the primary becomes the home row and every other live row of that repository becomes its lane. | `plugins/kxm/src/runtime-paths.ts` |
|
|
17
18
|
| Runtime event store | opened by the supervisor | `runtime/projects/<key>/run-events.db` | `run-events.db` | `plugins/kxm/src/runtime-paths.ts` |
|
|
@@ -56,7 +56,7 @@ flowchart LR
|
|
|
56
56
|
- **Claude Code plugin.** The MCP server uses the plugin's `auth_token` setting, else the project token the hub saved for this project. It never falls back to the saved admin token; without a project token, its tools report that and do nothing.
|
|
57
57
|
- **SessionStart hook.** It reads local state read-only. It mints no token, writes no file, and never prints a token.
|
|
58
58
|
- **Pi extension.** It uses `KXM_AUTH_TOKEN`, else the project token the hub saved for this project. It never uses the saved admin token, nor the one a hub it auto-started generated; without a project token it reports the fix and stays offline.
|
|
59
|
-
- **`kxm peer` and `kxm workflow` agent commands.** They act as a peer agent, so they choose a token as the Pi extension does, and exit 2 with `project_token_missing` when none resolves.
|
|
59
|
+
- **`kxm peer` and `kxm workflow` agent commands.** They act as a peer agent, so they choose a token as the Pi extension does, and exit 2 with `project_token_missing` when none resolves. The message names the project id that was sent and where it came from.
|
|
60
60
|
- **Dashboard and Runtime supervisor.** Operator tools use `KXM_AUTH_TOKEN`, else the saved project token, else the saved admin token.
|
|
61
61
|
|
|
62
62
|
## Project isolation
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Decisions"
|
|
3
|
+
description: "Decisions of medium significance or higher made by automated KXM work in this repository. One entry per decision: the options evaluated with their weights, and why the selected option won. Recorded the turn the decision is taken."
|
|
4
|
+
audience: "agents and maintainers"
|
|
5
|
+
updated: "2026-09-27"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Decisions
|
|
9
|
+
|
|
10
|
+
Automated work records here every decision of medium significance or
|
|
11
|
+
higher: the options it evaluated, the weight each option scored against
|
|
12
|
+
the criteria that mattered, and why the selected option won. Weights are
|
|
13
|
+
the session's own 0-to-1 scores, not measurements. A decision that was
|
|
14
|
+
made directly by the operator is recorded only when executing it required
|
|
15
|
+
a choice.
|
|
16
|
+
|
|
17
|
+
Entries run oldest first. Retention: this file keeps the last 50 entries. When one more would exceed
|
|
18
|
+
the cap, the oldest entries rotate to
|
|
19
|
+
`docs/contributing/decisions-archive.jsonl` as `kxm.decision-archive.v1`
|
|
20
|
+
lines (date, title, area, options with weights, selected, why, evidence),
|
|
21
|
+
oldest first. The archive is append-only cold storage; the md stays the
|
|
22
|
+
working set.
|
|
23
|
+
|
|
24
|
+
## 2026-09-26 — P2 critic transport while the engine was schema-blocked (dispatch)
|
|
25
|
+
|
|
26
|
+
- Context: installed 0.7.130 refused the P2 lane's new agent schemas, so
|
|
27
|
+
`kxm run`, drive, cancel, and receipt all answered 400. Both critics
|
|
28
|
+
still had to review the unit, and loop-dispatch wanted engine attempts.
|
|
29
|
+
- Options:
|
|
30
|
+
- Wait until #343 ships, then run critics through the engine — weight
|
|
31
|
+
0.2. Highest purity, but it stalls the unit for a release cycle and
|
|
32
|
+
the reviewers' context goes cold.
|
|
33
|
+
- Run a second runtime supervisor from the branch code — weight 0.1. It
|
|
34
|
+
would load the lane, but it mutates machine-global runtime state with
|
|
35
|
+
unreleased code and risks the exact registry corruption S24 just
|
|
36
|
+
fixed.
|
|
37
|
+
- Dispatch both critics through the harness runner with briefs copied
|
|
38
|
+
into the lane sandbox — weight 0.9. The documented relief for schema
|
|
39
|
+
cutover lanes, proven twice the same morning by the writer repairs;
|
|
40
|
+
costs only the improve-report attempt rows.
|
|
41
|
+
- Selected: harness runner. Fastest safe path; the engine-attempt proof
|
|
42
|
+
was deliberately deferred to the next unit rather than falsified.
|
|
43
|
+
Evidence: Evidence: the P2 lane store (bae17379) held the settled attempts while the control-root report read zero, and the 0.7.131 update plus runtime restart left the lane loadable with a verified simulated receipt.
|
|
44
|
+
|
|
45
|
+
## 2026-09-26 — Supervisor cadence interpretation (operations)
|
|
46
|
+
|
|
47
|
+
- Context: the operator ordered the schedule task changed to 30 minutes.
|
|
48
|
+
The improvement loop was anchored to wall-clock ("every sixth tick,
|
|
49
|
+
about 30 minutes"), which a longer tick would silently stretch to three
|
|
50
|
+
hours.
|
|
51
|
+
- Options:
|
|
52
|
+
- Keep "every sixth tick" literally — weight 0.3. Preserves the prompt's
|
|
53
|
+
letter, breaks the documented ~30-minute wall-clock cadence the
|
|
54
|
+
parenthetical pins.
|
|
55
|
+
- Improvement loop every tick — weight 0.8. Preserves both documented
|
|
56
|
+
wall-clock behaviours; the tick count stops appearing anywhere.
|
|
57
|
+
- Selected: every tick. The operator's order named the tick cadence; the
|
|
58
|
+
improvement loop's anchor was always the half hour. Stated in the report
|
|
59
|
+
so it can be flipped back with one word.
|
|
60
|
+
Evidence: Evidence: plans/kxm-roadmap/supervisor-prompt.md and the operator order of 2026-09-26.
|
|
61
|
+
|
|
62
|
+
## 2026-09-27 — Authoring witness misses committed work (engine)
|
|
63
|
+
|
|
64
|
+
- Context: the engine failed two writer runs (P2 morning, vision port)
|
|
65
|
+
with `authoringWitness: unchanged` while both lanes held the writer's
|
|
66
|
+
commit. `captureWorktreeWitness` fingerprints porcelain, unstaged, and
|
|
67
|
+
staged diffs but not HEAD, so a writer that fully commits reads as
|
|
68
|
+
unchanged and a `passed` write step is flipped to `failed`.
|
|
69
|
+
- Options:
|
|
70
|
+
- Add `git rev-parse HEAD` to the fingerprint — weight 0.9. One term in
|
|
71
|
+
one string; catches commits, resets, and branch switches, which are
|
|
72
|
+
all authoring-relevant moves of a lone-writer checkout.
|
|
73
|
+
- A separate commit-witness field with its own failure class — weight
|
|
74
|
+
0.6. Finer attribution (commit versus dirty edit) but a larger
|
|
75
|
+
surface for a distinction nothing consumes today.
|
|
76
|
+
- Trust the producer's `authored` metadata — weight 0.1. The module
|
|
77
|
+
documents that metadata is set here, not trusted from the producer.
|
|
78
|
+
- Selected: HEAD in the fingerprint, one named test (committed-only
|
|
79
|
+
change keeps `passed` with `authored: true`), shipped before any more
|
|
80
|
+
engine-driven write steps.
|
|
81
|
+
Evidence: Evidence: test/core/worktree-witness.test.ts (real temp git repositories), and the two failed lane runs run_fe3061b3 (vision) and run_f7a21c84 (P2) whose lanes held the writer commits.
|
|
82
|
+
|
|
83
|
+
## 2026-09-27 — Open PR queue: draft handling and landing order (landing)
|
|
84
|
+
|
|
85
|
+
- Context: six open PRs after #343. Two were drafts, one conflicted
|
|
86
|
+
against the restructured CLI, three were clean and non-draft. The
|
|
87
|
+
standing rule says every PR is landed without asking.
|
|
88
|
+
- Options:
|
|
89
|
+
- Land everything including drafts — weight 0.2. A draft is the
|
|
90
|
+
author's own hold signal; overriding it defeats the state and risks
|
|
91
|
+
landing half-work.
|
|
92
|
+
- Land only clean non-drafts now, defer the conflicted one to a port,
|
|
93
|
+
leave drafts — weight 0.9. Honours both the autonomy rule and the
|
|
94
|
+
draft semantics; the queue drains in one session.
|
|
95
|
+
- Ask the operator per PR — weight 0.1. The standing rule explicitly
|
|
96
|
+
removes this ask for open PRs.
|
|
97
|
+
- Selected: land non-drafts oldest-first (#341, #344, #346), leave
|
|
98
|
+
#325 and #342 as drafts, dispatch #345 as a port.
|
|
99
|
+
Evidence: Evidence: gh pr list on 2026-09-27 (six open: two drafts, one conflicting, three clean).
|
|
100
|
+
|
|
101
|
+
## 2026-09-27 — Outcome parser rejects real model output (engine)
|
|
102
|
+
|
|
103
|
+
- Context: the one-shot producer appends a "return a final JSON object
|
|
104
|
+
with an outcome field" contract to every prompt, and `determineOutcome`
|
|
105
|
+
requires the model's entire output to parse as that bare JSON. Both real
|
|
106
|
+
writers and critics answer with the brief's own review format instead
|
|
107
|
+
(grok prose, fable markdown), so every substantive engine-driven step
|
|
108
|
+
settles `failed` even when the transport and witness are clean.
|
|
109
|
+
- Options:
|
|
110
|
+
- Extract the last balanced JSON object in the text and apply the same
|
|
111
|
+
strict checks (object, string `outcome`, member of allowed outcomes;
|
|
112
|
+
anything else stays `failed`) — weight 0.9. Tolerates the prose
|
|
113
|
+
models actually produce; no path to success without a truthful
|
|
114
|
+
outcome token.
|
|
115
|
+
- Repeat the JSON contract as the first and last line of the prompt —
|
|
116
|
+
weight 0.3. Prompt engineering against measured behaviour; the brief's
|
|
117
|
+
own output section still wins.
|
|
118
|
+
- Per-harness structured output modes — weight 0.5. The durable fix but
|
|
119
|
+
a per-adapter surface change; too broad for the ship cycle this needs
|
|
120
|
+
to ride.
|
|
121
|
+
- Selected: last-JSON-object extraction, same strict checks, same
|
|
122
|
+
fail-closed default. Shipped with the witness fix in one release so the
|
|
123
|
+
engine can drive real steps at all.
|
|
124
|
+
- Addendum (2026-09-27, after two more real failures): the shipped rule
|
|
125
|
+
required the object alone on the final line; real critics write the
|
|
126
|
+
object inline after their summary prose and fail anyway. The rule is
|
|
127
|
+
now "the last top-level object of the reply, extending to the end of
|
|
128
|
+
the trimmed text": forward scan, depth- and string-aware, so trailing
|
|
129
|
+
prose, mid-text objects, and inner objects of a truncated outer object
|
|
130
|
+
all still fail, while the real inline-at-end shape passes.
|
|
131
|
+
Evidence: Evidence: test/core/oneshot-producer.test.ts (real reviewer shapes), runs run_79bd2d13 and run_041dfb8e on the vision lane, and the shipped forward pass in #368.
|
|
132
|
+
|
|
133
|
+
## 2026-09-27 — PR #345: rebase, close, or port (dispatch)
|
|
134
|
+
|
|
135
|
+
- Context: #345 adds `kxm vision assert`, but its base predates the CLI
|
|
136
|
+
restructure that deleted `plugins/kxm/src/cli/vnext.ts`; GitHub reports
|
|
137
|
+
DIRTY/CONFLICTING. The gate module `vision-gate.ts` already exists on
|
|
138
|
+
main; only the command surface is missing.
|
|
139
|
+
- Options:
|
|
140
|
+
- Force the rebase and hand-resolve inside the land pipeline — weight
|
|
141
|
+
0.3. The land rebase stage resolves only three union classes; a
|
|
142
|
+
deleted-file port is none of them, so it fails mid-pipeline anyway.
|
|
143
|
+
- Close #345 as superseded — weight 0.2. Discards reviewed intent
|
|
144
|
+
(skill gate-step wording, fail-closed exit contract) that is still
|
|
145
|
+
wanted.
|
|
146
|
+
- Port the four pieces (handler, registration, test, skill wording)
|
|
147
|
+
onto the current CLI structure through a writer lane — weight 0.9.
|
|
148
|
+
Small surface, the PR stays open until the port lands, and the
|
|
149
|
+
dispatch is the first engine-driven unit on 0.7.131, feeding
|
|
150
|
+
loop-dispatch.
|
|
151
|
+
- Selected: port through the engine lane `vision-assert-port`; the PR is
|
|
152
|
+
closed by its replacement landing, not by hand.
|
|
153
|
+
Evidence: Evidence: merge-base 77beda4 predates the CLI restructure; merge-tree showed cli/vnext.ts deleted on main; vision-gate.ts already on main.
|
|
@@ -13,6 +13,16 @@ entry whose fix has landed is deleted, not archived.
|
|
|
13
13
|
|
|
14
14
|
## Dispatch and lanes
|
|
15
15
|
|
|
16
|
+
- **A "no retired names anywhere" rule must exclude the history pages.**
|
|
17
|
+
The P2 brief asked that retired recipe names appear nowhere in docs; the
|
|
18
|
+
writer then rewrote dated lessons and rules on this page and on
|
|
19
|
+
`operating-rules.md` into nonsense ("applies to `kxm lane run` and
|
|
20
|
+
`kxm lane run`") and hand-edited generated roadmap pages. Sweeps like
|
|
21
|
+
that exclude `docs/contributing/learnings.md`, `operating-rules.md`,
|
|
22
|
+
`plans/`, and `CHANGELOG.md`, and the planner reverts any edit to them.
|
|
23
|
+
Evidence: omp-align-p2, 2026-09-26. Applies to: every brief with a
|
|
24
|
+
"returns nothing" grep.
|
|
25
|
+
|
|
16
26
|
- **Branch every lane from the current `origin/main`, and rebase before
|
|
17
27
|
review, not after.** Three branches cut before #330 and #331 landed each
|
|
18
28
|
needed a hand rebase with the same additive conflicts (`cli.ts`
|
|
@@ -31,11 +41,14 @@ entry whose fix has landed is deleted, not archived.
|
|
|
31
41
|
supervisor tick and any batch of writers finishing together.
|
|
32
42
|
- **The transport's stdin read can fail with `EAGAIN` under concurrent
|
|
33
43
|
detached dispatch.** Retry once; the request itself is fine. Evidence:
|
|
34
|
-
two occurrences on 2026-09-26 (backlog S18). Applies to:
|
|
35
|
-
|
|
44
|
+
two occurrences on 2026-09-26 (backlog S18). Applies to:
|
|
45
|
+
`scripts/harness-run.mjs` dispatches, which outlive the retired just
|
|
46
|
+
recipes.
|
|
36
47
|
- **Do not launch a writer under the Bash tool's ten-minute background
|
|
37
|
-
cap.** It kills the harness mid-run.
|
|
38
|
-
`kxm lane run`. Evidence: the first
|
|
48
|
+
cap.** It kills the harness mid-run. Give the dispatch call an unbounded
|
|
49
|
+
timeout, use the detached runner, or `kxm lane run`. Evidence: the first
|
|
50
|
+
lane-cli dispatch, 2026-09-26; omp-align-p2 repairs ran 15 to 36 minutes
|
|
51
|
+
in 2026-09-26 background jobs with an unbounded timeout and survived.
|
|
39
52
|
- **Do not run a standalone `npm run verify` on a branch that `kxm land`
|
|
40
53
|
will land.** The `verify` stage runs it again, so the standalone run
|
|
41
54
|
only spends one of the two verify slots twice. Run the critics on the
|
|
@@ -44,63 +57,47 @@ entry whose fix has landed is deleted, not archived.
|
|
|
44
57
|
|
|
45
58
|
## Engine and runtime
|
|
46
59
|
|
|
47
|
-
- **A lane
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
`
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
60
|
+
- **A lane whose `.kxm` schemas are ahead of the installed runtime cannot
|
|
61
|
+
be driven, observed, or cancelled by the engine.** Every run-scoped
|
|
62
|
+
request (status, drive, cancel, receipt) answers 400
|
|
63
|
+
`schema_additionalProperties`, because `loadKxmProject` validates the
|
|
64
|
+
project before the route: installed 0.7.130 refuses the P2 lane's
|
|
65
|
+
`role:` on `.kxm/agents/*.yaml` while the branch's own loader validates
|
|
66
|
+
clean. The morning `implement-only` run executed before the writer
|
|
67
|
+
rewrote the agent files (c352285 landed mid-run), then settled `failed`
|
|
68
|
+
with `authored: false` and witness unchanged, and the lane now refuses
|
|
69
|
+
new runs with `lane_run_open` because that run cannot be cancelled.
|
|
70
|
+
Until the branch ships, `kxm update --kxm` runs, and the runtime
|
|
71
|
+
supervisor restarts, dispatch repairs and critics through the harness
|
|
72
|
+
transport. Resolved for this lane by 0.7.131: after the update and a
|
|
73
|
+
runtime restart, the lane loads clean, the stuck run cancelled
|
|
74
|
+
idempotently, and a simulated drive returned a verified receipt.
|
|
75
|
+
Evidence: omp-align-p2 lane, 2026-09-26. Applies to: every
|
|
76
|
+
dispatch whose lane changes schemas.
|
|
64
77
|
|
|
65
|
-
- **The improvement
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
attempts show up only when the report runs inside that lane, or once the
|
|
76
|
-
lane is registered under the project (backlog S24).
|
|
78
|
+
- **The improvement reports read only the control root's own store.**
|
|
79
|
+
`kxm improve report` and `kxm routing report` read the run-events store
|
|
80
|
+
of the checkout they run in, so a registered lane's attempts are
|
|
81
|
+
invisible from the parent (backlog S30): on 2026-09-26 the control-root
|
|
82
|
+
report read 0 records while the lane store held the settled attempts.
|
|
83
|
+
Run the reports inside the lane, or dispatch through the engine from the
|
|
84
|
+
root you report on. Evidence: both reports on the P2 control root
|
|
85
|
+
(0 records) versus the same reports inside the omp-align-p2 and
|
|
86
|
+
docs-cadence lanes (settled attempts). Applies to: the supervisor's
|
|
87
|
+
improvement loop and any report run from a parent checkout.
|
|
77
88
|
|
|
78
|
-
- **A live agent step had a hard 120 second timeout with no configuration
|
|
79
|
-
path.** The supervisor built the one-shot producer without a timeout.
|
|
80
|
-
Fixed on the run-driver-timeouts branch (step `timeoutMs`, project
|
|
81
|
-
`limits.agentStepTimeoutMs`, default one hour). Delete this entry when
|
|
82
|
-
that lands.
|
|
83
|
-
- **A run with an unreconciled executing attempt could not be cancelled or
|
|
84
|
-
driven again**, and that survived a supervisor restart; deleting the
|
|
85
|
-
lane's Runtime project store was the only recovery. Fixed on the same
|
|
86
|
-
branch (`executing_unrecorded`, admission released on a handoff receipt).
|
|
87
|
-
Delete when it lands.
|
|
88
|
-
- **The engine sends `--reasoning-effort low` on a first attempt regardless
|
|
89
|
-
of the role's effort.** `engine.ts` hard-codes it. Open; covered by the
|
|
90
|
-
role alignment plan P2 and P6.
|
|
91
89
|
- **Template provenance is refused when the installed kxm moves ahead of
|
|
92
90
|
the stamped revision, and a project without the file validates as
|
|
93
91
|
ready.** Deleting the file is the sanctioned state until `kxm init` can
|
|
94
|
-
re-stamp. Evidence:
|
|
92
|
+
re-stamp. Evidence: backlog S3 (still open; the re-stamp decision is
|
|
93
|
+
unmade) and the live check at `plugins/kxm/src/project-config.ts`.
|
|
94
|
+
Applies to: every fresh lane.
|
|
95
95
|
|
|
96
96
|
## `kxm land`
|
|
97
97
|
|
|
98
98
|
- **Auto-merge cannot be enabled on a PR that is already `CLEAN`**; the
|
|
99
99
|
mutation answers "clean status" and the REST squash merge is the path.
|
|
100
100
|
While CI is paused every PR is clean, so this is the normal path.
|
|
101
|
-
- **The Release workflow's run is titled `Release`, never the PR title.**
|
|
102
|
-
Match it by time after the Auto-Release run. Fixed on kxm-land-followup;
|
|
103
|
-
delete when it lands.
|
|
104
101
|
- **A verify failure inside `kxm land` shows only the child's last output
|
|
105
102
|
line.** Re-run verify by hand to see the cause until backlog S19 lands.
|
|
106
103
|
|
|
@@ -110,9 +107,13 @@ entry whose fix has landed is deleted, not archived.
|
|
|
110
107
|
main's later additions as deletions.** Say the base commit in the brief
|
|
111
108
|
and tell the critic to review against it. Evidence: docs-site review,
|
|
112
109
|
two of five findings were base artifacts.
|
|
113
|
-
- **
|
|
114
|
-
|
|
115
|
-
|
|
110
|
+
- **Read-only critics cannot leave their lane sandbox.** The architecture
|
|
111
|
+
critic three times could not read a brief under the main checkout's
|
|
112
|
+
`.kxm/briefs/` and reviewed against the question list alone, once
|
|
113
|
+
re-flagging a decision the brief had already settled. Copy the brief
|
|
114
|
+
into the lane's gitignored `.kxm/logs/` and dispatch from that path.
|
|
115
|
+
Evidence: omp-align-p2 passes 1 to 3, 2026-09-26. Applies to: every
|
|
116
|
+
read-only critic dispatch.
|
|
116
117
|
|
|
117
118
|
## omp research, kept for the alignment plan
|
|
118
119
|
|
|
@@ -30,7 +30,8 @@ replacement.
|
|
|
30
30
|
merge, and follow through to the auto-release tag and the npm publish.
|
|
31
31
|
Report the outcome; do not stop to ask for the merge. Enforced by
|
|
32
32
|
`kxm land` (verify, docs, push, pr, rebase, unblock, merge, release,
|
|
33
|
-
milestone)
|
|
33
|
+
milestone); every stage ran green end to end on #338 with kxm 0.7.126,
|
|
34
|
+
so hand landing is the exception, not the rule. (2026-09-26.)
|
|
34
35
|
- **Documentation is regenerated after a green pipeline and before the
|
|
35
36
|
merge.** The `docs` stage of `kxm land` runs the roadmap generator and
|
|
36
37
|
commits the regenerated pages on the branch. (2026-09-26.)
|
|
@@ -54,9 +55,14 @@ replacement.
|
|
|
54
55
|
entry point is a `kxm` command: a group under `plugins/kxm/src/cli/`,
|
|
55
56
|
registered in `cli.ts`, owned by a bundled skill so `check:generated`
|
|
56
57
|
passes, documented in the CLI reference. Existing recipes retire as their
|
|
57
|
-
`kxm` verbs land; the transport recipes (`impl`, `plan`, `review
|
|
58
|
-
`impl-bg`)
|
|
59
|
-
|
|
58
|
+
`kxm` verbs land; the transport recipes (`impl`, `plan`, `review-arch`,
|
|
59
|
+
`review-cli`, `impl-bg`, `dispatch`) retired in #343, so units dispatch
|
|
60
|
+
through `kxm lane run <unit> --brief <file> --workflow implement-only`
|
|
61
|
+
and the read-only critic workflows `review-arch-only` and
|
|
62
|
+
`review-cli-only`. `just` keeps only the assignment-runner recipes
|
|
63
|
+
(`assign`, `witness`, `accept`, `observe-cost`, `attribute`,
|
|
64
|
+
`change-report`, `plan-current`), which are harness transport for the
|
|
65
|
+
issue 127 runner. (2026-09-26.)
|
|
60
66
|
|
|
61
67
|
## Accounts
|
|
62
68
|
|
|
@@ -72,6 +78,13 @@ replacement.
|
|
|
72
78
|
|
|
73
79
|
## Decisions and debt
|
|
74
80
|
|
|
81
|
+
- **Automated KXM work records every medium-or-higher decision it makes in
|
|
82
|
+
`docs/contributing/decisions.md`** for its working project: the options
|
|
83
|
+
evaluated, the weight each option scored and against what, and why the
|
|
84
|
+
selected option won. Recorded the turn the decision is taken, not at
|
|
85
|
+
session end. The doc keeps the last 50 entries; older ones rotate to
|
|
86
|
+
`docs/contributing/decisions-archive.jsonl` as `kxm.decision-archive.v1`
|
|
87
|
+
lines. (2026-09-27.)
|
|
75
88
|
- **Every option comes with pros and cons and two recommendations**, the
|
|
76
89
|
solid-product answer and the interim answer. (2026-09-26.)
|
|
77
90
|
- **Every shortcut goes on the backlog the same turn it is taken**, as an
|
|
@@ -102,10 +115,10 @@ refusals, and the two roadmap skills. (2026-09-26.)
|
|
|
102
115
|
form: `[{lane}/{agent}]: {phrase}. {No action|Review needed}. -
|
|
103
116
|
{E}e|{D}d ({M}m{S}s)`. Routine lines are not echoed back in chat.
|
|
104
117
|
(2026-09-26, formatter at `~/.claude/scripts/evt-monitor.sh`.)
|
|
105
|
-
- **A supervisor tick runs every
|
|
118
|
+
- **A supervisor tick runs every thirty minutes** while a session is open:
|
|
106
119
|
sweep the lanes, act on "Review needed", cap concurrent verifies at two,
|
|
107
120
|
regenerate the roadmap after a merge, and run the improvement loop every
|
|
108
|
-
|
|
121
|
+
tick. Its prompt is checked in at
|
|
109
122
|
`plans/kxm-roadmap/supervisor-prompt.md`; a tick that finds the schedule
|
|
110
123
|
missing or expiring recreates it from that file in the same chat session,
|
|
111
124
|
never a new one, so the loop continues under the same task. (2026-09-26.)
|
package/docs/glossary.md
CHANGED
|
@@ -104,7 +104,7 @@ Another [agent](#agent) in the same [project](#project). `kxm_list` and `kxm pee
|
|
|
104
104
|
|
|
105
105
|
### Project
|
|
106
106
|
|
|
107
|
-
The authentication and discovery namespace on the hub. Every command resolves it the same way: `--project` or `KXM_PROJECT`, then the [project ID](#project-id) in `.kxm/project.yaml`, then the `package.json` name, then the directory name. Its key in the hub's `KXM_PROJECT_TOKENS
|
|
107
|
+
The authentication and discovery namespace on the hub. Every command resolves it the same way: `--project` or `KXM_PROJECT`, then the active mode's `project` in `.kxm/config.yaml`, then the [project ID](#project-id) in `.kxm/project.yaml`, then the `package.json` name, then the directory name. Its token is a key reference in that config, or the matching key in the hub's `KXM_PROJECT_TOKENS`. Agents see only peers in the same project.
|
|
108
108
|
|
|
109
109
|
### Project ID
|
|
110
110
|
|
|
@@ -112,7 +112,7 @@ The stable `prj_` identifier in `.kxm/project.yaml`. It is the hub [project](#pr
|
|
|
112
112
|
|
|
113
113
|
### Project token
|
|
114
114
|
|
|
115
|
-
The credential that the agents of one [project](#project) use. The operator
|
|
115
|
+
The credential that the agents of one [project](#project) use. The operator points config at it with `key.op` (`op://vault/item/field`) or `key.env` (an environment variable name), or sets the hub's `KXM_PROJECT_TOKENS` JSON map. The config file never holds the token. Agents receive the resolved value as `KXM_AUTH_TOKEN` or the plugin's `auth_token`. Setting `KXM_PROJECT_TOKENS` replaces the hub's saved map, so list every project each time. A config `hub.projects` map is resolved in memory and is not saved.
|
|
116
116
|
|
|
117
117
|
### Session token
|
|
118
118
|
|
|
@@ -88,7 +88,7 @@ If a malformed claim remains, read the exact `.pid` JSON in the state directory
|
|
|
88
88
|
| `hub_bind_unauthenticated` | The URL is remote and this machine has no token for the project; export it and bind again |
|
|
89
89
|
| `hub_credential_unreadable` | Repair or remove `hub-env.json` under the user state root |
|
|
90
90
|
| `cloud_token_missing` | A `--cloud` binding's variable is empty and it has no working command. Export the variable or fix `--token-command`. This machine's hub-env token is not sent |
|
|
91
|
-
| `cloud_flag_required` | `--token-
|
|
91
|
+
| `cloud_flag_required` | `--token-command` was passed without `--cloud`. `--token-env` and `--key-op` are key references and are valid on a local bind |
|
|
92
92
|
| 401 after binding a loopback forward | The bind was not `--cloud`, so the client sent the local hub-env token. See [Cross-box peer attach](../operations.md#cross-box-peer-attach) |
|
|
93
93
|
|
|
94
94
|
## Claude Code plugin and MCP
|
|
@@ -99,7 +99,7 @@ The [plugin troubleshooting guide](../../plugins/kxm/README.md#troubleshooting)
|
|
|
99
99
|
|---|---|
|
|
100
100
|
| `kxm_*` tools do not appear | Check `/mcp` for the `kxm` server, check `node --version`, run `/reload-plugins`, and confirm `claude plugin list` shows `kxm@kxm` enabled |
|
|
101
101
|
| `KXM hub unreachable at <url>` | Start the hub, or correct `server_url` with `/plugin configure kxm@kxm` |
|
|
102
|
-
| `no project token for project <p>` |
|
|
102
|
+
| `kxm has no project token for project <p>` | The message names where `<p>` came from. Set `hub.local.project` or `hub.cloud.project` and a key reference in `.kxm/config.yaml`, or add `<p>` to the hub's full `KXM_PROJECT_TOKENS` map and restart the hub. Never paste the token into the file |
|
|
103
103
|
| `KXM hub rejected the project token for project <p>` | Enter the token the hub holds for `<p>` |
|
|
104
104
|
| `tool_policy_denied: Session token on disk is malformed or expired` | Run `kxm session token --clear` |
|
|
105
105
|
| Pushed requests never arrive | Start Claude Code with `claude --dangerously-load-development-channels plugin:kxm@kxm` and accept the trust prompt, or use `kxm_inbox` and `kxm_reply` |
|
package/docs/operations.md
CHANGED
|
@@ -92,7 +92,7 @@ Expected output:
|
|
|
92
92
|
|
|
93
93
|
```text
|
|
94
94
|
bound hub http://127.0.0.1:17331 · remote · health=on · token is not stored
|
|
95
|
-
hub health=true ready=true · remote hub
|
|
95
|
+
hub health=true ready=true · remote hub · mode=cloud project=prj_example (.kxm/config.yaml hub.cloud.project) key=env:KXMD_HUB_TOKEN
|
|
96
96
|
```
|
|
97
97
|
|
|
98
98
|
`--token-env` and `--token-command` can be combined. A non-empty variable wins.
|
|
@@ -115,8 +115,8 @@ kxm hub view
|
|
|
115
115
|
|---|---|---|
|
|
116
116
|
| Loopback URL | Scope `loopback`. No credential required | Scope `remote`, including an SSH forward |
|
|
117
117
|
| Token stored in `hub-binding.json` | No | No. The file names `tokenEnv` and/or `tokenCommand` |
|
|
118
|
-
| Credential later commands send | `KXM_AUTH_TOKEN`, then this machine's hub-env | The named source
|
|
119
|
-
| Missing source | Agent commands report `project_token_missing` | `cloud_token_missing` or `cloud_token_command_failed`. The local admin token is not sent |
|
|
118
|
+
| Credential later commands send | `KXM_AUTH_TOKEN`, then the active mode's key reference in `.kxm/config.yaml`, then this machine's hub-env | The active mode's key reference, then the binding's named source. Hub-env is not a fallback |
|
|
119
|
+
| Missing source | Agent commands report `project_token_missing` and name the project id that was sent | `cloud_token_missing` or `cloud_token_command_failed`. The local admin token is not sent |
|
|
120
120
|
| `kxm hub start` from an extension | May start a local hub | Does not start a local hub when the forward is down (`cloud_hub_unreachable`) |
|
|
121
121
|
|
|
122
122
|
`kxm hub view`, `kxm tenant status`, `kxm peer`, `kxm workflow` agent commands,
|
|
@@ -124,9 +124,60 @@ kxm hub view
|
|
|
124
124
|
all use that source. `kxm agent worker` puts `KXM_AUTH_TOKEN` in the child
|
|
125
125
|
process environment only. It does not write the token to disk.
|
|
126
126
|
|
|
127
|
-
The hub project id is the same value
|
|
128
|
-
|
|
129
|
-
`package.json` `name`, then the directory name.
|
|
127
|
+
The hub project id is the same value everywhere: `--project` or `KXM_PROJECT`,
|
|
128
|
+
then the active mode's `project` in `.kxm/config.yaml`, then the `id` in
|
|
129
|
+
`.kxm/project.yaml`, then `package.json` `name`, then the directory name.
|
|
130
|
+
|
|
131
|
+
### Hub identity in config
|
|
132
|
+
|
|
133
|
+
Hub URL, mode, project id, and key reference live in `.kxm/config.yaml`
|
|
134
|
+
(`kxm.config.v1`), the same file as `hub.autoStart`. `.kxm/project.yaml` stays
|
|
135
|
+
the stable project id. The project file wins over
|
|
136
|
+
`~/.config/kxm/config.yaml`. `KXM_PROJECT` and `KXM_SERVER_URL` select the
|
|
137
|
+
live connection for one process. They do not rewrite the file.
|
|
138
|
+
|
|
139
|
+
```yaml
|
|
140
|
+
hub:
|
|
141
|
+
autoStart: background
|
|
142
|
+
mode: local # local | cloud
|
|
143
|
+
local:
|
|
144
|
+
url: http://127.0.0.1:7331
|
|
145
|
+
project: prj_example # optional; defaults to the project.yaml id
|
|
146
|
+
key:
|
|
147
|
+
op: op://Private/kxm/local-project-token
|
|
148
|
+
env: KXM_LOCAL_PROJECT_TOKEN
|
|
149
|
+
cloud:
|
|
150
|
+
url: https://hub.kxmd.dev
|
|
151
|
+
project: prj_example
|
|
152
|
+
key:
|
|
153
|
+
op: op://Private/kxmd/project-token
|
|
154
|
+
env: KXMD_HUB_TOKEN
|
|
155
|
+
projects: # hub process map; references only
|
|
156
|
+
prj_example:
|
|
157
|
+
op: op://Private/kxm/local-project-token
|
|
158
|
+
env: KXM_LOCAL_PROJECT_TOKEN
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
`key.op` is an `op://vault/item/field` reference. `key.env` is an environment
|
|
162
|
+
variable name. A non-empty variable wins; otherwise `op read` runs when the
|
|
163
|
+
client or the hub needs the token. The resolved value is not written to
|
|
164
|
+
config, `hub-binding.json`, or `hub-env.json`. A literal token is refused
|
|
165
|
+
with `hub_config_invalid`.
|
|
166
|
+
|
|
167
|
+
`kxm hub bind` and `kxm hub bind --cloud` write the mode, URL, project id, and
|
|
168
|
+
key reference. `--key-op` is the `op://` reference for either mode.
|
|
169
|
+
`--token-env` names the variable for either mode. `--token-command` stays
|
|
170
|
+
cloud-only. `kxm hub view` prints the mode, URL, project id, and key source.
|
|
171
|
+
It does not print the token. `kxm hub unbind` removes the binding and
|
|
172
|
+
`hub.mode`, and leaves the `local` and `cloud` blocks in place.
|
|
173
|
+
|
|
174
|
+
On the hub, `hub.projects` is that same kind of map. `KXM_PROJECT_TOKENS`
|
|
175
|
+
still replaces the map and is saved. A config map is resolved in memory and
|
|
176
|
+
does not replace the saved file.
|
|
177
|
+
|
|
178
|
+
A setup whose hub map is still keyed by the package name should set
|
|
179
|
+
`hub.local.project` or `hub.cloud.project` to that name. Otherwise clients
|
|
180
|
+
send the `.kxm/project.yaml` id and the hub has no token for it.
|
|
130
181
|
|
|
131
182
|
### Remove the binding
|
|
132
183
|
|
|
@@ -134,8 +185,10 @@ The hub project id is the same value for peer commands and `kxm tenant status`:
|
|
|
134
185
|
kxm hub unbind
|
|
135
186
|
```
|
|
136
187
|
|
|
137
|
-
Unbind deletes `hub-binding.json
|
|
138
|
-
|
|
188
|
+
Unbind deletes `hub-binding.json` and clears `hub.mode` in `.kxm/config.yaml`.
|
|
189
|
+
The `local` and `cloud` blocks stay, so the next bind can switch mode again.
|
|
190
|
+
It does not delete hub-env, and it does not close the SSH forward. Stop the
|
|
191
|
+
forward by ending the `ssh -N` session.
|
|
139
192
|
|
|
140
193
|
## Troubleshooting
|
|
141
194
|
|
|
@@ -143,6 +196,7 @@ close the SSH forward. Stop the forward by ending the `ssh -N` session.
|
|
|
143
196
|
|---|---|---|
|
|
144
197
|
| 401 `invalid_auth` after binding `127.0.0.1:17331` | The bind was not `--cloud`, so the client sent this machine's hub-env admin token | Bind again with `--cloud` and a token source that holds the remote hub's token. Unset a stale `KXM_AUTH_TOKEN` that points at the local hub |
|
|
145
198
|
| `cloud_token_missing` | `KXMD_HUB_TOKEN` (or the variable you named) is unset or empty, and no command is configured | Export the variable or pass `--token-command`. The local hub-env token is intentionally unused |
|
|
199
|
+
| `project_token_missing` | The project id sent to the hub has no agent token. The message names that id and where it came from | Set `hub.local.project` or `hub.cloud.project` in `.kxm/config.yaml` to the id the hub already knows, and point `key.op` or `key.env` at the token. `KXM_PROJECT` or `--project` overrides the id for one command. Do not paste the token into the file |
|
|
146
200
|
| `cloud_token_command_failed` | `op` exited non-zero, timed out, or printed more than one line | Run the same command in a terminal and sign in to 1Password. Do not paste the token into the binding |
|
|
147
201
|
| Clients through one SSH host get locked out together | The hub rate-limits by agent id, otherwise by source address. Every forward from one SSH session shares `127.0.0.1` on the hub. `sshd` `MaxStartups` and `MaxSessions` can refuse new forwards first | Give each long-lived agent its own name. Raise the SSH limits on that host if many people share one jump host. Do not point two tenants at one hub |
|
|
148
202
|
| `kxm hub view` says `loopback` for the forward | `--cloud` was omitted | Bind again with `--cloud`. `KXM_SERVER_URL` overrides the binding URL and is labeled on its own |
|