@kontextmind/kxm 0.7.53 → 0.7.54
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 +18 -1
- package/docs/agent-skills.md +1 -1
- package/docs/configuration.md +0 -3
- package/docs/contracts/migration.md +50 -258
- package/docs/contracts/validation.md +15 -33
- package/docs/test-matrix.md +1 -1
- package/package.json +1 -1
- package/plugins/kxm/.claude-plugin/plugin.json +1 -1
- package/plugins/kxm/dist/cli.js +376 -2133
- package/plugins/kxm/dist/mcp-server.js +1 -1
- package/plugins/kxm/dist/runtime-supervisor.js +18 -98
- package/plugins/kxm/dist/runtime.js +18 -98
- package/plugins/kxm/dist/server.js +1 -1
- package/plugins/kxm/package.json +1 -1
- package/plugins/kxm/skills/kxm/SKILL.md +1 -1
- package/plugins/kxm/skills/kxm-project-setup/SKILL.md +4 -7
- package/plugins/kxm/src/autocomplete.ts +0 -3
- package/plugins/kxm/src/cli/project.ts +2 -133
- package/plugins/kxm/src/cli.ts +3 -24
- package/plugins/kxm/src/database.ts +1 -1
- package/plugins/kxm/src/init.ts +10 -6
- package/plugins/kxm/src/mcp-server.ts +1 -1
- package/plugins/kxm/src/project-config.ts +54 -173
- package/schemas/README.md +0 -3
- package/plugins/kxm/src/migrate.ts +0 -1848
- package/schemas/migration-decision.schema.json +0 -26
- package/schemas/migration-plan.schema.json +0 -123
- package/schemas/migration-receipt.schema.json +0 -52
package/CHANGELOG.md
CHANGED
|
@@ -35,6 +35,23 @@ All notable user-facing changes are documented here. The project follows [Semant
|
|
|
35
35
|
|
|
36
36
|
### Changed
|
|
37
37
|
|
|
38
|
+
- **`kxm migrate` is gone, and so is the state that only it could unlock.** Deleting the
|
|
39
|
+
migration lanes left a converter with nothing to convert into: `plugins/kxm/src/migrate.ts`
|
|
40
|
+
(1,848 lines), its 1,598-line suite, the `migrate plan|apply|verify` commands, the
|
|
41
|
+
`kxm.migration-plan.v1` / `-decision.v1` / `-receipt.v1` schemas and their registry
|
|
42
|
+
validators, the receipt reader / self-hash / byte-record helpers, and the
|
|
43
|
+
`.kxm/migration-receipt.yaml` path are all removed. A tree that still holds legacy
|
|
44
|
+
`.kxm/config` JSON now fails closed at load with `legacy_state_unsupported`, one issue per
|
|
45
|
+
legacy file, and no receipt, plan, or option unlocks it — previously a verified receipt made
|
|
46
|
+
a mixed tree loadable, which is exactly the dual-read surface this decision retires.
|
|
47
|
+
`kxm init` classifies such a tree as `mode: "legacy"` (was `"migrate"`), reports
|
|
48
|
+
`legacyInputs`, and writes nothing. `docs/contracts/migration.md` is rewritten as a
|
|
49
|
+
supported/refused matrix instead of a conversion spec, and the packed-install suite now
|
|
50
|
+
builds its trust and run-lifecycle fixture by initialising a project directly, so that
|
|
51
|
+
coverage survived rather than being deleted with the command. A new test asserts
|
|
52
|
+
`kxm migrate` is rejected as an unknown command: a retired verb must fail loudly, not
|
|
53
|
+
resolve to nothing.
|
|
54
|
+
|
|
38
55
|
- **No schema migration lanes, no legacy stamp tolerance (single-operator tool).** Stepwise
|
|
39
56
|
schema migration lanes are removed from the hub store and the per-project event store, and
|
|
40
57
|
the external-effects store no longer runs an in-place `ALTER TABLE ... ADD COLUMN` whose
|
|
@@ -42,7 +59,7 @@ All notable user-facing changes are documented here. The project follows [Semant
|
|
|
42
59
|
ever fire on an older store; the store has no production caller yet, so this closes the
|
|
43
60
|
lane rather than fixing a live upgrade).
|
|
44
61
|
A database stamped behind this build now fails closed with `runtime_schema_outdated` and
|
|
45
|
-
a message
|
|
62
|
+
a message naming the process that recreates the store (`kxm hub start` for hub state, the Runtime for registry/event stores; `kxm init` is project-only) — and the refusal never
|
|
46
63
|
advances `user_version`, so the store stays identifiably old (WAL sidecars may still be
|
|
47
64
|
checkpointed by opening the file, so the whole state set remains the backup unit — see
|
|
48
65
|
[`docs/operations.md`](docs/operations.md)). Relabelling a store it refused to open would
|
package/docs/agent-skills.md
CHANGED
|
@@ -10,7 +10,7 @@ authority, admit new writers, or replace trusted `.kxm/roster.yaml` policy.
|
|
|
10
10
|
| Feature Area | Skill | Commands Covered | Purpose |
|
|
11
11
|
|---|---|---|---|
|
|
12
12
|
| Core Routing | `kxm` | — | Select the right suite skill; state universal safety rules and portable CLI convention |
|
|
13
|
-
| Project Setup | `kxm-project-setup` | `init`, `
|
|
13
|
+
| Project Setup | `kxm-project-setup` | `init`, `trust`, `config`, `completion` | Initialize, review permission changes, configure, and install shell completion |
|
|
14
14
|
| Harness & Auth | `kxm-harness-auth` | `harness`, `auth`, `update`, `runtime`, `agent` | Inspect authenticated harness capability and operate supported runtimes/workers |
|
|
15
15
|
| Hub Operations | `kxm-hub-ops` | `hub`, `backup`, `restore` | Run and protect the local hub and its durable SQLite state |
|
|
16
16
|
| Session Management | `kxm-session` | `session`, `dash`, `studio` | Resume/inspect operator work and use UI capabilities each harness supports |
|
package/docs/configuration.md
CHANGED
|
@@ -273,9 +273,6 @@ The current hub command groups are `agent`, `session`, `workflow`, `gate`, `hub`
|
|
|
273
273
|
| Command | Purpose |
|
|
274
274
|
|---|---|
|
|
275
275
|
| `kxm init` | Atomically create a provenance-tracked minimal KXM project, validate it without rewriting, resume a pinned interrupted create/repair, apply conflict-free non-authority template updates, or join an existing clone with repeatable `--repository <id=absolute-path>` member bindings stored outside Git. `--dry-run` performs no writes. Provenance-free/ambiguous repair and permission-expanding changes remain planning-only. These configuration slices do **not** activate a KXM Runtime. `kxm init` is project-only; bind a running hub with `kxm hub bind <url>` |
|
|
276
|
-
| `kxm migrate plan` | Convert legacy `.kxm/config` JSON (agents, gates, workflow definitions) into a deterministic, secret-free `kxm.migration-plan.v1` report: source/target hashes, decision-requiring ambiguities (terminal status, transition budgets, evidence-policy strengthening, secret drops, narrowed ceilings, foreign producers), hashed unmapped fields, and explicit identity renames. Performs no writes, locks, or staging |
|
|
277
|
-
| `kxm migrate apply [--decisions <file>]` | Install a reviewed migration: re-checks the decision binding against current sources, validates the complete target bundle, refuses to overwrite existing paths, installs durably, and writes a self-hashed `kxm.migration-receipt.v1` that keeps legacy inputs read-only. Re-applying is an idempotent no-op. `--dry-run` performs no writes |
|
|
278
|
-
| `kxm migrate verify` | Re-check the migration receipt against current legacy sources and the target bundle (self-hash, source hashes, configuration revision, resource bytes). Performs no writes |
|
|
279
276
|
| `kxm trust diff [--base <rev>]` | Print the structured `kxm.permission-diff.v1` report between a base Git revision (default `HEAD`, materialized into a temporary shadow with a sanitized environment) and the working tree: every authority-bearing field change classified as expansion, narrowing, or neutral with per-field hashes. Performs no project writes |
|
|
280
277
|
| `kxm trust check [--base <rev>]` | Exit non-zero when any expansion exists, so an authority-bearing change cannot merge without a reviewed Git change. Formatting/description-only changes never require review |
|
|
281
278
|
| `kxm run <workflow> [prompt]` | Auto-start the KXM Runtime supervisor if needed, then create an immutable run offline: pins `homeRuntimeId` plus config/executor/tool policy revisions and stores only the prompt hash. `--dry-run` prints the plan without creating anything |
|
|
@@ -1,258 +1,50 @@
|
|
|
1
|
-
# Migration and compatibility
|
|
2
|
-
|
|
3
|
-
KXM
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
|
13
|
-
|
|
14
|
-
| `.kxm/config
|
|
15
|
-
|
|
|
16
|
-
|
|
|
17
|
-
|
|
|
18
|
-
|
|
|
19
|
-
|
|
|
20
|
-
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
- current `mesh_*` peer tools;
|
|
53
|
-
- current hub APIs behind a compatibility adapter;
|
|
54
|
-
- legacy JSON configuration read support while KXM writes only YAML;
|
|
55
|
-
- current completed workflow history read/export support;
|
|
56
|
-
- Runtime-managed KXM runs in new event stores with new identities;
|
|
57
|
-
- CLI labels for legacy versus KXM state;
|
|
58
|
-
- no implicit movement of active runs between engines.
|
|
59
|
-
|
|
60
|
-
Before activation, a repository MUST NOT use legacy and KXM definitions with
|
|
61
|
-
the same normalized identity. Validation reports the conflict and requires an
|
|
62
|
-
explicit migration choice. After a migration receipt activates the KXM copy,
|
|
63
|
-
the matching legacy definition is read-only compatibility input and cannot be
|
|
64
|
-
selected for a new KXM run.
|
|
65
|
-
|
|
66
|
-
## Migration commands
|
|
67
|
-
|
|
68
|
-
```text
|
|
69
|
-
kxm migrate plan
|
|
70
|
-
kxm migrate apply [--decisions <file>] [--project-id <id>] [--name <name>]
|
|
71
|
-
kxm migrate verify
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
`kxm init` invokes the planning flow when it detects legacy state.
|
|
75
|
-
|
|
76
|
-
> **Superseded (2026-09-20).** The single-operator decision removed every schema
|
|
77
|
-
> migration lane, so "database/WAL migration … remain later-phase work" below is
|
|
78
|
-
> no longer the plan: there will be none. The `kxm migrate` commands described on
|
|
79
|
-
> this page are deleted in the follow-up cut, and a tree still holding legacy JSON
|
|
80
|
-
> fails closed at load instead of being converted.
|
|
81
|
-
|
|
82
|
-
**Implementation status (Phase 1 slice):** the commands above are implemented
|
|
83
|
-
for **configuration migration only** — legacy `agents.json`, `gates.json`, and
|
|
84
|
-
workflow-definition JSON under `.kxm/config/`. Database/WAL migration,
|
|
85
|
-
active-run cutover, session migration, and rollback orchestration remain
|
|
86
|
-
later-phase work and are not performed by these commands.
|
|
87
|
-
|
|
88
|
-
### Plan
|
|
89
|
-
|
|
90
|
-
Produces a secret-free `kxm.migration-plan.v1` report containing:
|
|
91
|
-
|
|
92
|
-
- detected source files with sha256 and byte counts plus a combined
|
|
93
|
-
`sourceDigest`;
|
|
94
|
-
- target resource paths with their rendered content hashes;
|
|
95
|
-
- deterministic ambiguities, each with a stable decision key and the allowed
|
|
96
|
-
values: terminal status for legacy `$terminal` edges, per-edge budgets for
|
|
97
|
-
unbounded back-edges, missing global transition budgets, evidence-policy
|
|
98
|
-
strengthening (`replied` → `passed`), foreign producer identities, secret
|
|
99
|
-
field drops, narrowed permission ceilings, and identity normalization;
|
|
100
|
-
- unrecognized or unmappable fields preserved as hashed `unmapped` entries
|
|
101
|
-
(sensitive values are hashed, never copied);
|
|
102
|
-
- old-to-new identity renames;
|
|
103
|
-
- the resulting permission changes tied to their decision keys.
|
|
104
|
-
|
|
105
|
-
It changes nothing: no writes, no locks, no staging, no local state.
|
|
106
|
-
|
|
107
|
-
### Decisions
|
|
108
|
-
|
|
109
|
-
`kxm migrate apply` requires every ambiguity to be resolved. Decisions are
|
|
110
|
-
supplied either as a reviewed `kxm.migration-decision.v1` YAML file
|
|
111
|
-
(`--decisions <file>`) binding the exact `projectId`, `projectName`, and
|
|
112
|
-
`sourceDigest` of the plan, or programmatically. Unknown decision keys and
|
|
113
|
-
values outside the plan's allowed set fail closed before any write.
|
|
114
|
-
|
|
115
|
-
### Apply
|
|
116
|
-
|
|
117
|
-
1. Acquire the project mutation lock.
|
|
118
|
-
2. Recompute the plan and re-check the decision binding (project, source
|
|
119
|
-
digest, key set, allowed values).
|
|
120
|
-
3. Validate every converted resource against its exact schema and the whole
|
|
121
|
-
bundle against semantic rules.
|
|
122
|
-
4. Refuse to overwrite any existing target path.
|
|
123
|
-
5. Install resources with durable writes (fsync + rename).
|
|
124
|
-
6. Load and validate the complete installed bundle.
|
|
125
|
-
7. Write a hash-linked `kxm.migration-receipt.v1` binding source hashes,
|
|
126
|
-
decision digest, target configuration revision, and installed resource
|
|
127
|
-
hashes; the receipt is self-hashed.
|
|
128
|
-
8. Re-load the mixed tree: legacy inputs remain intact but receipt-pinned
|
|
129
|
-
read-only; `loadKxmProject` accepts coexistence only through the
|
|
130
|
-
verified receipt.
|
|
131
|
-
|
|
132
|
-
Re-applying with the receipt present is an idempotent no-op
|
|
133
|
-
(`already-migrated`). Editing a legacy source after the receipt makes both
|
|
134
|
-
`loadKxmProject` and `kxm migrate verify` fail closed.
|
|
135
|
-
|
|
136
|
-
### Verify
|
|
137
|
-
|
|
138
|
-
`kxm migrate verify` reopens the target, re-checks the receipt self-hash,
|
|
139
|
-
re-hashes legacy sources, and compares the target configuration revision and
|
|
140
|
-
installed resource bytes against the receipt. It performs no writes.
|
|
141
|
-
|
|
142
|
-
## Database migration
|
|
143
|
-
|
|
144
|
-
> **Superseded in part (2026-09-20).** What the code guarantees today is narrower than the
|
|
145
|
-
> checklist below and belongs to two different moments:
|
|
146
|
-
>
|
|
147
|
-
> - **Opening a store** verifies `user_version`, refuses a newer-than-known version, and
|
|
148
|
-
> enables WAL. That is implemented.
|
|
149
|
-
> - **Backing a store up** is where checkpointing, `-wal` handling, integrity verification,
|
|
150
|
-
> and hash recording happen — see the whole-state-set recipe in
|
|
151
|
-
> [`docs/operations.md`](../operations.md). Those are **not** properties of an ordinary open.
|
|
152
|
-
>
|
|
153
|
-
> The legacy-record import paragraphs describe a cutover that will not happen: this build
|
|
154
|
-
> migrates no database, and an older stamp is refused outright.
|
|
155
|
-
|
|
156
|
-
Before any database operation:
|
|
157
|
-
|
|
158
|
-
- verify SQLite `user_version`;
|
|
159
|
-
- refuse a newer unknown version;
|
|
160
|
-
- checkpoint WAL or copy using the SQLite backup API;
|
|
161
|
-
- include `-wal` state correctly rather than copying only the main file;
|
|
162
|
-
- verify backup integrity;
|
|
163
|
-
- record source and target hashes.
|
|
164
|
-
|
|
165
|
-
Current agents, messages, workflow runs, journal entries, and context items are
|
|
166
|
-
imported as typed **legacy records**. They are not fabricated into fine-grained
|
|
167
|
-
KXM run events whose original ordering was never observed.
|
|
168
|
-
|
|
169
|
-
Completed legacy runs remain queryable. A legacy active run must either finish
|
|
170
|
-
on the old engine or be explicitly cancelled/exported; it is not resumed as a
|
|
171
|
-
KXM run.
|
|
172
|
-
|
|
173
|
-
## Configuration migration
|
|
174
|
-
|
|
175
|
-
The implemented converter:
|
|
176
|
-
|
|
177
|
-
- reads legacy JSON with byte/depth/node bounds and token-level duplicate-key
|
|
178
|
-
rejection; linked files and linked `workflows/` directories are never
|
|
179
|
-
traversed for authoritative bytes;
|
|
180
|
-
- normalizes case-insensitive identities, records explicit old-to-new renames,
|
|
181
|
-
and rejects case-fold collisions and destination-invalid names;
|
|
182
|
-
- splits `agents.json` into `.kxm/agents/<id>.yaml` resources and emits one
|
|
183
|
-
`.kxm/models/<id>-primary.yaml` profile per agent whose legacy record pinned
|
|
184
|
-
a provider/model pair with a thinking level;
|
|
185
|
-
- maps roster-only concepts (`ownership`, `host`, top-level `project`) into
|
|
186
|
-
hashed `unmapped` report entries rather than dropping them silently;
|
|
187
|
-
- maps workflow stages to agent steps, preserves `reproOracle`, `planHash`,
|
|
188
|
-
`requirePlanHash`, typed transitions, immutable oracles, and global
|
|
189
|
-
transition budgets, and widens evidence-carrying steps into an explicit
|
|
190
|
-
assignment pool containing their producers;
|
|
191
|
-
- converts legacy peer-reply evidence policies (`acceptedStatuses:
|
|
192
|
-
["replied"]`) into KXM producer policies requiring `passed` only through
|
|
193
|
-
an explicit operator decision;
|
|
194
|
-
- requires decisions for: every legacy `$terminal` edge's terminal status
|
|
195
|
-
(legacy completed the run even on failure outcomes), every unbounded
|
|
196
|
-
back-edge's per-edge budget, missing global budgets, foreign producer
|
|
197
|
-
identities, secret-field drops, unimplemented gates, and each narrowed
|
|
198
|
-
permission ceiling;
|
|
199
|
-
- never copies secret values or environment indirections; webhook secret
|
|
200
|
-
fields are hashed into the report and dropped by explicit decision;
|
|
201
|
-
- records template provenance only for files whose exact generated baseline is
|
|
202
|
-
known; migrated files carry no template provenance and are never
|
|
203
|
-
retroactively adopted;
|
|
204
|
-
- validates the entire target project (exact schemas plus semantic rules)
|
|
205
|
-
before installation and shows the Git diff through normal review.
|
|
206
|
-
|
|
207
|
-
Unknown data is preserved in the migration report, not placed into a generic
|
|
208
|
-
runtime extension map.
|
|
209
|
-
|
|
210
|
-
Legacy typed workflows have a global transition budget but may lack KXM
|
|
211
|
-
per-back-edge caps. The migrator MUST NOT invent those caps silently. `migrate
|
|
212
|
-
plan` lists every affected edge and a proposed bounded value; `migrate apply`
|
|
213
|
-
requires the values in an operator-approved migration decision. The committed
|
|
214
|
-
KXM `/fix` fixture is one reviewed resolution, not a generic automatic rule.
|
|
215
|
-
|
|
216
|
-
Stage IDs, outcome keys, evidence keys, oracle references, plan-hash references,
|
|
217
|
-
and eligible producer identities are preserved by default. Any unavoidable
|
|
218
|
-
normalization appears as an explicit old-to-new mapping and rewrites all bound
|
|
219
|
-
references atomically.
|
|
220
|
-
|
|
221
|
-
## Session migration
|
|
222
|
-
|
|
223
|
-
Old shared Pi histories may contain content from broader scopes. They remain
|
|
224
|
-
archived under the old worker binding and are never selected for a KXM run.
|
|
225
|
-
The first KXM physical session starts clean. Durable facts must come from Git,
|
|
226
|
-
workflow evidence, artifacts, or promoted context rather than conversation
|
|
227
|
-
history.
|
|
228
|
-
|
|
229
|
-
## Rollback
|
|
230
|
-
|
|
231
|
-
Rollback is supported until the operator accepts the migration receipt and
|
|
232
|
-
starts a permission-expanding KXM-only run.
|
|
233
|
-
|
|
234
|
-
Rollback:
|
|
235
|
-
|
|
236
|
-
1. stop KXM writers;
|
|
237
|
-
2. preserve KXM stores as diagnostic artifacts;
|
|
238
|
-
3. restore the recorded legacy configuration selection and database path;
|
|
239
|
-
4. restart only compatible legacy processes;
|
|
240
|
-
5. verify legacy health and record rollback evidence.
|
|
241
|
-
|
|
242
|
-
Events created only by KXM are not reverse-translated into fabricated legacy
|
|
243
|
-
workflow history.
|
|
244
|
-
|
|
245
|
-
## Removal gate
|
|
246
|
-
|
|
247
|
-
> **Superseded (2026-09-20).** The operator decided removal happens **without** a
|
|
248
|
-
> compatibility release, so the list below no longer gates removal — it is kept only
|
|
249
|
-
> to record why the gate existed. Legacy readers are being deleted now, and old names
|
|
250
|
-
> fail closed by brake rather than alias.
|
|
251
|
-
|
|
252
|
-
Legacy readers and command aliases are removed only after:
|
|
253
|
-
|
|
254
|
-
- at least one compatibility release;
|
|
255
|
-
- migration telemetry shows no material unmapped cases;
|
|
256
|
-
- package/install/Windows tests cover KXM;
|
|
257
|
-
- operator documentation and rollback paths are proven;
|
|
258
|
-
- removal is announced in the changelog.
|
|
1
|
+
# Migration and compatibility
|
|
2
|
+
|
|
3
|
+
**KXM carries no migration path.** The product ships for a single operator, and
|
|
4
|
+
the operator decision (recorded in
|
|
5
|
+
[`plans/implementation-plan.md`](../../plans/implementation-plan.md)) is that
|
|
6
|
+
older state is replaced, not converted. Old names are not accepted; old state
|
|
7
|
+
is refused loudly. This page documents what that means at each boundary so no
|
|
8
|
+
one re-adds a compatibility lane by inference.
|
|
9
|
+
|
|
10
|
+
## What happens to older input
|
|
11
|
+
|
|
12
|
+
| Boundary | Behaviour |
|
|
13
|
+
|---|---|
|
|
14
|
+
| Project tree with legacy `.kxm/config` JSON | `loadKxmProject` fails closed with `legacy_state_unsupported`, one issue per legacy file. No receipt, plan, flag, or environment variable unlocks it. |
|
|
15
|
+
| `kxm init` on such a tree | Reports `mode: "legacy"`, lists `legacyInputs`, performs **no writes**. Recovery is a fresh project directory plus the YAML definitions worth keeping. |
|
|
16
|
+
| `kxm migrate` | Unknown command. It existed as `plan` / `apply` / `verify` for pre-KXM JSON and was deleted with this decision. |
|
|
17
|
+
| SQLite store stamped with an older `user_version` | Refused with `runtime_schema_outdated`; the refusal never advances `user_version`, so the store stays identifiably old. Delete the state file and let the process that owns it recreate the store (`kxm hub start` for hub state, the Runtime for registry/event stores). `kxm init` is **project-only** and rebuilds no database. Forward-only stamping is prohibited — it turns a clean failure into a later query against a column that does not exist. |
|
|
18
|
+
| Retired product and command names | Rejected by fail-closed brakes (lint + readiness tests), not aliased. |
|
|
19
|
+
| Shared/off-scope Pi history | Never imported into a narrower run scope. A new physical session starts clean; durable facts come from Git, workflow evidence, artifacts, or promoted context. |
|
|
20
|
+
| Historical run records | Never fabricated. Events whose real ordering was not observed stay absent rather than reconstructed into a finer-grained model. |
|
|
21
|
+
|
|
22
|
+
## What is *not* relaxed by this
|
|
23
|
+
|
|
24
|
+
Deleting conversion code does not soften the guarantees around the state that
|
|
25
|
+
does exist:
|
|
26
|
+
|
|
27
|
+
- **Fresh installs must be complete.** Every table, index, and default that a
|
|
28
|
+
store needs is declared in its current schema definition, so an empty store is
|
|
29
|
+
valid without any upgrade step.
|
|
30
|
+
- **Backups stay whole.** The hub state set is copied as documented in
|
|
31
|
+
[`docs/operations.md`](../operations.md); a single `kxm.db` copy is not a
|
|
32
|
+
backup.
|
|
33
|
+
- **Out-of-range versions refuse without touching the file.** The stamp is read
|
|
34
|
+
before anything that can modify the store, so a database this build refuses —
|
|
35
|
+
older or newer — comes back byte-identical: neither its schema nor its
|
|
36
|
+
`user_version` changes, and it is not converted to WAL as a side effect of being
|
|
37
|
+
rejected. A store ahead of this build is refused without downgrade.
|
|
38
|
+
- **Schema changes are additive-and-replace, not in-place.** Land the new
|
|
39
|
+
definition, delete the local state, and let the process that owns each store
|
|
40
|
+
recreate it — `kxm hub start` for hub state, the Runtime for registry and
|
|
41
|
+
event stores. `kxm init` is project-only and rebuilds no database.
|
|
42
|
+
Nothing in the runtime may rewrite an existing store's shape.
|
|
43
|
+
|
|
44
|
+
## If this ever changes
|
|
45
|
+
|
|
46
|
+
Re-introducing migration needs a written decision first, because the cost is
|
|
47
|
+
not the converter — it is the permanent dual-read surface (legacy names staying
|
|
48
|
+
loadable, receipts that unlock state, and a test matrix that must keep proving
|
|
49
|
+
both sides). Any such proposal has to name the state it protects and who owns
|
|
50
|
+
it; "someone might have an old directory" is not a reason on its own.
|
|
@@ -107,39 +107,21 @@ hard-link support fails safely. Create keeps its same-volume directory rename.
|
|
|
107
107
|
A newer process must finish the pinned transaction before planning another
|
|
108
108
|
template revision.
|
|
109
109
|
|
|
110
|
-
#### Legacy configuration
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
identities, secret-field drops, unimplemented gates, and each narrowed
|
|
126
|
-
permission ceiling. Unrecognized or unmappable fields are preserved as
|
|
127
|
-
hashed `unmapped` entries; sensitive values are hashed, never copied.
|
|
128
|
-
Identity normalization that changes a name is an explicit `renames` entry
|
|
129
|
-
applied to all bound references; case-fold collisions fail closed.
|
|
130
|
-
- Apply requires a reviewed `kxm.migration-decision.v1` (or programmatic
|
|
131
|
-
resolutions) binding the exact plan: project ID, project name, and source
|
|
132
|
-
digest. Unknown keys and values outside the allowed set fail closed before
|
|
133
|
-
any write. The complete target bundle must pass exact-schema and semantic
|
|
134
|
-
validation before installation; existing target paths are never overwritten.
|
|
135
|
-
- Installation uses durable writes under the project mutation lock and finishes
|
|
136
|
-
with a self-hashed `kxm.migration-receipt.v1` binding source hashes, decision
|
|
137
|
-
digest, target configuration revision, and installed resource hashes. The
|
|
138
|
-
receipt keeps the legacy inputs read-only: `loadKxmProject` accepts mixed
|
|
139
|
-
trees only through a verified receipt, and any later legacy-source edit makes
|
|
140
|
-
loading and `migrate verify` fail closed. Re-apply is an idempotent no-op.
|
|
141
|
-
- `plan`, `verify`, and every `--dry-run` path perform no writes, locks,
|
|
142
|
-
staging, backups, or Runtime-local state creation.
|
|
110
|
+
#### Legacy configuration is refused, not migrated
|
|
111
|
+
|
|
112
|
+
This build carries **no** legacy conversion path. A tree that still holds
|
|
113
|
+
`.kxm/config` JSON fails closed:
|
|
114
|
+
|
|
115
|
+
- `loadKxmProject` rejects it with `legacy_state_unsupported` per legacy file, and
|
|
116
|
+
no receipt, plan, or option unlocks it any more.
|
|
117
|
+
- `kxm init` classifies the tree as `mode: "legacy"`, reports the discovered
|
|
118
|
+
`legacyInputs`, and performs **no writes** — it never converts on the side.
|
|
119
|
+
- `kxm migrate` is not a command; invoking it is an unknown-command error.
|
|
120
|
+
|
|
121
|
+
The operator decision behind this is recorded in
|
|
122
|
+
[`plans/implementation-plan.md`](../../plans/implementation-plan.md): single
|
|
123
|
+
operator, no backwards compatibility. Recover by initialising a fresh project
|
|
124
|
+
directory and copying the YAML definitions worth keeping.
|
|
143
125
|
|
|
144
126
|
`--dry-run` may parse and classify a transaction but MUST NOT create the writer
|
|
145
127
|
mutex, state directories, staging, backups, temporary files, or cleanup. Live
|
package/docs/test-matrix.md
CHANGED
|
@@ -56,7 +56,7 @@ npm run verify
|
|
|
56
56
|
| Package and marketplace version consistency | `scripts/check-versions.mjs` |
|
|
57
57
|
| Planned KXM schemas, restricted YAML fixtures, cross-resource semantics, and sync-safe rejection | `test/core/contracts.test.ts` |
|
|
58
58
|
| Production KXM restricted loader, deterministic bundle hashing, Git discovery, fail-closed semantics, init classification, provenance-tracked atomic creation, exact three-way repair, authority-change blocking, pinned crash resumption, shadow validation, explicit join, Runtime-local bindings, CLI isolation, and idempotence | `test/core/project-config.test.ts`, `test/core/cli.test.ts`, `test/core/package-install.test.ts` |
|
|
59
|
-
|
|
|
59
|
+
| Legacy state is refused, never converted: a tree with `.kxm/config` JSON fails project load with `legacy_state_unsupported`, `kxm init` classifies it `mode: "legacy"` without writing, `kxm migrate` is an unknown command, and an older stamped store is refused without advancing `user_version` | `test/core/project-config.test.ts`, `test/core/cli.test.ts`, `test/core/e6-backup-restore-migrations.test.ts` |
|
|
60
60
|
| Permission-diff trust workflow: structured authority projections, conservative lattice classification (access, network, budgets, quorums, snapshots, secrets, transitions, shapes), prose neutrality, Git base shadowing, CLI diff/check gating, and packed-consumer round trips | `test/core/permission.test.ts`, `test/core/cli.test.ts`, `test/core/contracts.test.ts`, `test/core/package-install.test.ts` |
|
|
61
61
|
| Event-sourced local Runtime: supervisor singleton with stable logical identity, immutable home bindings, append-only per-project event stores, idempotent acceptance/cancel, projection rebuild equivalence, token-authenticated local API, auto-start, SIGKILL crash recovery, offline CLI, packed consumer | `test/core/runtime.test.ts`, `test/core/cli.test.ts`, `test/core/package-install.test.ts` |
|
|
62
62
|
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
|
|
3
3
|
"name": "kxm",
|
|
4
4
|
"displayName": "KXM",
|
|
5
|
-
"version": "0.7.
|
|
5
|
+
"version": "0.7.54",
|
|
6
6
|
"description": "Headless multi-agent orchestration, durable workflows, and a live operator dashboard for Pi and Claude Code",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "KontextMind",
|