Fold completed deltas into main specs (activity-feed, route-management, infrastructure, planner-session), add new background-jobs and demo-activity-bot capability specs, and move the three change dirs to openspec/changes/archive/. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2.9 KiB
2.9 KiB
Why
The demo-activity-bot is hardcoded to "Bruno the Berlin dog walker" — a persona that reads well for trails.cool itself but makes no sense for a self-hosted instance in Tokyo, Denver, or Edinburgh. If we want federated hosts to turn the demo on, each instance needs to choose its own demo identity, region, and copy so visitors see a plausible local-voice feed rather than a stranger's Berlin park patrol.
What Changes
- Make the demo user's identity (username, display name, bio) configurable per instance via env — today
ensureDemoUser()insertsbrunowith a fixed display name and bio. - Allow each instance to supply its own generated-content pools (route-name pool and description pool) in EN + DE — today these are hardcoded string arrays in
demo-bot.server.ts. - Allow each instance to restrict the demo to its preferred locale(s) — today the bot picks EN or DE with a coin flip.
- Keep all configuration in a single
DEMO_BOT_PERSONAJSON blob (env or file path) so operators can supply one artifact instead of threading five env vars. - Retain the current built-in Bruno persona as the default when no override is supplied, so
trails.coolitself keeps its current behavior with no operator action. - Keep
DEMO_BOT_ENABLED,DEMO_BOT_REGION, andDEMO_BOT_RETENTION_DAYSas they are today (region is a separate concern from persona; retention + enable-flag are orthogonal).
Capabilities
New Capabilities
None.
Modified Capabilities
demo-activity-bot: the bot's identity and generated copy become a persona contract supplied by the operator rather than a fixed Bruno/Berlin combination. The generation gate, retention, cap, and synthetic flag are unchanged.
Impact
- Code:
apps/journal/app/lib/demo-bot.server.ts— replace the four hardcoded*_POOL_*arrays and the threeDEMO_*constants with a loaded-onceDemoPersonaobject.ensureDemoUser()consumes the persona'susername/displayName/bio.templateName/templateDescriptionread from the persona's pools. - UX:
/users/<username>— the 🐕 demo badge needs to gate on a runtime-known username, not a literal"bruno". Move the gate to loader data (isDemoUserboolean) rather than a client-side string check. - Ops:
infrastructure/.env.example,docker-compose.yml— addDEMO_BOT_PERSONApassthrough; document the JSON shape. ExistingDEMO_BOT_REGIONet al. stay. - Docs: a short persona-authoring note in
docs/(one page) so host operators know the JSON shape + sensible pool sizes. - Tests: new unit tests for
loadPersona()(env → persona, fallback to built-in Bruno, malformed JSON → fallback + warn). Existing integration + E2E tests continue to work unchanged because the default persona is still Bruno. - No breaking change for
trails.cool: the built-in Bruno persona remains the default and is exactly the current hardcoded strings.