feat(events): an expired ledger status and ctx.events.expired (MODULE_API 1.11.0)
All checks were successful
PR Checks / client-build (pull_request) Successful in 35s
PR Checks / server-tests (pull_request) Successful in 5m48s
PR Checks / bot-tests (pull_request) Successful in 7m51s

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_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
2026-09-26 21:13:07 -05:00
parent 1a76b98d76
commit cc1f49af29
14 changed files with 309 additions and 10 deletions

View File

@@ -2560,7 +2560,7 @@ CREATE TABLE IF NOT EXISTS event_run_resources (
-- defensible. This column is core's copy of that promise, for the console and
-- for the boot-time check.
lease_until DATETIME NULL,
status ENUM('pending','confirmed','reverting','reverted','orphaned','drifted')
status ENUM('pending','confirmed','reverting','reverted','orphaned','drifted','expired')
NOT NULL DEFAULT 'pending',
-- Bounded like a step's `attempts`, and for the same reason: a revert that can
-- never succeed must become visible rather than cycling for ever. Engagement
@@ -2587,6 +2587,14 @@ CREATE TABLE IF NOT EXISTS event_run_resources (
INDEX idx_evres_live (status, lease_until)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- MODULE_API 1.11.0 (Rust PLAN_FIXES D183): `expired`, the game ending a resource
-- at its own deadline, for databases created before it. Terminal, so `live_marker`
-- releases the target. MODIFY has no IF NOT EXISTS form, but re-declaring the same
-- ENUM is an idempotent no-op -- checked against MariaDB 11.8 with the stored
-- `live_marker` column depending on it -- so it is safe on every boot.
ALTER TABLE event_run_resources MODIFY COLUMN status
ENUM('pending','confirmed','reverting','reverted','orphaned','drifted','expired') NOT NULL DEFAULT 'pending';
-- §K's last bound: "a scheduled definition that has never been verified is the
-- case worth refusing to start". A version is immutable, so a dry run that passed
-- against it stays true — which is what makes the pass a property of the VERSION