feat(events): an expired ledger status and ctx.events.expired (MODULE_API 1.11.0)
#209
Reference in New Issue
Block a user
No description provided.
Delete Branch "feat/events-expired-status"
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?
Core's half of Rust PLAN_FIXES F14. Decision D183 is in docs#288.
Until now, a game that ended a resource at its own deadline (a Rust zone erased when its time is up) could only reach core through
ctx.events.reconcile(). That filed it asorphaned: shown amber as "gone", and still claimable for a revert. This PR records it as the plan working.What changes
event_run_resources.statusgainsexpired. It is terminal likereverted: the sweep never tries to give it back,live_markerreleases the target, and it is in neitherHELDnorUNRESOLVED. The ENUMALTERsits below theCREATEand re-runs as a no-op on every boot. I checked this on MariaDB 11.8 with the stored generated column that depends onstatus.ctx.events.expired({ kind, ref })marks the calling module'spending,confirmedororphanedrows for that target asexpiredand writesresource.expiredto the run log. A revert already in flight is left to finish. The owner is bound by the loader, never read from the arguments, the same wayreconciledoes it. If this was the last unresolved row of a finished run, cleanup moves tocomplete, including fromincomplete, which the sweep no longer scans.MODULE_API_VERSIONgoes 1.10.0 → 1.11.0 in both halves.engagement-triggers.jsonis regenerated, since it embeds the version.Module-uo is unaffected (the org lead's condition)
coreApi: ^1.10.0, calls none of this, and reads no ledger status; the matches are comments only.frozen-manifestjob against this branch in a scratch clone. Core loaded it (registered module "uo" v0.6.0, 12 event actions), and the result wasroutes.manifest.json is current — 76 routes, all documented.eventModuleContract.test.jsnow assertsMODULE_API_VERSIONsatisfies^1.10.0, as well as pinning 1.11.0.Tests
eventCleanup.test.js: terminal, wins over orphaned, leaves a revert in flight alone, owner and target scoping, malformed input and targets nobody ledgered, and the cleanup-status transitions. Also amoduleLoaderprobe forctx.eventskeys and the owner binding.eventRunnerSql.test.js: 68/68 against a real MariaDB 11.8.routeManifest×2 also fail onmainin this working copy, and pass in a fresh clone of this branch (route manifest up to date (280 routes)).eventRunnerSqlskips without a DB and passed against one; it failed once in a full-suite run.teamActivityhangs to its file timeout onmaintoo.Follow-ups, not in this PR: EVENTS.md §L and MODULE_API.md ride in the step-2 docs PR. The Integration-kit pin moves only when someone re-reads the chapters against a shipped core, per its own
ci/core-ref.jsonrule. Module-Rust will declare^1.11.0when it starts calling this.Tracking: Module-Rust#21.
🤖 Generated with Claude Code
https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
expiredledger status and ctx.events.expired (MODULE_API 1.11.0)A game that ends a resource at its own deadline — a Rust zone erased when its time is up — could reach core only through ctx.events.reconcile(), which files it `orphaned`: amber, "it vanished", and still claimable for a revert. The new call files it as the plan working (Rust PLAN_FIXES F14, D170, D183): - event_run_resources.status gains `expired`, terminal like `reverted`: the sweep never takes it back, live_marker releases the target, and it joins neither HELD nor UNRESOLVED. The ENUM ALTER re-runs as a no-op on every boot (checked on MariaDB 11.8 with the stored generated column depending on it). - ctx.events.expired({ kind, ref }) marks the calling module's own pending, confirmed or orphaned rows for that target expired and logs `resource.expired`; a revert in flight is left to finish. The owner is bound by the loader, like reconcile. A finished run whose last unresolved row this was goes to cleanup `complete`, even from `incomplete`. - The run console shows it green, "ended by the game on time". Additions only, so minor. Module-uo (coreApi ^1.10.0) calls none of it and reads no ledger status; the contract test now asserts the range still holds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeYWalked, and one fix added (
224e2b4).I ran this branch plus Module-Rust#22 as the walk core against the
rust-oxiderig. A 3-minute event zone expired in the game, and its row wentexpiredwithresource.expiredin the run log. Cancelling the run then left it alone (0 revert attempts).That walk found a gap: when a run's last resource expires while the run is still going,
cleanup_statusstayedpendingfor ever once the run ended.runsNeedingCleanupjoins on an unresolved row, and there wasn't one. The sweep now settles finishedpendingruns that have no unresolved row ascomplete, and never touchesincomplete. There's a new test for it. I checked the query against the walk database: it returned exactly that run, which wentcompleteon the next sweep.CI is green on
224e2b4(server, client, bot).🤖 Generated with Claude Code