Skip to content

Support coordinated inbox delivery suspension #1362

Open
0 of 10 issues completed
Open

Description

@dahlia

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

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

No one assigned

    Type

    Fields

    Priority

    None yet

    Effort

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions