Repository navigation
Description
Motivation
A server undergoing planned maintenance can tell users when it expects to return, but other servers still attempt ActivityPub delivery until they observe failures. Circuit breaking (#620, implemented by #778) responds to failures; it does not express a controller's authenticated, temporary request to stop delivery in advance.
FEP-f799's motivation describes coordinated suspension for an exact inbox or HTTPS origin. Provide publication, authenticated receiving, delivery enforcement and operational tools in independently useful releases. Keep the reusable atomic storage work in a separate umbrella.
Proposed application model
Use existing KV adapters through AtomicKvStore. Register behavior on Federatable with setDeliverySuspension(), setDeliverySuspensionPublisher() and optional setDeliveryBacklog(). The same registration API works with Federation and FederationBuilder; returned management handles select a built runtime through Context<TData>.
The proposed configuration looks like this:
const federation = createFederation<AppData>({ kv, queue });
const receiver = federation.setDeliverySuspension({
mode: "apply",
policy: { profile: "baseline-v1" },
});
const publisher = federation.setDeliverySuspensionPublisher(
"/maintenance/{noticeId}",
{
activityPath: "/maintenance/{noticeId}/activities/{activityId}",
controllers: { sharedInbox: "server" },
},
);
const result = await publisher.create(ctx, {
operationId: "maintenance-create",
target: { kind: "inbox", inbox: "https://social.example/inbox" },
endTime,
announce: true,
notify: { delivery: "background", recipients: peers },
});These are proposed additions. kv is an appropriate persistent AtomicKvStore; the application provides its normal actor, key and inbox routes, a stable request/operation ID, and notification recipients selected by the application. A separate stateless API and CLI cover static publication without a running application or application DB.
Child issues and independence
- Vocabulary and raw shape parsing: Add FEP-f799 vocabulary and raw document parsers #1369.
- Online publisher: Publish and manage delivery-suspension notices #1371.
- Authenticated receiver and delivery gate: Honor authenticated delivery-suspension notices #1372.
- HTTP
Linkdiscovery: Discover delivery suspensions from HTTPLinkheaders #1373. - Standalone static tools: Provide standalone static delivery-suspension tools #1370.
- Profiles and default activation decision: Calibrate suspension profiles and decide default activation #1374.
- Stronger
Undo-before-Createguarantees: Retain admittedUndo-before-Createcancellations #1375. - Optional durable backlog: Add an optional durable outbound delivery backlog #1376.
- FEP-f799 integration with Add support for FEP-844e: Capability discovery #1012: Connect suspension receiving to FEP-844e capabilities #1377.
- Standalone CLI: Add standalone delivery-suspension CLI commands #1378.
The vocabulary, static tools and CLI do not wait for the atomic-storage umbrella. Storage-dependent features need the contract and at least one validated persistent implementation, not every adapter. Publishers need not receive notices. The baseline receiver must recheck and expire held work without the optional backlog or Link discoverer. General FEP-844e support stays in #1012; only its FEP-f799 integration is a child here.
Design constraints and alternatives
Start with receiving off and a complete finite opt-in profile. A separate child evaluates default-on behavior and profile tuning; the first receiver release must already have usable bounded behavior. immediate: true also follows suspension. The explicit ignoreDeliverySuspension option bypasses only notice-based holding, not circuit state, retry constraints or retention.
Configuration should not require a public initialize() call for each receiver, publisher and backlog registration or start I/O while modules load. Store preparation belongs to the first relevant asynchronous operation; worker execution belongs to existing startQueue() ownership or bounded cron methods. Builders retain configuration, not single-use preconstructed components.
Backend-specific suspension stores were considered, but would duplicate adapter setup and support across publisher, receiver and backlog. Use the reusable atomic KV contract instead. Do not replace it with unlocked get/set sequences or one global compare-and-swap (CAS) document. Do not equate signed shape facts with current authority, a file hash with complete signed-state equality, or an acknowledged HTTP POST with peer processing.
A valid cancellation is terminal. Replay facts and admitted pending cancellations must survive disable/re-enable and policy changes. Optional stronger Undo retention cannot use an invented original publication time or silently forget accepted pairs. Durable backlog leases do not establish exactly-once HTTP.
Documentation and completion
Add docs/manual/delivery-suspension.md in the first child that ships a usable runtime or static workflow. Each later child updates it with its supported behavior rather than future placeholders. Revise KV, federation, sending, inbox, actor/WebFinger, task/queue, deployment and circuit-breaker guidance in the child that changes that behavior. Add CLI/backlog guides where those children need them.
Every child includes its own tests, public API documentation, examples using package imports, affected agent skills and package changelog. Revise FEDERATION.md with the precise implemented FEP-f799 scope when protocol behavior ships; vocabulary-only support must not be advertised as full receiver conformance. Track release versions and supported backends here without tying every child to one release.
Related work: #1361.
Metadata
Metadata
Assignees
Labels
Type
Fields
Priority
Effort
Activity
Linkheaders #1373Undo-before-Createcancellations #1375