Skip to content

fix: atomically fence Calendar generation publication - #743

Merged
chubes4 merged 11 commits into
mainfrom
fix-742-calendar-generation-fence
Aug 25, 2026
Merged

fix: atomically fence Calendar generation publication#743
chubes4 merged 11 commits into
mainfrom
fix-742-calendar-generation-fence

Conversation

@chubes4

@chubes4 chubes4 commented Aug 25, 2026

Copy link
Copy Markdown
Member

Summary

  • add a site-scoped monotonic fence that owns Calendar generation, revision, publisher election, and warmer handoff state in one exact option row
  • make immediate invalidation and deferred publishers share atomic CAS/row-lock transitions so old or replayed work cannot restore a stale generation
  • persist each parent publication revision and five-minute window, using revision-specific operation keys while rejecting cross-site parent reuse

Root Cause

PR #741 used separate latest-window and generation option reads/writes. Those transitions were not one atomic ownership decision, and Data Machine direct workflow idempotency includes user/agent ownership in its key. An older task or a duplicate under another owner could therefore pass a stale check and publish after newer work.

Fence Contract

CalendarGenerationFence stores one non-autoloaded, site-local state row:

  • monotonic revision
  • canonical generation
  • elected publisher_job_id
  • durable warmer_scheduled receipt

MySQL/MariaDB transitions use exact serialized-value CAS with affected-row checks. Immediate invalidation falls back after bounded CAS contention to TransactionScope plus SELECT ... FOR UPDATE, preserving any enclosing Data Machine transaction through a savepoint. SQLite and explicitly unsupported engines never defer and retain the legacy immediate generation option.

Ordering And Replay Safety

  • every deferred parent persists a unique site-scoped obligation token before event persistence without advancing publication order
  • terminal accounting reserves and persists one publication revision plus its original five-minute window
  • operation keys include site, window, and revision
  • parent callback replay reuses the exact persisted revision, timestamp, and key even in a later wall-clock window
  • newer reservations or immediate edits supersede older tasks before generation publication
  • one publisher job wins each revision even when owner-scoped operation keys produce duplicate jobs
  • a claimed revision rejects a conflicting generation payload
  • warmer scheduling failure retries the elected publisher without rotating twice; the receipt prevents a completed replay from scheduling again

Failure And Multisite Safety

  • obligation-token creation or parent CAS failure rejects deferral, leaving immediate invalidation active
  • unsupported databases use immediate legacy invalidation and do not enter the row-lock path
  • a second site's use of a parent ID cannot replace the first site's persisted obligation
  • nested defer/resume scopes remain balanced through exceptions
  • editor cache bypass and the five-minute scheduling window are unchanged

Tests

  • 100-request generation/cache reuse
  • old/new publication in both execution orders
  • immediate invalidation between scheduling and execution
  • publication followed by warmer failure and replay
  • immediate edit between failed handoff and replay
  • owner-scoped duplicate publisher election
  • parent replay across a later wall-clock window
  • conflicting same-revision payload rejection
  • cross-site parent rejection and site-isolated revisions
  • exhausted CAS row-lock fallback
  • unsupported database immediate fallback
  • nested defer/resume exception balance

Verification

  • PHP syntax: pass for all changed files
  • git diff --check: pass
  • Homeboy PR audit: pass, no introduced findings
  • changed-file PHPCS/ESLint/PHPStan: pass, zero findings
  • hosted MySQL multisite suite: 853 total, 851 passed, 2 skipped, 0 failed

Closes #742

Freshness Starvation Correction

  • batch start records only a durable immutable obligation token; it does not advance the global publication fence
  • terminal scheduling reserves and persists the monotonic publication revision and original five-minute window
  • parent B starting after terminal parent A is scheduled cannot supersede A; A publishes first, and B receives a newer revision only when B reaches terminal
  • production-shaped tests prove 25 batch starts leave the fence unchanged and exercise the full A-schedules, B-starts, A-publishes, B-terminal-publishes sequence

Final hosted verification: audit, lint, and hosted MySQL multisite tests all pass on candidate 875b662.

