Skip to content

Merge next to main #35

Merged
sij411 merged 25 commits into
mainfrom
next
Jul 3, 2026
Merged

Merge next to main #35
sij411 merged 25 commits into
mainfrom
next

Conversation

@sij411

@sij411 sij411 commented Jul 3, 2026

Copy link
Copy Markdown
Member

Merged next to main. next will be removed afterwards since it is unnecessary.

Summary by CodeRabbit

  • New Features
    • Added a runnable local server with actor, note, health check, and WebFinger endpoints.
    • Added support for returning local actor data and preview notes over ActivityPub-style JSON.
  • Bug Fixes
    • Requests for unknown actors or notes now correctly return 404.
    • WebFinger requests without a resource now return 400.
  • Chores
    • Added cross-platform test coverage and a simple test command for local development.

sij411 added 25 commits June 28, 2026 23:02
  Assisted-by: Codex:gpt-5.5
Assisted-by: Codex:gpt-5.5
Update license description to allow only 3.0
  Assisted-by: Codex:gpt-5.5
Assisted-by: Codex:gpt-5.5
Expose GET /users/{username} from the server runtime and return the
  configured local actor as application/activity+json. Keep the local actor
  in
  AppState and pass a clone into FederCore so HTTP serving does not need to
  lock
  the core state.
  Cover the configured local actor route, unknown usernames, response
  content
  type, and serialized ActivityPub actor fields.

  Assisted-by: Codex:gpt-5.5
  Cover the seeded public Note route, unknown Note IDs, response content
  type,
  and serialized ActivityPub Note fields.

  Assisted-by: Codex:gpt-5.5
Implement ActivityPub discovery endpoints
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds a new feder-core crate implementing an in-memory ActivityPub decision engine (FederCore, FederState, Input/Action types) that handles follow and note-creation events, and a new feder-runtime-server Axum crate exposing health, actor, note, and WebFinger HTTP endpoints. Workspace, CI, and mise tooling are updated to include the new crate and cross-platform test matrix.

Changes

feder-core state engine

Layer / File(s) Summary
Core types and dispatcher
crates/feder-core/src/lib.rs
Defines FederConfig, FederState, Input, Action, Activity, Object, HandleResult and the FederCore::handle dispatcher.
Follow and note handling logic
crates/feder-core/src/lib.rs
Implements follower recording, delivery target updates, Accept activity emission, note creation, CreateNote fanout, and unit tests.

feder-runtime-server crate

Layer / File(s) Summary
Crate setup and workspace wiring
Cargo.toml, crates/feder-runtime-server/Cargo.toml, .../src/lib.rs, .../src/error.rs, .../README.md
Adds the new workspace member, tower dependency, crate manifest, module exports, Error enum, and README documentation.
Runtime config and app state
crates/feder-runtime-server/src/config.rs, .../src/app.rs
Defines RuntimeConfig::default_local, AppState with shared FederCore and seeded notes, and build_router/healthz.
HTTP handlers: actor, note, webfinger
.../src/actor.rs, .../src/note.rs, .../src/webfinger.rs
Implements actor, note, and WebFinger request handlers with validation, JSON responses, and tests.
Server entry point
crates/feder-runtime-server/src/main.rs
Adds main binding a TcpListener and serving the router with tracing and error mapping.
CI and tooling
.github/workflows/main.yaml, mise.toml, crates/feder-vocab/src/lib.rs, crates/feder-vocab/tests/phase1_shapes.rs
Adds a cross-platform test matrix job, a mise test task, and license headers in feder-vocab files.

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

Possibly related PRs

  • fedify-dev/feder#16: Both PRs add/expand crates/feder-core/src/lib.rs with FederCore::handle(Input) -> HandleResult and shared Input/Action types.
  • fedify-dev/feder#21: Both PRs implement the same core boundary in crates/feder-core/src/lib.rs including FederCore, FederConfig/FederState, and follow-to-accept/create-note flows.
  • fedify-dev/feder#28: The retrieved PR implements the initial feder-runtime-server skeleton with overlapping RuntimeConfig::default_local, build_router//healthz, and main.rs wiring.

Suggested labels: enhancement

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title is generic and only indicates a branch merge, not the substantive server and CI changes in the PR. Use a concise title that names the main change, such as adding the feder runtime server and cross-platform test CI.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ 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.

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

🧹 Nitpick comments (3)
crates/feder-runtime-server/src/app.rs (1)

64-73: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

No tracing/observability middleware on the router.

tracing/tracing-subscriber are dependencies, but build_router doesn't attach a request-tracing layer (e.g. tower_http::trace::TraceLayer), so per-request spans/logs won't be emitted for the HTTP endpoints.

🤖 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 `@crates/feder-runtime-server/src/app.rs` around lines 64 - 73, The router
built in build_router currently has no request-level tracing, so add an HTTP
tracing middleware layer to the Router returned from build_router using the
existing tracing-related dependencies. Attach a tower_http::trace::TraceLayer
(or equivalent request span/log layer) to the Router before with_state(state),
so all routes like healthz, webfinger, actor, and note emit per-request
spans/logs.
crates/feder-runtime-server/Cargo.toml (1)

7-19: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Inconsistent dependency management: some deps centralized, others not.

serde, serde_json, and tower are pulled via .workspace = true, but axum, thiserror, tokio, tracing, and tracing-subscriber are declared with hardcoded versions directly in this crate even though the root Cargo.toml's [workspace.dependencies] table already centralizes shared deps. As more crates are added to this workspace, version drift becomes likely.

♻️ Suggested consolidation
# In root Cargo.toml [workspace.dependencies]
+axum = "0.8"
+thiserror = "2"
+tokio = { version = "1", features = ["macros", "net", "rt-multi-thread"] }
+tracing = "0.1"
+tracing-subscriber = { version = "0.3", features = ["env-filter"] }

# In crates/feder-runtime-server/Cargo.toml
-axum = "0.8"
-thiserror = "2"
-tokio = { version = "1", features = ["macros", "net", "rt-multi-thread"] }
-tracing = "0.1"
-tracing-subscriber = { version = "0.3", features = ["env-filter"] }
+axum.workspace = true
+thiserror.workspace = true
+tokio.workspace = true
+tracing.workspace = true
+tracing-subscriber.workspace = true
🤖 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 `@crates/feder-runtime-server/Cargo.toml` around lines 7 - 19, The dependency
list in the feder-runtime-server Cargo.toml is mixing workspace-managed and
hardcoded versions, which can lead to version drift. Update the package manifest
to use the root workspace dependency entries for axum, thiserror, tokio,
tracing, and tracing-subscriber, similar to serde and serde_json. Keep the
feder-core and feder-vocab path dependencies as-is, and adjust the
[dependencies] and [dev-dependencies] entries to reference the workspace-managed
symbols consistently.
crates/feder-runtime-server/src/main.rs (1)

29-32: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Consider graceful shutdown handling.

axum::serve runs without a shutdown signal, so in-flight requests are dropped abruptly on SIGINT/SIGTERM during restarts/redeploys.

♻️ Suggested addition
     let listener = tokio::net::TcpListener::bind(config.bind)
         .await
         .map_err(Error::Bind)?;
-    axum::serve(listener, app).await.map_err(Error::Serve)?;
+    axum::serve(listener, app)
+        .with_graceful_shutdown(async {
+            let _ = tokio::signal::ctrl_c().await;
+        })
+        .await
+        .map_err(Error::Serve)?;
🤖 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 `@crates/feder-runtime-server/src/main.rs` around lines 29 - 32, Add graceful
shutdown handling to the server startup flow in main by wiring a shutdown signal
into the axum::serve call instead of awaiting it directly. Update the
listener/app serving block to use a shutdown future (for example from a
SIGINT/SIGTERM handler) so in-flight requests can finish cleanly during
restarts, and keep the error mapping through Error::Bind and Error::Serve
intact.
🤖 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 @.github/workflows/main.yaml:
- Around line 24-37: The new cross-platform job’s checkout step should disable
Git credential persistence to avoid unnecessary repo write access. Update the
actions/checkout usage in the cross-platform workflow step to include
persist-credentials set to false, since this job only runs cargo test and does
not need to push or write back. Refer to the cross-platform job and its checkout
step in the workflow when making the change.

In `@crates/feder-runtime-server/src/main.rs`:
- Around line 18-25: main is still using RuntimeConfig::default_local(), which
hardcodes local-only settings instead of reading deployment configuration.
Update the main entry point to construct the RuntimeConfig from
environment-backed settings or a loader method, and then pass that env-derived
config into build_router so the server respects deployment values rather than
127.0.0.1:3000 and alice.

---

Nitpick comments:
In `@crates/feder-runtime-server/Cargo.toml`:
- Around line 7-19: The dependency list in the feder-runtime-server Cargo.toml
is mixing workspace-managed and hardcoded versions, which can lead to version
drift. Update the package manifest to use the root workspace dependency entries
for axum, thiserror, tokio, tracing, and tracing-subscriber, similar to serde
and serde_json. Keep the feder-core and feder-vocab path dependencies as-is, and
adjust the [dependencies] and [dev-dependencies] entries to reference the
workspace-managed symbols consistently.

In `@crates/feder-runtime-server/src/app.rs`:
- Around line 64-73: The router built in build_router currently has no
request-level tracing, so add an HTTP tracing middleware layer to the Router
returned from build_router using the existing tracing-related dependencies.
Attach a tower_http::trace::TraceLayer (or equivalent request span/log layer) to
the Router before with_state(state), so all routes like healthz, webfinger,
actor, and note emit per-request spans/logs.

