Skip to content

Fix follower cleanup semantics#26

Merged
dahlia merged 21 commits into
fedify-dev:0.4-maintenancefrom
dahlia:fix/25
Jul 5, 2026
Merged

Fix follower cleanup semantics#26
dahlia merged 21 commits into
fedify-dev:0.4-maintenancefrom
dahlia:fix/25

Conversation

@dahlia

@dahlia dahlia commented Jul 5, 2026

Copy link
Copy Markdown
Member

This pull request fixes how follower records are maintained when the same actor has more than one accepted Follow request, or when an existing follow request ID is reassigned to another actor.

The old behavior treated a single follow request as if it owned the follower record. That broke down when a remote server sent duplicate follows, replayed a follow under a new ID, or otherwise left multiple accepted follow requests pointing at the same actor. Removing one request could delete the shared follower record even though another request still made the actor a follower. It could also make Bot.onUnfollow fire too early, because removeFollower() returned an actor even when the follower was still present.

This PR changes the repository contract so removeFollower() returns an actor only when the follower record is actually removed. If an actor still has another active follow request, the specific request is removed but the method returns undefined, which keeps Bot.onUnfollow aligned with hasFollower() and countFollowers().

The same semantics are now applied across packages/botkit/src/repository.ts, packages/botkit-sqlite/src/mod.ts, and packages/botkit-postgres/src/mod.ts. MemoryRepository, KvRepository, MemoryCachedRepository, SqliteRepository, and PostgresRepository all keep the follower row until no remaining follow request references it, and they clean up stale follower rows when a follow request is reassigned to a different actor.

For KvRepository, the fix uses KvStore.list() to scan existing follow request entries instead of introducing a new reverse index, so existing KV data remains usable without a migration. For SQLite, the follow request table now has an index on follower_id, and INSERT OR REPLACE was replaced with conflict updates to avoid deleting parent rows that still have valid references.

Regression tests were added in packages/botkit/src/repository.test.ts, packages/botkit-sqlite/src/mod.test.ts, packages/botkit-postgres/src/mod.test.ts, and packages/botkit/src/bot-impl.test.ts. The tests cover duplicate follow requests, reassigned follow request IDs, and the bot-level unfollow event behavior that made the return value bug visible.

Fixes #25.

Summary by CodeRabbit

  • Bug Fixes
    • Fixed follower tracking so multiple follow requests for the same follower no longer create duplicate removals or premature unfollow events.
    • Reassigning a follow request to a different follower now updates records correctly, preventing stale follower entries.
    • Improved follower removal handling across storage backends to avoid unexpected errors and ensure a follower is removed only after the last active follow request is gone.

@dahlia dahlia requested a review from Copilot July 5, 2026 08:42
@dahlia dahlia self-assigned this Jul 5, 2026
@dahlia dahlia added the bug Something isn't working label Jul 5, 2026

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Jul 5, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9876b491-8e9a-472e-91ed-9d90cf56a843

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@dahlia

dahlia commented Jul 5, 2026

Copy link
Copy Markdown
Member Author

@codex review

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request fixes issues across multiple repositories (MemoryRepository, KvRepository, MemoryCachedRepository, SqliteRepository, and PostgresRepository) where removing one of multiple active follow requests for the same actor would prematurely delete the follower or fail to clean up stale followers during reassignment. The changes ensure that a follower is only removed when no active follow requests remain. Feedback on these changes highlights a potential performance bottleneck in KvRepository due to an $O(N)$ full scan over follow requests, and recommends using BEGIN IMMEDIATE TRANSACTION in SQLite to prevent potential SQLITE_BUSY errors during write transactions.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread packages/botkit/src/repository.ts Outdated
Comment thread packages/botkit-sqlite/src/mod.ts Outdated
@codecov

codecov Bot commented Jul 5, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.21656% with 37 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
packages/botkit/src/repository.ts 91.60% 15 Missing and 8 partials ⚠️
packages/botkit-sqlite/src/mod.ts 76.47% 6 Missing and 2 partials ⚠️
packages/botkit-postgres/src/mod.ts 0.00% 6 Missing ⚠️
Files with missing lines Coverage Δ
packages/botkit-postgres/src/mod.ts 2.93% <0.00%> (ø)
packages/botkit-sqlite/src/mod.ts 55.52% <76.47%> (ø)
packages/botkit/src/repository.ts 87.93% <91.60%> (ø)
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@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: 14937cdc87

