Skip to content

Calibrate suspension profiles and decide default activation #1374

Description

@dahlia

Motivation

The initial receiver is explicitly enabled with a complete finite baseline. That avoids silently changing existing delivery behavior, but it leaves every adopter to decide whether the recommended limits fit a real deployment. Turning the receiver on by default also affects immediate sends, storage requirements and rollout behavior; it is not just a queue optimization.

Evaluate default activation and profile tuning after the baseline receiver works. This issue must not become a prerequisite for basic bounded retention, rechecking or resume pacing in that first release.

Policy surface and scenarios

Keep policy input separate from a complete resolved policy:

function getDeliverySuspensionProfile(name: DeliverySuspensionProfileName):
  DeliverySuspensionPolicy;
function resolveDeliverySuspensionPolicy(options: DeliverySuspensionPolicyOptions):
  DeliverySuspensionPolicy;

interface DeliverySuspensionPolicyOptions {
  profile: DeliverySuspensionProfileName;
  maxNoticeAge?: Temporal.DurationLike;
  maxFuturePublishedSkew?: Temporal.DurationLike;
  maxControlEvidenceAge?: Temporal.DurationLike;
  maxControlActivityAge?: Temporal.DurationLike;
  maxDeferredRetention?: Temporal.DurationLike;
  recheckInterval?: Temporal.DurationLike;
  minRevalidationInterval?: Temporal.DurationLike;
  resumeConcurrencyPerOrigin?: number;
  minResumeInterval?: Temporal.DurationLike;
  maxResumeJitter?: Temporal.DurationLike;
  // Optional scheduling/count limits retain the receiver's defined semantics.
}

The names describe the proposed receiver API; this issue chooses any justified new profile/version or default change. Preserve pinned profile meanings rather than silently changing their numbers. Configuration tools can inspect resolved policies without I/O:

const policy = resolveDeliverySuspensionPolicy({
  profile: "baseline-v1",
  maxDeferredRetention: { days: 3 },
});
const receiver = federation.setDeliverySuspension({ mode: "observe", policy: {
  profile: policy.profile,
  maxDeferredRetention: policy.maxDeferredRetention,
} });
// Explicit opt-out on another deployment remains:
otherFederation.setDeliverySuspension(false);

The override is illustrative, not a selected universal default. Promote a deployment from observe to apply by explicit configuration/redeployment, not mutable per-process policy setters.

Decision and compatibility work

Use measured replay/fetch traffic, retained-state size, maintenance durations, resume load and outage/restart behavior to justify limits. Preserve the finite notice age, skew, control-evidence age, wrapper replay age and independent queued retention required by the baseline. Reject invalid/calendar/negative durations where a fixed operational duration is required.

Record whether default-on is appropriate, its eligible store/mode behavior, and what happens for an existing store implementing only base KvStore methods. Do not silently treat an unavailable atomic store as no notices. Keep explicit false and development-only behavior clear. A default change that alters existing immediate delivery or storage failures needs a compatibility/release decision, not an assumed non-breaking label.

Define boundaries independently: notice age is rejected when greater than max age, an interval applies strictly before its effective end, unknown published times at or below the replay cutoff are refused, and queued retention ends at or beyond its deadline. Retention starts at the immutable queued/owned start time and is not extended by hold credit.

Tightening can shorten existing stamped deadlines. Loosening applies prospectively and cannot revive an expired authority grant or a deleted replay record. Disable/observe/re-enable and schema rollback preserve facts. Unsupported formats produce bounded state-unavailable behavior rather than a fresh empty store.

Immediate default-on with arbitrary numbers was rejected because it hides these compatibility choices. A mutable policy setter was rejected because workers could disagree about admission/GC. Deferring all numerical policy to applications was also rejected: opt-in users need a usable complete profile from the first receiver release.

Shipping criteria and docs

Ship a recorded decision with the resulting versioned profile/default behavior and operational guidance. Keeping default-off is a valid outcome if the evidence favors it; document the recommendation and reason rather than implying activation was promised. Test off/observe/apply transitions, repeated expansion, equality boundaries, retained pending/replay facts, unavailable storage, supported rollback and health-independent capability behavior.

Revise docs/manual/delivery-suspension.md, relevant kv.md, deploy.md, send.md and monitoring guidance, explicit opt-out examples, framework/migration skills if affected, JSDoc and release notes/fragments. Do not place ordinary Fedify version-upgrade instructions in manual/migrate.md, which is about moving from other libraries. No numerical setting in this draft is a normative FEP-f799 value.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Fields

    Priority

    None yet

    Effort

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions