Live progress + your action queue. Page auto-refreshes every 2 minutes. Bookmark me.
my.aijetlabs.com/. /cockpit/ 308→/jet-reach/. /login 302→Google OAuth. Six legacy apps renamed (habits→jet-habits, medical→jet-ehr, notes→jet-notes, prefs→jet-prefs, receipts→jet-receipts, uopeople→jet-uni); old paths 301 to new ones. jet-mail v0.1.0 + jet-usa/jet-passports/jet-pages placeholder apps live.
Empty for now. Optional sudo apt installs (tesseract-ocr / libzbar0 / libreoffice) + real-browser OAuth e2e click-through tracked under "What's queued".
nginx 308 redirect /cockpit/ → /jet-reach/ deployed. Subroutes (/cockpit/inbox, /cockpit/campaigns) still proxy through the prefix block; cockpit subroute migration plan written at jet-playbook/plans/cockpit-subroute-migration.md (171 routes categorized, 5 rounds, 10-14 days estimated).
labs_op cookie across all jet-* apps
done 2026-05-08
Every jet-* app's login_required now accepts the shared labs_op cookie set by /admin/ Google OAuth (single sign-on across the family). Each app's login.html surfaces a primary "Login with Google" button; the operator-token form moved into a collapsed "Operator access (advanced)" fallback. /auth/google?next=<path> honored end-to-end so users land back on the page they started from.
habits → jet-habits, medical → jet-ehr, notes → jet-notes, prefs → jet-prefs, receipts → jet-receipts, uopeople → jet-uni. Old paths 301 to new ones (bookmarks survive). GitHub repos renamed via gh repo rename for the 4 standalone (medical-tracker, preferences-tracker, receipt-tracker, uopeople). Local folders + remote URLs updated. DEPRECATED-PATH.md per renamed dir explains the change.
Tools / Health & Habits / Finance / Comms / Data / Planning / System. Live healthz dot per card. Renamed apps show "was: name" badge. Planning cards link to GitHub with planning badge. cockpit shown under System with deprecated badge. 22 cards total.
New private repo github.com/jeremytrindade/jet-mail. Live at my.aijetlabs.com/jet-mail/ (port 8111). Skeleton ships dashboard + inbox placeholder + compose with 5 academic templates (assignment question, late-submission request, clarification, peer-assessment follow-up, personal intro) + UoPeople tab. v2 wires IMAP / Gmail OAuth + migrates cockpit /inbox/* + adds SMTP send (tracked in jet-mail/ISSUES.md #1-#3).
Each repo previously held only research docs (PRD, PROGRESS, RESEARCH). Now each has a minimal Flask placeholder at /jet-usa/, /jet-passports/, /jet-pages/ rendering the planning lede + key links + PROGRESS.md inline. Auth via shared labs_op cookie. Standard deploy/<name>.service + deploy/nginx.conf. Ports 8112 / 8113 / 8114.
admin hub at /admin/ with Google OAuth, master-only, 14-card grid (admin, jet-reach, jet-trash, jet-fit, jet-scan, jet-ocr, jet-pdf, jet-cards, jet-book, jet-form, jet-clip, jet-meet, jet-ask-local, plus planning links to jet-usa/jet-passports/jet-pages). Live healthz dots on each card via JS fetch.
Phase 0 auth: shared/auth_db.py users + permissions, shared/oauth.py Google OAuth blueprint, OperatorAuth extended with allow_guests=True for per-subapp delegation. Master via OAuth lands on /admin/; guest lands on pending.html. Five bugs fixed in cascade (placeholder oauth.py never implemented; admin port 8087 collided with receipts → moved to 8089; authlib OAuth needs app at init; LABS_OPERATOR_TOKEN was in trindade_ask.env not cockpit.env; redirect_uri came back http → forced HTTPS).
Phases 1-11: 11 new private repos under jeremytrindade/ (jet-ask-local, jet-trash, jet-fit, jet-scan, jet-ocr, jet-pdf, jet-cards, jet-book, jet-form, jet-clip, jet-meet) all deployed under /home/jeremytrindade/labs/apps/<repo>/. labs/deploy/update.sh auto-detects each subapp via the apps/* walk. Final HTTP self-check: every healthz=200, every root=302 to login.
Fresh repo at github.com/jeremytrindade/jet-reach (private). Live at my.aijetlabs.com/jet-reach/. Three workflows: track (prospects CRUD), compose (5 templates pre-loaded from jet-pages/OUTREACH.md, auto-fills [Name]+[Business Name], copy-to-clipboard), log (campaigns timeline with response logging). Pricing tiers from jet-pages/PRICING.md visible on dashboard + composer. Auth via shared labs_op cookie + optional guest permission.
/login shortcut live: 302 → Google OAuth
done 2026-05-08
Exact-match location = /login in admin's nginx fragment. The URL the operator can memorise — my.aijetlabs.com/login — goes straight to Google consent without a Flask round-trip. trindade_ask's stale /login alias removed to avoid duplicate-location nginx error.
Roadmap repos for USA immigration, passport maximizer, and selling jet-pages landing pages to local businesses. All private under jeremytrindade/. Linked from the admin hub as “planning” cards.
180 references updated across 19 live-doc files in jet-aij + jet-playbook + jet-sync + aijetlabs-infra. Historical journal entries under claude/entries/ intentionally untouched (SPEC §5.3, do not churn time-frozen narratives).
Memory-external guide so deploys from a phone (Termux + Tailscale) are zero-friction. README + cheatsheet of one-liners. Born from a real session where the desktop SSH key wasn't authorised, briefly blocking deploys.
Phase 1 (DNS): Cloudflare CNAME my.aijetlabs.com -> e7534561-a1a2-446a-9459-440204789e05.cfargotunnel.com (Proxied) live. Phase 1 ran in a Cowork-session earlier this evening.
Phase 2 (cloudflared + nginx): ingress rule for my.aijetlabs.com added to /etc/cloudflared/config.yml on RPi (above the existing labs.jeremytrindade.com hostname); cloudflared restarted; nginx server_name updated to labs.jeremytrindade.com my.aijetlabs.com; nginx reloaded. SSL handled automatically by Cloudflare universal cert via the tunnel. Smoke test from PC external: HTTP/1.1 200 on root, HTTP/1.1 302 on /trindade-ask/ (correct auth redirect).
Master plan at jet-playbook/plans/aijetlabs-architecture-PLAN.md covers: 8 target repos, OAuth + per-user-app ACL with master account, my-access app for permissions + per-user landing, per-app SQLite, systemd-per-app, no Docker on RPi, no VMs on 4GB.
Foundational repo at github.com/jeremytrindade/aijetlabs-infra (private). Holds parent nginx config (placeholder), deploy orchestration script (placeholder), backup strategy (decided: Cloudflare R2 + USB SSD, ~$2/mo), recovery runbook, the canonical STATUS dashboard.
Renamed from private versioning. Sanitized sensitive data (real GCP IP, deprecated email, GCP project ID), squashed git history before going public, swept references across 6 caller repos. Live at github.com/jeremytrindade/jet-versions.
/cockpit/ root now 308→/jet-reach/ after the pending RPi deploy, but subroutes (/cockpit/inbox, /cockpit/campaigns, etc.) still hit the legacy monolith. Each gets its own jet-* repo or migration into an existing one, then cockpit service is fully retired.
allow_guests=True
~30 min
Currently only /jet-ask/ accepts guest sessions with permission. When a guest needs access to /jet-fit/ or another subapp, that subapp's OperatorAuth(...) line gets subapp_name + allow_guests=True. Master continues to access everything via the shared labs_op cookie.
After 2-4 weeks of parallel running with both URLs serving. Then labs.jeremytrindade.com permanently redirects to my.aijetlabs.com.
Public OSS tool extracting generic patterns from aijetlabs-infra. Gated until aijetlabs-infra runs in production for 2+ weeks AND the cockpit retirement is complete. Sister to HashiCorp's open-source-Terraform / private-customer-modules pattern.
jet-ocr / jet-scan / jet-pdf gracefully degrade without these system packages. Install needs interactive sudo (NOT in NOPASSWD): sudo apt install -y tesseract-ocr tesseract-ocr-por libzbar0 libreoffice && cd ~/labs/apps/jet-scan && .venv/bin/pip install pyzbar Pillow && sudo systemctl restart jet-ocr jet-scan jet-pdf.
Code paths verified end-to-end via curl. Final manual: incognito → my.aijetlabs.com/login → sign in as jeremytrindade@gmail.com → expect to land on /admin/ hub. From another incognito with a non-master Gmail → expect pending.html. Grant that user jet-ask permission via /admin/users; sign in again as guest, confirm /jet-ask/ opens.
Resolved by the cutover itself: Cloudflare universal SSL handles cert for my.aijetlabs.com automatically via the tunnel. No certbot, no Let's Encrypt needed. Cert renewal is Cloudflare's responsibility.
Resolved as v2.1.0.0, PHASE 2 Sunset + GEN 1 RPi era. Instead of bumping cleanly to v1.4.0.0 (which would have extended the labs PHASE-1 timeline past its actual lifecycle reality) or merely documenting the deviation, the missed substrate change was rolled into the PHASE 1 -> 2 transition. PHASE bump zeroes everything; GEN immediately bumped to 1 because the substrate of this Sunset era is the RPi self-hosted server, the first generation of the sunset era. Documented in jet-versions/HISTORY.md entry dated 2026-05-07.
Google primary. GitHub queued. Microsoft and Apple Sign In nice-to-haves. Add when a real user requests one.
Static HTML at jeremytrindade.com/labsmigration/. Auto-refreshes every 2 minutes. Updated by hand (or by an AI session running aijmaj) whenever a deliverable ships or a decision lands. Public URL so you can check it from your phone without logging in to anything.
Source of truth for the architecture: jet-playbook/plans/aijetlabs-architecture-PLAN.md (private). Source of truth for live infra state: aijetlabs-infra/STATUS.html (private). This public page is the phone-friendly mirror.