ℹ️ 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".

Comment thread CHANGES.md

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
packages/botkit-sqlite/src/mod.ts (1)

418-466: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Move the check inside the transaction and delete by both IDs. A concurrent addFollower() can reassign the same follow_request_id after the pre-transaction lookup, so this code may delete the newly assigned request while cleaning up the stale actorId. Make the DELETE constrain both follow_request_id and follower_id.

🤖 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 `@packages/botkit-sqlite/src/mod.ts` around lines 418 - 466, The
pre-transaction existence check in removeFollower can race with addFollower,
allowing a reused follow_request_id to be deleted for the wrong follower. Move
the validation into the transaction in removeFollower and make the DELETE in
deleteRequestStmt constrain both follow_request_id and follower_id. Use the same
row lookup and cleanup flow, but only commit after confirming the row still
matches the expected actorId, so cleanupFollower cannot act on a reassigned
request.
packages/botkit/src/repository.ts (2)

569-592: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Make follower cleanup atomic and indexed

cleanupFollower can still delete a follower after another request has already reassigned that follower ID, because the follow-request check happens before the lock/delete section. The follow-request lookup is also a full scan on every add/remove path; a reverse index would avoid that linear work.

🤖 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 `@packages/botkit/src/repository.ts` around lines 569 - 592, The follower
cleanup flow is not atomic and can still delete a follower after it has been
reassigned, because cleanupFollower checks hasFollowRequestForFollower before
entering the lock/delete loop. Move the follow-request existence check into the
locked section and re-validate the follower state immediately before deleting,
using the existing lockKey/listKey logic in cleanupFollower to prevent stale
deletes. Also replace the full scan in hasFollowRequestForFollower with a
reverse index keyed by followerId so add/remove paths can do direct lookups
instead of iterating all followRequests entries.

511-531: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Guard addFollower with a CAS/lock. Concurrent writes for the same followRequestId can leave the losing actor persisted only in the followers list/JSON, since previousFollowerId is read before any write and the cleanup only applies to that stale value. Mirror the Postgres lockFollowRequest path or use the existing kv.cas pattern here.

🤖 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 `@packages/botkit/src/repository.ts` around lines 511 - 531, Guard addFollower
against concurrent updates by using the same CAS/lock approach used elsewhere in
Repository, since reading previousFollowerId before writing can leave a losing
follower partially persisted. Update addFollower to serialize per
followRequestId (or use kv.cas) around the read/write/cleanup sequence, and
ensure the cleanup only runs for the actor that actually won the write. Refer to
Repository.addFollower, cleanupFollower, and the existing
lockFollowRequest/kv.cas patterns when implementing the fix.
🤖 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.

Outside diff comments:
In `@packages/botkit-sqlite/src/mod.ts`:
- Around line 418-466: The pre-transaction existence check in removeFollower can
race with addFollower, allowing a reused follow_request_id to be deleted for the
wrong follower. Move the validation into the transaction in removeFollower and
make the DELETE in deleteRequestStmt constrain both follow_request_id and
follower_id. Use the same row lookup and cleanup flow, but only commit after
confirming the row still matches the expected actorId, so cleanupFollower cannot
act on a reassigned request.

In `@packages/botkit/src/repository.ts`:
- Around line 569-592: The follower cleanup flow is not atomic and can still
delete a follower after it has been reassigned, because cleanupFollower checks
hasFollowRequestForFollower before entering the lock/delete loop. Move the
follow-request existence check into the locked section and re-validate the
follower state immediately before deleting, using the existing lockKey/listKey
logic in cleanupFollower to prevent stale deletes. Also replace the full scan in
hasFollowRequestForFollower with a reverse index keyed by followerId so
add/remove paths can do direct lookups instead of iterating all followRequests
entries.
- Around line 511-531: Guard addFollower against concurrent updates by using the
same CAS/lock approach used elsewhere in Repository, since reading
previousFollowerId before writing can leave a losing follower partially
persisted. Update addFollower to serialize per followRequestId (or use kv.cas)
around the read/write/cleanup sequence, and ensure the cleanup only runs for the
actor that actually won the write. Refer to Repository.addFollower,
cleanupFollower, and the existing lockFollowRequest/kv.cas patterns when
implementing the fix.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cb4caa19-e934-44f1-b5ef-7c669be4f6be

