Summary
transform_mode: "rust" works on a store that has never had it enabled. On any subsequent activation, every pass fails in host-side state_sync with UNIQUE constraint failed: mc_workspaces.name, because the authority workspace row from the first activation is still there and the insert has no conflict handling.
The module is never reached (module=0.0 ms), so it fails closed — but it fails on every pass, permanently, until the row is removed by hand.
Evidence
Every pass after enabling:
rust pass: decision=error reason=none served_from=raw in=417 out=417 applied=false
row_version=0 elapsed=2386.1 ms module=0.0 ms
stages=prefix_guard:0.0 ordinal_resolve:65.6 state_sync:2053.0 clone:0.0 wire_build:0.0
lkg_miss
rust transform failed; attempting LKG replay:
store: store: storage backend: UNIQUE constraint failed: mc_workspaces.name
All the elapsed time is in state_sync; module=0.0 ms confirms dispatch never happens.
The offending row, written by the first activation:
id name created_at updated_at
1 authority-workspace-aa195aa5…-8cebe0c8… 0 0
Root cause
crates/mc-store/src/lib.rs has two inserts into mc_workspaces. Only one is idempotent.
// :14066 — safe
INSERT INTO mc_workspaces (name, share_categories) VALUES (?1, ?2)
ON CONFLICT(name) DO NOTHING
// :15608 — the activation path, no conflict handling
INSERT INTO mc_workspaces (name, created_at, updated_at, share_categories)
VALUES (?1, 0, 0, ?2)
let workspace_id = tx.last_insert_rowid();
mc_workspaces.name is TEXT NOT NULL UNIQUE. The literal 0, 0 in the second statement matches the created_at=0, updated_at=0 on the live row, which is how I attributed it to that path.
Note the follow-on: last_insert_rowid() immediately after means a bare ON CONFLICT DO NOTHING is not sufficient — the fix needs get-or-create semantics returning the existing id (ON CONFLICT(name) DO UPDATE SET name=excluded.name RETURNING id, or a select-then-insert).
Reproduction
- Enable
transform_mode: "rust", restart, let at least one pass run (this seeds mc_workspaces).
- Revert to
ts, restart.
- Re-enable
rust, restart.
Every pass now errors as above. Deleting the mc_workspaces row restores a working first-activation.
Two smaller things noticed alongside
decision=error reason=none. The pass line carries an empty reason while the actual cause (UNIQUE constraint failed) is only in a separate rust transform failed; attempting LKG replay: line. Propagating the store error into reason= would make the pass line self-diagnosing.
Project-tier subc is stripped, and the message is good. Setting subc.connection_file in a project config is silently ignored (correctly — project-security.ts:415), and rust mode declines with rust mode requires user-level subc configuration; running ts. That diagnostic named the fix exactly; no complaint, noting it because the working split is user-tier subc + project-tier transform_mode, which isn't obvious from the config docs.
Environment
magic-context fork on upstream master (all of #376/#378/#379/#381 present), ck-mc rebuilt at matching generation (1160 tests pass). Live store: schema v82, ~3200 memories. Fails identically on every pass across four restarts.
Summary
transform_mode: "rust"works on a store that has never had it enabled. On any subsequent activation, every pass fails in host-sidestate_syncwithUNIQUE constraint failed: mc_workspaces.name, because the authority workspace row from the first activation is still there and the insert has no conflict handling.The module is never reached (
module=0.0 ms), so it fails closed — but it fails on every pass, permanently, until the row is removed by hand.Evidence
Every pass after enabling:
All the elapsed time is in
state_sync;module=0.0 msconfirms dispatch never happens.The offending row, written by the first activation:
Root cause
crates/mc-store/src/lib.rshas two inserts intomc_workspaces. Only one is idempotent.mc_workspaces.nameisTEXT NOT NULL UNIQUE. The literal0, 0in the second statement matches thecreated_at=0, updated_at=0on the live row, which is how I attributed it to that path.Note the follow-on:
last_insert_rowid()immediately after means a bareON CONFLICT DO NOTHINGis not sufficient — the fix needs get-or-create semantics returning the existing id (ON CONFLICT(name) DO UPDATE SET name=excluded.name RETURNING id, or a select-then-insert).Reproduction
transform_mode: "rust", restart, let at least one pass run (this seedsmc_workspaces).ts, restart.rust, restart.Every pass now errors as above. Deleting the
mc_workspacesrow restores a working first-activation.Two smaller things noticed alongside
decision=error reason=none. The pass line carries an empty reason while the actual cause (UNIQUE constraint failed) is only in a separaterust transform failed; attempting LKG replay:line. Propagating the store error intoreason=would make the pass line self-diagnosing.Project-tier
subcis stripped, and the message is good. Settingsubc.connection_filein a project config is silently ignored (correctly —project-security.ts:415), and rust mode declines withrust mode requires user-level subc configuration; running ts. That diagnostic named the fix exactly; no complaint, noting it because the working split is user-tiersubc+ project-tiertransform_mode, which isn't obvious from the config docs.Environment
magic-context fork on upstream master (all of #376/#378/#379/#381 present),
ck-mcrebuilt at matching generation (1160 tests pass). Live store: schema v82, ~3200 memories. Fails identically on every pass across four restarts.