Skip to content

F.1: GoToSocial bundle (fediverse microblog pilot)#10

Open
kh0pper wants to merge 1 commit intof0-caddy-federation-helpers-and-hardware-gatefrom
f1-gotosocial-bundle
Open

F.1: GoToSocial bundle (fediverse microblog pilot)#10
kh0pper wants to merge 1 commit intof0-caddy-federation-helpers-and-hardware-gatefrom
f1-gotosocial-bundle

Conversation

@kh0pper
Copy link
Copy Markdown
Owner

@kh0pper kh0pper commented Apr 12, 2026

Summary

First federated app on top of F.0. GoToSocial is the lightweight single-binary ActivityPub server (512 MB min / 1 GB recommended), chosen as the pilot per the Phase 2 plan — proves the full template end-to-end (shared docker network, hardware gate, rate limiter, consent text, queued moderation, media prune) on Pi hardware before the 7 heavier bundles follow.

Stacked on #9 (F.0). Merge F.0 first.

What ships

Bundle (`bundles/gotosocial/`)

  • `manifest.json` — `consent_required: true` with full EN/ES blast-radius text (replication irreversibility, defederation risk, media cache growth). `min_ram_mb=512`, `recommended_ram_mb=1024`. `requires.bundles: ["caddy"]` — F.0's hardware + dep gates refuse install if Caddy is missing or RAM insufficient.
  • `docker-compose.yml` — pinned `superseriousbusiness/gotosocial:0.18.0`; joins external `crow-federation` network; NO host port publish (Caddy reaches `gotosocial:8080` by service name); `mem_limit: 1g`; SQLite default backend for Pi simplicity.
  • `server/server.js` — 14 MCP tools following the plan's verb taxonomy:
    • Content: `gts_status`, `gts_post`, `gts_feed`, `gts_search`, `gts_follow`, `gts_unfollow`
    • User-level moderation (inline + rate-limited): `gts_block_user`, `gts_mute_user`
    • Instance-level moderation (queued — human-in-the-loop): `gts_block_domain`, `gts_defederate`, `gts_import_blocklist`
    • Read-only moderation: `gts_review_reports`, `gts_report_remote`
    • Ops: `gts_media_prune`
    • All wrapped with F.0's shared rate-limiter. Destructive instance-level verbs INSERT pending rows into `moderation_actions` + create a Crow notification; operator confirms from Nest panel before the action fires.
  • `skills/gotosocial.md` — triggers, tool surface, Caddy-expose recipe, moderation workflow, federation etiquette warnings, troubleshooting.
  • `panel/` — status + federation peer count + public/home timeline preview (XSS-safe). Moderation queue confirmation UI deferred to F.11.
  • `scripts/` — `backup.sh` (SQLite online-backup + media tar), `media-prune.sh` (daily cron, retention from env), `post-install.sh` (network verify + next-step output).

Platform wiring

  • `registry/add-ons.json` — entry with full env_vars schema
  • `extensions.js` — three new category colors: `federated-social` (magenta), `federated-media` (pink), `federated-comms` (violet) + CATEGORY_LABELS pointers
  • `i18n.js` — EN/ES for the three new category keys
  • `nav-registry.js` — federated-social/comms → `core` sidebar group, federated-media → `media`
  • `skills/superpowers.md` — EN/ES trigger row for gotosocial
  • `CLAUDE.md` — Skills Reference entry

Design notes

  • Lazy shared-dep imports (pattern borrowed from knowledge-base): the bundle imports `../../../servers/shared/rate-limiter.js` / `/db.js` / `/notifications.js` inside `try/catch`. When installed to `~/.crow/bundles/gotosocial/` those paths don't resolve; the wrapper falls back to a no-op limiter so the tools still function (best-effort). Monorepo mode gets real rate limiting + real moderation queuing.
  • No host port publish. Federated apps are reachable only through Caddy on the shared `crow-federation` network (per F.0 decision). Debug override via `docker compose --profile debug up` — not in use for this bundle.
  • Queued moderation with 72h pending TTL — destructive instance-level verbs never fire inline; operator click in the Nest panel is the real authorization. `confirm: "yes"` arg is AI-advisory only.
  • Media prune is not optional. `scripts/media-prune.sh` runs daily from day 1; retention window comes from `GTS_MEDIA_RETENTION_DAYS` (14 default, 7 on Pi). Operators raise the window but can't disable pruning without editing the schedule directly.

Test plan

  • `node --check` on all changed files
  • MCP server boots via `createGotosocialServer()` with lazy shared-dep fallback
  • `docker compose -f bundles/gotosocial/docker-compose.yml config` parses cleanly
  • `registry/add-ons.json` is valid JSON
  • `npm run check` passes
  • Live (grackle): install GoToSocial → hardware gate accepts (grackle has capacity) → `caddy_add_federation_site` against a throwaway subdomain → container healthy → `caddy_cert_health` OK
  • Live (federation round-trip): create admin account, generate token, `gts_follow @Gargron@mastodon.social`, verify the follow resolves via WebFinger and a test toot reaches that account
  • Live (rate limit): call `gts_post` 11 times in rapid succession — 11th returns `rate_limited` with `retry_after_seconds`
  • Live (queued moderation): call `gts_defederate` for a test domain — expect "queued", no effect on federation; observe pending row in `moderation_actions`
  • Live (Pi refusal): attempt install on colibri with force disabled — confirm hardware gate allows (512 MB min, Pi 4 typically has headroom) OR warns under-recommended

Live verification happens as part of F.1 merge validation on grackle; deferred here until F.0 is merged and the Caddy bundle is reinstalled with the new tools.

First federated app on top of F.0. GoToSocial is the lightweight
single-binary ActivityPub server (512 MB min / 1 GB recommended), chosen
as the pilot per the Phase 2 plan — proves the full template end-to-end
(shared docker network, hardware gate, rate limiter, consent text,
queued moderation, media prune) on Pi hardware before the 7 heavier
bundles follow.

Bundle (bundles/gotosocial/):

- manifest.json  consent_required: true with full EN/ES blast-radius
                 text (replication irreversibility, defederation risk,
                 media cache growth). min_ram_mb=512, recommended=1024.
                 requires.bundles: ["caddy"] — F.0 hardware + dep gates
                 refuse install if Caddy is missing or RAM insufficient
- docker-compose.yml  pinned 0.18.0; joins external crow-federation
                 network; NO host port publish (Caddy reaches
                 gotosocial:8080 by service name); mem_limit 1g; SQLite
                 default backend for Pi simplicity
- server/server.js  14 MCP tools following the plan's verb taxonomy:
                 gts_status / gts_post / gts_feed / gts_search /
                 gts_follow / gts_unfollow / gts_block_user /
                 gts_mute_user / gts_block_domain / gts_defederate /
                 gts_review_reports / gts_report_remote /
                 gts_import_blocklist / gts_media_prune
                 Content + inline moderation wrapped with shared
                 rate-limiter. Destructive instance-level verbs
                 (defederate, block_domain, import_blocklist) QUEUED
                 into moderation_actions with notification; operator
                 confirms from Nest panel before the action fires.
                 Pattern: knowledge-base-style try/catch lazy imports
                 of shared deps so installed-mode bundles don't hard-
                 fail when servers/shared/... isn't resolvable
- skills/gotosocial.md  triggers, tool surface, Caddy-expose recipe,
                 moderation workflow, federation etiquette warnings,
                 troubleshooting
- panel/  status + federation peer count + public/home timeline
                 preview. XSS-safe (textContent + createElement only).
                 Moderation queue confirmation UI deferred to F.11
- scripts/  backup.sh (sqlite online backup + media tar),
                 media-prune.sh (daily cron, retention from env),
                 post-install.sh (network verify + next-step output)

Platform wiring:

- registry/add-ons.json  entry with full env_vars schema + notes
- servers/gateway/dashboard/panels/extensions.js  three new
                 category colors: federated-social (magenta),
                 federated-media (pink), federated-comms (violet).
                 Matching CATEGORY_LABELS pointers
- servers/gateway/dashboard/shared/i18n.js  EN/ES for the three
                 new category keys
- servers/gateway/dashboard/nav-registry.js  federated-social/comms
                 → core sidebar group, federated-media → media
- skills/superpowers.md  EN/ES trigger row for gotosocial
- CLAUDE.md  Skills Reference entry

Verified:

- node --check on all changed files
- docker compose -f bundles/gotosocial/docker-compose.yml config parses
- JSON validation: registry/add-ons.json
- npm run check passes
- MCP server boots in isolation (createGotosocialServer resolves with
  lazy shared-dep fallback; no main-repo dependency leak)

Deferred to F.11 / live verification:

- Moderation queue confirmation UI (Nest panel) — bundle writes pending
  rows; manual DB apply until the queue UI lands
- Live install + Caddy add_federation_site + federated round-trip to
  @Gargron@mastodon.social on grackle
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant