fix(rust): protocol 13 step 2 — expiry, plugin loads, the loading hold, NPC names, the link fleet (F2 F5 F6 F7 F8 F13 F14)
The module's half of PLAN_FIXES §6 step 2 (decisions D181-D185, docs#288). - F13/F14 (D170, D183): `world.expired`, recognisable from protocol 13 by its `what`, is handed to core as the resource the zone step ledgered (`world`, `<serverId>:<id>`) through ctx.events.expired, which records it `expired`. coreApi moves to ^1.11.0 (website#209). - F8 (D184): `plugin.loaded` / `plugin.unloaded` mark the permission sync dirty when the plugin added or removed permissions, so an unresolved grant lands on the next tick instead of the fifteen-minute audit. - Catalogue: plugin.loaded/unloaded, world.expired and lease.expired are staff kinds. The last two were never classified (default deny kept them off public pages); the test now covers every event kind through protocol 13. - F7: permission and title pushes hold while the stored hello says `worldReady: false` (a human's "sync now" does not); a failed or refused permission sync now logs at warn. - F2 (D185): the killfeed names an NPC attacker — a family (Scientist, Bandit guard, Bradley APC…) or the prefab without its variant digits (wolf2 → Wolf). - F5/F6: a link code is asked of the servers that minted one in the last six minutes first, then of the rest, each group in parallel; "unsure" only when one of the minting servers is unreachable. - D182: the admin server list carries the ZoneManager helper's state from the hello, and the servers page says what a missing or failed helper costs. 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, and protocol 13’s config.outcome', () => {
|
||||
test('the classification covers exactly the event kinds the protocol defines, through protocol 13', () => {
|
||||
// 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,9 +127,18 @@ test('the classification covers exactly the kinds the protocol defines, through
|
||||
'clan.member.added',
|
||||
'clan.member.left',
|
||||
'clan.member.kicked',
|
||||
// Protocol 8 (§14) and protocol 9 (§15): an event's machinery ending on its
|
||||
// own deadline. Never classified until protocol 13 made `world.expired`
|
||||
// recognisable (F13) — default deny kept both off public pages meanwhile.
|
||||
'lease.expired',
|
||||
'world.expired',
|
||||
// Protocol 13 (§19). A configuration save's outcome carries the server's
|
||||
// log tail, which is an operator's console: staff only.
|
||||
'config.outcome',
|
||||
// Protocol 13 (§19, F8, D184). Which plugins a server runs and what each
|
||||
// registers: an operator's inventory.
|
||||
'plugin.loaded',
|
||||
'plugin.unloaded',
|
||||
]
|
||||
|
||||
assert.deepEqual([...catalogue.ALL_KINDS].sort(), [...PROTOCOL_4].sort())
|
||||
@@ -139,6 +148,9 @@ test('the classification covers exactly the kinds the protocol defines, through
|
||||
}
|
||||
|
||||
assert.equal(catalogue.isPublic('config.outcome'), false, 'a server’s log tail must not be public')
|
||||
for (const kind of ['plugin.loaded', 'plugin.unloaded', 'lease.expired', 'world.expired']) {
|
||||
assert.equal(catalogue.isPublic(kind), false, `${kind} is staff-only`)
|
||||
}
|
||||
})
|
||||
|
||||
test('every kind that names a player who was on is behind the presence setting', () => {
|
||||
|
||||
Reference in New Issue
Block a user