This project was created in a single sitting using the Ralph Wiggum Loop, an agentic development workflow designed to keep implementation tightly scoped, sequential, and context-isolated.
The process started with brainstorming and the creation of a detailed design specification containing the full functional scope of the project. That specification was then split into implementation layers, each one describing a concrete stage of the system to be built.
The repository also included:
- A structured
AGENTS.mdfile defining the agent workflow and execution rules. - A Create skill, responsible for analyzing each implementation layer and producing atomic development tasks.
- An Execute skill, responsible for implementing those tasks sequentially and validating the resulting code.
The workflow was executed using Codex CLI, with ** GPT-5.5 High** for task creation, repository analysis, and specification analysis.
Code implementation was executed using ** GPT-5.5 Medium**, using the tasks generated by the Create skill as the execution input.
This split kept the higher-reasoning model focused on planning, validation, and decomposition, while using a separate implementation pass for writing and refining the actual code.
The Ralph Wiggum Loop worked as follows:
- The script inspected the design specification and compared it with the current repository.
- If an implementation layer was still missing, the loop selected the next pending layer in order.
- For that layer, the Create skill analyzed the repository and generated small, atomic task files in Markdown, similar to Jira issues.
- The Execute skill then implemented those tasks one by one.
- After each execution step, the resulting code was validated against the expected behavior and the project specification.
- The loop repeated this process sequentially across all layers until the full project was complete.
Each skill was executed in its own independent session, so only the information required for that specific step was loaded into context. This avoided unnecessary context pollution and reduced the risk of the agent drifting away from the specification.
The finished product was completed successfully and meets the original specifications.
No production code was written manually. The implementation was generated through the Ralph Wiggum Loop from the initial specification, task creation, sequential execution, and validation process.
LifeQuest is a Django modular monolith for personal gamified productivity. The product model combines user-owned workspaces, recurring tasks, category currencies, an immutable points ledger, and a reward shop with stock periods and immediate purchase consumption.
The first runtime target is a simple Docker Compose deployment for a VPS:
web: Django served by Gunicorn.scheduler: the same Django image running idempotent management commands.postgres: the source-of-truth database.caddy: HTTPS, static/media serving, and reverse proxy.static_filesandmedia_files: Docker volumes for collected static files and uploaded reward media.
The codebase starts from stable documentation in docs/ and implementation work in tasks/. For agentic work, read AGENTS.md first.
- Python
3.12 - Django
5.2 LTS uvfor Python dependency management- PostgreSQL in Docker/production
- SQLite by default for native local development
- Tailwind CSS via npm
- Docker Compose for the local production-shaped runtime
config/: Django settings, URLs, WSGI, and ASGI entrypoints.lifequest/: domain apps for accounts, workspaces, recurrence, tasks, economy, shop, media, content, and UI.templates/: shared Django templates.static/: committed frontend source and compiled CSS.tests/: pytest suite.docs/: stable architecture, domain, contract, and reference documentation.tasks/: scoped implementation task files.Dockerfile,docker-compose.yml,Caddyfile: container runtime and deployment skeleton.
Install:
- Python
3.12 uv- Node.js and npm
Docker is optional for native local development, but required for the production-shaped Compose runtime.
Install dependencies:
uv sync --extra dev
npm installBuild the committed CSS:
npm run build:cssFor active UI work, run the Tailwind watcher in a separate terminal:
npm run watch:cssRun database migrations. Without DATABASE_URL, local settings use db.sqlite3:
uv run python manage.py migrateStart Django:
uv run python manage.py runserverOpen:
- App:
http://127.0.0.1:8000/ - Health check:
http://127.0.0.1:8000/health/
Run tests:
uv run pytest -qUseful management commands:
uv run python manage.py scheduler_tick
uv run python manage.py create_active_periods
uv run python manage.py close_expired_periodsThe scheduler/domain commands are intentionally idempotent. scheduler_tick
remains a harmless smoke command; create_active_periods and
close_expired_periods run the registered task and shop active-period handlers.
Create a Compose environment file:
cp .env.example .envFor local Compose, the defaults are enough to boot the stack. Then run:
docker compose up --buildOpen:
- App through Caddy:
http://localhost/ - Health check:
http://localhost/health/
The web service runs migrations, collects static files, and starts Gunicorn.
The scheduler service loops over create_active_periods and
close_expired_periods using SCHEDULER_INTERVAL_SECONDS.
Useful Compose commands:
docker compose ps
docker compose logs web
docker compose logs scheduler
docker compose exec web python manage.py createsuperuserThe supported first production shape is Docker Compose on a VPS.
Install on the server:
- Docker Engine
- Docker Compose plugin
- Git or another deployment mechanism for the repository
Point your DNS record at the server before enabling a domain-based Caddy address.
Create .env on the server from .env.example and change production values:
DJANGO_SECRET_KEY=<strong-random-secret>
DJANGO_DEBUG=false
DJANGO_ALLOWED_HOSTS=example.com,www.example.com
DJANGO_CSRF_TRUSTED_ORIGINS=https://example.com,https://www.example.com
DJANGO_TIME_ZONE=Europe/Madrid
DJANGO_LANGUAGE_CODE=en
DJANGO_STATIC_URL=/static/
DJANGO_STATIC_ROOT=/app/staticfiles
DJANGO_MEDIA_URL=/media/
DJANGO_MEDIA_ROOT=/app/media
DATABASE_URL=postgres://lifequest:<strong-db-password>@postgres:5432/lifequest
POSTGRES_DB=lifequest
POSTGRES_USER=lifequest
POSTGRES_PASSWORD=<strong-db-password>
CADDY_SITE_ADDRESS=example.com
SCHEDULER_INTERVAL_SECONDS=300Use CADDY_SITE_ADDRESS=:80 only when you intentionally want plain HTTP, for example behind another TLS terminator.
From the repository root on the server:
docker compose up -d --buildOn startup, web applies migrations and collects static files before Gunicorn starts.
Verify:
docker compose ps
curl -s https://example.com/health/
docker compose logs web
docker compose logs schedulerRun the release smoke checks after first deployment and after each update:
LIFEQUEST_SMOKE_BASE_URL=https://example.com scripts/release-smoke.shThe smoke script reads .env, rejects missing required release settings and
example secrets, validates docker compose config, confirms postgres, web,
scheduler, and caddy are running, checks unapplied migrations, verifies
/health/, verifies Caddy static serving, writes and fetches a temporary media
probe through Caddy, and runs scheduler_tick in the scheduler container.
For a local Compose-only rehearsal that intentionally uses .env.example
defaults, allow the insecure example values explicitly:
LIFEQUEST_SMOKE_ALLOW_INSECURE_DEFAULTS=true scripts/release-smoke.shCreate an admin user when needed:
docker compose exec web python manage.py createsuperuserProduction data lives in Docker volumes:
postgres_data: PostgreSQL data.media_files: uploaded reward images and generated media.static_files: collected static files.caddy_data: Caddy certificates and runtime data.caddy_config: Caddy config state.
Backups are not automated in the first version. At minimum, back up postgres_data, media_files, and caddy_data before upgrades or server changes.
Manual PostgreSQL and media backup examples:
mkdir -p backups
docker compose exec -T postgres sh -c 'pg_dump -U "$POSTGRES_USER" "$POSTGRES_DB"' > backups/lifequest-postgres.sql
docker compose exec -T web sh -c 'tar -czf - -C "$DJANGO_MEDIA_ROOT" .' > backups/lifequest-media.tar.gzStore backups off the VPS after creation and test restores before relying on them for production recovery.
Core environment variables:
DJANGO_SECRET_KEY: Django secret key. Required to be strong in production.DJANGO_DEBUG:trueorfalse; keepfalsein production.DJANGO_ALLOWED_HOSTS: comma-separated hostnames.DJANGO_CSRF_TRUSTED_ORIGINS: comma-separated trusted origins including scheme.DJANGO_TIME_ZONE: default application timezone.DJANGO_LANGUAGE_CODE: default language code.DATABASE_URL:sqlite:///...,postgres://..., orpostgresql://....DJANGO_STATIC_ROOT: directory wherecollectstaticwrites files.DJANGO_MEDIA_ROOT: directory for uploaded media.CADDY_SITE_ADDRESS: Caddy site address, such asexample.comor:80.SCHEDULER_INTERVAL_SECONDS: scheduler loop interval.
See docs/reference/settings.md for the stable settings contract.
For repository changes, use this read order:
AGENTS.mddocs/indexes/README.md- only the architecture, domain, contract, or reference docs pointed to by the indexes for the area being changed
Stable system knowledge belongs in docs/. Operational implementation work belongs in tasks/.

