docs: capture remaining architecture vision; draft route-federation change
Gap analysis of docs/architecture.md against openspec/ and docs/ideas/ found the envisioned-but-uncaptured remainder. This commit captures it: New OpenSpec change (validated): - route-federation — the collaboration half of the federation vision: routes as dereferenceable trails:Route objects, Create/Update fan-out, Invite/Accept collaboration mirroring (arch decision #2), cross-instance Planner edits via HTTP-Signature-requested scoped tokens (decisions #3/#12), mirror sync healing (#16). Depends on social-federation §6 + route-sharing; carries the 2026-06-07 soak lessons as design constraints. New docs/ideas/ explorations: - instance-administration — registration toggle, suspend/ban, federation blocklists, reports (moderation now gates the federated comments idea) - social-interactions — local likes + comments (don't exist even locally; the foundation federated kudos/comments attach to) - activity-participants — group tagging with confirm/decline + federated mentions (the participants jsonb column is an untyped stub) - multi-day-collections — architecture open question #1, directions evaluated architecture.md cleanup: - Mastodon-compat section annotated with shipped/captured state + the live-soak interop lessons (attachment arrays, tombstones, 10s timeout, no backfill) - api.trails.cool removed (contradicted resolved decision #18) - Phase 1 ticked (shipped); Phase 2/3 items annotated with where each is tracked; specs/ → openspec/, activity.* → journal.*, cx21 → cx23 - brouter-web open question marked resolved-in-practice; new section pointing to where the unshipped vision is tracked Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a26d59c804
commit
bf9787e56a
11 changed files with 580 additions and 50 deletions
46
docs/ideas/activity-participants.md
Normal file
46
docs/ideas/activity-participants.md
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
# Activity participants (group tagging)
|
||||
|
||||
Pre-spec exploration. From `docs/architecture.md` §Activity Sharing &
|
||||
Participants: when people ride/hike together, the activity creator tags
|
||||
the others; tagged users confirm or decline; confirmed participants see
|
||||
the activity on their own profile and can attach their own GPS trace and
|
||||
photos. "Like photo tagging on social media, but for rides."
|
||||
|
||||
The `activities.participants` jsonb column exists as an untyped stub —
|
||||
no flow, UI, or spec behind it.
|
||||
|
||||
## Scope sketch
|
||||
|
||||
**v1 (local)**
|
||||
- Tag local users on your activity (search by username, like the
|
||||
share dialog planned in `route-sharing`)
|
||||
- Notification `participant_tagged` → confirm / decline (Requests-tab
|
||||
pattern from follow requests)
|
||||
- Confirmed participation renders the activity on the participant's
|
||||
profile (clearly attributed: "with @alice")
|
||||
- Participant may attach their own trace + photos to the shared
|
||||
activity — or link their own existing activity as "same outing"
|
||||
(the second option composes better with imports: Bob's Garmin
|
||||
recording is already its own activity)
|
||||
- Schema: promote from jsonb stub to a real
|
||||
`journal.activity_participants` table
|
||||
(`activity_id, user_id | participant_actor_iri, status, own_activity_id?`)
|
||||
— the exactly-one-of local/remote pattern from `follows` again
|
||||
|
||||
**v2 (federated)**
|
||||
- Tagging across trails instances; Mastodon sees mentions
|
||||
(`"Rode with @bob@bob.trails.xyz"`) per the architecture
|
||||
- Confirm/decline crosses instances → needs a small custom activity
|
||||
vocabulary or reuse of `Invite`/`Accept` (the same pair
|
||||
route-federation needs — design together)
|
||||
|
||||
## Constraints & notes
|
||||
|
||||
- Privacy: being tagged must never reveal more than the tagger could
|
||||
already see; declined/pending tags are visible only to tagger +
|
||||
taggee. Tagging requires the activity to be visible to the taggee.
|
||||
- The "link own activity as same outing" model doubles as the natural
|
||||
seed for multi-day collections' "shared trip" case — see
|
||||
`multi-day-collections.md`.
|
||||
- Mention-style federation means participant handles end up in public
|
||||
Note content — privacy manifest update when v2 lands.
|
||||
49
docs/ideas/instance-administration.md
Normal file
49
docs/ideas/instance-administration.md
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
# Instance administration & moderation
|
||||
|
||||
Pre-spec exploration. Envisioned in `docs/architecture.md` (§Instance
|
||||
Administration) since day one, never spec'd. Now that federation is live
|
||||
on staging — a public inbox accepting traffic from arbitrary instances —
|
||||
the moderation half has moved from "eventually" to "before the federated
|
||||
surface grows."
|
||||
|
||||
## Scope sketch
|
||||
|
||||
**Instance settings**
|
||||
- Instance name, description, rules page (rendered at `/about`)
|
||||
- Open/close registration (env var today at best; should be a runtime
|
||||
admin setting)
|
||||
- Instance-level contact / operator info (some of this exists for the
|
||||
legal pages — consolidate)
|
||||
|
||||
**User management**
|
||||
- Admin role (first user? env-designated? explicit grant)
|
||||
- Suspend / unsuspend users (suspended: no login, content hidden,
|
||||
federation stops — actor 404s like a private profile)
|
||||
- Delete user + content (GDPR path; account-management spec covers
|
||||
self-deletion, not admin-initiated)
|
||||
|
||||
**Federation management**
|
||||
- Per-instance blocklist: refuse inbox traffic, drop follows, stop
|
||||
deliveries to blocked domains (checked in the inbox rate-limit layer
|
||||
we already have — `federationSourceHost` is the natural hook)
|
||||
- Per-instance silence (content hidden from shared surfaces but
|
||||
follows still work) — maybe later; block first
|
||||
- Visibility into federation peers: which instances follow us /
|
||||
we deliver to, volumes, error rates (remote_actors table + Fedify
|
||||
logs already hold most of this)
|
||||
|
||||
**Reports & moderation queue**
|
||||
- Report content/users (local reports first; ActivityPub `Flag`
|
||||
federation later)
|
||||
- Simple queue: open → resolved/dismissed, with action taken
|
||||
|
||||
## Constraints & notes
|
||||
|
||||
- Mastodon's admin model is the obvious reference; ours can be a tiny
|
||||
subset (single-admin instances are the norm for self-hosters).
|
||||
- The federated-comments idea (`fediverse-enhancements.md`) explicitly
|
||||
depends on at least instance blocks + report handling existing.
|
||||
- Suspension must compose with federation the same way profile privacy
|
||||
does today: suspended ⇒ actor 404, push delivery suppressed (the
|
||||
`social-federation` spec's 9.3 mechanics generalize).
|
||||
- Admin surfaces are user-facing strings → i18n from the start (en+de).
|
||||
45
docs/ideas/multi-day-collections.md
Normal file
45
docs/ideas/multi-day-collections.md
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
# Multi-day activity collections
|
||||
|
||||
Pre-spec exploration. This is `docs/architecture.md`'s **explicit open
|
||||
question #1** (§Multi-Day Route Support: "Exact data model for
|
||||
collections TBD — needs more design work"). Multi-day *routes* shipped
|
||||
(day-break waypoints, per-day stats, track segments per day); the
|
||||
activity side — recording a 5-day bikepacking trip as one entity with
|
||||
five day-recordings — is captured nowhere.
|
||||
|
||||
## The shape from the architecture
|
||||
|
||||
- A multi-day activity is a **collection linking individual
|
||||
day-activities**
|
||||
- Each day-activity keeps its own GPS trace, photos, description
|
||||
(possibly imported from different devices/apps per day)
|
||||
- The collection references the planned multi-day route as a whole
|
||||
- Day-activities can be imported one at a time (Garmin/Komoot/Wahoo per
|
||||
day) and attached as the trip progresses
|
||||
|
||||
## Data-model directions to evaluate
|
||||
|
||||
1. **Collection row + membership table** —
|
||||
`journal.trips (id, owner, name, description, route_id?)` +
|
||||
`journal.trip_activities (trip_id, activity_id, day_index)`.
|
||||
Activities stay fully independent (visibility, federation, photos);
|
||||
the trip is a presentation/grouping layer. Cheapest; probably right.
|
||||
2. **Self-referencing activities** (`parent_activity_id` + a `kind`
|
||||
column). Fewer tables but overloads the activity model and makes
|
||||
feed/outbox queries carry exclusion rules forever.
|
||||
3. Whatever we pick must answer: trip-level visibility vs per-day
|
||||
visibility (suggest: trip visibility caps day visibility), trip-level
|
||||
stats (sum of days), and how a trip federates (one Note per day as
|
||||
today, plus a trip page link? A trip-level Note at completion?).
|
||||
|
||||
## Notes
|
||||
|
||||
- Pairs naturally with `activity-participants.md` (group trips) and the
|
||||
"Tour mode" sketch in `fediverse-enhancements.md` (day N/M check-in
|
||||
posts are trivial once a trip entity exists).
|
||||
- The route side already encodes day breaks in GPX track segments —
|
||||
importing a multi-day route's recording per segment could pre-seed
|
||||
day-activities.
|
||||
- Keep GPX exportability: a trip should export as one GPX with track
|
||||
segments per day (mirror of the route format), preserving the
|
||||
data-ownership principle.
|
||||
47
docs/ideas/social-interactions.md
Normal file
47
docs/ideas/social-interactions.md
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
# Local likes & comments
|
||||
|
||||
Pre-spec exploration. The architecture's Journal feature list has
|
||||
"Social: Following, likes, comments" — follows shipped
|
||||
(`social-follows`), likes and comments don't exist **even between local
|
||||
users**. The federated halves are sketched separately in
|
||||
`fediverse-enhancements.md` (kudos = inbound Like/Announce, comments =
|
||||
inbound replies); this idea is the local foundation those would attach
|
||||
to.
|
||||
|
||||
## Scope sketch
|
||||
|
||||
**Likes (kudos)**
|
||||
- One per (user, activity); toggleable; count on activity cards + detail
|
||||
- Notification to the activity owner (`notifications` spec has the
|
||||
pattern; new type `activity_liked`)
|
||||
- Storage: `journal.likes (user_id, activity_id, created_at)` or a
|
||||
generalized reactions table if we ever want more than ❤️ — start
|
||||
with likes only (simplicity principle)
|
||||
- Federation hook-in later: inbound Mastodon `Like` increments the same
|
||||
counter with `remote_actor_iri` instead of `user_id` (same
|
||||
exactly-one-of pattern as `follows.follower_id`/`follower_actor_iri`)
|
||||
|
||||
**Comments**
|
||||
- Flat list on activities first (no threading — Mastodon-reply
|
||||
interop pushes toward flat anyway); plain text → maybe limited
|
||||
markdown later
|
||||
- Owner can delete comments on their activities; commenter can delete
|
||||
their own
|
||||
- Notification type `activity_commented`
|
||||
- Federation hook-in later: inbound replies (`inReplyTo`) land in the
|
||||
same table with remote attribution; outbound, local comments on a
|
||||
federated activity would need to federate back as replies
|
||||
|
||||
## Constraints & notes
|
||||
|
||||
- Visibility: liking/commenting requires the activity to be visible to
|
||||
you — public activities only for non-owners today; revisit when
|
||||
followers-only content lands (§7/§8 of social-federation).
|
||||
- The `activities.owner_id` NOT NULL open question (design.md of
|
||||
social-federation) applies to remote comment authors the same way —
|
||||
decide once.
|
||||
- Decide whether routes also get likes/comments or activities only.
|
||||
The architecture says activities; start there.
|
||||
- Moderation precedes federated comments (see
|
||||
`instance-administration.md`) but NOT local comments — local users
|
||||
are accountable accounts on your own instance.
|
||||
Loading…
Add table
Add a link
Reference in a new issue