Главная идея

Единственная точка правды — SQLite-файл

Foundry демонстративно отказывается от любой общей памяти и очередей в RAM. В одной базе живёт очередь задач, FSM-состояние, append-only лог событий для лайв-наблюдения и долговременная память по репозиториям. Worker пишет, API и UI читают — никаких RPC, никакого Redis, никаких подписок. Это даёт «бесплатно» персистентность, идемпотентность стадий через stage_results и переживание рестартов: задача со статусом RUNNING после крэша подхватится на следующем тике и продолжит ровно с той стадии, где упала. Второй ключевой ход — оркестратор сам решает все переходы; стадии — это просто функции, возвращающие dict, без собственной state-машины.

Высокоуровневая схема

Три процесса вокруг одной базы

Worker гоняет конвейер и пишет в SQLite. FastAPI и React-UI только читают. Отдельный pr-feedback listener следит за уже открытыми PR. Никаких внешних брокеров.

GitHub Issues
источник задач · label agent-task
gh issue list раз в 30 сек
worker (listener)
синхронный однопоточный · одна задача за раз
↓ запускает dev_task
CLI-агент в worktree
stdio NDJSON · claude / codex / opencode / stub
↓ пишет события + state
SQLite — единая шина
tasks · task_events · stage_results · agent_sessions · repo_memory
↓ читают параллельно
FastAPI ↔ React-UI
REST + SSE с replay по Last-Event-ID

Что важно понять

  • Никаких очередей в RAM. Очередь задач — это просто таблица tasks в SQLite. Worker SELECT'ит её каждый тик.
  • Идемпотентность через stage_results. Каждая стадия перед стартом проверяет, не выполнялась ли уже. Упал на verify — после рестарта plan и implement пропустятся.
  • Per-stage AgentSettings. Можно поставить haiku на план/verify, sonnet — только на implement. Дешёвая модель работает на дешёвых шагах.
  • SSE с «бесплатным» resume. EventSource сам шлёт Last-Event-ID на reconnect — replay работает «из коробки», без custom-протокола.
dev_task — линейная партитура

Шесть стадий конвейера

Каждая задача проходит фиксированную цепочку: fetch → context → plan → implement → verify → pr. Между implement и verify крутится локальный quality-gate цикл (по умолчанию две попытки).

Quality-gate цикл: если verifier сказал FAIL retryable — worktree откатывается через git reset --hard, бинарный патч прошлой попытки сохраняется в data/checkpoints/, в промпт implement'а дописывается «previous feedback», запускается попытка №2. Непонятный вердикт или маркер NEED_VERIFICATION от агента → задача уходит в BLOCKED.
Agent runtime

Четыре CLI под одним протоколом

Foundry не использует ни SDK провайдеров, ни HTTP-клиенты. Все агенты — это локальные CLI, запускаемые subprocess'ом. Различия — в адаптерах, которые нормализуют события к единому виду: agent_tool, agent_text, agent_thinking, agent_result.

Polling-only архитектура

Три разнотемповых цикла

Никаких webhook'ов, никаких подписок на GitHub events. Простота за счёт latency — для single-tenant сценария это оптимальный компромисс.

Из чего собран

Двенадцать строительных блоков

От фонового worker'а до тонкого security wrapper'а вокруг shell-команд — каждый компонент решает одну конкретную задачу. Используйте фильтр для просмотра по категориям.

Жизненный цикл

Что происходит с типичной задачей

От момента, когда оператор поставил label agent-task на issue, до открытого PR — пятнадцать шагов через шесть стадий dev_task.

На чём всё держится

Ключевые свойства архитектуры

Девять решений, которые делают Foundry простым, идемпотентным и предсказуемым после падений.