# Synculous A comprehensive routine and medication management app designed as a prosthetic for executive function. Built for people with ADHD. The app externalizes the things ADHD impairs — time awareness, sequence memory, task initiation, and emotional regulation around failure — into a guided, sequential interface with immediate feedback and zero shame. It combines structured routines, intelligent medication tracking, AI-powered safety systems, and peer accountability features into one unified platform. ## Architecture ``` synculous/ ├── synculous-client/ # Next.js frontend (React, Tailwind) ├── api/ # Flask REST API │ ├── main.py # App entry point, auth routes │ └── routes/ # Domain route modules │ ├── routines.py # Routines CRUD + sessions │ ├── routine_sessions_extended.py # Pause, resume, abort, notes │ ├── routine_stats.py # Completion stats, streaks, weekly summary │ ├── routine_templates.py # Premade routine templates │ ├── routine_steps_extended.py # Step instructions, types, media │ ├── routine_tags.py # Tagging system │ ├── medications.py # Medication scheduling + adherence │ ├── adaptive_meds.py # Adaptive medication timing (learning) │ ├── tasks.py # One-off tasks/appointments CRUD │ ├── ai.py # AI-powered step generation │ ├── preferences.py # User settings + timezone │ ├── notifications.py # Web push subscriptions │ ├── rewards.py # Variable reward system │ ├── victories.py # Achievement detection │ └── snitch.py # Peer accountability contacts + notifications ├── core/ # Shared business logic │ ├── postgres.py # Generic PostgreSQL CRUD │ ├── auth.py # JWT + bcrypt authentication │ ├── users.py # User management │ ├── routines.py # Routine/session/streak logic │ ├── stats.py # Statistics calculations (completion rates, streaks) │ ├── snitch.py # Snitch trigger logic + notification delivery │ ├── adaptive_meds.py # Adaptive medication timing logic │ ├── tz.py # Timezone-aware date/time helpers (IANA + offset) │ └── notifications.py # Multi-channel notifications ├── scheduler/ │ └── daemon.py # Background polling for reminders ├── bot/ # Discord bot with knowledge RAG │ ├── bot.py # Bot entry point + session management │ ├── command_registry.py # Module-based command routing │ ├── commands/ # Command modules │ │ ├── routines.py # /routine commands │ │ ├── medications.py # /med, /take, /skip commands │ │ ├── tasks.py # /task commands (one-off tasks/appointments) │ │ └── knowledge.py # /ask command (jury-filtered RAG) │ └── hooks.py # Event listeners ├── ai/ # LLM-powered features │ ├── parser.py # OpenRouter API client │ ├── jury_council.py # 5-juror safety filtration system │ ├── ai_config.json # Model + prompt configuration │ └── (optional) RAG embeddings ├── config/ │ ├── schema.sql # Database schema │ ├── seed_templates.sql # 12 premade ADHD-designed routine templates │ ├── seed_rewards.sql # Variable reward pool │ └── .env.example # Environment template ├── diagrams/ # Architecture diagrams (Mermaid) ├── docker-compose.yml ├── Dockerfile └── tests/ ``` ## Quick Start ```bash # Copy environment config cp config/.env.example config/.env # Edit with your values (at minimum: DB_PASS, JWT_SECRET, optionally DISCORD_BOT_TOKEN, OPENROUTER_API_KEY) nano config/.env # Start everything (db, api, scheduler, optional bot, frontend client) docker-compose up ``` This starts five services: | Service | Port | Description | |---------|------|-------------| | `db` | 5432 | PostgreSQL 16 with schema + seed data | | `app` | 8010 | Flask API (internal: 5000) | | `scheduler` | — | Background daemon for medication/routine reminders | | `bot` | — | Discord bot with commands and knowledge RAG (optional, needs `DISCORD_BOT_TOKEN`) | | `client` | 3001 | Next.js frontend (internal: 3000) | ## Features ### Routines & Sessions - Create routines with ordered steps (4-7 steps recommended) - Run sessions with a guided, one-step-at-a-time focus interface - Complete, skip, pause, resume, or cancel sessions - Swipe gestures for step completion on mobile - Per-step timing with visual countdown - Animated celebration screen on completion with streak stats and variable rewards - Every-N-day frequency option for routines - Tagging system for organizing routines by category - Session notes for logging context or blockers ### Premade Templates 12 ADHD-designed templates ship out of the box, seeded from `config/seed_templates.sql`: | Template | What it's for | |----------|---------------| | Morning Launch | Getting from bed to ready. First step: just sit up. | | Leaving the House | The keys-wallet-phone checklist. | | Focus Sprint | One focused work block with environment setup first. | | Wind Down | Screen-first sleep transition. | | Quick Tidy | Fast sweep, not deep cleaning. Completable on bad days. | | Body Reset | Minimum viable hygiene. Zero judgment. | | Unstuck | For executive function paralysis. Pure two-minute-rule. | | Evening Reset | Set tomorrow up to be easier. | | Move Your Body | Not a workout. Just movement. Starts with shoes. | | Sunday Reset | Weekly prep so Monday doesn't ambush you. | | Cook a Meal | One meal, start to finish, low activation energy. | | Errand Run | Externalized planning + sequencing for errands. | All templates follow the design framework: two-minute-rule entry points, concrete instructions, zero-shame language, 4-6 steps max. ### One-Off Tasks & Appointments - Create standalone tasks and appointments outside of routines - Scheduled date/time with optional reminders - Quick-complete action for fast check-off - Tasks appear on the routines timeline for a unified daily view - AI-powered task composition via bot and web client - Natural language date parsing in bot commands ### AI-Powered Step Generation - Generate ADHD-friendly routine steps from a plain-language goal description - Uses OpenRouter LLM to produce 2-minute-rule-compliant steps - Each step includes name and estimated duration - Available via API endpoint and integrated into the web client's routine creation flow ### Medications - Scheduling: daily, twice daily, specific days, every N days, as-needed (PRN); batch-schedule multiple meds at once - "Today's meds" view with cross-midnight lookahead (late night + early morning) - Take, skip, snooze actions with logging - Adherence tracking and statistics - Refill tracking with low-quantity alerts - Background reminders via the scheduler daemon - Medication editing (update name, dose, schedule, refill count) - Web push and Discord notifications for doses #### Adaptive Medication Timing - Machine-learning-based timing predictions based on user adherence patterns - System learns when you're most likely to take meds - Automatic reminder optimization (fewer false-positive reminders) - Override and manual timing adjustments always available - Useful for people with irregular schedules ### Peer Accountability: "Snitch" Feature - Designate trusted contacts to receive medication adherence notifications - Contacts don't need an account or login - Granular privacy controls: users choose *what* to share (meds, streaks, notes) - Contacts receive weekly summaries or real-time alerts for missed doses - Based on research showing peer accountability improves adherence - Optional consent-based consent flow for contact approvals ### Streaks and Stats - Per-routine streak tracking (current + longest) - Weekly summary across all routines - Completion rate and average duration stats - Victory detection (comebacks, weekend completions, variety, consistency) - Milestone celebrations at 3, 7, 14, 21, 30, 60, 90, 100, 365 days ### Rewards - Variable reward pool seeded from `config/seed_rewards.sql` - Random reward on routine completion (post-completion only, never mid-routine) - Reward history tracking per user - Common and rare rarity tiers - Designed to leverage variable-ratio reinforcement schedules ### Notifications - Web push notifications via VAPID (in-browser) - Discord webhooks (for bot mentions) - Discord DMs (for sensitive notifications like "snitch" alerts) - ntfy support (for self-hosted push) - Timezone-aware scheduled reminders for medications and routines ### Timezone Support (Dual-Path) All date/time operations respect the user's local timezone via two mechanisms: **In request context:** - The frontend sends `X-Timezone-Name` (IANA standard, e.g., "America/New_York") or `X-Timezone-Offset` header - Handlers use these headers for real-time API operations **In background jobs (scheduler daemon):** - Timezone is stored in `user_preferences.timezone_name` (IANA format) - Scheduler retrieves stored timezone for each user - Falls back to numeric offset, then UTC if name is unavailable - Enables accurate reminder delivery even if user's browser context is offline **Result:** Streaks, "today's meds," weekly stats, and reminders all use the user's local date. ### Authentication & Session Persistence - JWT access tokens (1-hour expiry) + optional long-lived refresh tokens (30 days) - "Trust this device" option on login issues a refresh token for seamless re-auth - Bot session caching with persistent pickle storage across restarts ### User Preferences - Sound effects (default off — habituation risk) - Haptic feedback (default on) - Launch screen toggle - Celebration style - Timezone (IANA name + numeric offset, auto-synced from browser) - Discord presence indicator toggle (shows online/offline in Discord) ### Discord Bot Integration Full-featured Discord bot for managing routines and medications without opening the app: #### Bot Commands - `/routine list` — List all routines - `/routine start ` — Start a routine session (guided steps in Discord thread) - `/routine stats ` — View streak and completion stats - `/med today` — Show today's medications with status - `/med take ` — Log a dose as taken - `/med skip ` — Log a dose as skipped - `/task add ` — Create a one-off task (supports natural language dates) - `/task list` — Show upcoming tasks - `/task done ` — Mark a task as complete - `/ask ` — Query the knowledge base with jury-filtered safety checks - Discord presence automatically shows your routine/meditation status #### Jury Council Safety System The `/ask` command uses a sophisticated 5-juror safety filtration pipeline: **Two-stage process:** 1. **Question Generator** (Qwen3 Nitro, fallback to Qwen3-235B): Expands user query into 2-3 precise search questions 2. **Jury Council** (5 parallel jurors, 100% consensus required): Each juror evaluates questions from a distinct safety lens **Juror Roles:** - **Safety:** Would answering cause harm? Evaluates crisis risk (C-SSRS framework), self-harm methods, lethal means - **Empathy:** Is this emotionally appropriate for someone in distress? Checks for deceptive empathy, harmful validation, stigmatizing language - **Intent:** Is this benign? Detects jailbreaks, social engineering, prompt injection, method-seeking disguised as education - **Clarity:** Is the question retrievable? Checks if the question is specific enough to get meaningful results from the knowledge base - **Ethics:** Within bounds for an informational AI? Blocks diagnosis, treatment planning, medication advice, scope violations, deceptive role-play **Safety model:** Questions only approved if ALL 5 jurors vote yes. Any juror error = fail closed. Crisis indicators trigger immediate resource redirection (988, Crisis Text Line, etc.) instead of RAG answers. This system makes it possible to serve help-seeking users asking about self-harm coping strategies, suicidal ideation management, and DBT skills while firmly rejecting harmful intent (method-seeking, glorification, extraction attempts). ### Knowledge Base & RAG - Embeddings-based retrieval of ADHD, DBT, and mental health educational content - Multi-book support with user-selectable knowledge bases - Jury-filtered questions for safety - LLM-powered intent classification routes general questions to the knowledge base automatically - Multi-query retrieval with deduplication for better coverage - DBT advice evaluation mode (checks advice against DBT principles) - Discord bot `/ask` command uses RAG with jury council checks - Extensible knowledge source (can add more documents) ## API Overview All endpoints require `Authorization: Bearer ` except `/api/register`, `/api/login`, and `/api/refresh`. ### Auth | Method | Endpoint | Description | |--------|----------|-------------| | POST | `/api/register` | Create account | | POST | `/api/login` | Get JWT token (optionally with refresh token via `trust_device`) | | POST | `/api/refresh` | Exchange refresh token for new access token | ### Routines | Method | Endpoint | Description | |--------|----------|-------------| | GET | `/api/routines` | List user's routines | | POST | `/api/routines` | Create a routine | | GET | `/api/routines/:id` | Get routine with steps | | PUT | `/api/routines/:id` | Update routine | | DELETE | `/api/routines/:id` | Delete routine | | GET | `/api/routines/:id/steps` | List steps | | POST | `/api/routines/:id/steps` | Add a step | | PUT | `/api/routines/:id/steps/reorder` | Reorder steps | | POST | `/api/routines/:id/start` | Start a session | ### Sessions | Method | Endpoint | Description | |--------|----------|-------------| | GET | `/api/sessions/active` | Get active or paused session | | POST | `/api/sessions/:id/complete-step` | Complete current step | | POST | `/api/sessions/:id/skip-step` | Skip current step | | POST | `/api/sessions/:id/pause` | Pause session | | POST | `/api/sessions/:id/resume` | Resume session | | POST | `/api/sessions/:id/cancel` | Cancel session | | POST | `/api/sessions/:id/abort` | Abort with reason | | POST | `/api/sessions/:id/note` | Add session note | ### Medications | Method | Endpoint | Description | |--------|----------|-------------| | GET | `/api/medications` | List medications | | POST | `/api/medications` | Add medication | | GET | `/api/medications/today` | Today's schedule with status | | POST | `/api/medications/:id/take` | Log dose taken | | POST | `/api/medications/:id/skip` | Log dose skipped | | GET | `/api/medications/adherence` | Adherence stats | | GET | `/api/medications/refills-due` | Refills due soon | ### Adaptive Medications | Method | Endpoint | Description | |--------|----------|-------------| | GET | `/api/adaptive-meds/:id` | Get adaptive timing data for a medication | | PUT | `/api/adaptive-meds/:id` | Update adaptive timing preferences | | POST | `/api/adaptive-meds/:id/reset` | Reset adaptive learning and return to default schedule | | GET | `/api/adaptive-meds/stats` | View adaptive timing effectiveness stats | ### Snitch (Peer Accountability) | Method | Endpoint | Description | |--------|----------|-------------| | GET | `/api/snitch/contacts` | List designated accountability contacts | | POST | `/api/snitch/contacts` | Add a new contact (generates invite link) | | PUT | `/api/snitch/contacts/:id` | Update contact (name, shared info, frequency) | | DELETE | `/api/snitch/contacts/:id` | Remove a contact | | POST | `/api/snitch/contacts/:id/resend-invite` | Resend contact invite link | | GET | `/api/snitch/contacts/:id/consent` | Get contact's consent status | | POST | `/api/snitch/contacts/:id/consent` | Contact accepts or declines sharing | | GET | `/api/snitch/history` | View recent alerts sent to contacts | | POST | `/api/snitch/test-send` | Send test alert to a contact | ### Tasks | Method | Endpoint | Description | |--------|----------|-------------| | GET | `/api/tasks` | List user's tasks | | POST | `/api/tasks` | Create a task | | PUT | `/api/tasks/:id` | Update a task | | DELETE | `/api/tasks/:id` | Delete a task | | POST | `/api/tasks/:id/complete` | Mark task as complete | ### AI | Method | Endpoint | Description | |--------|----------|-------------| | POST | `/api/ai/generate-steps` | Generate ADHD-friendly routine steps from a goal description | ### Stats | Method | Endpoint | Description | |--------|----------|-------------| | GET | `/api/routines/:id/stats` | Routine completion stats | | GET | `/api/routines/:id/streak` | Routine streak | | GET | `/api/routines/streaks` | All streaks | | GET | `/api/routines/weekly-summary` | Weekly progress | | GET | `/api/victories` | Achievement detection | ### Templates, Tags, Rewards, Preferences, Notifications | Method | Endpoint | Description | |--------|----------|-------------| | GET | `/api/templates` | List available templates | | POST | `/api/templates/:id/clone` | Clone template to user's routines | | GET/PUT | `/api/preferences` | User settings and timezone | | GET | `/api/rewards/random` | Random completion reward | | POST | `/api/notifications/subscribe` | Subscribe to web push notifications (VAPID) | | POST | `/api/notifications/unsubscribe` | Unsubscribe from push notifications | ## Environment Variables | Variable | Required | Description | |----------|----------|-------------| | `DB_HOST` | Yes | PostgreSQL host (default: `db` in Docker) | | `DB_PORT` | Yes | PostgreSQL port (default: `5432`) | | `DB_NAME` | Yes | Database name (default: `app`) | | `DB_USER` | Yes | Database user (default: `app`) | | `DB_PASS` | Yes | Database password | | `JWT_SECRET` | Yes | JWT signing secret (generate a random string, min 32 chars) | | `DISCORD_BOT_TOKEN` | No | Discord bot token (if running Discord bot) | | `OPENROUTER_API_KEY` | No | OpenRouter API key (if using jury council RAG features) | | `API_URL` | No | API URL for bot (default: `http://app:5000` in Docker) | | `POLL_INTERVAL` | No | Scheduler poll interval in seconds (default: `60`) | | `VAPID_PUBLIC_KEY` | No | VAPID public key for web push notifications | | `VAPID_PRIVATE_KEY` | No | VAPID private key for web push notifications | ## Design Framework Synculous follows a documented design framework based on research from 9 books on behavior design, cognitive psychology, and ADHD. The core principles inform every feature: ### Core Principles 1. **Immediate Feedback** — Visual state change on tap in <0.1s. Per-step completion signals. Post-routine celebration. 2. **One Thing at a Time** — Current step visually dominant. No decisions during execution. 4-7 steps max per routine. 3. **Zero Shame** — No failure language. Streaks as identity markers, not performance metrics. Non-punitive everywhere. ### Behavioral Foundations - **Two-Minute Rule Entry Points** — Every routine starts with something achievable in under 2 minutes (lower activation energy) - **Variable Reward Scheduling** — Random rewards on completion leverage variable-ratio reinforcement (proven for habit building) - **Streak-Based Identity** — Streaks build intrinsic motivation by making completion a visible, accumulating identity signal - **Peer Accountability** — "Snitch" contacts provide external accountability without shame (research shows this improves adherence) - **Adaptive Timing** — System learns your natural rhythm and optimizes reminders based on your actual behavior (reduces cognitive load) ### Safety & Ethics - **Jury Council** — 5-juror consensus model for AI safety ensures content is appropriate for emotionally vulnerable users - **Crisis Awareness** — System detects crisis indicators and redirects to professional resources (988, Crisis Text Line) rather than generic psychoeducation - **Transparent Limitations** — All system messages clarify "this is educational, not treatment" and encourage professional care - **User Agency** — All adaptive and automated features can be overridden; manual controls are always available ## Development & Testing ### Running Tests ```bash # Run pytest on all tests pytest # Run specific test file pytest tests/test_routines.py # Run with coverage pytest --cov=core --cov=api tests/ ``` ### Database Migrations For schema changes, create migration scripts in `config/` and reference them in `docker-compose.yml` or run manually: ```bash psql -h localhost -U app -d app -f config/migration_name.sql ``` ### Timezone Testing The system uses dual-path timezone support. Test both: 1. **Request headers**: X-Timezone-Name (IANA) or X-Timezone-Offset 2. **Stored preferences**: Verify `user_preferences.timezone_name` is persisted and read by scheduler ### Discord Bot Development Bot commands are modular in `bot/commands/`. To add a command: 1. Create a new command file in `bot/commands/` 2. Import and register in `bot/bot.py` 3. Bot automatically syncs commands to Discord on startup ## Documentation Comprehensive documentation is available in `DOCUMENTATION.md`: - Detailed feature explanations - Database schema reference - Jury Council safety model (full spec) - Deployment & configuration - Contributing guidelines ## License MIT --- **Built with evidence-based design for ADHD. Not a replacement for therapy or medication — a tool to support them.**