Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/joseluis-dev/harness-ai/llms.txt

Use this file to discover all available pages before exploring further.

Phase 0 is the foundation of the entire Harness AI roadmap. It installs no AI capabilities, no agents, and no external integrations — its sole purpose is to prove that the monorepo, infrastructure services, execution pipeline, and audit trail work end-to-end on a single Docker Compose stack and can be reproduced identically in a Dokploy production deployment. Without Phase 0 there is no Harness Core, no audit trail, and no execution surface for any subsequent phase to build upon.

Objective

Establish the monorepo, the support services (PostgreSQL, Redis), and the minimum audit and execution schema so the system starts locally with Docker Compose and is deployable to Dokploy. Every subsequent phase depends on the tables, queues, and health checks created here.

Dependencies

This is the initial phase of the 0–13 roadmap. It has no upstream dependencies.

What to Implement

Monorepo structure

Single repository with clearly separated apps (harness-core, runtime-python) and an infra/ directory for Docker Compose files, migrations, and Dokploy notes.

Astro SSR

harness-core Astro application with server-side rendering enabled, capable of handling API routes and serving the executions UI.

PostgreSQL

Relational store for executions, audit events, and all future phase tables. Exposed only on private-harness-net; never published to host except via Astro.

Redis

Job queue backing store for RQ. Used by runtime Python to consume execution jobs. Internal to private-harness-net.

Runtime Python

Single container running both uvicorn (internal API on port 8000) and rq worker via entrypoint.sh. No separate worker sidecar exists in the Compose definition.

Docker Compose + migrations

docker-compose.local.yml and docker-compose.prod.yml with the same 4-service topology. Alembic (or equivalent) migrations run on startup; schema is reproducible from zero.

Health checks

All 4 services report healthy status (Up (healthy)) before Astro accepts traffic. Compose depends_on: condition: service_healthy enforces ordering.

executions table

Tracks every harness execution: id (UUID), status (queued → running → completed/failed), source_type, intent, risk_level, timestamps.

audit_events table

Append-only event log. Written exclusively by runtime/audit/event_builder.py. Records execution_id, event_type, from_status, to_status, and timestamp for every state transition.

RQ job queue

Astro enqueues a job after creating an execution row; the RQ worker in runtime-python picks it up, transitions the execution, and writes audit events.

Executions page

The first UI artifact — a server-rendered Astro page that lists executions and their current status. Serves as the end-to-end smoke-test surface.

Acceptance Criteria

All criteria are LIVE verified (2026-07-05). Each check below maps to a specific command and expected response.
1

[LIVE 2026-07-05] System starts with Docker Compose — 4 services healthy

Run the local stack and confirm all four services reach the healthy state:
docker compose \
  -f infra/compose/docker-compose.local.yml \
  --env-file .env \
  up -d --build
docker compose ps
Expected output — all four services Up (healthy):
NAME               STATUS          PORTS
harness-postgres   Up (healthy)    5432/tcp
harness-redis      Up (healthy)    6379/tcp
runtime-python     Up (healthy)    8000/tcp
harness-core       Up (healthy)    0.0.0.0:4321->4321/tcp
Only harness-core publishes a host port. runtime-python exposes 8000/tcp internally only.
2

[LIVE 2026-07-05] Astro creates a fictitious execution → 201

curl -fsS -X POST http://localhost:4321/api/executions \
  -H "Content-Type: application/json" \
  -d '{
    "source_type": "manual",
    "intent": "smoke-test",
    "risk_level": "low"
  }'
Expected response — HTTP 201:
{
  "id": "5b47cba7-...",
  "status": "queued"
}
3

[LIVE 2026-07-05] Runtime Python consumes the job

Verify that runtime-python hosts both processes under its entrypoint.sh supervisor:
docker exec runtime-python \
  sh -c 'cat /proc/[0-9]*/comm 2>/dev/null | sort -u'
Expected output includes both process names:
uvicorn
rq
ps is not available in python:3.12-slim; inspect /proc directly. There is no separate worker service in the Compose definition — both uvicorn (port 8000) and rq worker executions run inside the same container via bash /app/infra/docker/entrypoint.runtime-python.sh.
4

[LIVE 2026-07-05] Execution reaches 'completed' state

Poll the execution until it transitions to completed:
EXEC_ID="5b47cba7-..."   # substitute the id from step 2

curl -fsS http://localhost:4321/api/executions/${EXEC_ID}
Expected response — status has advanced:
{
  "id": "5b47cba7-...",
  "status": "completed"
}
The transition typically completes within ~1.5 s (controlled by EXECUTION_WORKER_FAKE_WORK_SECONDS).
5

[LIVE 2026-07-05] Audit events registered — 2 events in order

curl -fsS http://localhost:4321/api/executions/${EXEC_ID}/events
Expected response — exactly 2 events in chronological order:
[
  {
    "event_type": "execution.running",
    "from_status": "queued",
    "to_status": "running"
  },
  {
    "event_type": "execution.completed",
    "from_status": "running",
    "to_status": "completed"
  }
]
Both events are written by runtime/audit/event_builder.py — the sole writer of the audit_events table. The execution.running event captures the queued → running transition; execution.completed captures running → completed.
6

[LIVE 2026-07-05] Deployable to Dokploy — config validates cleanly

docker compose \
  -f infra/compose/docker-compose.prod.yml \
  config --quiet
echo "exit code: $?"
Expected output:
exit code: 0
The prod topology uses the same 4 services, same images, and same environment variables as local. The only structural difference is the absence of ports: on all services except harness-core:4321. See infra/dokploy/deployment-notes.md for the Dokploy deployment procedure.

Operational Notes

Phase 0 does not include any agents, any AI models, or any external identity integration. Adding those components before Phase 0 acceptance criteria are verified will produce an untestable system — the audit and execution foundations must be solid before anything else is layered on top.
  • The executions and audit_events tables created here are the canonical schema for all future phases. No phase may bypass them.
  • The executions page is the first UI artifact and acts as the primary smoke-test surface throughout the roadmap.
  • The audit_events table is append-only: no phase may update or delete rows. New events are always inserted; never mutated.
  • All state transitions in executions go through the runtime Python worker; Astro only reads and enqueues — it never writes execution status directly.
  • EXECUTION_WORKER_FAKE_WORK_SECONDS is the environment variable that controls the simulated delay in the worker. Its default value produces the ~1.5 s latency observed in the Phase 0 smoke test.
See the Quickstart guide for step-by-step setup instructions, environment variable reference, and local development prerequisites before running the Phase 0 commands above.

Build docs developers (and LLMs) love