- Vite 6 + React 19 + MUI 6 SPA at ui/ - Routes: Dashboard, Items (MUI DataGrid), ItemDrawer - /v1/items filter+sort+limit wired to URL hash for shareable links - React Query hooks (useStats, useListItems, useItemDetail, useRecentEvents) - Playwright e2e suite: 4 tests against fixture API on :9110 (dashboard widgets, items table, drawer with item+open_issues+recent_events, phase filter narrows results) - Multi-stage Dockerfile (node:22-alpine build -> /bundle) - Compose service damascus-ui-build: one-shot, writes dist/ to named volume damascus_ui for the (P2) damascus-api container to mount - Fixture FastAPI app (tests/e2e/fixture_api.py) for e2e runs without a live damascus-api (P4 ships ahead of P2 by design) Acceptance: build green, 4/4 e2e tests green
Damascus Orchestrator
A self-hosted work-item state machine that autonomously advances stories through spec → build → review → merge. Designed per multi-project-orchestration-plan_1.md (the design doc this repo implements).
Quick start
# Start the stack (Postgres + Redis + Taskiq worker + scheduler)
docker compose up -d --build
# Apply schema (creates the DB + all tables/types/triggers)
docker compose exec orchestrator damascus init
# Manual one-shot cycle (operators / E2E). The Taskiq worker is the
# automatic trigger — you do not normally need to run this by hand.
docker compose exec orchestrator damascus cycle
# External concurrency view
docker compose exec orchestrator damascus status
# Run the contract + unit suite (needs a Postgres on 127.0.0.1:5432)
pip install -e . pytest psycopg[binary]
pytest tests/contract/ tests/unit/ -v
# Run the E2E suite (needs the docker-compose stack up)
pip install pytest psycopg
pytest tests/ -v
What this repo contains
src/damascus/— the Python package (cycle, phases, state, git_ops, llm, cli, relay, wiki, tasks, config)tests/— the suite (contract + unit + E2E; the executable form of the design doc)schema.sql— Postgres 16 schema (work_items, coordination_gates, human_issues, cost_ledger, events_outbox)docker-compose.yml— the stack (db + redis + orchestrator worker + scheduler + sidecar-status)Dockerfile— the orchestrator image (Python 3.12 + git + claude-code + BMAD + LLM-wiki + ollama binary).gitea/workflows/— CIskills/SKILL.md— operator-facing skill
What this repo does NOT contain
- The wiki (
kaykayyali/damascus-wiki) — separate repo with the contract docs - The test project repos (
wh40k-pc,restitution) — separate repos with their own BMAD stories - The lore entry about this project (
kaykayyali/lore→Infrastructure/Damascus-Orchestrator)
Architecture (one paragraph)
Postgres is the source of truth on work-item state (design §3). Each story row
flows through three loops: spec-refiner (LLM via LiteLLM writes an implementable
spec), code-builder (Claude Code via LiteLLM writes the code in a git worktree,
opens a real Gitea PR), reviewer (re-runs the spec's test command, gates on
objective pass/fail, merges via Gitea API on pass). Atomic claim uses
SELECT ... FOR UPDATE SKIP LOCKED. Taskiq (a BullMQ-equivalent Python queue,
§13) with a Redis broker is the recurring trigger; the worker's --concurrency N
is the global concurrency cap (§10). Every phase transition emits a typed
verdict and an events_outbox row in the same transaction. An attempt budget
guarantees termination — a non-pass verdict that exhausts the budget parks the
item as blocked and opens a human_issue (§5/§16). The human is async — open
questions become human_issues rows, never synchronous blocks.
Full design + contracts in the wiki: kaykayyali/damascus-wiki.
Cross-references
- Design doc:
kaykayyali/damascus-wiki/raw/articles/multi-project-orchestration-plan-1.md - Contracts:
kaykayyali/damascus-wiki/concepts/spec-refiner-contract.md,builder-contract.md,reviewer-contract.md,state-resume-protocol.md - Lore entry:
kaykayyali/lore→Infrastructure/Damascus-Orchestrator - Test session:
kaykayyali/damascus-wiki/queries/damascus-orchestrator/2026-06-23-test-session.md - Spec-refiner gap:
kaykayyali/damascus-wiki/queries/damascus-orchestrator/spec-refiner-gap-2026-06-23.md
License
Internal.