Atlas is a chat-first brain-dump scheduler MVP. A user sends freeform text, the system turns it into structured tasks, places them onto a simple internal schedule, and follows up through its messaging bot surface.
apps/web: the only deployable Next.js apppackages/core: product types, validation schemas, planning logic, and scheduling rules for the MVPpackages/db: Drizzle schema and persistence layerpackages/integrations: Telegram, OpenAI, and future calendar adaptersdocs: product, architecture, decisions, and active project contextscripts: local automation and repo utilities
pnpm dev: run the Next.js app locallypnpm build: build all workspacespnpm eval:all: run the full live OpenAI prompt-eval loop and write a consolidated report topackages/integrations/manual-eval-report.jsonpnpm eval:confirmed-mutation-recovery: run the live OpenAI confirmed-mutation recovery eval fixture set against the current promptpnpm eval:conversation-context: run the live OpenAI conversation-context eval fixture set against the current promptpnpm eval:planner: run the live OpenAI planner eval fixture set against the current promptpnpm eval:router-confirmation: run the live OpenAI router-confirmation eval fixture set against the current promptpnpm eval:turn-router: run the live OpenAI turn-router eval fixture set against the current promptpnpm lint: lint all workspacespnpm typecheck: run TypeScript checks across the repopnpm test: run the test suitepnpm telegram:webhook:set: register the Telegram webhook and print Telegram's current webhook infopnpm db:test:start: start the local Homebrew Postgres test service and createatlas_testpnpm db:test:reset: reset the localatlas_testdatabase schema for integration rerunspnpm db:test:stop: stop the local Homebrew Postgres test service
Database schema commands are owned by packages/db:
cd packages/db && DATABASE_URL=... pnpm db:generatecd packages/db && DATABASE_URL=... pnpm db:checkcd packages/db && DATABASE_URL=... pnpm db:migratepnpm --filter @atlas/db db:generatewithDATABASE_URLalready setpnpm --filter @atlas/db db:checkwithDATABASE_URLalready setpnpm --filter @atlas/db db:migratewithDATABASE_URLalready set
Atlas treats prompt changes as product behavior changes. Use the live eval harness to iterate on prompts deliberately instead of editing blind.
Recommended loop:
- Edit the owning prompt, schema, or parser in
packages/integrationsandpackages/coretogether when the contract changes. - Run the narrowest relevant live eval first:
pnpm eval:plannerpnpm eval:turn-routerpnpm eval:router-confirmationpnpm eval:conversation-contextpnpm eval:confirmed-mutation-recovery
- Inspect the suite-specific report written under
packages/integrations/*.manual-eval-report.json. - If the suite fails, inspect the generated prompt-improvement brief under
packages/integrations/*.prompt-improvement.mdand use it as the starting point for the next prompt revision. - Tighten the prompt or contract based on the actual failing model output.
- Run
pnpm eval:allbefore merging to confirm the full prompt surface still passes together.
Notes:
pnpm eval:allwrites the canonical consolidated report topackages/integrations/manual-eval-report.json.- Single-suite evals write suite-specific reports such as
packages/integrations/conversation-context.manual-eval-report.json. - Failing suites also write suite-specific prompt-improvement briefs such as
packages/integrations/conversation-context.prompt-improvement.md. - Generated eval reports are ignored by git and should not be committed.
- Generated prompt-improvement briefs are also ignored by git and should not be committed.
- Live evals help judge prompt quality, but they do not replace deterministic tests and schema validation.
Atlas supports an explicit local Postgres workflow for integration tests on macOS with Homebrew postgresql@16.
Typical flow:
- Run
pnpm db:test:start - Create
apps/web/.env.test.localwithDATABASE_URL='postgresql://$USER@localhost:5432/atlas_test' - Run
pnpm --filter @atlas/integration-tests test - Run
pnpm db:test:stopwhen you are done
Notes:
- These commands are convenience helpers for local integration testing, not part of normal app startup.
- The scripts expect Homebrew
postgresql@16and target the disposableatlas_testdatabase by default. pnpm db:test:resetis useful if you want a clean local database between manual test runs.
Copy .env.example into apps/web/.env.local for local development and provide real values through your deployment environment for hosted runs.
For local-only test credentials, prefer apps/web/.env.test.local, which is gitignored and loaded by the Next app and integration test runner.
DATABASE_URL: Postgres connection stringAPP_BASE_URL: canonical deployed app origin used when generating Google Calendar connect linksOPENAI_API_KEY: OpenAI API keyTELEGRAM_BOT_TOKEN: Telegram bot tokenTELEGRAM_WEBHOOK_SECRET: shared secret used to verify Telegram webhook deliveriesTELEGRAM_ALLOWED_USER_IDS: comma-separated Telegram user id allowlist for private-beta access; required in all environmentsGOOGLE_CLIENT_ID: Google OAuth client id for Calendar linkingGOOGLE_CLIENT_SECRET: Google OAuth client secret for Calendar linkingGOOGLE_OAUTH_REDIRECT_URI: OAuth callback URL for Google Calendar linkingGOOGLE_LINK_TOKEN_SECRET: secret used only for one-time Telegram-to-browser Google link handoff tokensGOOGLE_CALENDAR_TOKEN_ENCRYPTION_KEY: base64-encoded 32-byte key used to encrypt stored Google access and refresh tokensCRON_SECRET: bearer token required for protected cron routes such as Google Calendar reconciliation and follow-up dispatch
To register the production Telegram webhook once those values are set, also export ATLAS_WEBHOOK_URL as the full deployed route URL and run pnpm telegram:webhook:set.
For hosted rollout steps, use docs/workflows/production-deploy-checklist.md as the main production deploy runbook and docs/workflows/vercel-telegram-webhook.md for the narrower webhook-only setup flow.
Production schema changes are not applied from local laptops. Merge to main, let the GitHub Actions migration workflow apply packages/db/drizzle/ against the production database, and only release after that workflow succeeds.
Atlas no longer exposes public planner/debug mutation routes. The intended externally reachable surfaces are:
POST /api/telegram/webhookGET /google-calendar/connectGET /api/google-calendar/oauth/startGET /api/google-calendar/oauth/callback- protected cron routes that require
Authorization: Bearer $CRON_SECRET
The production deployment serves protected cron routes from Vercel, but GitHub Actions owns the schedules:
- send-followups.yml calls
POST /api/cron/send-followupsevery 15 minutes - reconcile-google-calendar.yml calls
POST /api/cron/reconcile-google-calendarevery 30 minutes
Both workflows use the APP_BASE_URL and CRON_SECRET repository secrets.
This repo is designed for human-plus-agent collaboration.
- Keep route handlers thin and move product logic into packages.
- Prefer extending
packages/coreor a repository method over route-local logic. - Every bug fix should add a regression test near the affected behavior.
- Update
docs/current-work.mdwhen priorities or handoff context changes. - Capture architectural changes in
docs/decisions/.
Atlas includes repo-specific Codex skills under skills/. These are versioned with the repo so they can evolve with Atlas architecture, workflow rules, and testing expectations rather than living as global defaults.
Current skills:
atlas-feature-deliveryatlas-planning-changeatlas-webhook-and-conversationatlas-schema-and-migrationatlas-openai-contracts-and-evalsatlas-google-calendar-flowatlas-reviewer
Use these when working inside Atlas and the task matches the skill name. Keep the repo copy as the source of truth.
- The current messaging webhook receives a freeform message.
- If the sender is allowlisted but does not have an active Google Calendar connection, the app replies with a signed Google connect link and stops before ingress persistence.
- Linked users enter the normal flow: the app persists the inbox item, loads relevant task, schedule, and user-profile context, and sends a structured planning request through the OpenAI Responses API.
- Validated planning actions create or update tasks and schedule blocks through the repository layer.
- The messaging bot sends reminders tied to scheduled tasks.