Skip to content

feat(devvit): add pending post reconciliation operations - #70

Merged
imjlk merged 4 commits into
mainfrom
codex/devvit-post-reconciliation
Jul 14, 2026
Merged

imjlk merged 4 commits into
mainfrom
codex/devvit-post-reconciliation

Conversation

@imjlk

@imjlk imjlk commented Jul 14, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • add an optional indexed durable-store capability and listPending() cursor pagination for Devvit post operations
  • establish stable, scope-bound operation registry membership before durable state creation and retain it across every state transition
  • lazily backfill registry membership when known pre-index operations are executed, read, reconciled, or transitioned
  • preserve exact-operation read/retry availability when a best-effort migration write is temporarily unavailable
  • surface prepared, reconciliation-required, and terminal-unresolved work without scanning Redis keys or invoking Reddit
  • keep the shared target and generated starter wrapper/docs in parity

Safety contract

  • listing is read-only and never restores submit permission
  • attempted operations still require exact-envelope reconciliation
  • terminal ambiguity remains fail-closed
  • stable operation-key members cannot move behind a cursor during pending state transitions
  • initial index failure prevents state creation; initial state failure can leave only a safe stale member
  • published and stale registry members are filtered while pagination remains bounded
  • pre-index records are backfilled from their stored canonical descriptor, including conflict reads
  • exact reads tolerate a failed best-effort backfill, while new state creation and every state CAS require registry membership before mutation
  • Redis keyspace scanning is deliberately not introduced
  • existing custom stores keep execute/read/reconcile compatibility; pending discovery requires the complete indexed capability

Validation

  • mise exec -- pnpm check
  • mise exec -- pnpm test
  • mise exec -- pnpm graph:preflight
  • mise exec -- pnpm --filter @mpgd/adapter-devvit test (78 tests on latest head)
  • mise exec -- pnpm build:devvit
  • git diff --check

pnpm sampo:release:dry-run parsed the workspace and then stopped because releases are restricted to main, as expected on a feature branch.

Open Code Review was invoked for all four commits. The configured external glm-5.2 endpoint timed out or failed before completing any file reviews: five files on the initial commit, two files on the stable-registry patch, two files on the initial backfill patch (session 60a00399-7b3d-4e87-8963-179eaaac9dc2), and one file on the exact-read availability patch (session 4d5ed4d3-3ba3-4572-9357-d77ae8828311). No OCR code comments were produced; GitHub Codex and CodeRabbit reviews remain required before merge.

Release

Adds a Sampo changeset for:

  • @mpgd/adapter-devvit: minor
  • @mpgd/cli: patch
  • @mpgd/create-game: patch

imjlk commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

@codex review

Please focus on the atomic state/index transaction boundary, scope-bound cursor semantics, normal concurrent transitions, and the invariant that pending discovery never restores submit permission.

@coderabbitai

coderabbitai Bot commented Jul 14, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds indexed durable Devvit post-operation storage, scope-bound cursor pagination through listPending, atomic Redis sorted-set mutations, expanded tests, updated application wrappers, documentation, template validation, and release notes.

Changes

Devvit pending-operation recovery

