• v3.0.1 9f07a2eab7

    v3.0.1
    All checks were successful
    Debian Package / Debian package validation (push) Successful in 1m33s
    Container / Container and Caddy validation (push) Successful in 1m58s
    Test / Go, Redis, and Python validation (push) Successful in 2m23s
    Stable

    alan released this 2026-09-30 19:16:22 +00:00 | 15 commits to master since this release

    Signed by alan
    SSH key fingerprint: SHA256:yvtkLe2vkdG0Y1CCxra56JR6gjOJFURf52LUTVpWqPw

    Activity-Relay v3.0.1

    • Application version: 3.0.1
    • Debian package version: 3.0.1-1
    • Release type: Patch reliability release
    • Stable outbound-signature default: dual

    Overview

    Activity-Relay 3.0.1 is a focused reliability release that hardens follower-state handling and relay fan-out.

    The release addresses a production failure mode in which an incomplete follower record could be recreated in Redis during a stale mutual-follow status update. That malformed record could contain no valid inbox URL and subsequently cause delivery planning to abort fan-out for otherwise healthy receivers.

    3.0.1 prevents that state from being created, excludes malformed follower records from live relay state, and isolates invalid delivery destinations so one bad receiver cannot block healthy fan-out.

    No configuration migration is required.

    Fixed

    Follower-state validation

    Follower registrations are now validated as complete state transitions before they are persisted.

    A valid follower record must include:

    • a valid follower domain;
    • a valid HTTP(S) actor ID;
    • a valid HTTP(S) inbox URL;
    • the originating Follow activity ID; and
    • a valid mutual-follow state.

    Incomplete follower records are not admitted into the relay's active receiving set.

    Existing one-way followers with:

    mutually_follow = 0
    

    remain valid and are unaffected.

    Race-safe mutual-follow updates

    Mutual-follow status changes now update follower state atomically.

    A delayed or stale Accept/Reject response can no longer recreate a follower hash after that follower has already been removed.

    If a mutual-follow update encounters an incomplete persisted follower record, the invalid record is removed rather than extended into a partial hash.

    This closes the race that could previously produce records containing only:

    mutually_follow
    

    with no actor, inbox, or originating activity.

    Fan-out isolation

    Relay fan-out no longer fails globally because one destination is malformed or cannot be prepared for delivery.

    Delivery planning now:

    • validates each target independently;
    • skips invalid or unplannable destinations;
    • continues queuing healthy receivers;
    • reserves queue capacity only for deliveries that were actually planned; and
    • records remaining-delivery counts based on the successfully planned target set.

    A failed or malformed destination therefore cannot prevent delivery to otherwise healthy receiving instances.

    Follow acceptance ordering

    Follower acceptance now commits valid follower state before sending the remote ActivityPub Accept.

    If the follower cannot be stored as valid state, the relay does not acknowledge that registration as successful.

    Manual follow approval follows the same rule and preserves pending state when the transition cannot be completed.

    Build and CI maintenance

    Forgejo container validation was updated for Debian Trixie's split Docker packages.

    CI now installs the Docker client and Buildx components explicitly where required, while the canonical release workflow uses the client-only package with its isolated remote Docker engine.

    These changes affect build and release infrastructure only and do not change the Activity-Relay runtime container.

    Compatibility

    Activity-Relay 3.0.1 does not change:

    • the relay actor ID;
    • the #main-key identity;
    • ActivityPub endpoint URLs;
    • the configuration schema;
    • normal subscriber or publisher record formats;
    • the Redis instance or database layout;
    • queued task compatibility;
    • the Activity-Relay Directory protocol; or
    • the default dual outbound-signature policy introduced in 3.0.0.

    Existing 3.0.0 installations can upgrade directly to 3.0.1.

    As with any upgrade, operators should retain backups of the relay actor key, configuration, and Redis persistence.

    Production validation

    The 3.0.1 candidate was installed over 3.0.0 on the production relay.argentwolf.org deployment.

    Post-upgrade validation confirmed:

    • package version 3.0.1-1;
    • relay --version reports 3.0.1;
    • Redis, API server, and worker services restarted successfully;
    • /actor remained unchanged and valid;
    • /nodeinfo/2.1 reported Activity-Relay 3.0.1;
    • /status.json remained healthy with schema version 5;
    • persisted follower records contained the required actor, inbox, and activity fields;
    • a fresh public WordPress ActivityPub post was accepted for fan-out;
    • healthy Friendica and Mastodon receivers successfully received that activity; and
    • a separate receiver returning HTTP 503 continued through its own retry path without preventing successful delivery to the healthy receivers.

    This directly validates the primary 3.0.1 regression fix: failure of one destination no longer aborts otherwise healthy fan-out.

    Upgrade

    Debian / Ubuntu

    Install the 3.0.1 package over the existing installation:

    sudo dpkg -i activity-relay_3.0.1-1_amd64.deb
    

    The package preserves existing configuration, actor identity, Redis data, and operator-managed website content.

    Container

    After publication, update the configured image to:

    ghcr.io/thystra/activity-relay:3.0.1
    

    and recreate the relay containers using the normal deployment procedure.

    Release candidates and canonical validation artifacts should continue to use their complete immutable version tags.

    Release artifacts

    The canonical Forgejo release workflow produces the accepted release artifact set from the exact reviewed release commit, including:

    • Ubuntu amd64 Debian package;
    • CycloneDX SBOM;
    • multi-architecture linux/amd64 + linux/arm64 OCI archive;
    • BUILD-METADATA.txt;
    • RELEASE-NOTES.md; and
    • SHA256SUMS.

    The canonical accepted bytes are the release bytes. Publishing the Forgejo release, registry images, and downstream GitHub mirror must not rebuild or replace the already-validated artifacts.

    Summary

    Activity-Relay 3.0.1 is recommended for all 3.0.0 operators.

    The release specifically improves resilience around follower lifecycle races and malformed receiver state while preserving the existing ActivityPub identity, configuration, storage, and delivery semantics of the 3.0 stable line.

    Downloads
  • v3.0.0 73a93ac8dc

    Activity-Relay 3.0.0
    All checks were successful
    Container / Container and Caddy validation (push) Successful in 35s
    Debian Package / Debian package validation (push) Successful in 1m10s
    Test / Go, Redis, and Python validation (push) Successful in 4m0s
    Stable

    alan released this 2026-09-03 15:10:29 +00:00 | 21 commits to master since this release

    Signed by alan
    SSH key fingerprint: SHA256:yvtkLe2vkdG0Y1CCxra56JR6gjOJFURf52LUTVpWqPw

    Activity-Relay v3.0.0

    • Application version: 3.0.0
    • Debian package version: 3.0.0-1
    • Accepted release-candidate baseline: 3.0.0-rc2
    • Stable outbound-signature default: dual

    Stable scope

    Activity-Relay 3.0 promotes the accepted 3.0 release-candidate line to stable
    after mixed-profile interoperability, two-relay isolation, and Activity-Relay
    Directory lifecycle acceptance. The stable preparation selects
    destination-aware dual as the omitted/default outbound HTTP-signature policy.
    Explicit legacy and rfc9421 modes remain supported for fixed-profile
    operation and troubleshooting.

    The 3.0 line adds RFC 9421 HTTP Message Signatures and RFC 9530
    Content-Digest alongside the established Fediverse Signature profile,
    bounded destination-aware negotiation, stable per-delivery retry profile
    selection, strict inbound modern-signature validation, and the opt-in
    Activity-Relay Directory version 1 client and scheduler.

    Compatibility and upgrade

    The stable promotion does not rotate or replace the relay actor, #main-key,
    public endpoints, Redis instance, subscriptions, publishers, receiver-health
    history, or operator-owned website content. Existing queued task formats remain
    readable. Back up the actor key, Redis persistence, configuration, and
    operator-owned web content before upgrading according to the normal deployment
    procedure.

    Native deployments use:

    activity-relay_3.0.0-1_amd64.deb
    

    Container deployments use the stable 3.0.0 image/tag after registry
    publication. Release acceptance is based on the canonical multi-architecture OCI
    archive built by Forgejo; do not rebuild a second release image from the tag.

    HTTP-signature behavior

    When OUTBOUND_SIGNATURE_PROFILE is omitted, 3.0 uses dual. Negotiation keeps
    fetch and delivery evidence separate, permits only the bounded GET compatibility
    fallback defined by the implementation, and does not resend a delivery POST
    under a different signature grammar. Operators that require a fixed profile may
    set legacy or rfc9421 explicitly.

    The stock NodeBB 4.15.1 forced-RFC-9421 Announce rejection tracked in upstream
    NodeBB issue #14732 remains classified as receiver-specific interoperability
    unless new wire evidence identifies an Activity-Relay defect. The accepted
    mixed-profile path does not require Activity-Relay to block stable release on
    that receiver behavior.

    Activity-Relay Directory

    The Directory client remains opt-in. Stable acceptance against
    directory.argentwolf.org included:

    • schema-3 Directory status consumption while retaining schema-2 compatibility;
    • simultaneous healthy public projection of two independent relays;
    • natural scheduler-driven heartbeat refresh from both relays;
    • authenticated unregister with durable local suppression;
    • verified Directory absence while the test relay remained disabled; and
    • re-enable plus scheduler-driven registration returning the test relay to a
      healthy public projection.

    For Compose deployments that use the stock single-file config.yml bind, an
    atomic host-file replacement changes the host inode while an existing container
    can remain attached to the old inode. Follow docs/DIRECTORY-CLIENT.md: persist
    the desired enabled state on the host, recreate the API/server before trusting
    scheduler state, keep the public actor/key endpoint online during unregister,
    and recreate workers afterward so every long-running container observes the
    current bind. File-backed unregister also requires writable access to the host
    configuration directory so the CLI can create its sibling temporary/backup
    files and perform atomic replacement.

    Accepted interoperability

    The 3.0 stable decision is based on mixed-profile testing with Mastodon,
    Friendica, WordPress, NodeBB, and the independent two-relay topology. The
    release retains the no-reflection invariant and destination-aware signature
    selection while preserving explicit legacy compatibility.

    Release artifacts and authority

    Forgejo is the source and release authority. The manual canonical release
    workflow requires an exact reviewed commit, exact version, and explicit build
    confirmation. It emits one checksummed release bundle containing:

    • the Ubuntu amd64 Debian package;
    • CycloneDX SBOM;
    • linux/amd64 + linux/arm64 OCI archive;
    • BUILD-METADATA.txt;
    • RELEASE-NOTES.md; and
    • SHA256SUMS.

    The accepted canonical bytes are the release bytes. Tagging, release
    publication, registry publication, downstream mirroring, and deployment are
    separate operator-controlled gates; none authorizes rebuilding the accepted
    Debian package or OCI archive.

    Downloads
  • v3.0.0-rc2 dd869fbba5

    v3.0.0-rc2
    All checks were successful
    Container / Container and Caddy validation (push) Successful in 14s
    Debian Package / Debian package validation (push) Successful in 5m46s
    Test / Go, Redis, and Python validation (push) Successful in 2m2s
    Pre-release

    alan released this 2026-09-01 21:32:02 +00:00 | 26 commits to master since this release

    Activity-Relay v3.0.0-rc2

    • Application version: 3.0.0-rc2
    • Debian package version: 3.0.0~rc2-1

    Important

    This is the second Activity-Relay 3.0 release candidate. It carries one
    Directory status-compatibility correction discovered during RC1 integration
    acceptance. The omitted/default outbound signature profile remains legacy
    until the remaining mixed-profile interoperability gate is complete.

    Summary

    RC2 retains the complete Activity-Relay 3.0 RC1 feature set and changes the
    Directory public-status client so it interoperates with the RC-level Directory
    status schema actually deployed during acceptance.

    RC1 lifecycle registration, scheduler persistence, NodeBB 4.15.1
    authorized-fetch interoperability, relay identity, Redis state, and ordinary
    ActivityPub delivery all passed the exercised paths. RC1 exposed one
    non-lifecycle compatibility defect: relay directory status <origin> rejected
    the Directory RC4 public status document because the client accepted only status
    schema version 2 while Directory RC4 serves schema version 3.

    Directory status schema compatibility

    RC2 accepts Directory public status schema versions 2 and 3.

    Schema version 3 adds the public-listing state fields:

    • public_listing_enabled; and
    • public_listing_available.

    The client exposes those fields in its validated status model while continuing
    to use strict JSON decoding. This is an explicit schema addition rather than a
    relaxation of unknown-field or malformed-response handling.

    This correction affects only the Directory public GET /v1/status inspection
    path. The signed version 1 register, heartbeat, unregister, and synchronization
    lifecycle contract is unchanged.

    RC1 acceptance evidence carried forward

    The canonical RC1 container was deployed to the controlled test relay while
    preserving its actor key, Redis state, subscriptions, and delivery-health
    history.

    A fresh NodeBB 4.15.1 authorized-fetch regression test used the stock upstream
    NodeBB release and the canonical Activity-Relay RC1 image with
    OUTBOUND_SIGNATURE_PROFILE: dual. A new public Mastodon post traversed the
    relay, NodeBB completed the canonical-object fetch and displayed the post, the
    relay recorded another successful NodeBB delivery without another failure, and
    the corresponding logs contained no new 401, 403, or 424 failure. This verifies
    the upstream application-actor signing correction for that path.

    The same RC1 relay registered successfully with Activity-Relay Directory RC4.
    The Directory public projection listed it as healthy, and the relay's local
    scheduler state remained registered after API restart. Those results
    demonstrate that the RC1/RC4 signed lifecycle protocol itself was interoperable;
    the schema mismatch was isolated to the remote public-status inspection command.

    Compatibility and defaults

    RC2 does not rotate actor.pem, change the relay actor ID, change the
    #main-key key ID, require a Redis migration, or invalidate existing
    subscription, publisher, receiver-health, capability, or scheduler state.

    Existing configurations that omit OUTBOUND_SIGNATURE_PROFILE continue to use
    legacy. Existing configurations that omit
    PUBLIC_ADDRESS_DISTRIBUTION_POLICY continue to use public_and_unlisted.
    Directory configuration remains empty and its scheduler remains false by
    default.

    The full 3.0 feature and upgrade description remains in
    v3.0.0-rc1.

    RC2 build and tag gates

    Before creating tag v3.0.0-rc2:

    1. run the normal Forgejo source, race, Python, package, Caddy, and container
      validation on the exact RC2 preparation commit;
    2. run Canonical Release Candidate Artifacts with the exact full commit,
      version 3.0.0-rc2, and confirmation BUILD 3.0.0-rc2;
    3. inspect the retained Debian, CycloneDX SBOM, multi-architecture OCI,
      checksum, Lintian, build-metadata, and OCI-index evidence; and
    4. prove that the accepted artifact bytes can be published without rebuilding
      them.

    After tagging and publishing the accepted RC2 bytes:

    1. deploy the exact RC2 candidate to the controlled test relay;
    2. verify relay directory status <origin> succeeds against Directory RC4 and
      reports its schema-3 lifecycle, enrollment, and public-listing state;
    3. continue heartbeat aging and exercise unregister/re-register behavior;
    4. complete the remaining Mastodon, Friendica, WordPress, production-relay, and
      two-relay interoperability matrix; and
    5. select and document the stable 3.0 outbound-signature default only from that
      retained evidence.

    A new runtime/default-policy defect found during these checks requires another
    release candidate rather than stable promotion.

    Repository and release authority

    Forgejo at forgejo.argentwolf.org/alan/activity-relay remains the repository,
    CI, and release authority. GitHub remains a downstream public mirror and
    independent validation surface.

    The RC2 tag must not be created until the canonical Forgejo artifact gate has
    passed and the exact accepted artifact bytes have been identified. Passing the
    candidate build is not itself publication or deployment.

    Downloads
  • v3.0.0-rc1 d5f7ddc770

    Activity-Relay 3.0.0-rc1
    All checks were successful
    Container / Container and Caddy validation (push) Successful in 47s
    Debian Package / Debian package validation (push) Successful in 2m27s
    Test / Go, Redis, and Python validation (push) Successful in 2m9s
    Pre-release

    alan released this 2026-09-01 18:01:36 +00:00 | 28 commits to master since this release

    Activity-Relay v3.0.0-rc1

    • Application version: 3.0.0-rc1
    • Debian package version: 3.0.0~rc1-1

    Important

    This is the first Activity-Relay 3.0 release candidate. It is intended for
    controlled interoperability and Directory integration testing, not stable
    production promotion. The omitted/default outbound signature profile remains
    legacy until the mixed-profile interoperability gate is complete.

    Summary

    Activity-Relay 3.0 modernizes HTTP message authentication, adds explicit
    destination-aware signature negotiation, introduces a configurable public
    address-distribution policy, and adds the opt-in Activity-Relay Directory v1
    client and lifecycle scheduler.

    The release candidate preserves the existing relay actor ID, #main-key
    identity, Redis deployment model, existing subscription state, and the legacy
    outbound-signature default. Automatic Directory lifecycle behavior is disabled
    unless both a Directory entry and the lifecycle scheduler are explicitly
    enabled; manual lifecycle commands remain explicit operator actions.

    HTTP message signatures

    3.0 RC1 adds RFC 9421 HTTP Message Signatures and RFC 9530 Content-Digest
    alongside the established Fediverse Signature/Digest profile.

    Inbound requests with Signature-Input are verified through the modern
    profile with bounded time validation, actor/key binding, digest verification,
    Redis-backed nonce replay protection, and bounded metrics. Requests without
    Signature-Input continue through the legacy verifier; malformed modern
    requests do not fall back to legacy verification.

    OUTBOUND_SIGNATURE_PROFILE accepts:

    • legacy for the established wire profile;
    • rfc9421 for fixed modern signing; and
    • dual for destination-aware selection.

    dual keeps fetch and delivery evidence separate. Unknown authenticated GETs
    start with RFC 9421 and may make one bounded legacy fallback only after
    recognized compatibility evidence. Delivery POSTs never fall back or get
    re-sent under another signature grammar. New queued deliveries persist the
    selected concrete wire profile across delayed retries, while old two-argument
    tasks remain readable.

    The RC1 default remains legacy. Selecting the stable 3.0 default is explicitly
    deferred until the mixed Mastodon, Friendica, NodeBB, WordPress, and two-relay
    interoperability matrix is complete.

    Public address distribution

    PUBLIC_ADDRESS_DISTRIBUTION_POLICY accepts:

    • explicit_public_only; or
    • public_and_unlisted.

    Fresh example configurations select explicit_public_only, where ActivityStreams
    Public must appear in the primary to audience for public fan-out. Public only
    in cc remains acknowledged and publisher-accounted without relay fan-out.

    For upgrade compatibility, an omitted value retains the pre-3.0
    public_and_unlisted behavior. Operators upgrading an existing deployment
    should set the desired value explicitly.

    /status.json schema version 5 exposes the effective policy and human-readable
    label, and the generated website presents the effective policy.

    Activity-Relay Directory client

    The opt-in Directory v1 client supports up to eight independently enabled
    canonical HTTPS Directory origins and provides:

    • relay directory status;
    • relay directory register;
    • relay directory heartbeat;
    • relay directory unregister; and
    • relay directory sync.

    Lifecycle requests use the Directory-specific RFC 9421/RFC 9530 profile with
    strict bounded responses and redirect refusal.

    The API-process scheduler is disabled by default. When explicitly enabled it
    reconciles startup state, schedules stable-jittered heartbeats, persists closed
    state, applies bounded retry including validated Retry-After, and coordinates
    with manual unregister through renewable Redis leases and fencing tokens.
    Workers do not schedule Directory traffic.

    File-backed unregister durably disables the selected entry before network
    traffic, preserves unrelated YAML and file metadata, and retains a recoverable
    backup.

    Compatibility and upgrade notes

    The RC1 preparation does not rotate actor.pem, change the relay actor ID,
    change the #main-key key ID, require a Redis data migration, or invalidate
    existing subscription state.

    Existing configurations that omit OUTBOUND_SIGNATURE_PROFILE continue to use
    legacy. Existing configurations that omit PUBLIC_ADDRESS_DISTRIBUTION_POLICY
    continue to use public_and_unlisted. Directory configuration remains empty
    and its scheduler remains false by default.

    The new delivery task carries a concrete signature-profile argument, but workers
    remain compatible with previously queued two-argument tasks.

    NodeBB 4.15.1 retest gate

    Activity-Relay 2.5 validation found that NodeBB 4.14.x could accept a signed
    relay delivery and then fail with HTTP 424 because its application-context
    canonical-object fetch was unsigned when the remote object required authorized
    fetch.

    NodeBB upstream changed that path in commit
    8e61543b0ae19fd741bd4175d478aab6c79982ca, restoring key loading and signing
    for application actor ID 0. RC1 acceptance requires a fresh NodeBB 4.15.1
    retest.

    If the retest still fails, retain NodeBB's outgoing Date, Signature, and
    keyId so the remaining failure can be classified as key
    discovery/interoperability rather than missing request signing.

    RC1 validation and promotion gates

    Before creating tag v3.0.0-rc1:

    1. run the normal Forgejo source, race, Python, package, Caddy, and container
      validation on the exact preparation commit;
    2. run Canonical Release Candidate Artifacts with the exact full commit,
      version 3.0.0-rc1, and confirmation BUILD 3.0.0-rc1;
    3. inspect the retained Debian, CycloneDX SBOM, multi-architecture OCI,
      checksum, Lintian, build-metadata, and OCI-index evidence; and
    4. prove that accepted artifact bytes can be published without rebuilding them.

    After tagging and publishing the accepted RC1 bytes:

    1. deploy the accepted RC1 application code first to relay2.argentwolf.org;
    2. retest NodeBB 4.15.1 and the mixed Mastodon, Friendica, NodeBB, and WordPress
      paths;
    3. upgrade relay.argentwolf.org to the accepted 3.0 RC code; and
    4. exercise both relays against directory.argentwolf.org, including
      registration, heartbeat, scheduler restart, unregister/re-register, public
      projection, and the existing two-relay no-reflection invariant.

    These deployment and interoperability checks are gates for stable v3.0.0
    promotion, not for creating the RC1 tag itself. A runtime/default-policy change
    discovered during this testing requires another release candidate rather than
    stable promotion.

    Repository and release authority

    Forgejo at forgejo.argentwolf.org/alan/activity-relay is the repository, CI,
    and release authority. GitHub remains the downstream public mirror and
    independent validation surface.

    The RC tag must not be created until the canonical Forgejo artifact gate has
    passed and the exact accepted artifact bytes have been identified. Passing the
    candidate build is not itself publication or deployment.

    Downloads