Files
captoys/social-coop-checklist.md
T
dckcandClaude Opus 5.5 1e6436e089 capsite: social.coop tree at the ActivityPub level (fedi-cache)
Mastodon is one implementation; the cache speaks the protocol: outbox
for backfill, and fedi-cache as a follower actor so Update/Delete are
delivered rather than polled for. Its own keypair replaces an access
token, so webapp drops out of this one.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-07 11:16:05 -05:00

5.7 KiB

social.coop cache goal tree

The same conventions as the diigo goal tree: each - [ ] is a goal, its indented children must pass first, working notes sit under each goal.

  • madmode's weekly roundup includes my fediverse activity (#23, PESOS): fedi-cache holds the posts and boosts of @dckc@social.coop, speaking ActivityPub only — no server-specific API, so the cache works against any server and survives an account move. social.coop grants it nothing; madmode holds no credential

    • 0. Decide the shape (user's call before code): - [ ] 0-i. A new worker fedi-cache/ beside diigo-cache/; extract shared pieces (date window/q query module, fill job, webkey page) once two caches work. - [ ] 0-ii. Pull, push, or both? Pull: read the actor's outbox (an OrderedCollection of Create and Announce) — public posts only. Push: fedi-cache is itself an actor that follows @dckc; social.coop delivers Create/Update/Delete/Announce to its inbox, including followers-only posts once the follow is approved. Recommendation: both — outbox for backfill, inbox for freshness. - [ ] 0-iii. What's out of reach at the protocol level: likes (Like goes to the post's author, not to followers, and Mastodon serves no liked collection) and bookmarks (not ActivityPub at all). Accept the gap, or take them from the account archive (likes.json, bookmarks.json) as a manual import.

    • 1. Authority: fedi-cache's own actor keypair, generated in its DO and never exported; HTTP Signatures on outgoing GETs (servers in authorized-fetch mode require them) and on the Follow. The authority it holds is exactly what @dckc grants by approving the follow, and removing the follower revokes it. No token, no cookie, so webapp isn't needed. Ids → password manager, as with diigo.

    • 2. Pull: the outbox cache: - [ ] 2-i. Resolve the actor: WebFinger (/.well-known/webfinger?resource=acct:dckc@social.coop) → actor document → outbox. - [ ] 2-ii. Storage: activities and objects keyed by their id URI, objects with updated. Durable state from day one: a SCHEMA_V1 step. - [ ] 2-iii. Fill: follow the collection's first/next pages with Accept: application/activity+json; politeness delay per request; back off on 429. - [ ] 2-iv. Tests: pnpm lint && pnpm test, the real worker against a fake ActivityPub server (WebFinger, actor, paged outbox, a 429). - [ ] 2-v. Complete: a filled cache matches the account archive's outbox.json — the archive is itself an ActivityPub collection, so the comparison stays at the protocol level (the analogue of diigo's scripts/compare-export.ts).

    • 3. Push: fedi-cache as a follower: - [ ] 3-i. Serve its own actor: WebFinger, actor document with publicKey, inbox. Needs a public HTTPS origin, so dev wants a tunnel or a deployed test instance (and the user runs it, per AGENTS.md). - [ ] 3-ii. Send Follow; record Accept. - [ ] 3-iii. Inbox: verify the HTTP Signature against the sender's key, accept only activities whose actor is @dckc, apply Create/Update/Delete/Announce/Undo. - [ ] 3-iv. Tests: signed deliveries in; a forged one and one from another actor rejected; an edit and a delete reflected.

    • 4. Read surfaces: /public/dckc with diigo 1d's date window and q filter, HTML and JSON; JSON shape pinned by a test. Only objects addressed to as:Public appear there: followers-only posts (which only push brings in) never reach a public page; a test says so.

    • 5. madmode's weekly page includes it: diigo's goal 4 (/bookmarks/2026-W41) grows a section from this cache, or becomes a combined /weekly/2026-W41. Same editorial question as there: a raw list, or a draft the user edits.

    • 6. Deployed: rate-limit /public/*; the actor's origin is its identity (moving it changes the follower), so choose the hostname once.

    • 7. Revocation: if the follow is removed or deliveries stop, the public page keeps serving what's stored and says when it last heard from @dckc; outbox polling still covers public posts.

How to run

TBD with goal 2; it should mirror the diigo how-to-run.

Working rules

capsite AGENTS.md: dev servers are the user's job; durable state, loud about breaking changes; secrets discipline; generated config types.

Pointers