Layer / File(s) Summary
Coordinator indexed API and pending discovery
adapters/devvit/src/server/post-operation.ts
Adds indexed-store contracts, paginated pending-operation types, atomic index-aware transitions, cursor validation, and read-only listPending discovery.
Redis indexed storage and transactions
adapters/devvit/src/server/redis-post-operation-store.ts
Adds sorted-set operations, atomic indexed create/CAS mutations, lexicographic listing, contention handling, and page-limit validation.
Indexed coordinator and Redis behavior tests
adapters/devvit/src/server/*post-operation*.test.ts
Tests pagination, scope and cursor checks, capability gating, index consistency, sorted-set behavior, CAS updates, and transaction contention.
Application templates and release documentation
apps/target-devvit/..., packages/cli/templates/phaser-game/..., docs/..., tools/validate-starter-workflow.ts, .sampo/changesets/*
Updates wrapper types, generated guidance, durable-operation documentation, starter-template checks, and package release notes.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant RecoveryWorker
  participant Coordinator
  participant IndexedStore
  participant Redis
  RecoveryWorker->>Coordinator: listPending(scope, cursor, limit)
  Coordinator->>IndexedStore: listIndex(scope/type index, cursor, limit)
  IndexedStore->>Redis: zRange lex range
  Redis-->>IndexedStore: indexed members
  Coordinator->>IndexedStore: read referenced durable records
  Coordinator-->>RecoveryWorker: pending page and nextCursor
Loading

Possibly related PRs

  • imjlk/mpgd-kit#43: Adds the durable Devvit post-operation coordinator and Redis store extended by this change.
  • imjlk/mpgd-kit#1: Introduces the starter-workflow validation script updated here.
  • imjlk/mpgd-kit#4: Related starter-workflow validation updates for the Devvit template.

Poem

I’m a bunny with a cursor to hop,
Through indexed records in one tidy crop.
Redis sorts the trail just right,
Recovery pages stay bounded and light.
Read-only paws, no submit spree—
Fail closed safely, hoppy as can be!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly summarizes the main change: adding pending post reconciliation operations for Devvit.
Description check ✅ Passed The description is detailed and covers summary, safety, validation, and release info, though it uses Release instead of the template's Notes section.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/devvit-post-reconciliation

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 286b1ab8a6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
adapters/devvit/src/server/post-operation.ts (1)

6-7: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract the shared page-limit cap instead of duplicating it.

maximumPendingPageLimit = 100 here has an implicit "+1" contract with the hardcoded 101 cap in assertIndexPageLimit (redis-post-operation-store.ts). Since this constant isn't exported, the Redis store can't reference it, so the two values must be kept in sync by hand. See consolidated comment for both sites.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@adapters/devvit/src/server/post-operation.ts` around lines 6 - 7, Extract the
shared pending-page limit cap into an exported common constant and update both
maximumPendingPageLimit in post-operation handling and the hardcoded 101 bound
in assertIndexPageLimit to reference it, preserving the existing implicit +1
contract without duplicated numeric literals.
adapters/devvit/src/server/redis-post-operation-store.ts (1)

291-296: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Hardcoded 101 duplicates the coordinator's page-limit contract.

This cap is maximumPendingPageLimit + 1 from post-operation.ts, but that constant isn't exported/shared, so the two values can silently drift. See consolidated comment.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@adapters/devvit/src/server/redis-post-operation-store.ts` around lines 291 -
296, The hardcoded 101 in assertIndexPageLimit duplicates the coordinator
page-limit contract and can drift. Export or otherwise share the
maximumPendingPageLimit-based limit from post-operation.ts, then reuse that
symbol in assertIndexPageLimit instead of embedding 101, preserving the existing
validation and error behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@adapters/devvit/src/server/redis-post-operation-store.ts`:
- Around line 15-34: Update DevvitRedisTransactionLike to match the Devvit Redis
SDK: define zAdd as accepting a single sorted-set member object or array, zRem
as accepting a string or string array, and zRange with positional start/stop
arguments plus options supporting by 'rank' or 'score'. Replace the incompatible
DevvitRedisRangeOptions shape and adjust the related method signatures without
changing unrelated transaction methods.

---

Nitpick comments:
In `@adapters/devvit/src/server/post-operation.ts`:
- Around line 6-7: Extract the shared pending-page limit cap into an exported
common constant and update both maximumPendingPageLimit in post-operation
handling and the hardcoded 101 bound in assertIndexPageLimit to reference it,
preserving the existing implicit +1 contract without duplicated numeric
literals.

In `@adapters/devvit/src/server/redis-post-operation-store.ts`:
- Around line 291-296: The hardcoded 101 in assertIndexPageLimit duplicates the
coordinator page-limit contract and can drift. Export or otherwise share the
maximumPendingPageLimit-based limit from post-operation.ts, then reuse that
symbol in assertIndexPageLimit instead of embedding 101, preserving the existing
validation and error behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9f9f0475-b54b-40fb-aef3-da12742e7583

📥 Commits

Reviewing files that changed from the base of the PR and between e4a89d7 and 286b1ab.

📒 Files selected for processing (11)
  • .sampo/changesets/devvit-post-reconciliation-operations.md
  • adapters/devvit/src/server/post-operation.test.ts
  • adapters/devvit/src/server/post-operation.ts
  • adapters/devvit/src/server/redis-post-operation-store.test.ts
  • adapters/devvit/src/server/redis-post-operation-store.ts
  • apps/target-devvit/README.md
  • apps/target-devvit/src/server/postOperationStore.ts
  • docs/DEVVIT_DURABLE_POST_OPERATIONS.md
  • packages/cli/templates/phaser-game/apps/target-devvit/README.md
  • packages/cli/templates/phaser-game/apps/target-devvit/src/server/postOperationStore.ts
  • tools/validate-starter-workflow.ts

imjlk commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

@codex review

Please re-review latest head c18ae98. The follow-up replaces phase/timestamp pending members with stable operation-key registry membership established before state creation and retained for the durable record lifetime. Verify that live work cannot be hidden by command errors or concurrent state transitions, and that sparse published/stale pages preserve bounded cursor progress.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c18ae98663

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

imjlk commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

@codex review

Please review latest head 7f6be3c, with particular attention to pre-index durable-record backfill, read/CAS failure behavior, stable cursor discovery, and whether any existing operation can remain undiscoverable after an exact-operation recovery path.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7f6be3cace

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

imjlk commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

@codex review

Please re-review latest head a82550e. Verify that conflict reads backfill from the validated stored descriptor, best-effort migration failures do not mask exact-operation results, and all state mutation paths still require registry membership before changing durable state.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🎉

Reviewed commit: a82550e97e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@imjlk
imjlk merged commit 7d1108e into main Jul 14, 2026
6 checks passed
@imjlk
imjlk deleted the codex/devvit-post-reconciliation branch July 15, 2026 13:41
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.

1 participant