Late-Night Boundary Correction

Hosted verification crossed the configured late-night cutoff and exposed #744: display-date inventory boundaries were reapplied as raw calendar dates, excluding valid after-midnight and ongoing events. The owner fix converts display ranges back to cutoff-aware raw datetime bounds and retains ongoing prior-display-date buckets. A deterministic bound test covers 05:00:00 through next-day 04:59:59.

Closes #744

@homeboy-ci

homeboy-ci Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Homeboy Results — data-machine-events

Review audit

review audit — passed

Deep dive: homeboy review audit data-machine-events --changed-since 283acff

Artifacts and drill-down
  • CI results artifact: homeboy-ci-results-data-machine-events-review-audit-homeboy-Linux-node24 contains immediate command JSON for this action invocation.
  • Observation artifact: homeboy-observations-data-machine-events-review-audit-homeboy-Linux-node24 contains exported Homeboy run history for deeper queries.
  • Drill-down: download the observation artifact, then run homeboy runs import <dir>, homeboy runs list, and homeboy runs findings <run-id>.
  • Artifacts are attached to the workflow run: https://github.com/Extra-Chill/data-machine-events/actions/runs/32801762549

Review lint

review lint — passed

ℹ️ Auto-fix: homeboy refactor data-machine-events --path /home/runner/work/data-machine-events/data-machine-events --changed-since 283acff --from lint --write
ℹ️ Some issues may require manual fixes
ℹ️ Full options: homeboy self docs commands/lint
Deep dive: homeboy review lint data-machine-events --changed-since 283acff

Artifacts and drill-down
  • CI results artifact: homeboy-ci-results-data-machine-events-review-lint-homeboy-Linux-node24 contains immediate command JSON for this action invocation.
  • Observation artifact: homeboy-observations-data-machine-events-review-lint-homeboy-Linux-node24 contains exported Homeboy run history for deeper queries.
  • Drill-down: download the observation artifact, then run homeboy runs import <dir>, homeboy runs list, and homeboy runs findings <run-id>.
  • Artifacts are attached to the workflow run: https://github.com/Extra-Chill/data-machine-events/actions/runs/32801762549

Review test

review test — failed

  • 1 failed out of 853 total
  • 2 skipped

ℹ️ Ignored a malformed test-failures sidecar (JSON error); the primary run result is preserved. Re-run with --analyze after the extension emits a valid sidecar for failure classification.
ℹ️ To run specific tests: homeboy review test data-machine-events -- --filter=TestName
ℹ️ Auto-fix lint issues: homeboy refactor data-machine-events --from lint --write
ℹ️ Collect coverage: homeboy review test data-machine-events --coverage
ℹ️ Save test baseline: homeboy review test data-machine-events --baseline
ℹ️ Analyze failures: homeboy review test data-machine-events --analyze
ℹ️ Pass args to test runner: homeboy review test -- [args]
ℹ️ Full options: homeboy self docs commands/test
Deep dive: homeboy review test data-machine-events

Artifacts and drill-down
  • CI results artifact: homeboy-ci-results-data-machine-events-review-test-homeboy-Linux-node24 contains immediate command JSON for this action invocation.
  • Observation artifact: homeboy-observations-data-machine-events-review-test-homeboy-Linux-node24 contains exported Homeboy run history for deeper queries.
  • Drill-down: download the observation artifact, then run homeboy runs import <dir>, homeboy runs list, and homeboy runs findings <run-id>.
  • Artifacts are attached to the workflow run: https://github.com/Extra-Chill/data-machine-events/actions/runs/32800813493
Tooling versions
  • Homeboy CLI: homeboy 0.360.3+0aa8229d2361
  • Extension: wordpress from https://github.com/Extra-Chill/homeboy-extensions
  • Extension revision: 5b6e872a
  • Action: Extra-Chill/homeboy-action@v2

@chubes4
chubes4 merged commit f8d8066 into main Aug 25, 2026
3 checks passed
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.

fix: align late-night display buckets with Calendar row boundaries fix: atomically fence coalesced Calendar generation publication

1 participant