No description
  • Go 99.7%
  • Dockerfile 0.3%
Find a file
thystra afcedf3272
Some checks are pending
Build / Container (push) Waiting to run
Test / Go 1.23.x (push) Waiting to run
Test / Go 1.25.x (push) Waiting to run
Merge pull request #2 from thystra/feature/deterministic-health-projection
Add deterministic relay health projection
2026-08-06 08:25:31 -04:00
.github Add RFC 9530 content digest contract 2026-08-04 14:09:45 -04:00
cmd/activity-relay-directory Add local operator moderation commands 2026-08-05 19:41:11 -04:00
contrib Add bounded request admission 2026-08-04 21:57:49 -04:00
docs Add deterministic relay health projection 2026-08-06 07:33:10 -04:00
internal Add deterministic relay health projection 2026-08-06 07:33:10 -04:00
testdata Complete cross-repository client contract 2026-08-05 08:29:14 -04:00
.dockerignore Initialize Activity-Relay Directory scaffold 2026-08-04 13:02:43 -04:00
.env.example Complete cross-repository client contract 2026-08-05 08:29:14 -04:00
.gitignore Wire SQLite into runtime readiness 2026-08-04 20:18:17 -04:00
AGENTS.md Add deterministic relay health projection 2026-08-06 07:33:10 -04:00
ARCHITECTURE.md Add deterministic relay health projection 2026-08-06 07:33:10 -04:00
CHANGELOG.md Add deterministic relay health projection 2026-08-06 07:33:10 -04:00
compose.yml Complete cross-repository client contract 2026-08-05 08:29:14 -04:00
Dockerfile Wire SQLite into runtime readiness 2026-08-04 20:18:17 -04:00
go.mod Add transactional SQLite schema foundation 2026-08-04 19:12:33 -04:00
go.sum Add transactional SQLite schema foundation 2026-08-04 19:12:33 -04:00
LICENCE Initialize Activity-Relay Directory scaffold 2026-08-04 13:02:43 -04:00
README.md Add deterministic relay health projection 2026-08-06 07:33:10 -04:00
SECURITY.md Initialize Activity-Relay Directory scaffold 2026-08-04 13:02:43 -04:00
TODO.md Add deterministic relay health projection 2026-08-06 07:33:10 -04:00

Activity-Relay Directory

Activity-Relay Directory is an independent directory and health service for discovering public Activity-Relay instances.

Current state

This repository currently provides a conservative service scaffold only:

  • GET /healthz
  • GET /readyz
  • GET /v1/status
  • strict configuration validation
  • lifecycle routes disabled by default and enrollment independently closed by default
  • signed register, heartbeat, and unregister APIs, disabled together by default
  • no public listing, network moderation, or pruning API; the health projection remains an internal read model
  • version 1 protocol vocabulary and JSON compatibility fixtures
  • network-free canonical relay identity and URL validation
  • network-free RFC 9530 SHA-256 Content-Digest generation and verification
  • stateless RFC 9421 directory-request verification contracts and fixture
  • atomic opaque-key replay-store contract and concurrency-tested reference
  • strict authenticated registration requests with audited handler persistence
  • strict authenticated heartbeat requests with server-owned liveness storage
  • deterministic bounded health projection with fixed 36-hour, 7-day, and 30-day version 1 boundaries
  • strict authenticated unregister-request contract without state deletion
  • startup SQLite migration and database-backed readiness checks
  • atomic register, heartbeat, and unregister state transitions behind handlers
  • atomic administrative suspend and restore transitions with private bounded audit records and a local operating-system-authorized command surface
  • durable opaque replay reservations with bounded expiry cleanup
  • bounded SSRF-resistant ActivityPub actor and signing-key resolution with a success-only key cache
  • bounded two-stage source, authenticated-actor, and concurrency admission
  • fail-closed handler composition with durable replay and audited SQLite state
  • local audited admin enrollment status|open|close policy commands
  • local admin suspend|restore|show|audit moderation commands with bounded private audit pagination
  • a byte-compatible request fixture generated by the dormant Activity-Relay client

The directory protocol is being introduced in reviewed contract-first tranches. The lifecycle routes remain fail-closed unless DIRECTORY_LIFECYCLE_ENABLED=true and the complete dependency graph starts successfully. With the default false value, no request can trigger actor retrieval, replay reservation, or lifecycle mutation. Activity-Relay itself also has no enabled directory URL by default. The retired pre-release DIRECTORY_REGISTRATION_ENABLED name is rejected so it cannot be confused with the independent enrollment policy.

When explicitly enabled, the server composes bounded body parsing, direct-peer source derivation, two-stage admission, safe actor/key resolution and caching, RFC 9530 and RFC 9421 verification, durable nonce reservation, suspension checks, and audited SQLite transitions. See docs/HANDLERS.md, docs/PERSISTENCE.md, docs/MODERATION.md, docs/RESOLUTION.md, and docs/ADMISSION.md. Public listings, network moderation transport, health classification, pruning, and release/deployment integration remain later work. Their dependency order, review tranches, and completion gates are tracked in TODO.md.

Enrollment starts closed in durable state. A local operator may inspect or change it without enabling a remote administrative endpoint:

activity-relay-directory admin enrollment status
activity-relay-directory admin enrollment open --operator operator-id
activity-relay-directory admin enrollment close --operator operator-id

Closing enrollment rejects only actors with no retained relay row. It does not modify accepted relays; retained relays may continue lifecycle operations, subject to moderation and the normal authenticated request gates.

Local moderation is authorized only by operating-system access to the executable and owner-only SQLite database. State-changing commands require typing the exact canonical actor, or an explicit --yes acknowledgement for reviewed automation:

activity-relay-directory admin suspend \
  --actor https://relay.example/actor \
  --moderator operator-id \
  --reason security_review

activity-relay-directory admin restore \
  --actor https://relay.example/actor \
  --moderator operator-id \
  --reason review_complete \
  --yes

activity-relay-directory admin show \
  --actor https://relay.example/actor \
  --format json

activity-relay-directory admin audit \
  --actor https://relay.example/actor \
  --limit 50 \
  --after 1730000000:42 \
  --format json

Audit output contains private moderator and reason tokens. Protect command output as carefully as the database. The CLI does not create a preemptive blocklist and does not add a remote administrative endpoint.

Privacy boundary

The directory is intended to learn about relay instances, not the identities or membership of sites connected to those relays. Registration payloads must not include connected-site identities, relay followers, or user information.

Development

mkdir -p data
chmod 0700 data
export DIRECTORY_PUBLIC_BASE_URL=http://127.0.0.1:8080
export DIRECTORY_DATABASE_PATH="$PWD/data/directory.sqlite"
go test -count=1 ./...
go run ./cmd/activity-relay-directory

Container development:

cp .env.example .env
docker compose up --build

Optional, host-neutral Nginx, Apache, and Caddy examples are under contrib/. They are not installed or enabled automatically. See docs/REVERSE-PROXY.md before adapting one for a public deployment.

Licence

GNU Affero General Public License version 3. See LICENCE.

Maintenance transparency

Development may use AI-assisted tooling for drafting, analysis, testing, and review support. A human maintainer reviews and approves changes, runs release gates, controls deployments, and remains accountable for the project.