Skip to content

feat(runtime): generation-fence Case status and terminal commits - #28

Merged
jamespud merged 3 commits into
mainfrom
codex/t4-case-generation-fencing
Oct 10, 2026
Merged

jamespud merged 3 commits into
mainfrom
codex/t4-case-generation-fencing

Conversation

@jamespud

@jamespud jamespud commented Oct 9, 2026 •

Copy link
Copy Markdown
Owner

Stale workers can currently change Case state after a newer generation returns the Case to the same status, and successful terminal commits leave a window before Job settlement in which an expired Job can be claimed into a new generation.

This change extends the T3 artifact fence to ordinary Case transitions, retry reset, successful terminal commits, and final failure. Successful terminal commits atomically persist Case, Resolution (when resolved), completion Event, and Job settlement, so settlement delay cannot advance a terminal Case's generation.

Fixes #22. Builds on #27; part of #17.

Changes

  • Add explicit owner-aware Case capabilities. Positive-generation execution fails closed when the capability or owner is missing; generation-0 and explicitly non-durable fixtures retain their compatibility behavior.
  • Reuse one transaction ownership check: lock Job, then Case, and validate the complete owner, both generations, expected Case status, and lease against database time after lock acquisition.
  • Restrict legacy UpdateStatus, UpdateStatusIfCurrent, and UpdatePaused to persisted generation 0, with rejected/missing writes reported accurately. Legacy completion/status/failure Events also lock and check the persisted Case inside their insertion transaction, so a generation-0 input cannot bypass the positive-generation boundary.
  • Validate Resolution references against the same Case and generation before committing the terminal write set. Fence final failure through the same ownership protocol.
  • Make Pause/Cancel and Resume atomic across Job and Case. Pause records the status read under the Case lock. Claim refuses terminal Cases before allocating a generation and reconciles historical terminal Jobs at their existing generation. Historical MEMORY_INDEXED and INSUFFICIENT_EVIDENCE retain RunManager's successful Job classification.
  • Persist Event execution generation with S28; existing events remain generation 0. Bootstrap upgrades the column after verifying the existing event sequence contract.
  • On uncertain COMMIT results, use an independent bounded read to confirm the exact Case/generation, Resolution ID when present, Event ID/payload/sequence, and settled Job. Unconfirmed results return ErrCommitOutcomeUnknown without replay, failure compensation, or success publication.

Validation

  • Full backend go test -race -p 1 -count=1 -json ./... with an isolated real MySQL 8.4 schema: all 52 packages with tests passed. Four real CodeRunner sandbox tests were skipped; MySQL tests ran.
  • Real MySQL acceptance covers status ABA, terminal ABA, same-worker delayed final failure, Cancel wins, Pause wins, cross-generation reference rollback, and actual post-COMMIT reply loss. Failed writes assert persisted Case, Job, Resolution, Event, and cursor state; current-generation success controls are included.
  • Additional coverage: retry reset ABA/concurrent claim, lease expiry while waiting for locks, control rollback/reply loss, missing capabilities, terminal reconciliation without generation advance, event insertion rollback, and S28 upgrade/history preservation.
  • Removing owner/generation predicates made all four status/reset/terminal/same-worker final-failure ABA checks fail; the production predicates were restored before the full run.
  • CI exposed a pre-existing data race in the dataset test fake (also reproduced on baseline 0a3d6a0). The fake now stores detached Run copies; a channel barrier makes the active-run assertion deterministic and waits for worker completion. Reintroducing pointer aliasing deterministically fails the test. The dataset package passed 100 repetitions with -race.
  • Review regressions first failed on db533de against real MySQL: all three legacy status writers, generation-0 completion/status/failure Events on generation 2, missing-row success reporting, and both historical success classifications. The fixes preserve the full rejected write set and include successful owned terminal and generation-0 compatibility controls. Existing ABA fixtures now use owned transitions/resets, controls use the atomic capability, and historical split-settlement fixtures are explicitly constructed through SQL.
  • Remote CI run 38007017814 on review-fix HEAD 01a1117 passed all five gates, including real MySQL migration/runtime invariants and the full backend race suite.
  • go vet ./..., Go formatting, and git diff --check passed.
  • Frontend lint, 188 tests across 32 files, and production build passed.
  • Operational script syntax, backup planning dry-run, and restore bundle verification dry-run passed.

No T5 retention/GC or T6 deployment gate changes are included.

@jamespud
jamespud merged commit ab8f9b9 into main Oct 10, 2026
5 checks passed
@jamespud
jamespud deleted the codex/t4-case-generation-fencing branch October 24, 2026 08:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[IMPL] T4 — Fence Case status and terminal commits by active ExecutionGeneration

1 participant