Skip to content

Promote portable core foundation to main#21

Merged
sij411 merged 24 commits into
mainfrom
next
Jun 18, 2026
Merged

Promote portable core foundation to main#21
sij411 merged 24 commits into
mainfrom
next

Conversation

@sij411

@sij411 sij411 commented Jun 18, 2026

Copy link
Copy Markdown
Member

Summary

  • Add minimal ActivityPub vocabulary types for actors, notes, follows, accepts, and creates.
  • Add typed ID-or-object and scalar-or-array vocabulary helpers.
  • Establish the portable Input -> FederCore -> Action boundary without runtime I/O.
  • Add in-memory follower, delivery-target, object, and activity state.
  • Implement Follow-to-Accept and local Create(Note) decision flows.
  • Add mocked end-to-end coverage proving the core boundary.

Milestone

Merging this pull request completes the planned work for Milestone 1: Phase 1. All issues assigned to the milestone are complete, and the milestone can be closed after this promotion lands on main.

Scope

This promotes the completed portable core foundation from next to main. Networking, persistent storage, HTTP signatures, actor resolution, delivery workers, and partial JSON-LD normalization remain runtime work for later milestones.

Validation

  • cargo test --workspace
  • mise run check

sij411 and others added 24 commits June 2, 2026 18:52
Add minimal ActivityPub vocab types
Refine multi-value vocab references
Assisted-by: Codex:gpt-5.5
Assisted-by: Codex:gpt-5.5
Assisted-by: Codex:gpt-5.5
Assisted-by: Codex:gpt-5.5
Assisted-by: Codex:gpt-5.5
Assisted-by: Codex:gpt-5.5
Assisted-by: Codex:gpt-5.5
Assisted-by: Codex:gpt-5.5
Assisted-by: Codex:gpt-5.5
Assisted-by: Codex:gpt-5.5
Assisted-by: Codex:gpt-5.5
Assisted-by: Codex:gpt-5.5
Assisted-by: Codex:gpt-5.5
Assisted-by: Codex:gpt-5.5
@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR introduces two new no_std Rust crates. feder-vocab provides ActivityStreams/ActivityPub vocabulary types (Reference<T>, References<T>, Actor, Note, Follow, Accept, Create<T>) with serde JSON-LD serialization. feder-core implements a no-I/O engine (FederCore) that processes Input variants into deferred Action lists via FederState. Workspace-level dependency declarations for iri-string, serde, and serde_json are also added.

Changes

ActivityPub Vocabulary and Core Engine

Layer / File(s) Summary
Workspace dependency declarations
Cargo.toml, crates/feder-vocab/Cargo.toml
Adds [workspace.dependencies] for iri-string, serde, and serde_json; wires them into the feder-vocab manifest.
Vocab foundation: Iri, Reference, References, kind enums
crates/feder-vocab/src/lib.rs
Establishes #![no_std] crate base: ACTIVITYSTREAMS_CONTEXT, Iri alias, untagged Reference<T> enum, References<T> with custom serde scalar/array/absent behavior, and macro-generated kind enums (NoteType, FollowType, AcceptType, CreateType, ActorType).
Vocab activity structs: Actor, Note, Follow, Accept, Create
crates/feder-vocab/src/lib.rs
Defines Actor, Note, Follow, Accept, and generic Create<T> with serde JSON-LD field renames and constructors that populate the context constant and default kind values.
Vocab inline and integration tests
crates/feder-vocab/src/lib.rs, crates/feder-vocab/tests/phase1_shapes.rs
Inline roundtrip tests for all activity structs, Reference/References shape variants, and type-mismatch rejection; integration tests covering Follow deserialization, Accept/Create serialization, and absent-vs-empty References behavior.
Core public API contracts: Input, Action, HandleResult
crates/feder-core/src/lib.rs
Defines the full deferred-work model: Input, ReceivedFollow, UserCreateNote, Follower, DeliveryTarget, Action and store/send payload structs, Activity/Object enums, and HandleResult.
FederCore, FederConfig, FederState, and core decision flows
crates/feder-core/src/lib.rs
Implements FederCore entry point routing inputs; FederConfig carrying local_actor; FederState with in-memory collections and record_follow/record_created_note logic; plus the HasId/reference_id helper.
FederCore unit tests
crates/feder-core/src/lib.rs
Covers follower recording, inbox upsert, non-local actor ignore paths, note storage, delivery fan-out to multiple targets, end-to-end follow-then-create flow, and local actor reference normalization.

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant FederCore
  participant FederState
  participant Actions as "Vec<Action>"

  rect rgba(70, 130, 180, 0.5)
    Note over Caller,Actions: ReceivedFollow path
    Caller->>FederCore: handle(Input::ReceivedFollow { follow, accept_id })
    FederCore->>FederState: record_follow(follow, accept_id)
    FederState->>FederState: validate following == local_actor
    FederState->>FederState: deduplicate + store Follower
    FederState->>FederState: upsert DeliveryTarget inbox from embedded actor
    FederState-->>Actions: StoreFollower, StoreDeliveryTarget, SendActivity(Accept)
    FederCore-->>Caller: HandleResult { actions }
  end

  rect rgba(60, 179, 113, 0.5)
    Note over Caller,Actions: UserCreateNote path
    Caller->>FederCore: handle(Input::UserCreateNote { note_id, create_id, actor, content })
    FederCore->>FederState: record_created_note(...)
    FederState->>FederState: validate actor == local_actor
    FederState->>FederState: normalize actor ref → local actor ID
    FederState->>FederState: store Note object + CreateNote activity
    FederState-->>Actions: StoreObject, StoreActivity, SendActivity × delivery_targets.len()
    FederCore-->>Caller: HandleResult { actions }
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • fedify-dev/feder#17: Directly replaces the placeholder FederCore with the same stateful FederCore/FederConfig/FederState and in-memory follower/delivery-target logic introduced in this PR.
  • fedify-dev/feder#13: Makes parallel changes to workspace dependency setup and implements the same minimal ActivityPub vocab types (Actor, Note, Follow, Accept, Create<T>) in crates/feder-vocab/src/lib.rs.
  • fedify-dev/feder#20: Adjusts FederState::record_follow to emit StoreFollower only for newly added followers, directly overlapping with the core follow-recording flow added here.

Suggested labels

enhancement, phase 1

🐇 A rabbit hops through the ActivityPub stream,
Sending Accepts and Notes like a well-crafted dream.
No I/O, no blocking — just actions deferred,
Each Follow recorded, each inbox inferred.
With vocab and core now neatly aligned,
The federation engine is perfectly designed! 🌐

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: promoting a portable core foundation to the main branch, which aligns with the PR's primary objective of establishing a minimal ActivityPub implementation layer.
Docstring Coverage ✅ Passed Docstring coverage is 84.29% which is sufficient. The required threshold is 80.00%.
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 next

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 and usage tips.

@sij411 sij411 self-assigned this Jun 18, 2026
@sij411 sij411 added the phase 1 label Jun 18, 2026
@sij411 sij411 merged commit 1abcbfd into main Jun 18, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant