fix(rust): protocol 13 — a configuration save that settles after its reload (F9, D179)
The plugin now answers a save once the files are written, with pending and a writeId, and reports the reload later as a config.outcome event. The save is recorded as reloading with a settle_by of two plugin ceilings plus slack on the database's clock; ingest settles the row by (server, writeId), only while it is still reloading, so a replay moves nothing and a late outcome still lands. A row past settle_by reads as lost. GET /admin/rust/config/:serverId/writes/:writeId serves the poll; the page polls it every two seconds, holds the Save button while it waits, and says whether a rolled-back plugin came back on its old file. config.outcome is a staff kind: it carries the server's log tail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
@@ -651,7 +651,7 @@ CREATE TABLE IF NOT EXISTS rust_config_writes (
|
||||
-- whole document.
|
||||
tier VARCHAR(16) NOT NULL DEFAULT 'form',
|
||||
user_id INT NULL,
|
||||
-- `applied` | `rolled-back` | `refused` | `unreachable`
|
||||
-- `applied` | `rolled-back` | `refused` | `unreachable` | `reloading` (protocol 13)
|
||||
outcome VARCHAR(24) NOT NULL,
|
||||
reloaded TINYINT(1) NOT NULL DEFAULT 0,
|
||||
changes LONGTEXT NULL,
|
||||
@@ -669,6 +669,28 @@ CREATE TABLE IF NOT EXISTS rust_config_writes (
|
||||
KEY idx_rust_config_writes_server (server_id, created_at)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- Protocol 13 (PLAN_FIXES.md F9, D177–D179). A save that reloads a plugin no
|
||||
-- longer waits for the reload: it is recorded as `reloading` the moment the files
|
||||
-- land, and ingest settles it from the plugin's `config.outcome`.
|
||||
--
|
||||
-- • `write_id` is the plugin's own name for the write — the frame carries it,
|
||||
-- and the sidecar's request ids restart with the sidecar, so they cannot.
|
||||
-- • `settle_by` is when a write that never heard back is LOST rather than slow:
|
||||
-- two of the plugin's ceilings (the edit's reload and a restore's) plus
|
||||
-- slack. Reads report `lost` past it; the row itself stays `reloading`, so an
|
||||
-- outcome that arrives late — a link that was down — still settles it.
|
||||
-- • `log_tail` is the server's log at the moment a reload failed. It used to go
|
||||
-- straight back to the browser that asked; nothing is waiting now, so the
|
||||
-- page reads it from here. Operator console output: admin-only like the rest.
|
||||
-- • `restored` is whether the plugin came back on its old file after a
|
||||
-- rollback. NULL when there was no rollback.
|
||||
ALTER TABLE rust_config_writes ADD COLUMN IF NOT EXISTS write_id VARCHAR(64) NULL;
|
||||
ALTER TABLE rust_config_writes ADD COLUMN IF NOT EXISTS settle_by DATETIME NULL;
|
||||
ALTER TABLE rust_config_writes ADD COLUMN IF NOT EXISTS settled_at DATETIME NULL;
|
||||
ALTER TABLE rust_config_writes ADD COLUMN IF NOT EXISTS log_tail TEXT NULL;
|
||||
ALTER TABLE rust_config_writes ADD COLUMN IF NOT EXISTS restored TINYINT(1) NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_rust_config_writes_write ON rust_config_writes (server_id, write_id);
|
||||
|
||||
|
||||
-- ── Who may see who is online (the presence fix, 2026-09-22) ──────────────
|
||||
--
|
||||
|
||||
Reference in New Issue
Block a user