docs(events): what the integration kit's fifth chapter settled (Phase 15) #226
Reference in New Issue
Block a user
No description provided.
Delete Branch "docs/events-p15-kit"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
EVENTS.md§F's Integration Kit paragraph gains what building it produced, anddetailbecomes a real envelope member. Pairs with Integration-kit#10 and website#197.It is three chapters, not one
The plan said "a fifth chapter". Building it found that was not enough: the book as it stood taught a read-only data path end to end — a sidecar that listens and stores, a plugin that never blocks the game thread, a module that reads its own tables. Nothing anywhere told a reader to build a command path. So a chapter 5 teaching a module to send an idempotency key would have been addressing it to a sidecar with nowhere to put it.
Chapter 3 gains §2a and chapter 4 gains "A command that changes the world runs at most once". Both open by saying they are skippable until you want chapter 5.
Two defects, and the prose found neither
Both came from running the kit template's real declarations through core's real registry and its real envelopes through core's real
events/dispatch.jsclassifier atedge.1. An idempotency key belongs on a command, never on a question. A read that carries one is answered by an at-most-once store with the first read's reply, forever. The lease applied correctly, the game changed correctly, and the module could no longer see either —
read()reported the pre-run baseline andinForce()said nothing was held. Recorded in §F, with the narrower rule that falls out of it: a key is for a write whose repetition would be a second effect; a write that merely sets a value to X is idempotent by its own nature.2.
detailwas not an envelope member, and §H said it was.classify()readsok,retry,error,await,holdFor,resourcesandparticipants— and had never read adetail.module-uotook §H at its word twice:uo.item.grantanswers{ granted, missed, why }anduo.world.saveanswers{ started: true }, and both were writing into nothing. The grant is the one that mattered — a grant reaches the players a run's participation ledger holds, and which of them missed out is knowable only to the module, so an operator saw a stepdoneand never learned four of twelve got nothing.The second one is now fixed, not just recorded
Fixed by making the member real rather than by deleting the reporting, because §H's sentence was right and only its example was wrong.
website#197carries it; this PR documents it.MODULE_API.md§1.1, 1.10.0detailas a third envelope member beside Phase 10's two — optional, both success shapes, objects only, 4KB, dropped-and-logged rather than failing the stepMODULE_API.md§2.4EVENTS.md§FdescribeLogLinedefault returns a kind word, so the new line would have rendered as the literal stringstep.detail: the channel existing and showing nothingEVENTS.md§Hdetailis unread, and no longer spells a successful revert with onemodule-uoneeded no change — the code it already shipped started working.MODULE_API_VERSIONstays 1.10.0, amended in place; still onedge. The failure channel is unchanged and is stillerroralone.EVENTS_PLAN.mdPhase 15 is annotated with what it actually was.🤖 Generated with Claude Code
https://claude.ai/code/session_016wDDVXWMDz82WqE1i969r4
§F's Integration Kit paragraph gains what building it produced, and §H loses an envelope member that does not exist. **It is three chapters, not one.** The book taught a read-only data path end to end and never told anyone to build a command path, so a chapter 5 teaching a module to send an idempotency key would have addressed it to a sidecar with nowhere to put it. Chapters 3 and 4 each gain one section, both skippable. **Two defects, both found by running the template through core's real registry and real dispatcher rather than by writing prose:** * **An idempotency key belongs on a command, never on a question.** A read carrying one is answered by an at-most-once store with the FIRST read's reply, forever — the lease applied correctly and the module could no longer see it. * **§H named a `detail` member on an envelope and `classify()` has never read one.** The sentence §H was making is right and its example was wrong: a revert of something gone is `{ ok: true }`. Corrected in place, with the finding recorded in §F. That second one has a consequence outside this PR: **`module-uo` took §H at its word twice.** `uo.item.grant` answers `detail: { granted, missed, why }` and `uo.world.save` answers `detail: { started: true }`, and neither reaches a screen or the ledger. The grant is the one that matters — which recipients did not receive the item is reported nowhere else. Recorded here rather than fixed; the fix is a Module-uo change and is the org lead's call. Pairs with Integration-kit#10, which is red on `checkCoreApi` by design and merges in the P16 cutover with its pin move. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016wDDVXWMDz82WqE1i969r4