DEV Community

Miguel Miranda de Mattos
Miguel Miranda de Mattos

Posted on

From Single Files to Full Systems: Agentic Coding for Complete Repositories

Agentic Coding - Full Systems

Introduction

In earlier experiments, we explored a simple but powerful idea:

An agent can generate code, run it, observe failures, and iteratively fix itself.

That approach worked well for single-file applications across Python, Go, and TypeScript.

But real systems are not single files.

They are:

  • structured\
  • layered\
  • multi-module\
  • opinionated

This raises a deeper question:

Can agents generate complete repositories β€” β€” not just code?

In this article, we push agentic coding one step further:

πŸ‘‰ generating a Clean Architecture notes application
πŸ‘‰ as a multi-file Python project
πŸ‘‰ verified with unit tests (pytest)

The Shift: From Code to Systems
system = structure + boundaries + contracts + code

Target Architecture

project_agent_coded_python_clean_arch/
  domain/
    models.py0
  application/
    services.py
  infrastructure/
    db.py
  api/
    main.py
  tests/
    test_notes.py
Enter fullscreen mode Exit fullscreen mode

The Agent Evolution

generate β†’ run β†’ validate β†’ test β†’ fix

Running the Agent

python agent_coder_python_clean_arch.py
Enter fullscreen mode Exit fullscreen mode

The agent will:

  • generate the full project structure\
  • install dependencies\
  • start the API\
  • execute tests\
  • fix issues iteratively

Generated Project
project_agent_coded_python_clean_arch/

Run Generated API

cd project_agent_coded_python_clean_arch
python api/main.py
Enter fullscreen mode Exit fullscreen mode

Run Tests

cd project_agent_coded_python_clean_arch
pytest
Enter fullscreen mode Exit fullscreen mode

Generated Unit Tests

from fastapi.testclient import TestClient
from api.main import app
client = TestClient(app)
def test_create_note():
    response = client.post("/notes", json={"content": "test"})
    assert response.status_code in (200, 201)
    data = response.json()
    assert "id" in data
    assert data["content"] == "test"
def test_get_notes():
    response = client.get("/notes")
    assert response.status_code == 200
    assert isinstance(response.json(), list)
Enter fullscreen mode Exit fullscreen mode

Why This Matters

From: code generation
To: verified system construction

Appendix A β€” β€” FULL AGENT CODE

import os
import subprocess
import time
import json
import sys
from openai import OpenAI
# ============================================================
# CONFIGURATION
# ============================================================
client = OpenAI()
WORKDIR = "project_agent_coded_python_clean_arch"
os.makedirs(WORKDIR, exist_ok=True)
GOAL = """
Build a Clean Architecture notes REST API in Python.
Structure:
- domain/models.py
- application/services.py
- infrastructure/db.py
- api/main.py
- tests/test_notes.py
Requirements:
- Use FastAPI
- Use SQLite
- POST /notes
- GET /notes
- Include pytest tests
- Must run with: python api/main.py
"""
# ============================================================
# CODE GENERATION
# ============================================================
def generate_repo(goal, error=None):
    """
    Generate a full multi-file repository using the LLM.
The model must return a JSON object mapping file paths β†’ file contents.
Args:
        goal (str): High-level system description
        error (str | None): Feedback from previous attempt
Returns:
        str: Raw JSON string (must be parsed)
    """
prompt = f"""
You are an autonomous coding agent.
Goal:
{goal}
Return ONLY valid JSON mapping file paths to contents.
Rules:
- No markdown
- All files must be included
- Tests must use pytest
- Code must run without modification
Previous error:
{error}
"""
response = client.responses.create(
        model="gpt-4.1-mini",
        input=prompt
    )
return response.output_text
# ============================================================
# FILE SYSTEM OPERATIONS
# ============================================================
def write_files(file_map):
    """
    Write generated files to disk.
Creates directories as needed.
Args:
        file_map (dict): { path: content }
    """
    for path, content in file_map.items():
        full_path = os.path.join(WORKDIR, path)
os.makedirs(os.path.dirname(full_path), exist_ok=True)
with open(full_path, "w") as f:
            f.write(content)
# ============================================================
# RUNTIME EXECUTION
# ============================================================
def run_app():
    """
    Start the generated API.
Returns:
        (success, process, error)
Success means the server started and did not crash immediately.
    """
