Skip to content

Connect suspension receiving to FEP-844e capabilities #1377

Description

@dahlia

Motivation

Once an application actually honors FEP-f799 notices, other software can benefit from discovering that support. Generic FEP-844e vocabulary and discovery are already proposed in #1012. Reimplementing that engine inside suspension receiving would duplicate ownership and couple two independently useful features.

Add the FEP-f799-specific connection after both the receiver and #1012 are available. FEP-f799 capability discovery is optional metadata, not an authorization shortcut or a prerequisite for accepting a valid notice.

Proposed API and use

Use #1012's capability types and merge/discovery behavior. Add the FEP-f799 descriptor factory and an async method taking the owning ctx on the same receiver handle:

const DELIVERY_SUSPENSION_CAPABILITY_HREF: "https://w3id.org/fep/f799";
function createDeliverySuspensionCapability(): Capability;
interface DeliverySuspensionReceiver<TData> {
  getCapabilities(ctx: Context<TData>): Promise<readonly Capability[]>;
}

The factory returns a fresh descriptor. The following proposed actor-dispatcher use calls the merge helper owned by #1012; its final symbol name should follow that issue rather than establish a second general API here.

federation.setActorDispatcher("/users/{identifier}", async (ctx, identifier) => {
  const generator = mergeCapabilities(
    new Application({ name: "My application" }),
    await receiver.getCapabilities(ctx),
  );
  return new Person({
    id: ctx.getActorUri(identifier),
    preferredUsername: identifier,
    generators: [generator],
  });
});

generators is the current vocabulary constructor property. Bind normal keys and other actor properties through the existing dispatchers; sign the completed parent only after generator composition. An application with a genuine external implementation can explicitly merge createDeliverySuspensionCapability() even without Fedify's built-in receiver.

Eligibility and design choices

Automatic contribution comes from the same registered, internally prepared production apply receiver. Observe/off, the development-v1 profile, volatile MemoryKvStore storage, publisher-only operation, static tools, Link parsing and CLI do not imply receiving support. Atomic type membership alone does not establish durable storage; the deployment must meet the receiver's production storage contract.

getCapabilities(ctx) awaits first internal preparation, then uses stable registration/eligibility state rather than probing remote endpoints or changing advertisements on each transient DB health fluctuation. A synchronous context-free getter was rejected because it would require a public initialization step. Keep explicit operational failures distinguishable from an empty claim, and preserve application context types and registration ownership.

Use the expanded https://w3id.org/fep/844e/implements property with its preloaded unordered-set context. Test anonymous/nested Application, single-item arrays and warm-cache recompaction against #1012. Capability href equality is exact identifier comparison, not origin normalization or HTTP Link relation case folding.

Merge local unsigned modeled Application data, preserving existing name/id/fields and capabilities and deduplicating the same href. Do not mutate signed generator/parent objects while retaining invalid proofs. Parsed raw-cache presence does not prove local provenance or unknown-field preservation. Reject unsupported secured inputs rather than recursively stripping proofs. A generator-only helper cannot inspect its parent proof; document the local unsigned-before-parent-sign use contract.

Automatic actor rewriting, another contributor framework, warnings for not advertising, and using advertisement to skip authority checks were rejected. The app controls its generator and FEP advertisement is optional. An automatic contribution being absent must not remove an app's truthful external descriptor.

Shipping criteria and docs

Complete integration with #1012 rather than another capability engine. Test off/observe/apply/development eligibility, repeated build/ctx ownership, first preparation, health stability, external descriptors, merge-before-sign and the context/serialization cases above. Whichever prerequisite ships second completes this child once both are available; do not mark integration complete from vocabulary alone.

Revise docs/manual/delivery-suspension.md, the actor/capability instructions introduced by #1012, public JSDoc and relevant actor/FEP/framework skills. Revise FEDERATION.md only for the actual implemented scope and add the relevant package fragment. General server-level discovery remains with #1012 and its own dependencies.

Metadata

Metadata

Assignees

No one assigned

    Fields

    Priority

    None yet

    Effort

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions