ActivityPub implementation validator (CLI + lint plugin)
Problem
Developers new to ActivityPub often struggle to identify which components need to be implemented for a working server. It's easy to miss required dispatchers or handlers.
Solution
Add fedify checklist command that shows:
$ fedify checklist
ActivityPub Server Checklist
===========================
Core Requirements:
✅ Actor Dispatcher (setActorDispatcher)
✅ Key Pairs Dispatcher (setKeyPairsDispatcher)
❌ NodeInfo Dispatcher (setNodeInfoDispatcher)
❌ Inbox Listeners (setInboxListeners)
- Missing handlers: Follow, Accept, Create, Undo
Recommended:
❌ Outbox Dispatcher (setOutboxDispatcher)
❌ Followers Collection (setFollowersDispatcher)
❌ Following Collection (setFollowingDispatcher)
Optional:
- Object Dispatchers
- Featured/Liked Collections
- Additional activity handlers (Update, Delete, Like, Announce)
3/10 components implemented
Benefits
- Clear implementation roadmap
- Prevents missing critical components
- Improves federation compatibility
- Reduces learning curve
Implementation Ideas
- Analyze existing federation setup
- Show progress with checkmarks
- Link to relevant docs
- Optional boilerplate generation
This would greatly help newcomers understand what's needed for a complete ActivityPub implementation.
Would you let me take this issue? 괜찮다면 제가 이 이슈 맡아봐도 될까요?
I think this issue still needs more discussion. We haven't decided how to implement it yet—whether through the fedify checklist command, as an eslint plugin, or by logging at the "debug" level…
아직 이 이슈는 좀 더 논의되어 봐야 할 것 같아요. 아직 어떤 식으로 구현해야 할 지 정해지지 않았거든요. fedify checklist 커맨드로 구현할지, 아니면 eslint 플러그인으로 구현할지, 아니면 "debug" 레벨로 로그를 남기게 할지…
I think we can implement this in a way that provides maximum flexibility and coverage across different environments.
My proposal is to create a @fedify/lint package that implements lint rules compatible with both Deno lint and eslint APIs (according to Deno's documentation, they share similar AST-based patterns). This single package would provide three ways to use it:
- Deno lint plugin: for Deno projects to get real-time feedback in their IDE
- eslint plugin: for Node.js/Bun projects with the same real-time feedback
fedify checkCLI command: embeds eslint internally and runs the same rules, providing formatted checklist output without requiring any lint configuration
The CLI approach makes it immediately accessible (just run fedify check), while the lint plugins give developers real-time feedback as they code. The rules would detect missing dispatchers (actor, keypairs, inbox listeners, etc.) and could support different profiles (minimal, microblogging, media-server) with appropriate requirements for each use case.
What do you think about this approach? It would provide the checklist functionality you proposed while also enabling progressive enhancement for developers who want deeper integration.
@2chanhaeng This issue has been assigned for over two weeks without updates. Please provide a status update, or unassign yourself if you're unable to continue working on it.
Based on the analysis of runtime warnings in the packages/fedify/src/federation/ directory, here's a proposed list of lint rules that should be implemented for the @fedify/lint package:
Proposed lint rules
The following table lists 23 lint rules derived from existing runtime warnings in Fedify. These rules will help developers catch common mistakes during development rather than at runtime.
| Rule ID | Category | Severity | Description | Code location |
|---|---|---|---|---|
fedify/actor-id-required |
Actor | Error | Actor dispatcher must return an actor with an id property set via Context.getActorUri(identifier) |
builder.ts:249-253 |
fedify/actor-id-mismatch |
Actor | Error | Actor's id property must match the URI returned by Context.getActorUri(identifier) |
builder.ts:254-260 |
fedify/actor-following-property-required |
Collection | Warning | When following collection dispatcher is configured, actor must have a following property set via Context.getFollowingUri(identifier) |
builder.ts:265-270 |
fedify/actor-following-property-mismatch |
Collection | Warning | Actor's following property must match the URI returned by Context.getFollowingUri(identifier) |
builder.ts:271-280 |
fedify/actor-followers-property-required |
Collection | Warning | When followers collection dispatcher is configured, actor must have a followers property set via Context.getFollowersUri(identifier) |
builder.ts:286-291 |
fedify/actor-followers-property-mismatch |
Collection | Warning | Actor's followers property must match the URI returned by Context.getFollowersUri(identifier) |
builder.ts:292-301 |
fedify/actor-outbox-property-required |
Collection | Warning | When outbox collection dispatcher is configured, actor must have an outbox property set via Context.getOutboxUri(identifier) |
builder.ts:307-312 |
fedify/actor-outbox-property-mismatch |
Collection | Warning | Actor's outbox property must match the URI returned by Context.getOutboxUri(identifier) |
builder.ts:313-321 |
fedify/actor-liked-property-required |
Collection | Warning | When liked collection dispatcher is configured, actor must have a liked property set via Context.getLikedUri(identifier) |
builder.ts:327-332 |
fedify/actor-liked-property-mismatch |
Collection | Warning | Actor's liked property must match the URI returned by Context.getLikedUri(identifier) |
builder.ts:333-341 |
fedify/actor-featured-property-required |
Collection | Warning | When featured collection dispatcher is configured, actor must have a featured property set via Context.getFeaturedUri(identifier) |
builder.ts:347-352 |
fedify/actor-featured-property-mismatch |
Collection | Warning | Actor's featured property must match the URI returned by Context.getFeaturedUri(identifier) |
builder.ts:353-361 |
fedify/actor-featured-tags-property-required |
Collection | Warning | When featured tags collection dispatcher is configured, actor must have a featuredTags property set via Context.getFeaturedTagsUri(identifier) |
builder.ts:367-372 |
fedify/actor-featured-tags-property-mismatch |
Collection | Warning | Actor's featuredTags property must match the URI returned by Context.getFeaturedTagsUri(identifier) |
builder.ts:373-383 |
fedify/collection-filtering-not-implemented |
Collection | Warning | Collection should implement filtering to avoid large response payloads. See: https://fedify.dev/manual/collections#filtering-by-server | handler.ts:496-504 |
fedify/actor-inbox-property-required |
Inbox | Warning | When inbox listeners are configured, actor must have an inbox property set via Context.getInboxUri(identifier) |
builder.ts:386-391 |
fedify/actor-inbox-property-mismatch |
Inbox | Warning | Actor's inbox property must match the URI returned by Context.getInboxUri(identifier) |
builder.ts:392-400 |
fedify/actor-shared-inbox-property-required |
Inbox | Warning | When inbox listeners are configured, actor must have an endpoints.sharedInbox property set via Context.getInboxUri() |
builder.ts:401-406 |
fedify/actor-shared-inbox-property-mismatch |
Inbox | Warning | Actor's endpoints.sharedInbox property must match the URI returned by Context.getInboxUri() |
builder.ts:407-415 |
fedify/actor-public-key-required |
Keys | Error | When key pairs dispatcher is configured, actor must have a publicKey property set via Context.getActorKeyPairs(identifier) |
builder.ts:418-423 |
fedify/actor-assertion-method-required |
Keys | Error | When key pairs dispatcher is configured, actor must have an assertionMethod property set via Context.getActorKeyPairs(identifier) |
builder.ts:425-431 |
fedify/rsa-key-required-for-http-signature |
Keys | Warning | At least one RSASSA-PKCS1-v1_5 key must be provided to sign HTTP requests | send.ts:216-228 |
fedify/rsa-key-required-for-ld-signature |
Keys | Warning | At least one RSASSA-PKCS1-v1_5 key must be provided to create Linked Data signatures | middleware.ts:1013-1023 |
fedify/ed25519-key-required-for-proof |
Keys | Warning | At least one Ed25519 key must be provided to create Object Integrity Proofs | middleware.ts:1033-1043 |
Priority levels
High priority
These rules catch errors that directly impact ActivityPub spec compliance and security:
- All Actor category rules (actor identity)
- All Keys category rules (cryptographic signatures)
- All Inbox category rules (federation message handling)
Medium priority
These rules ensure proper collection setup:
- All Collection property rules
Low priority
fedify/collection-filtering-not-implemented(performance optimization)
Implementation notes
-
Static analysis limitations: Some rules depend on runtime values and may require heuristic pattern matching in the AST. For example, checking if
actor.idmatchescontext.getActorUri(identifier)requires tracking the return value through the code. -
AST patterns to detect:
- Calls to
setActorDispatcher()and analysis of the dispatcher function body - Correlation between collection dispatcher configuration and actor property assignments
- Key pairs dispatcher configuration and related property assignments
- Calls to
-
Auto-fix potential: Some rules could provide auto-fix suggestions (e.g., inserting missing property assignments).
Would this lint rules list address the concerns raised in this issue?
@2chanhaeng This issue has been assigned for over two weeks without updates. Please provide a status update, or unassign yourself if you're unable to continue working on it.
@2chanhaeng This issue has been assigned for over two weeks without updates. Please provide a status update, or unassign yourself if you're unable to continue working on it.
@2chanhaeng This issue has been assigned for over two weeks without updates. Please provide a status update, or unassign yourself if you're unable to continue working on it.
I'm working on https://github.com/2chanhaeng/fedify/tree/linter and it's almost done.