feat(events): UO wave 1 — the verbs that need no protocol change (Phase 9)
module-uo registers its first event actions: `uo.broadcast`, `uo.towncrier.post` and `uo.news.post`, plus the `uo.broadcasts` budget dimension and the three spawn-atlas option sources. The write plane they use has existed since protocol 2.1; what is new is the declaration that lets the event engine drive it unattended. Three things the tree corrected about the plan: - The plan's `on_failure: 'skip'` for `uo.broadcast` is already the default for `risk: 'notify'`, and `on_failure` is what happens AFTER the retries. The lever a module actually has is the failure envelope, so the action answers `retry: false` to everything — and every action declares `budgetMs: 15000`, because core's 10s default deadline fires before `uoLinkClient`'s 12s timeout and `classify()` answers `retry` for a timeout without asking the module. Without the budget the retry refusal is unreachable. - `reconcile()` needs no protocol work. A shard restart wipes both the crier lines and an event's news article, so `perform()` stamps the shard `bootId` into the resource payload and `reconcile()` reports in force exactly the rows whose stamp still matches — correct for the module's own trigger and for core's boot sweep alike. `shardIngest` fires `ctx.events.reconcile()` on a changed `bootId`, after `recordStatus` so the comparison reads the new boot. - Event articles post under `evt-<idempotencyKey>`, because `newsGump.js` uses the bare website post id and re-pushes that set on every reconnect. `ci/core-ref.json` moves to a website `edge` sha for the length of this workstream: `registerEventActions` exists only from MODULE_API 1.10.0, so under the old `main` pin the module does not load at all. Verified locally — the frozen-manifest rig passes against the new pin. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -104,7 +104,16 @@ module.exports = {
|
||||
// do with a storage failure of core's. `inbox.push` additionally does not report
|
||||
// "the user has this switched off", because a module that could see that would
|
||||
// be a module that could enumerate people's preferences one write at a time.
|
||||
events: { emit: (...args) => need().events.emit(...args) },
|
||||
events: {
|
||||
emit: (...args) => need().events.emit(...args),
|
||||
// MODULE_API 1.10.0 (EVENTS.md F, Phase 8). "Ask every action of mine which
|
||||
// of its ledgered resources the game still has." Core cannot know when to
|
||||
// ask -- it has no concept of the game being up -- so the module says when,
|
||||
// and `shardIngest` says it on a changed `bootId`. Fire-and-forget like
|
||||
// `emit`, and for the same reason: core owns what happens next and there is
|
||||
// nothing a game-event handler could correctly do with the answer.
|
||||
reconcile: (...args) => need().events.reconcile(...args),
|
||||
},
|
||||
inbox: { push: (...args) => need().inbox.push(...args) },
|
||||
secretBox: {
|
||||
encrypt: (...args) => need().secretBox.encrypt(...args),
|
||||
|
||||
Reference in New Issue
Block a user