p1_lld.html, p2_lld.html, … will use the same five sections.
By end of P0, OmniTutor runs on its own infrastructure with zero shared state against any other agent (Canvas A · Physolympiad · DhyanHQ · DreamBook). New repo · new database · new service · new bucket · new auth realm · new deploy pipeline. No code in this phase touches the user-facing product yet — that begins at P1.
omnitutor-canvas-a.service on port 8780/home/ubuntu/omnitutor/canvas-a/ (fork of canvas-a)lessons/ · data/ · canvas-audio/ point to Canvas AOmniTutor / Omni2026$$)scp · no CIomnitutor.service on port 8790/home/ubuntu/omnitutor-app/ (own git repo)data/lessons/ · data/audio/ · data/cache/omnitutor Postgres DB · own user · own roleomnitutor-assets bucket · own CloudFrontSequential. Each step verifies before moving to the next.
github.com/mukesh-bansal/omnitutor · independent of canvas-a · MIT-private · seed README.md + .gitignore + schema_v0.sqlomnitutor, role omnitutor_app with restricted permissions · run schema_v0.sqlomnitutor-assets in us-east-1 · CloudFront distribution · own CORS allowing omnitutor.aiGET /healthz + POST /v1/session · wire to Postgres · no business logic yetomnitutor.service on port 8790 · EnvironmentFile=/etc/omnitutor/env with API keysomnitutor.ai → localhost:8790 · TLS via Let's Encrypt · keep /_design/ static carve-outmain · SSH into devbox · git pull + systemctl restart omnitutor/_design/*.html static files under the new server · ensure no Canvas A code path is involvedomnitutor-canvas-a.service on port 8780 · break the symlinks · verify Canvas A still works at canvasa.physolympiad.comgrep -ri "canvas-a\|physolympiad\|dreambook" omnitutor/ in the new repo returns 0 hits in source codepytest (unit) · playwright (E2E) · k6 (load). Sample test in each runs green./omnitutor/prod/* holds Anthropic + ElevenLabs keys. Devbox IAM role grants ssm:GetParametersByPath. GitHub Actions deploy step pulls + writes /etc/omnitutor/env.model_runs · raises OT_OVER_QUOTA flag at $50 · service reads flag before every plan/stream call.pg_dump omnitutor → s3://omnitutor-assets/backups/YYYY-MM-DD.sql.gz · 30-day retention via S3 lifecycle policy.What we run to prove the cutover landed.
curl https://omnitutor.ai/v1/healthz returns {ok:true, ts}POST /v1/session creates a row in users + sessions · returns session cookieschema_v0.sql in <60s · all 8 tables present · constraints intactmain · GitHub Action runs · service restarts · healthcheck still greencanvasa.physolympiad.com · its own healthcheck greengrep -ri returns 0 hits for cross-agent paths in new repoPOST /v1/plan from one IP within an hour returns code:"over_quota"POST /v1/plan returns code:"refused" · refusal logged as safety.refused eventOT_OVER_QUOTA=1 · next POST /v1/plan returns over_quota immediately, no model callpg_dump file in S3 · restore into a scratch DB · all tables intactLast-Event-ID · stream resumes without losing beatsP0 ships when every line below is true. P1 cannot start until then.
schema_v0.sql committed in the new omnitutor repo · runs cleanly against an empty Postgresschema_v0.sql in <60sv1.0-p0-shipped