These instructions apply to the entire Activity-Relay repository.
Activity-Relay is a maintained public fork of yukimochi/Activity-Relay.
Changes should remain useful to operators outside the maintainer's own
infrastructure. Do not add private hostnames, personal paths, credentials,
deployment transcripts, or machine-specific instructions to the repository.
Keep maintainer-local notes and deployment helpers outside the checkout or in
an ignored AGENTS.local.md or .local/ directory. Private continuity guides
may supplement this file, but they must not be copied into the public
repository.
https://forgejo.argentwolf.org/alan/activity-relayis the authoritative development and release repository.https://github.com/thystra/Activity-Relayis a downstream public mirror and independent-validation surface. Do not develop against or tag the GitHub mirror as though it were authoritative.- Normal maintainer pushes and release tags go to the Forgejo
origin; mirror propagation to GitHub is a separate state that must be verified when it matters. - GitHub workflows must remain validation-only. They must not publish release artifacts or mutable container tags from mirrored commits or tags.
- Canonical release artifacts must be built and promoted by the authoritative Forgejo release path. If that path is unavailable, release publication is blocked rather than delegated back to GitHub.
- Repository authority does not change the public Go module path,
github.com/thystra/Activity-Relay.
Before a substantial change, review:
- this file;
ARCHITECTURE.md;TODO.md;readme.md;CHANGELOG.md;docs/RELEASING.mdfor release work;docs/UPSTREAM.mdfor upstream ports; and- the current branch, working-tree state, remotes, and recent commits.
- Verify the repository, branch, remote, and expected baseline commit before changing files.
- Require a clean working tree unless the task explicitly preserves known local changes. Never overwrite unknown work.
- Build and validate the prospective result in a temporary tree before changing the checkout whenever practical.
- Prefer complete-file installation or a reviewed unified patch. Use structural transformations when semantic scope matters; use plain-text replacement only for small files with unique, controlled anchors.
- Keep backups outside the Git worktree. After backup creation, use an
EXITtransaction guard that restores replaced and removed files and deletes newly created files unless a success flag is set. - Version applicators as
apply-<project>-<change>-r<number>.sh. Do not silently replace a script that may already have been downloaded or used. - Applicators must be idempotent or refuse an already-applied state clearly.
- Use
git ls-fileswhen validating tracked-source manifests. Report ignored build output separately. - Put strict shell modes inside scripts or explicit subshells. Do not enable
set -e,set -u, orpipefaildirectly in an interactive operator shell.
Distinguish proposed design, generated patch, applied local changes, passing local tests, commit, push, tag, built artifact, deployment, and production validation. Do not claim a later state because an earlier state succeeded.
Before committing changes:
- Run
gofmton modified Go files. - Run
go vet ./.... - Run Redis-backed tests with a disposable Redis instance:
REDIS_URL=redis://127.0.0.1:6381 go test -count=1 -p 1 ./... - Run the full serialized race suite:
REDIS_URL=redis://127.0.0.1:6381 go test -race -count=1 -p 1 ./...Activity-Relay package tests share Redis and some packages clear the selected database, so package-level test processes must remain serialized unless each package receives an isolated Redis database. - Run the static-site tests:
python3 -m unittest discover -s contrib/web -p 'test_*.py' - Run the operations tests:
python3 -m unittest discover -s contrib/ops -p 'test_*.py' - Run
git diff --check. - Validate changed shell scripts with
sh -norbash -n, as appropriate. - When changing the Caddy example, validate it with Caddy 2, for example:
docker run --rm -v "$PWD/contrib/caddy/Caddyfile.example:/etc/caddy/Caddyfile:ro" caddy:2.11.2-alpine caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile - When changing the container, build it and verify both
/usr/bin/relayand/usr/share/activity-relay/web/build-site.py. - When changing Debian packaging, build the binary package, inspect its
contents and metadata, and run Lintian on the generated
.changesfile.
Never run tests against production Redis.
- Preserve the relay actor identity and never overwrite an existing actor key.
- Preserve operator-owned configuration and website content during upgrades.
- Debian packages must not enable or start services automatically.
- Keep existing ActivityPub endpoints and stored Redis data compatible unless a documented major release intentionally changes them.
- Directory integration remains disabled by default. The optional scheduler
may run only in the API process, must coordinate replicas and unregister with
the same per-directory lease, and must recheck durable file-backed enablement
after acquiring it. Every scheduler state mutation must be fenced by the
current lease token. Runtime gate disablement and entry removal are durable
suppression, not scheduler failures. File-backed unregister must coordinate
through Redis whenever
REDIS_URLremains present, fail closed on malformed state, and durably disable and suppress the entry before remote traffic. Workers must never schedule directory traffic. Directory signatures use their own expiring nonce-bearing application profile and shared fixture; they must not change the ActivityPub signing profile. Protocol v1 remains the compatibility fallback. Protocol v2 is selected only from a valid schema-4 status capability, uses its own signature tag, carries the complete normalized descriptive profile only on register, permits bounded self-reported receiving-site telemetry on register/heartbeat, and keeps unregister identity-only. Scheduler state may retain only the profile digest/protocol version, never profile contents. - Open publisher ingestion must retain HTTP-signature, actor-host, blocked domain, limited-domain, and person-only policy enforcement.
- The bundled public website is optional. Relay operation must not depend on serving or generating it.
- Reverse-proxy examples are optional operator references, not runtime dependencies or package-enabled services.
- The Go module path is
github.com/thystra/Activity-Relay.
-
ARCHITECTURE.mddescribes components, data ownership, federation flows, security invariants, and failure behavior. -
TODO.mdtracks current milestones, deferred work, release gates, and dated status notes. -
CHANGELOG.mdrecords user-visible changes by release; it is not the sole development plan. -
Versioned release notes under
docs/releases/describe the artifact actually published for that tag. -
docs/INTEGRATION-TESTING.mddefines host-neutral container and native-package release gates; private transcripts and host details remain outside the repo. -
docs/SECURITY.mdrecords the current signature architecture, compatibility policy, and future hardening considerations. -
docs/FEP-AE0C-COMPATIBILITY.mdrecords the two retrospective relay families, Activity-Relay extensions, unresolved behavior questions, and the characterization fixtures that must remain synchronized with protocol changes. -
Update
readme.mdand affected deployment documentation whenever behavior, packaging, configuration, or release procedures change.
- Stable tags use
vX.Y.Z; release-candidate tags usevX.Y.Z-rcN. - A stable promotion after an RC must either preserve the exact validated application code or repeat all affected integration and production gates. Documentation and package-metadata-only promotion commits must be identified explicitly.
- Audit every current-version example and release-status statement before tagging; historical changelog and release-candidate records must remain clearly historical.
- Stable Debian versions use
X.Y.Z-1; prerelease versions useX.Y.Z~rcN-<revision>. - Uploaded release filenames must not contain
~; the package's internal Debian version retains it. - Prereleases must not move stable container tags such as
latest, major, or major/minor. - Do not move a published tag. Correct release mistakes with a later release candidate or patch release.
- After publication, verify release checksums, internal package version, architecture, installed example files, canonical Forgejo release metadata, downstream GitHub tag propagation, and container manifests before declaring the release complete.
Follow docs/UPSTREAM.md. Review and port specific upstream commits, issues, or
pull requests rather than wholesale-merging upstream after architectural
divergence. Preserve authorship and record upstream references in the commit or
changelog.
Do not commit generated .deb, .changes, .buildinfo, coverage, cache,
Redis-data, backup, or local deployment files. Keep external backups in a
maintainer-owned backup directory outside the checkout. Public files should use
repository-relative or portable example paths, never a maintainer-specific
absolute path.