Both changes are implemented and merged (#539, #541). Promote their deltas into openspec/specs/, move the changes to changes/archive/2026-06-14-*, and add the two capabilities to the CAPABILITIES index. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
7.8 KiB
7.8 KiB
Capabilities Index
Top-level index of every spec under openspec/specs/, grouped by area. Each spec describes a capability the platform exposes (or supports internally). Use this as the entry point when navigating the spec library — the alphabetical directory listing is fine for grep, but groupings make it easier to spot drift, overlap, and coverage gaps.
When adding a new spec, slot it into the most relevant group below and update this index in the same change. When merging or splitting specs, update both the directory and this index in the same change.
Identity & access
journal-auth— cookie session, terms-of-service consent gate (initial accept + re-accept on version bump).authentication-methods— passkeys (WebAuthn), magic links, 6-digit codes, the method toggle on register/login forms.security-hardening— cross-cutting hardening (CSP, headers, rate-limit-adjacent concerns).rate-limiting— per-route rate-limit policy.
Profile & settings
profile-settings— display name, bio, profile-visibility editing UX.account-management— email change with re-verification, account deletion (irreversible, cascades).connected-services— third-party integrations (Wahoo today; Strava, Garmin later) connected from settings.public-profiles—/users/:usernamepage (full vs. locked stub), open-graph metadata.
Social
social-follows— follow API, follower/following collections (with locked-account access rules), Pending request lifecycle,/feed.activity-feed— the/feedaggregation behavior (note: also referenced fromsocial-follows; this spec covers feed-specific concerns).explore—/explorepage: paginated local user directory (public profiles only) ordered by recent public activity, plus an "Active recently" sub-section. Reachable to both signed-in users and anonymous visitors.
Notifications & realtime
notifications—notificationstable, four event types (follow_request_received / follow_request_approved / follow_received / activity_published), generation hooks, fan-out,/notificationspage with cursor pagination, mark-read APIs, 90-day retention.sse-broker—/api/eventsendpoint, in-process pub/sub registry, clientEventSourcehook, Caddy passthrough. Transport-only; specific event payloads are owned by the capability that emits them (notifications today).
Routes (Planner core)
planner-session— anonymous Yjs session lifecycle.session-notes— per-session shared notes.route-management— CRUD around saved routes.route-preview— preview rendering of saved routes.route-drag-reshape— drag-to-reshape interaction.route-splitting— split routes at points.route-coloring— generic line color modes.road-type-coloring— road-type-specific color mode.elevation-map-interaction— hover-to-locate between elevation chart and map.multi-day-routes— overnight markers + per-day export.no-go-areas— drawn polygons that re-route avoidance.crash-recovery— recovering an interrupted session.planner-journal-handoff— JWT-callback save flow back to Journal.
Routing engine
brouter-integration— BRouter container + routing-host election + the API the client expects.
Map / overlays
map-core— shared Leaflet wrappers in@trails-cool/map.map-display— base-tile selection and rendering.osm-tile-overlays— OSM raster overlays.osm-poi-overlays— POI overlay layer.
Imports & exports
gpx-import— GPX file parsing and route ingestion.wahoo-import— Wahoo activity sync rules.wahoo-route-push— pushing routes to Wahoo (POST on first push, PUT on re-push, stableexternal_id, push-status UI).
Journal landing & content
journal-landing— anonymous landing + signed-in personal dashboard.activity-sport-type— sport/activity-type enum on activities (set on create or normalized on import), shown as a badge + feed verb, federated as a Note PropertyValue.activity-stats— the canonical headline metric set + reusable stat row (sport-aware avg pace/speed, moving-vs-elapsed time) across feed, detail, and profile.journal-elevation-profile— read-only elevation profile chart + chart↔map "active distance" hover/click sync on the route & activity detail pages.profile-stats— profile roll-up header (lifetime totals + last-4-weeks count), viewer-scoped, computed on the fly (no cache table).profile-weekly-distance— weekly distance bar chart on the profile (12-week axis, gridlines, hover readout), SQL gap-filled.legal-disclaimers— Terms / Privacy / Imprint pages.transactional-emails— magic-link, welcome, etc. email templates.demo-activity-bot— synthetic-content bot (Bruno by default) seeded for demo instances; configurable persona, retention, and seed region.
Infrastructure & ops
infrastructure— Hetzner host topology, Caddy front, vSwitch.local-dev-environment—pnpm devorchestration, Docker services.secret-management— SOPS-encrypted env files, key rotation.observability— Prometheus, Loki, Grafana dashboards.background-jobs— pg-boss queue, cron scheduling, retry policy, handler timeouts shared across the apps.shared-packages— workspace package boundaries (@trails-cool/types,@trails-cool/map,@trails-cool/fit, etc.).
Conventions
- Spec filenames use kebab-case capability names (
profile-settings,social-follows,sse-broker). - Cross-spec references should link to the other spec's path rather than duplicate requirements (see
public-profileslinking tosocial-followsfor the followers/following list access rule, andaccount-managementlinking tojournal-authfor the Terms gate). - New behavior lands through
openspec/changes/<name>/with a delta inspecs/<capability>/spec.md. The delta is promoted to the top-level spec when the change is archived (via/opsx:archive). - Drift catch-up — i.e. updating a spec to match shipped code without changing behavior — can be edited directly without a change, since there's no behavioral payload to propose. Always update
CAPABILITIES.mdin the same edit if a spec is added, removed, or renamed.