A personal portfolio and platform site built from scratch on AWS, with AI coding agents as
the primary development tool throughout. Claude Code (Γ2), ChatGPT Codex, and Google Gemini
take shifts on the same production server β alternating to keep momentum when one hits a usage cap.
A personal portfolio and professional showcase site, built from scratch on AWS infrastructure
with AI coding agents as the primary development tool throughout. It started as a travel map
and has grown into a multi-page platform spanning GPS tracking, job hunting, AI tooling,
hardware, gaming, smart home, and more.
The backend is a single Flask app (22,000+ lines)
behind Caddy, backed by SQLite. Auth uses HttpOnly session cookies (bcrypt, 30-day expiry) with
three user roles. All AI calls route through OpenRouter; the server also hosts an Anthropic
Claude CLI, a ChatGPT Codex CLI, and a Moveworks natural-language agent.
Across all agents, β tokens processed and β commits made building this site.
See the
Features
What was built
AI & Intelligence
Intelligent features
Multi-model chatbot β floating assistant on every page; streaming SSE, 7+ OpenRouter models, RAG knowledge base (PDF/DOCX/TXT ingestion)
Document Intelligence (IDP) β extracts structured data from PDFs and images via vision models; confidence scores, templates, JSON/CSV export
Moveworks agent β plain-English queries across 6 integrations: server health, access logs, job hunt data, GitHub, notifications, Google Calendar
Granola meeting backup β daily MCP sync of meeting transcripts and speaker-parsed summaries to SQLite
Daily AI content β fresh Claude-generated piece each morning (fact series, thought experiments, etymology), cached until Sydney midnight
Job Hunt
ATS & career tools
Full pipeline tracker β kanban board + sortable table; real company logos, drag-and-drop status, Sydney timestamps, per-listing refresh
AI daily shortlist β 5 Codex-generated role suggestions each morning; URL-validated and archive-probed before save, expired listings detected
Salary intelligence β stated salary (from listing text) separated from AI-estimated market rates via Glassdoor/Codex; two distinct columns
Interview hub β cover letters, STAR stories, application questions, plus tax comparison and cost-of-living analysis (AU vs SG)
Company tracker β Codex-suggested and manual target companies with careers URLs, investigation notes, and last-checked dates
Travel & GPS
Location & maps
Interactive world map β D3 Natural Earth, 4-tier visit frequency, city dot markers, hover tooltips; Claude-generated country fun facts (cached)
Actions API + Swagger UI β per-user tokens, 8 auth methods, interactive curl examples; machine-readable access to site data
Site-wide search β SQLite FTS5, Cmd+K overlay, highlighted excerpts, auto-reindex on every git commit
Status & monitoring β 90-day uptime, GA4 analytics, AI services token tracking, automated pen-test reports, Page Health Monitor
Hardware
ESP32 firmware projects
XiaoZhi AI voice assistant β custom Bitcraft ESP32-S3 firmware with OTA updates, streaming audio, sync video playback (audio-clocked), live telemetry dashboard
Watchy smartwatch β Chronos firmware OTA server for SQFMI Watchy v3 ESP32-S3; WiFi credentials generator; parked pending first compile
Steam gaming β live Steam Web API data, server-side proxied and cached
Cryptocurrency miner β XMRig/Kryptex worker with live hashrate charts, admin Start/Stop, throttle controls
Smart Home Radar β Tuya Zigbee device catalog with per-user wishlist and dismiss states
Google integrations β Calendar (read/write via OAuth) and Photos (day-based browsing via OAuth)
Gym timetable β live class schedule scraper with booking links and timetable filters
Multi-agent Workflow
How the site is built
Four agents in shifts β Claude Code (Γ2 accounts), Codex CLI, Gemini CLI each take shifts when others hit usage limits; all share the same server, repo, and deploy flow
Attribution tracking β every commit carries a Co-Authored-By trailer; the AI Agents tab shows a live Claude/Codex/Gemini breakdown by page area
Handover system β each agent writes structured handover notes and memory files; any agent can pick up where the last left off
CI/CD β GitHub Actions auto-deploys on push; post-commit search re-index; Flask restarts via systemd on every deploy
Technology
The stack
Technologies were chosen for being lightweight, proven, and appropriate to the scale β
no unnecessary frameworks, no over-engineering.
Mapping
D3.js v7 + TopoJSON
Interactive SVG world map with zoom, pan, hover tooltips, and dynamic country colouring
Backend API
Python + Flask
Single-file REST API handling auth, data, and AI integrations; runs as a systemd service on port 5001
Authentication
bcrypt + HttpOnly cookies
Passwords hashed with bcrypt (12 rounds); sessions use HttpOnly cookies (ds_session, 30-day expiry). Three roles: admin, readonly_admin, standard.
Zero-config TLS β Caddy obtains and renews certificates automatically with no manual intervention
Frontend
Vanilla HTML/CSS/JS
No frontend framework β intentionally minimal, fast, and maintainable. Strict CSP with no inline scripts.
Infrastructure
Hosted on AWS
The site runs on a single AWS Lightsail instance, consolidated alongside a Foundry VTT
game server. The migration from EC2 was planned and executed entirely by Claude.
PlatformAWS Lightsail β Ubuntu 22.04 LTS
Web serverCaddy v2 β static files + reverse proxy to Flask on port 5001
TLS / HTTPSLet's Encrypt via Caddy β zero-config, auto-renewing certificates
API processsystemd service β Flask starts on boot, restarts on failure
Data storageSQLite β users, sessions, permissions, job hunt, starboard, OwnTracks in users.db; monitor in monitor.db; search index in search.db
Securityfail2ban β SSH brute-force protection; key-auth only, no password login
CI/CDGitHub Actions β every push to main SSHes in, runs git pull, and restarts the Flask service via a dedicated ED25519 deploy key
Domainwww.danscodellaro.com β DNS pointed to Lightsail static IP
History
Full feature changelog
Every feature added to the site, in the order it was built. For a grouped current-state summary, see the tab.
Phase 1 β March 2026: Foundation
Interactive world map β D3 Natural Earth projection with drag-to-pan and scroll-to-zoom
Visit frequency colour coding β four tiers from "visited once" through "5+ visits", giving an honest picture of familiarity with each country
City & region markers β purple dot markers for specific cities visited within countries, with hover tooltips
Live stats header β countries, cities, continents and percentage progress toward 195 countries, computed dynamically from data
Country rules β a displayed standard for what qualifies as a visited country (overnight stay or 24+ hours)
Password-protected admin panel β full CRUD interface to add/remove countries and cities, set visit tiers, and save changes
JWT authentication β the admin API is secured with signed tokens (30-hour expiry). Legacy JWT still accepted for backward compatibility.
REST API β clean separation between data and presentation; map fetches live data on every load
Responsive & resilient map β re-renders on window resize; graceful fallback if the API is unreachable
Social profile links β LinkedIn, GitHub, and Salesforce Trailhead linked from the homepage
"Chat with Dan" RAG chatbot β floating AI assistant powered by the Claude API, grounded in a curated knowledge base (website content, LinkedIn, GitHub, uploaded documents)
Knowledge base document ingestion β server-side folder auto-parses .txt, .pdf, and .docx files and feeds them into the chatbot context
Country fun facts β clicking a visited country generates three surprising facts via Claude, permanently cached server-side
Daily AI content page β /random generates a fresh piece each day (fact series, thought experiment, etymology, etc.) via Claude, cached until Sydney midnight
Ideas log β a running backlog of planned features with full CRUD API and a password-protected browser interface
Shared admin session β single password login persists across all admin-capable pages via localStorage
Admin map improvements β every country clickable in admin mode; new cities geocoded via Nominatim on save
Private podcast hosting β audio files served via secret-URL RSS feeds; supports multiple named channels, each with its own feed URL; browser interface with drag-drop upload, XHR progress, channel management, and file deletion
Steam gaming page β live data from the Steam Web API showing top games by playtime, total library stats, and achievement counts; server-side cached and proxied via Flask
Server migration β entire site migrated from AWS EC2 (Nginx, Amazon Linux) to AWS Lightsail (Caddy, Ubuntu), consolidated with an existing Foundry VTT game server; DNS cutover, SSL provisioning, and systemd setup with zero downtime
Uptime monitoring & status page β live status page showing 90-day uptime history, powered by an internal heartbeat service and an external uptime monitor; response times and downtime events logged as colour-coded day blocks
Document Intelligence (IDP) β AI-powered document extraction tool reads PDFs, images, and Word docs to extract structured data with confidence scores; multiple vision models (Claude, GPT-4o, Gemini), shareable templates, sync/async API
GitHub integration & CI/CD β GitHub Actions workflow auto-deploys on every push to main via a dedicated SSH deploy key
Streaming chatbot responses β "Chat with Dan" now streams tokens live via Server-Sent Events with an animated cursor
MCP experiment β a local stdio MCP prototype was built and later removed after it proved heavier than necessary for same-process chatbot access
Claude API usage dashboard β the status page tracks chatbot token consumption per day with metric cards and an interactive D3 bar chart
Published work section β homepage features an embedded Salesforce video and two authored Salesforce blog articles as equal-width cards
Phase 2 β MarchβApril 2026: Scale
Personal VPN service β click-to-provision ephemeral EC2 t3.nano exit nodes across 7 AWS regions using Tailscale for the mesh; nodes auto-terminate after inactivity; cost tracked per-session; interactive D3 world map, live connection visualisation, Tailscale key management
Site-wide search β full-text search across all pages powered by SQLite FTS5; Cmd+K overlay with debounced as-you-type results, arrow-key navigation; auto-reindexes on every git commit via a post-commit hook
Google Analytics dashboard β GA4 Data API integration showing realtime active users, page views (today/7d/30d), top pages bar chart, and visitor countries; 5-minute server-side cache
Site-wide RAG chatbot β floating chat bubble on every page powered by a knowledge base of uploaded documents; all traffic via OpenRouter with a model picker (Gemini, Llama 4, DeepSeek, Mistral, Qwen3); admins can upload files or paste text via /knowledge.html
Full OpenRouter routing β all AI calls (chatbot, IDP, Doom AI commentary) now route exclusively through OpenRouter, consolidating billing and enabling model switching without code changes
GPS tracking & route visualisation β OwnTracks on iOS/Android posts coordinates via MQTT over TLS to Mosquitto; GPX tracks batch-processed to per-day GeoJSON; interactive Leaflet map at /travel/gps.html with collapsible sidebar, day-by-day timeline, per-person colour coding, Overview/Live/Narrative modes, date-range filter, D3 heatmap, and floating activity stats panel
Settings page β centralised /settings.html for per-user account preferences; a Python bulk-update script propagated the Settings nav link across all site pages preserving per-file indentation
OwnTracks user management β dedicated tab in the admin User Management panel; admins provision, reset, and revoke MQTT credentials per user; deactivating a user automatically revokes their MQTT account
Content Security Policy (Phase 2) β all inline scripts and event handlers extracted to external .js files; no unsafe-inline in script-src; inline handlers replaced with addEventListener and data-* delegation across all pages
Multi-model chatbot β the site chatbot now supports Claude CLI and Codex CLI as selectable backends in addition to OpenRouter models
Time-spent widget β this page shows a live estimate of total hours spent building the site, broken down by agent, derived from JSONL session logs; auto-refreshes every five minutes
Persistent Steam cache β Steam API data written to disk so the gaming page loads instantly after server restarts
Pre-baked VPN AMIs β a Python bake script pre-installs Tailscale + iptables on a temporary EC2, captures an AMI, and terminates the instance; launch instances now use a slim bootstrap, cutting expected boot time significantly
Jobhunt daily cron β job suggestions auto-generate at 06:00 each morning (Australia/Sydney time) via a cron-safe Flask app-context script; server timezone changed to Australia/Sydney
VPN global expansion β added 5 new regions (Canada Central, Ireland, Singapore, Sydney, US West) with pre-baked AMIs; interactive map now shows 7 clickable dots
Security hardening β SRI integrity hashes on CDN resources; _get_ip() fixed to use remote_addr to prevent X-Forwarded-For spoofing; burst rate limiting on login; SSRF block in job hunt URL archiver; archived HTML served as Content-Disposition: attachment to prevent stored XSS; fail2ban jail for MQTT port 8883; unauthenticated API endpoints audited
IDP page fully functional β discovered 11 functions that were referenced but never defined since the page's creation; the synchronous updateRunBtn() call during page init had been silently blocking all rendering; now fully implemented including confidence bars, JSON/CSV export, template saving with shareable links, and auto-detect fields
GPS travel wishlist β admin can add future destinations via the sidebar form with Nominatim geocoding; gold star markers on the map; stored in S3 with full CRUD API
Automated homepage thumbnails β replaced hand-crafted SVG card thumbnails with live Playwright screenshots of every page, captured daily at 03:00 via a headless Chromium service; Caddy thumbnail cache changed to max-age=3600, must-revalidate
Page Health Monitor β admin-only service at /status/monitor/ that takes full-page Playwright screenshots of every site page, sends each to the OpenRouter vision API (Gemini 2.0 Flash) for AI-powered visual review, and surfaces issues as a card-based dashboard; runs on-demand or automatically at 04:00 daily
Three-tier user roles β user auth extended to admin, readonly_admin, and standard roles; read-only admins can inspect admin pages but mutating requests are blocked server-side
Role migration repair β initial three-role rollout only derived role from the legacy is_admin flag; the live site used '*' page permissions as the real source of truth; migration now promotes any legacy '*'-permission account correctly
Jobhunt auth bootstrap fix β name collision between shared nav bundle and jobhunt script caused a SyntaxError before auth initialisation ran, producing a blank page; jobhunt-specific session state is now namespaced
User management redirect-loop fix β the real failure was a missing #nav-email element in the admin page JS, which threw and redirected back to login; the init path now guards that optional element
User-menu impersonation β impersonation now starts from User Management; admins can swap into another user account while the original session is preserved in a separate cookie; the shared nav exposes a global "Stop impersonating" action
Phase 3 β April 2026: Job Hunt & Feature Depth
Job Hunt ATS (initial) β private page at /jobhunt/ with a full kanban + table pipeline tracker, AI daily shortlist generation via Codex, per-opportunity editing, and an internal ideas roadmap
Android emulator β live Android 14 emulator on an on-demand EC2 t3.large with KVM acceleration; ffmpeg captures both virtual framebuffer (MJPEG) and PulseAudio (Opus) and streams to the browser; touch events and hardware buttons forwarded via adb shell input; custom AMI cuts cold-start to under 5 minutes
Automated pen-testing β weekly cron job runs nuclei against the live site; timestamped reports stored and surfaced at /status/security/ with pass/fail badges and expandable output; full HTTP security header suite added to Caddy
User management & full auth overhaul β replaced single shared admin password with SQLite users.db; bcrypt passwords; HttpOnly session cookie; Caddy forward-auth; Google OAuth; Resend invite emails; per-user page permissions; admin panel at /admin/users.html
Shortlist "Already applied" action β today's jobhunt shortlist includes an "Already applied" button that updates the persistent ATS status and removes the role from the shortlist in-place
Declined shortlist items disappear β shortlist state filter now suppresses roles whose ATS opportunity has been marked not_interested
Dedicated CSP security subtab β the security page treats CSP as a first-class scan artifact; a new daily audit script writes csp.json after scanning the current CSP header, recent browser report evidence, and frontend source matches
Status page visibility fix β the main container carried the shared hidden class from initial page load; the load completion path now explicitly removes it before revealing the dashboard
Jobhunt closed stage and split salary columns β distinct closed status added across backend, filter dropdown, and kanban board; compensation separated into "Stated Salary" (from listing text) and "AI Estimated Salary" (Glassdoor/Codex market estimate)
Per-listing jobhunt refresh β each ATS row has a refresh action that re-runs the machine-owned parts of the pipeline (metadata, archive, salary estimation, match rationale) while leaving human-managed fields untouched
Jobhunt multi-picklist filters β Status and Source filters are now checkbox-based multi-picklists; default status selection hides declined and closed outcomes
Jobhunt Sydney timestamps and ATS badges β timestamps stored and rendered as explicit Australia/Sydney ISO datetimes; company cells render a CSP-safe generated badge; location cells show SVG flag images
Jobhunt real company logos β ATS company column fetches and caches real logo images server-side from archived job HTML, serving them from the site's own origin
Jobhunt shortlist now requires direct role URLs β search-result pages (Google, LinkedIn, Seek, etc.) are rejected; both generation-time validation and read-time filtering enforce direct job or application page URLs
Workday shortlist URL repair β fixed a Workday URL builder that dropped the board segment from relative /job/... paths, producing 404s for live listings
Jobhunt shortlist URL verification β every generated role URL is now fetched by the backend before save; only suggestions whose pages archive successfully are kept; the generation prompt explicitly tells Codex that unverifiable listings will be rejected
Jobhunt action bindings restored β the page had lost its boot-time event wiring for static controls; buttons like "Generate today's five" and "Refresh today" now rebind on load
Jobhunt generation reports real outcomes β the shortlist generator returns proposed, verified, saved, and rejected counts; the frontend status line rotates through live generation phases before finishing with a truthful summary
Jobhunt ATS delete action β dedicated Delete action in both table and kanban views; deleting an opportunity also clears any matching entry from today's shortlist
Kryptex XMR setup β the cryptocurrency page was converted from a generic plan into a Kryptex-specific implementation; new /api/crypto/stats endpoint probes the local XMRig service; admin Start/Stop controls manage xmrig.service via systemd
Cryptocurrency live integration β XMRig installed and mining against Kryptex via xmr.kryptex.network:8029; stats endpoint handles the real XMRig summary payload shape; Start/Stop polls through the RandomX warm-up
Cryptocurrency charts and condensed layout β the page was compressed from a long-form plan into an operator dashboard; charts show hashrate, accepted shares, and service state over the last 24 hours
Cryptocurrency throttle reduced β XMRig CPU thread hint and systemd hard cap reduced from 50% to 25% to be gentler on the server
Monitor evidence surfaced β Page Health Monitor now exposes the actual affected URL and captured AI evidence for each open issue; issue cards show the failing page URL and extracted findings
Smart Home Radar β /smarthome/ curates Tuya Zigbee device recommendations with compatibility evidence links; per-user wishlist and not_interested selections stored in users.db
Smart Home pricing β buy links on /smarthome/ now show indicative Australia pricing ranges next to Amazon AU and AliExpress searches
Jobhunt company tracker β new "Companies to investigate" flow persists Codex suggestions into a dedicated company table; editable last-checked dates and notes; manual add supported; Codex auto-fills careers URL, domain, and rationale; column sorting; hidden-rows filter
Tokaido planning page β public travel sub-page at /travel/tokaido-2-electric-boogaloo/; includes the actual Tokyo-to-Kyoto route from the uploaded itinerary CSV, day-by-day stage sequence, Google Maps vs actual distances, revised buffered itinerary, and per-stage GPS coordinates
Breadcrumb navigation service β every page carries a two- or three-level breadcrumb rail generated by scripts/add_crumbs.py; each crumb has a dropdown listing siblings at the same depth
AI attribution visualisation β this page shows a live graphic of which AI built which part of the site, sourced from Co-Authored-By git commit trailers; site-wide summary bar plus a per-card grid with colour-coded split bars; served from a 1-hour server-side cache
AGENTS.md β Codex system instructions β a repo-root AGENTS.md is auto-loaded by the Codex CLI as its system prompt; encodes git hygiene, CSP safety, auth patterns, breadcrumb conventions, and salary column rules
Anthropic application questions β admin-only page at /jobhunt/application-questions/ storing drafted answers for the Anthropic application form
Jobhunt salary column rules enforced β "Salary" renamed to "Stated Salary" (listing-only) and "Estimated" renamed to "AI Estimated Salary" (AI market estimates); rules encoded in server.py, AGENTS.md, and applied retroactively
Jobhunt expired listing detection β Greenhouse-style soft-redirects now detected via final-URL pattern matching and page title blocklist; an expired badge shown on manually-tagged ATS rows
Jobhunt paused roles hidden by default β daily shortlist suppresses paused, rejected, and archived statuses; tracker status filter no longer includes "On hold" in its default selection
Page Health Monitor false-positive suppression β the monitor AI prompt now includes page-specific hints to prevent recurring false positives; previously flagged false-positive issues resolved with notes in monitor.db
Admin cross-user jobhunt management β the jobhunt page supports an admin-only "manage pipeline for" switcher; all jobhunt routes resolve a target user safely, letting admins view and edit another user's full pipeline
Jobhunt companies-to-investigate panel β today's shortlist is now split into two columns: left shows today's five AI-suggested roles; right shows a Codex-generated list of companies worth investigating
Jobhunt switcher removed β the temporary admin "manage pipeline for" control removed from the jobhunt page; user switching now lives only in User Management
Phase 4 β Late April 2026: Integrations & Hardware
Salesforce OAuth2 integration β OAuth2 with PKCE flow connects the site to a Salesforce org; the refresh token is stored server-side for authenticated API queries; the /salesforce page manages the connection state
Actions API and Swagger UI β a per-user token system provides machine-readable access to site data; the Swagger UI at /api/ exposes all endpoints with interactive curl examples and 8 auth methods
Moveworks natural-language agent β a plain-English query interface at /moveworks backed by 6 capability integrations: server health, site access logs, job hunt pipeline data, GitHub activity (repos, issues, commits), notification dispatch, and Google Calendar events
Google Calendar integration β OAuth2 connection; upcoming events are readable and writable via the Moveworks agent and a dedicated /google/calendar page
Google Photos integration β OAuth2-gated page at /googlephotos for browsing and curating personal photos by date
GitHub integration page β dedicated page at /github for querying repositories, issues, and commits; powers the GitHub capability in the Moveworks agent
Notifications system β admin-managed notification type and delivery channel registry with live delivery stats at /notifications
Gymrat timetable β live gym class schedule at /gymrat pulling the local gym's timetable with booking links and time filters
Job Hunt: Tax Comparison β financial tool at /jobhunt/taxcomparison/ comparing after-tax take-home across AU and SG roles; full tax breakdowns, OTE splits, FX conversion, and bonus modelling
Job Hunt: Cost of Living β comparison tool at /jobhunt/costofliving/ with monthly living costs across Australian cities and Singapore; housing, food, transport, utilities, and quality-of-life breakdowns
Granola meeting notes backup β daily background sync at /granola pulls meeting transcripts and summaries from the Granola MCP server into SQLite; speaker blocks parsed and stored; page supports both REST API and live MCP source views
XiaoZhi video sync architecture β the ESP32 firmware moved from a pushed batch queue to a sync_v1 model inspired by atomic14/esp32-tv; audio is the master clock; video frames fetched ahead of the audio position via server-side batch endpoints; the LVGL image path replaced the direct SPI present path to eliminate display tearing on the Bitcraft board
Watchy smartwatch page and OTA server β public documentation page at /esp32/watchy/ covering the SQFMI Watchy v3 ESP32-S3 hardware and Chronos firmware ecosystem; OTA server endpoint returns firmware JSON for device update checks; WiFi credentials generator included; project parked pending first compile
Four-agent development workflow β the development model now runs four agents: two Claude Code accounts (for session/quota independence), OpenAI Codex CLI, and Google Gemini CLI; each uses a distinct Co-Authored-By commit trailer; the AI Agents tab tracks their commit attribution live
β± Time Building This Site
β
Total hours est.
β
Claude Code hrs
β active days
β
Codex CLI hrs
β active days
β
Calendar days
β
How this is calculated βΈ
Data sources
Claude Code β reads JSONL conversation transcripts from ~/.claude/projects/ on the server. Any calendar day with at least one AI response counts as an active day. Days before the JSONL logs started are covered by git commit history instead.
Codex CLI β reads session logs from ~/.codex/sessions/. Any day with at least one turn is counted.
Git history β anchors the project start date (first commit: March 9 2026) and fills in active days before JSONL logging began.
Estimation method
Active days Γ assumed average session length per tool:
Claude Code: 3 h/day β sessions typically involve longer back-and-forth, planning, and iterative debugging.
Codex CLI: 1.5 h/day β shorter focused bursts, picking up where Claude left off when rate limits hit.
Calendar span runs from the first git commit to today. These are intentionally rough estimates. Data refreshes live from the server every 5 minutes.
Claude Code Usageβ
β
AI responses
β
Output tokens
β
Input tokens
β
Cache reads
Output tokens per day
Loadingβ¦
Claude.ai Plan Usageβ
Current session (5 hr window)β
Weekly limit (all models)β
Extra usage spend (monthly)β
β Data may be stale β polling script may need a fresh session cookie
βΈ Update session cookie
To get your sessionKey:
1. Open claude.ai in Chrome while logged in
2. DevTools (F12) β Application tab β Cookies β https://claude.ai
3. Find the row named sessionKey β double-click its Value β copy
Codex CLI Usageβ
β
Turns
β
Output tokens
β
Input tokens
β
Cached input
Output tokens per day
Loadingβ¦
ChatGPT Codex Plan Usageβ
Primary windowβ
Secondary windowβ
Code review windowβ
β Data may be stale β cookie or device ID may need refreshing
βΈ Update ChatGPT session details
From a request to backend-api/wham/usage on
chatgpt.com/codex/settings/usage, copy:
1. the full Cookie request header
2. the full Authorization header
3. the oai-device-id header
Every commit is tagged Co-Authored-By β this graphic is generated live from git history. Historical commits without the tag are attributed to Claude (accurate: Codex and Gemini only joined recently).
βcommits
Claude βCodex βGemini β
Loading attribution dataβ¦
Why Four
Why four agents are in the loop
The boring answer is the real answer: to dodge usage ceilings without moving to a more expensive
subscription tier. When one tool is rate-limited or at a context boundary, another picks up and
keeps momentum going.
The four agents are:
Claude Code (account 1) β carried most of the original build before usage limits were hit. Now less active but still available. Commits tagged Co-Authored-By: Claude Sonnet 4.6.
Claude Code (account 2) β the current primary agent. Handles complex multi-file work, planning, and iterative debugging. Same trailer as account 1 β both appear as Claude in the attribution graph.
OpenAI Codex CLI β CLI-based agent, typically driven from PuTTY directly on the server. Handles focused implementation tasks when Claude is capped. Commits tagged Co-Authored-By: OpenAI Codex.
Google Gemini CLI β occasional shift agent with its own memory and rules file. Steps in when both Claude accounts are at their limits. Commits tagged Co-Authored-By: Google Gemini.
All four read the same handover file, write structured memory files after each session, and commit to the same branch. The operator surface differs (Claude Desktop over SSH, PuTTY CLI, Gemini CLI) but the repo, deploy process, and architecture stay coherent across shifts.
Workflow
How the shift handoff works
Each agent reads the shared handover file and its own memory files at the start of a session,
checks git status, and picks up where the previous agent left off. After significant work it
updates the handover notes and its own memory index for the next session.
In practice the four tools are not competing architectures. They are interchangeable implementation
hands on the same codebase. The important thing is that the repo, deployment process, and site
behaviour stay coherent even as the active assistant changes mid-feature.
On AI-assisted development: Using multiple AI agents is a force multiplier, not a shortcut.
It doesn't replace product thinking, architectural judgement, or knowing what you're trying to build β
it accelerates the translation of clear requirements into working software. Every decision on this site
was made deliberately; the agents handled the typing, and alternating between tools means there's rarely a dead stop.