process = subprocess.Popen(
        [sys.executable, "api/main.py"],
        cwd=WORKDIR,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        text=True
    )
# Give the server time to start
    time.sleep(3)
# If still running β†’ success
    if process.poll() is None:
        return True, process, ""
# Otherwise, capture failure
    stdout, stderr = process.communicate()
    return False, None, stderr
def stop_app(process):
    """
    Stop the running API process.
    """
    if process:
        process.terminate()
# ============================================================
# VALIDATION (PRIMARY = PYTEST)
# ============================================================
def run_tests():
    """
    Execute pytest inside the generated project.
This is the PRIMARY validation mechanism.
Returns:
        (bool, str):
            - success flag
            - error output (if any)
    """
result = subprocess.run(
        [sys.executable, "-m", "pytest"],
        cwd=WORKDIR,
        capture_output=True,
        text=True
    )
if result.returncode == 0:
        return True, ""
return False, result.stdout + result.stderr
# ============================================================
# DEPENDENCY HEALING
# ============================================================
def install_missing(error):
    """
    Attempt to auto-install missing dependencies.
The agent inspects error messages and installs packages dynamically.
Returns:
        bool: whether a fix attempt was made
    """
if not error:
        return False
if "No module named" in error:
        pkg = error.split("'")[1]
        subprocess.run([sys.executable, "-m", "pip", "install", pkg])
        return True
if "pytest" in error:
        subprocess.run([sys.executable, "-m", "pip", "install", "pytest"])
        return True
return False
# ============================================================
# ENVIRONMENT PREPARATION
# ============================================================
def clean_port():
    """
    Kill any process using port 8000.
Prevents conflicts between agent iterations.
    """
    subprocess.run(
        "lsof -ti :8000 | xargs kill -9",
        shell=True,
        stdout=subprocess.DEVNULL,
        stderr=subprocess.DEVNULL
    )
# ============================================================
# AGENT EXECUTION LOOP
# ============================================================
"""
============================================================
AUTONOMOUS AGENT LOOP
This loop implements a full self-healing coding cycle:
1. Generate repository from goal
    2. Write files to disk
    3. Run the generated API
    4. Validate using pytest
    5. Feed errors back into the model
    6. Repeat until success
IMPORTANT DESIGN DECISIONS:
- pytest is the PRIMARY validation mechanism
- HTTP validation (Appendix B) is optional and NOT used here
- The agent stops ONLY when tests pass
============================================================
"""
clean_port()
error = None
for attempt in range(5):
print(f"\n--- Attempt {attempt+1} ---")
# --------------------------------------------------------
    # STEP 1: GENERATE CODE
    # --------------------------------------------------------
    raw = generate_repo(GOAL, error)
try:
        file_map = json.loads(raw)
    except Exception:
        error = "Invalid JSON output"
        continue
# --------------------------------------------------------
    # STEP 2: WRITE FILES
    # --------------------------------------------------------
    write_files(file_map)
# --------------------------------------------------------
    # STEP 3: RUN APPLICATION
    # --------------------------------------------------------
    success, process, err = run_app()
if not success:
        # Try to fix missing dependencies
        if install_missing(err):
            error = err
            continue
error = err
        continue
# --------------------------------------------------------
    # STEP 4: VALIDATE USING PYTEST
    # --------------------------------------------------------
    test_ok, test_error = run_tests()
# Stop API before continuing
    stop_app(process)
if test_ok:
        print("\nSUCCESS: All tests passed. System is valid.")
        break
# --------------------------------------------------------
    # STEP 5: SELF-HEALING LOOP
    # --------------------------------------------------------
    if install_missing(test_error):
        error = test_error
        continue
# Feed test failures back into next generation
    error = test_error
Appendix B β€” β€” Optional API Validation
import requests
def validate_api():
    try:
        r = requests.get("http://localhost:8000/notes")
        if r.status_code != 200:
            return False, r.text
        return True, ""
    except Exception as e:
        return False, str(e)
Enter fullscreen mode Exit fullscreen mode

Conclusion

This is no longer code generation.

This is autonomous system construction with verification.

Full Modular Agent Code Example

https://github.com/mmmattos/agentic-coding-python-clean-arch

Top comments (0)