In `@crates/feder-runtime-server/src/main.rs`:
- Around line 29-32: Add graceful shutdown handling to the server startup flow
in main by wiring a shutdown signal into the axum::serve call instead of
awaiting it directly. Update the listener/app serving block to use a shutdown
future (for example from a SIGINT/SIGTERM handler) so in-flight requests can
finish cleanly during restarts, and keep the error mapping through Error::Bind
and Error::Serve intact.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: a443c948-c7e3-41a1-9c95-8b2b08a8ea9f

📥 Commits

Reviewing files that changed from the base of the PR and between 1abcbfd and ccc1623.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (16)
  • .github/workflows/main.yaml
  • Cargo.toml
  • crates/feder-core/src/lib.rs
  • crates/feder-runtime-server/Cargo.toml
  • crates/feder-runtime-server/README.md
  • crates/feder-runtime-server/src/actor.rs
  • crates/feder-runtime-server/src/app.rs
  • crates/feder-runtime-server/src/config.rs
  • crates/feder-runtime-server/src/error.rs
  • crates/feder-runtime-server/src/lib.rs
  • crates/feder-runtime-server/src/main.rs
  • crates/feder-runtime-server/src/note.rs
  • crates/feder-runtime-server/src/webfinger.rs
  • crates/feder-vocab/src/lib.rs
  • crates/feder-vocab/tests/phase1_shapes.rs
  • mise.toml

Comment on lines +24 to +37
cross-platform:
name: cargo test (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
- ubuntu-latest
- macos-latest
- windows-latest
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
- run: cargo test --workspace

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

Add persist-credentials: false to the new checkout step.

Static analysis flags the new cross-platform job's checkout for credential persistence (artipacked). Since this job only runs tests and doesn't push/write to the repo, disable credential persistence.

🔒️ Proposed fix
     steps:
     - uses: actions/checkout@v6
+      with:
+        persist-credentials: false
     - uses: dtolnay/rust-toolchain@stable
     - run: cargo test --workspace
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
cross-platform:
name: cargo test (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
- ubuntu-latest
- macos-latest
- windows-latest
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
- run: cargo test --workspace
cross-platform:
name: cargo test (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
- ubuntu-latest
- macos-latest
- windows-latest
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
- uses: dtolnay/rust-toolchain@stable
- run: cargo test --workspace
🧰 Tools
🪛 zizmor (1.26.1)

[warning] 35-35: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[warning] 24-38: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block

(excessive-permissions)

🤖 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 @.github/workflows/main.yaml around lines 24 - 37, The new cross-platform
job’s checkout step should disable Git credential persistence to avoid
unnecessary repo write access. Update the actions/checkout usage in the
cross-platform workflow step to include persist-credentials set to false, since
this job only runs cargo test and does not need to push or write back. Refer to
the cross-platform job and its checkout step in the workflow when making the
change.

Source: Linters/SAST tools

Comment on lines +18 to +25
#[tokio::main]
async fn main() -> Result<(), Error> {
tracing_subscriber::fmt()
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
.init();

let config = RuntimeConfig::default_local();
let app = build_router(&config);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -n 'impl RuntimeConfig' -A 40 crates/feder-runtime-server/src/config.rs
rg -n 'from_env|std::env|env::var' crates/feder-runtime-server/src/config.rs crates/feder-runtime-server/src/main.rs

Repository: fedify-dev/feder

Length of output: 1218


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== main.rs ==\n'
cat -n crates/feder-runtime-server/src/main.rs | sed -n '1,220p'

printf '\n== config.rs ==\n'
cat -n crates/feder-runtime-server/src/config.rs | sed -n '1,220p'

printf '\n== runtime config usages ==\n'
rg -n "RuntimeConfig|default_local|from_env|std::env|env::var" crates/feder-runtime-server -S

Repository: fedify-dev/feder

Length of output: 6046


Load runtime config from the environment RuntimeConfig::default_local() hardcodes 127.0.0.1:3000 and alice, so this entry point still ignores deployment settings. Wire main to an env-backed constructor/loader instead of the local defaults.

🤖 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 `@crates/feder-runtime-server/src/main.rs` around lines 18 - 25, main is still
using RuntimeConfig::default_local(), which hardcodes local-only settings
instead of reading deployment configuration. Update the main entry point to
construct the RuntimeConfig from environment-backed settings or a loader method,
and then pass that env-derived config into build_router so the server respects
deployment values rather than 127.0.0.1:3000 and alice.

@sij411 sij411 merged commit 469982a into main Jul 3, 2026
9 checks passed
@sij411 sij411 deleted the next branch July 3, 2026 08:12
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