Autonomous Coding Demo is a local, operator-facing reference stack for an agentic software delivery loop.
It is intentionally small enough to run on a laptop, but complete enough to show a real workflow:
Kanboard -> orchestrator -> aider -> local tests -> Gitea Actions -> live app
This repository is a public demo inspired by a larger proprietary internal workflow. The architecture, task lifecycle, and operational model are real. The domain model, data, and surrounding product context are reduced and anonymized for open publication.
Representative local screens from the running demo stack:
Pet App dashboard: the live application surface where deploy-visible changes become obvious.
Control Room: the operator view for task state, pipeline status, and recent execution events.
Pet App products: a second user-facing screen that makes inventory and merchandising fixes easy to verify.
- human task intake through
Kanboard - automatic task claiming by the
orchestrator - isolated task execution in dedicated
git worktreecheckouts - policy-constrained coding with
aider - local verification before push
- independent CI in
Gitea Actions - promotion of successful changes into a live runtime checkout
- browser-visible deploy artifacts in the sample application
This is not a chat wrapper around a toy app. It is a compact demo of a real operator workflow for autonomous code delivery.
pet-app: the sample target applicationcontrol-room: the operator view for pipeline status and artifactsorchestrator: the task lifecycle enginekanboard: the human intake boardgitea: git hosting and branch visibilitygitea-actions-runner: the independent CI runneraider: the coding engine, launched directly by the orchestrator
- A human moves a task to
ReadyinKanboard. - The
orchestratorclaims the task. - A dedicated task branch and
git worktreeare created. aideredits only the files allowed by the execution profile anddocs/AGENT_POLICY.md.- Local tests run inside the task worktree.
- The task branch is committed and pushed to
Gitea. Gitea Actionsvalidates the branch independently.- A successful commit is promoted into the live runtime checkout at
data/live_runtime. pet-appserves the promoted code, so browser-visible changes are deploy artifacts, not just branch artifacts.
Current branch semantics:
main: repository baseline and manual developmentcodex/development: long-lived development branch used by the democodex/<task-id>-<suffix>: isolated autonomous task branchescodex/runtime: the live runtime branch used for promote-to-live
The coding engine is aider, configured through project .env values and
constrained by one versioned policy file:
That file defines:
- global instructions such as smallest-patch behavior
- area-specific heuristics and write-scope expectations
- soft limits that keep autonomous edits narrow and reviewable
The current default coding model is:
- provider:
OpenRouter - model:
openrouter/qwen/qwen3-coder-plus - reasoning effort:
medium
aider runs in strict diff mode and must not mutate .gitignore.
- Create a local environment file:
cp .env.example .env- Fill in the required placeholders in
.env:
OPENROUTER_API_KEYKANBOARD_ADMIN_USERNAMEKANBOARD_ADMIN_PASSWORDGITEA_ADMIN_USERNAMEGITEA_ADMIN_PASSWORDGITEA_PUSH_USERNAMEGITEA_PUSH_PASSWORDGITEA_RUNNER_REGISTRATION_TOKEN
If the local Gitea instance is recreated or moved to another port, you can force a clean runner re-registration by setting:
GITEA_RUNNER_FORCE_REREGISTER=true
- Create the local Python environment:
python3.12 -m venv .venv
.venv/bin/pip install -e ".[dev]"- Start the full stack:
docker compose up --build -d- Seed Kanboard and the demo task catalog if needed:
.venv/bin/python scripts/seed_kanboard.py- Open
Kanboard. - Move a backlog card into
Ready. - Watch the task progress in
Control Room. - Inspect the task branch and CI run in
Gitea. - After
Done, verify the visible change in the livepet-app.
Good candidate tasks for a manual run:
BL-013Minimal seed-data enrichment without logic changesBL-014Return-rate fix through a narrow domain-only patchBL-015Low-stock indicator without new API surfacesBL-016Live build badge through a minimal platform patch
The demo has already completed a full end-to-end run for:
BL-014Return-rate fix through a narrow domain-only patch
That run went through:
Kanboard -> aider -> local tests -> Gitea Actions -> live promote -> Done
pet-app: http://localhost:18000control-room: http://localhost:18010orchestrator: http://localhost:18020kanboard: http://localhost:18080gitea: http://localhost:13000
18000->pet-app:800018010->control-room:801018020->orchestrator:802018080->kanboard:8013000->gitea:300012222->gitea:22
Do not run bare pytest from the repository root once data/live_runtime or
task worktrees exist. Mirrored test files in runtime checkouts can cause
duplicate collection.
Use targeted test commands instead:
PYTHONPATH=. .venv/bin/pytest tests/test_kanboard_sync.py tests/test_orchestrator.py tests/test_store.py tests/test_control_room.py tests/test_git_safety.py tests/test_live_runtime.pyPYTHONPATH=. .venv/bin/pytest tests/test_aider_executor.py tests/test_pet_app.pyBefore every commit, run:
./scripts/check_no_secrets.shThis repository is intentionally a demo stack, not a production platform.
Current demo constraints:
- persistence is still centered on local demo state
- the stack is optimized for local reproducibility, not multi-tenant isolation
- live deploy currently promotes to
codex/runtimerather thanmain - credentials are expected to come from local
.env, not a secret manager - the sample application is intentionally small and anonymized
This repository is safe to publish as a public demo only if you keep real
credentials out of .env and out of git history.
The tracked repository intentionally ships with placeholders such as:
replace-medemo.operator@example.invalidadmin@example.invalid
Do not replace them with real values in tracked files.
This repository is licensed under the MIT License.
Third-party software remains under its own licenses. See THIRD_PARTY_LICENSES.md.