📥 Commits

Reviewing files that changed from the base of the PR and between cec1d5b and 14937cd.

⛔ Files ignored due to path filters (1)
  • deno.lock is excluded by !**/*.lock
📒 Files selected for processing (8)
  • CHANGES.md
  • packages/botkit-postgres/src/mod.test.ts
  • packages/botkit-postgres/src/mod.ts
  • packages/botkit-sqlite/src/mod.test.ts
  • packages/botkit-sqlite/src/mod.ts
  • packages/botkit/src/bot-impl.test.ts
  • packages/botkit/src/repository.test.ts
  • packages/botkit/src/repository.ts

dahlia added a commit to dahlia/botkit-fork that referenced this pull request Jul 5, 2026
Move follower removal checks into the protected update path so stale
follow request state cannot delete or report the wrong follower.  SQLite
now validates and deletes by both follow_request_id and follower_id in one
transaction, while the KV repository serializes updates per follow request
and revalidates follower state before cleanup.

fedify-dev#26 (review)

Assisted-by: Codex:GPT-5
dahlia added a commit to dahlia/botkit-fork that referenced this pull request Jul 5, 2026
Use immediate transactions for follower add and remove paths so SQLite
reserves the write lock before reading rows that the same transaction will
update.  This avoids deferred transaction upgrades failing with SQLITE_BUSY
under concurrent writers.

fedify-dev#26 (comment)

Assisted-by: Codex:GPT-5
dahlia added a commit to dahlia/botkit-fork that referenced this pull request Jul 5, 2026
Place the follower cleanup changelog entries under the unreleased 0.4.4
section instead of the already released 0.4.3 section.  This keeps the
release history intact and leaves the upcoming release notes populated.

fedify-dev#26 (comment)

Assisted-by: Codex:GPT-5
@dahlia

dahlia commented Jul 5, 2026

Copy link
Copy Markdown
Member Author

@codex review

@dahlia

dahlia commented Jul 5, 2026

Copy link
Copy Markdown
Member Author

/gemini review

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request resolves issues across multiple repository implementations (MemoryRepository, KvRepository, MemoryCachedRepository, SqliteRepository, and PostgresRepository) where removing one of multiple active follow requests for the same actor could prematurely delete the follower or trigger an early unfollow event. It also ensures that reassigning a follow request does not leave stale followers behind. Key improvements include adding an index in SQLite, introducing a robust locking mechanism in KV storage, and adding comprehensive unit tests to cover these scenarios. I have no feedback to provide.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@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: 644bff122c

ℹ️ 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".

Comment thread packages/botkit/src/repository.ts Outdated
dahlia added a commit to dahlia/botkit-fork that referenced this pull request Jul 5, 2026
Store follower lock keys with a short TTL so a process crash after lock
acquisition cannot leave persistent CAS-backed stores blocked forever.
This keeps the existing lock protocol but lets abandoned lock entries age
out without manual cleanup.

fedify-dev#26 (comment)

Assisted-by: Codex:GPT-5
dahlia added a commit to dahlia/botkit-fork that referenced this pull request Jul 5, 2026
Move follower removal checks into the protected update path so stale
follow request state cannot delete or report the wrong follower.  SQLite
now validates and deletes by both follow_request_id and follower_id in one
transaction, while the KV repository serializes updates per follow request
and revalidates follower state before cleanup.

fedify-dev#26 (review)

Assisted-by: Codex:gpt-5.5
dahlia added a commit to dahlia/botkit-fork that referenced this pull request Jul 5, 2026
Use immediate transactions for follower add and remove paths so SQLite
reserves the write lock before reading rows that the same transaction will
update.  This avoids deferred transaction upgrades failing with SQLITE_BUSY
under concurrent writers.

fedify-dev#26 (comment)

Assisted-by: Codex:gpt-5.5
dahlia added a commit to dahlia/botkit-fork that referenced this pull request Jul 5, 2026
Place the follower cleanup changelog entries under the unreleased 0.4.4
section instead of the already released 0.4.3 section.  This keeps the
release history intact and leaves the upcoming release notes populated.

fedify-dev#26 (comment)

Assisted-by: Codex:gpt-5.5
dahlia added a commit to dahlia/botkit-fork that referenced this pull request Jul 5, 2026
Store follower lock keys with a short TTL so a process crash after lock
acquisition cannot leave persistent CAS-backed stores blocked forever.
This keeps the existing lock protocol but lets abandoned lock entries age
out without manual cleanup.

fedify-dev#26 (comment)

Assisted-by: Codex:gpt-5.5
dahlia added 5 commits July 5, 2026 21:32
Preserve follower records while any accepted follow request still points at
the actor, and only report an unfollow when the last active request is
removed.  This keeps repository state and Bot.onUnfollow delivery aligned
across the memory, KV, SQLite, and PostgreSQL backends.

Also clean up stale followers when a follow request is reassigned, add
regression tests for duplicate and reassigned follow requests, and record
the change in the changelog.

Fixes fedify-dev#25

Assisted-by: Codex:gpt-5.5
Move follower removal checks into the protected update path so stale
follow request state cannot delete or report the wrong follower.  SQLite
now validates and deletes by both follow_request_id and follower_id in one
transaction, while the KV repository serializes updates per follow request
and revalidates follower state before cleanup.

fedify-dev#26 (review)

Assisted-by: Codex:gpt-5.5
Use immediate transactions for follower add and remove paths so SQLite
reserves the write lock before reading rows that the same transaction will
update.  This avoids deferred transaction upgrades failing with SQLITE_BUSY
under concurrent writers.

fedify-dev#26 (comment)

Assisted-by: Codex:gpt-5.5
Place the follower cleanup changelog entries under the unreleased 0.4.4
section instead of the already released 0.4.3 section.  This keeps the
release history intact and leaves the upcoming release notes populated.

fedify-dev#26 (comment)

Assisted-by: Codex:gpt-5.5
Store follower lock keys with a short TTL so a process crash after lock
acquisition cannot leave persistent CAS-backed stores blocked forever.
This keeps the existing lock protocol but lets abandoned lock entries age
out without manual cleanup.

fedify-dev#26 (comment)

Assisted-by: Codex:gpt-5.5
@dahlia

dahlia commented Jul 5, 2026

Copy link
Copy Markdown
Member Author

@codex review

@dahlia

dahlia commented Jul 5, 2026

Copy link
Copy Markdown
Member Author

/gemini review

Collapse duplicated follower-index pruning branches into one update path while
preserving the same cleanup result.

fedify-dev#26 (comment)

Assisted-by: Codex:gpt-5.5
@dahlia

dahlia commented Jul 5, 2026

Copy link
Copy Markdown
Member Author

@codex review

@dahlia

dahlia commented Jul 5, 2026

Copy link
Copy Markdown
Member Author

/gemini review

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request fixes issues across several repositories (MemoryRepository, KvRepository, MemoryCachedRepository, SqliteRepository, and PostgresRepository) where removing one of multiple active follow requests for the same actor could prematurely delete the follower or trigger incorrect unfollow events, and where reassigning follow requests left stale followers. The changes introduce robust follower cleanup logic, indexing, and transaction/locking improvements. The review feedback highlights a valuable optimization opportunity in KvRepository.addFollower where checking if a follower is brand new can prevent an expensive O(N) scan of the follow requests space.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread packages/botkit/src/repository.ts
Comment thread packages/botkit/src/repository.ts

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request addresses issues across @fedify/botkit and its database adapters (SQLite and PostgreSQL) where removing one of multiple active follow requests for the same actor would prematurely delete the follower or trigger an unfollow event. It introduces a robust locking mechanism and index management in KvRepository, updates MemoryRepository and SQL repositories to only clean up followers when no active follow requests remain, and adds extensive test coverage. The review feedback correctly notes that setting "sideEffects": true in @fedify/botkit's package.json prevents tree-shaking and suggests moving this configuration to the PostgreSQL package if it was meant for the Temporal polyfill.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread packages/botkit/package.json
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

Reviewed commit: f4de91e819

ℹ️ 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".

Avoid scanning the follow-request keyspace when adding the first request for a
brand new follower. New follower rows can start from an empty reverse index,
while existing followers still rebuild missing legacy indexes as needed.

fedify-dev#26 (comment)
fedify-dev#26 (comment)

Assisted-by: Codex:gpt-5.5
@dahlia

dahlia commented Jul 5, 2026

Copy link
Copy Markdown
Member Author

@codex review

@dahlia

dahlia commented Jul 5, 2026

Copy link
Copy Markdown
Member Author

/gemini review

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request fixes issues in MemoryRepository, KvRepository, MemoryCachedRepository, SqliteRepository, and PostgresRepository where removing one of multiple active follow requests for the same actor would prematurely delete the follower or fire an unfollow event, and reassigning a follow request left stale followers behind. It introduces robust locking mechanisms, indexing of follow requests per follower, and updates database queries to safely handle conflicts and cleanups. Comprehensive unit tests have been added across the packages to verify these behaviors. There are no review comments, so I have no feedback to provide.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@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: a6fb587221

ℹ️ 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".

Comment thread packages/botkit/src/repository.ts Outdated
Rebuild a missing follower reverse index even when the follower row is being created. Upgraded stores can still have legacy follow request mappings for that actor, so treating every missing follower row as a clean slate can recreate the premature-unfollow case.

fedify-dev#26 (comment)

Assisted-by: Codex:gpt-5.5
@dahlia

dahlia commented Jul 5, 2026

Copy link
Copy Markdown
Member Author

@codex review

@dahlia

dahlia commented Jul 5, 2026

Copy link
Copy Markdown
Member Author

/gemini review

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request fixes issues in @fedify/botkit, @fedify/botkit-sqlite, and @fedify/botkit-postgres repositories where removing one of multiple active follow requests for the same actor would prematurely delete the follower or trigger a premature unfollow event. The repositories have been updated to only clean up followers when no active follow requests remain. Additionally, KvRepository has been refactored to use expiring follower locks and index follow requests. The review feedback highlights a potential ReferenceError due to module-level Temporal duration definitions in repository.ts, suggesting they be initialized lazily or inside the methods where they are used to ensure safety with polyfills.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread packages/botkit/src/repository.ts Outdated
Comment thread packages/botkit/src/repository.ts
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep them coming!

Reviewed commit: 5523b67a32

ℹ️ 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".

Avoid evaluating Temporal.Duration at repository module load time. Some source-loading environments register the Temporal polyfill after import ordering is already underway, so the lock durations now initialize only when the CAS lock path runs.

fedify-dev#26 (comment)
fedify-dev#26 (comment)

Assisted-by: Codex:gpt-5.5
@dahlia

dahlia commented Jul 5, 2026

Copy link
Copy Markdown
Member Author

@codex review

@dahlia

dahlia commented Jul 5, 2026

Copy link
Copy Markdown
Member Author

/gemini review

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request resolves issues across @fedify/botkit repositories (Memory, SQLite, Postgres, and KV) where removing one of multiple active follow requests for the same actor could prematurely delete the follower or trigger unfollow events, and where reassigning follow requests left stale followers. It introduces a cleanupFollower mechanism to ensure followers are only deleted when no active follow requests remain, adds database indexes, and improves transaction and locking safety. Review feedback highlights a potential compilation error under strictNullChecks in the SQLite repository due to a possibly undefined row object, and advises reverting the sideEffects change to false in packages/botkit/package.json to preserve tree-shaking.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread packages/botkit-sqlite/src/mod.ts Outdated
Comment thread packages/botkit/package.json
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

Reviewed commit: b614c2352a

ℹ️ 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".

Guard the removed follower row explicitly before reading actor_json. This keeps the post-transaction parse path easy for strict null checking to follow without changing the removal behavior.

fedify-dev#26 (comment)

Assisted-by: Codex:gpt-5.5
@dahlia

dahlia commented Jul 5, 2026

Copy link
Copy Markdown
Member Author

@codex review

@dahlia

dahlia commented Jul 5, 2026

Copy link
Copy Markdown
Member Author

/gemini review

@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: cc0c83b526

ℹ️ 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".

Comment thread CHANGES.md
@gemini-code-assist

Copy link
Copy Markdown

Warning

Gemini encountered an error creating the review. You can try again by commenting /gemini review.

@dahlia dahlia merged commit 81ae02e into fedify-dev:0.4-maintenance Jul 5, 2026
5 checks passed
@dahlia dahlia deleted the fix/25 branch July 5, 2026 16:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants