Skip to content

Preserve bot follows when an account moves - #56

Merged
dahlia merged 1 commit into
fedify-dev:mainfrom
dahlia:feat/follow-move
Oct 3, 2026
Merged

dahlia merged 1 commit into
fedify-dev:mainfrom
dahlia:feat/follow-move

Conversation

@dahlia

@dahlia dahlia commented Oct 3, 2026 •

Copy link
Copy Markdown
Member

For a push-mode Move, check the destination's own actor document for an alias back to the origin before following the destination and unfollowing the old account. Fetch remote destinations with a bot's signed loader instead of trusting embedded actors. Transient lookup failures can still be retried.

Use the follow reverse index to migrate every affected bot, even for personal inbox delivery, because Fedify deduplicates queued activities across recipients. Allow Follow/Accept/Reject/Undo between sibling bots to support local destinations. onFolloweeMove reports the change; a new follow request may still await acceptance.

Fixes #49.

Summary by CodeRabbit

  • New Features
    • Bots now automatically follow a verified replacement account when someone they follow moves, then unfollow the old account. An event handler can respond after these actions.
  • Bug Fixes
    • Fixed delivery of follow requests, acceptances, rejections, and unfollows between bots on the same instance, including follow requests to migration targets.

Follow an alias-verified destination when a followed account sends a
push-mode Move, then unfollow the origin and notify onFolloweeMove
handlers. Route migrations to all following bots, including dynamic
groups, and retry transient document failures without trusting embeds.

Allow Follow, Accept, Reject, and Undo delivery between sibling bots so
migrations to a local actor complete through real HTTP inboxes. Cover
validation, retries, duplicates, callbacks, and delivery in both runtimes,
and document the event's request and acceptance semantics.

Design and implementation were AI-assisted, with independent design and
code reviews. Validated with mise run test and mise run docs:build.

Fixes fedify-dev#49

Assisted-by: OpenCode:deepseek-flash
Assisted-by: Codex:gpt-6.1-sol
Assisted-by: Claude Code:claude-fable-5-1
Assisted-by: Claude Code:claude-opus-5-5
@dahlia dahlia added this to the BotKit 0.6 milestone Oct 3, 2026
@dahlia dahlia self-assigned this Oct 3, 2026
@dahlia dahlia added the enhancement New feature or request label Oct 3, 2026
@coderabbitai

coderabbitai Bot commented Oct 3, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

🧰 Additional context used
📚 Code guidelines (1)
AGENTS.md — auto-discovered

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 2670f03a-343a-4c33-8f62-0d2191e3898a
📥 Commits

Reviewing files that changed from the base of the PR and between 758c26c and fe651b2.

📒 Files selected for processing (14)
  • CHANGES.md
  • changes.d/botkit/followee-move.md
  • changes.d/botkit/local-follows.md
  • docs/concepts/events.md
  • docs/concepts/session.md
  • packages/botkit/src/bot-impl.ts
  • packages/botkit/src/bot.ts
  • packages/botkit/src/events.ts
  • packages/botkit/src/follow-impl.ts
  • packages/botkit/src/follow-local.test.ts
  • packages/botkit/src/follow-move.test.ts
  • packages/botkit/src/instance-impl.ts
  • packages/botkit/src/session-impl.ts
  • packages/botkit/src/uri.ts

Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 1 remain after this review.


📝 Walkthrough

Walkthrough

BotKit now processes verified account moves for followed actors, migrates follows to verified target accounts, and provides an onFolloweeMove callback. Follow-related activity delivery also uses recipient-specific options, with integration tests covering delivery between bots on the same instance.

Changes

Followee move handling

Layer / File(s) Summary
Move callback API and documentation
packages/botkit/src/events.ts, packages/botkit/src/bot.ts, packages/botkit/src/bot-impl.ts, docs/concepts/events.md, docs/concepts/session.md, CHANGES.md, changes.d/botkit/followee-move.md
Adds and wires the onFolloweeMove callback. Documentation describes its arguments, configuration, timing, and migration outcomes.
Move dispatch and actor validation
packages/botkit/src/instance-impl.ts, packages/botkit/src/follow-move.test.ts
Routes Move activities to processing that validates activity and actor data, resolves old and destination actors, and handles fetch failures. Tests cover validation and lookup outcomes.
Follow migration and callback execution
packages/botkit/src/instance-impl.ts, packages/botkit/src/follow-move.test.ts, packages/botkit/src/follow-local.test.ts
Migrates eligible follows, invokes callbacks, and handles duplicate moves and transition failures. Tests cover migration state, handler wiring, and local-target behavior.

Same-instance follow delivery

Layer / File(s) Summary
Local follow delivery and integration coverage
packages/botkit/src/uri.ts, packages/botkit/src/session-impl.ts, packages/botkit/src/follow-impl.ts, packages/botkit/src/follow-local.test.ts, CHANGES.md, changes.d/botkit/local-follows.md
Adds recipient-specific delivery options for follow, unfollow, accept, and reject operations. HTTP integration tests cover sibling-bot migration and rejection.

Priority: ➖ Normal

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

Change: Feature · Severity of issue fixed: Medium

Sequence Diagram(s)

sequenceDiagram
  participant InboxListener
  participant InstanceImpl
  participant DocumentLoader
  participant SessionImpl
  participant Bot
  InboxListener->>InstanceImpl: Dispatch Move to onMoved
  InstanceImpl->>DocumentLoader: Resolve old and destination actors
  DocumentLoader-->>InstanceImpl: Return actor documents
  InstanceImpl->>SessionImpl: Follow destination when needed
  InstanceImpl->>SessionImpl: Unfollow old actor
  InstanceImpl->>Bot: Invoke onFolloweeMove
Loading

Merge Risk: ⚪ Minimal · up to fe651

This change lets bots move their follows to an account's verified new address and allows follow-related activities between bots on the same instance. The review found no concrete defect that should block merging.

Security Architecture Review

Security architecture risk: 🟡 Moderate · up to fe651

Destination verification and bot-specific ownership checks constrain migration. However, failed cleanup can leave local and remote follow relationships inconsistent without automatic recovery. Authorization of the original sender and coordination across multiple running instances remain incompletely established.

Retained concerns

  • Medium · reliability · inferred: Automatic migration uses the old accepted-follow record both to authorize processing and to select retries, but deletes it before submitting Undo. If submission fails, subsequent Moves skip cleanup and notification while the old remote account may retain the relationship. The underlying unfollow ordering is pre-existing; the PR expands its exposure through remotely initiated, multi-bot migration. Documenting this limitation clarifies the contract but does not restore convergence of local and remote ownership.
Security review details

Security Blast Radius

  • observed — A qualifying Move can migrate every resolved bot on the receiving instance that still has an accepted follow of the old actor, including when delivered to one personal inbox. Missing bots, unrelated bots, and a bot that is itself the destination are excluded.

Trust Boundaries and Controls

  • inferred — Authorization of the old account is delegated to the federation inbox verifier: onMoved checks activity-field consistency, not authenticated signer ownership. The unverified-activity hook has no Move-specific exception. The signed HTTP integration test demonstrates legitimate migration but does not establish rejection of a Move signed by a different actor; sender-forgery resistance remains an evidence gap, not a verified bypass.

Resilience and Maintainability Implications

  • observed — Immediate destination-Follow submission failure preserves that bot’s old relationship and allows retry while other bots proceed. In contrast, failed Undo submission leaves the old local relationship removed and neither cleanup nor the migration event is replayed. These distinct recovery states are documented and represented in tests.

Hardening Proposals

  • proposed — Persist per-bot migration progress or an Undo outbox entry before deleting the relationship used for retry selection, so cleanup can converge independently of the accepted-follow record. Define durable idempotency if multiple processes may share the repository.
  • proposed — Establish the upstream signer-to-actor authorization contract and add a real-inbox negative case where a different authenticated actor signs a Move claiming the followed origin.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 9 files. (5 skipped: 5… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: preserving bot follows when a followed account moves.
Linked Issues check ✅ Passed Issue #49 requires push-mode Move validation, reverse-index lookup of affected bots, a destination actor fetched with a bot’s signed loader, alias verification, idempotent follow migration, and the on…
Out of Scope Changes check ✅ Passed The changes stay within issue #49. The follow-delivery changes in uri.ts, session-impl.ts, and follow-impl.ts allow sibling bots to exchange Follow, Undo, Accept, and Reject activities. This supports …
Full details: Docstring Coverage

Explanation

Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 9 files. (5 skipped: 5 unsupported.)

  • Fix all pre-merge checks with AI
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@codecov

codecov Bot commented Oct 3, 2026

Copy link
Copy Markdown

Codecov Report

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

Files with missing lines Patch % Lines
packages/botkit/src/instance-impl.ts 94.61% 2 Missing and 10 partials ⚠️
Files with missing lines Coverage Δ
packages/botkit/src/bot-impl.ts 89.91% <100.00%> (+0.21%) ⬆️
packages/botkit/src/bot.ts 100.00% <ø> (ø)
packages/botkit/src/follow-impl.ts 91.93% <100.00%> (+0.13%) ⬆️
packages/botkit/src/session-impl.ts 89.39% <100.00%> (+0.47%) ⬆️
packages/botkit/src/uri.ts 100.00% <100.00%> (ø)
packages/botkit/src/instance-impl.ts 82.66% <94.61%> (+3.88%) ⬆️
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@dahlia
dahlia merged commit 683c1fe into fedify-dev:main Oct 3, 2026
6 checks passed
@dahlia
dahlia deleted the feat/follow-move branch October 3, 2026 07:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Follow accounts that move while a bot follows them

1 participant