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:
@@ -95,7 +95,7 @@ test('every kind is classified exactly once', () => {
|
||||
assert.equal(seen.size, catalogue.PUBLIC_KINDS.length + catalogue.STAFF_KINDS.length)
|
||||
})
|
||||
|
||||
test('the classification covers exactly the kinds the protocol defines, through protocol 6', () => {
|
||||
test('the classification covers exactly the kinds the protocol defines, through protocol 6, and protocol 13’s config.outcome', () => {
|
||||
// The spec lives in another repository, so the list is restated here rather
|
||||
// than parsed — and restating it is the point: adding a kind to the protocol
|
||||
// without deciding who may see it has to fail somewhere, and this is where.
|
||||
@@ -127,6 +127,9 @@ test('the classification covers exactly the kinds the protocol defines, through
|
||||
'clan.member.added',
|
||||
'clan.member.left',
|
||||
'clan.member.kicked',
|
||||
// Protocol 13 (§19). A configuration save's outcome carries the server's
|
||||
// log tail, which is an operator's console: staff only.
|
||||
'config.outcome',
|
||||
]
|
||||
|
||||
assert.deepEqual([...catalogue.ALL_KINDS].sort(), [...PROTOCOL_4].sort())
|
||||
@@ -134,6 +137,8 @@ test('the classification covers exactly the kinds the protocol defines, through
|
||||
for (const kind of PROTOCOL_4.filter((k) => k.startsWith('clan.'))) {
|
||||
assert.equal(catalogue.isPublic(kind), false, `${kind} is members-only and must not be public`)
|
||||
}
|
||||
|
||||
assert.equal(catalogue.isPublic('config.outcome'), false, 'a server’s log tail must not be public')
|
||||
})
|
||||
|
||||
test('every kind that names a player who was on is behind the presence setting', () => {
|
||||
|
||||
Reference in New Issue
Block a user