Your agent can write the code. FlowGate makes it prove the work.
You handed the task to an autonomous agent, said "it'll figure it out," and walked away. It says it's done. Is it?
A typed document pipeline where completion isn't a claim — it's evidence. Requirement → Task → Task Report → Approval — every handoff passes a gate a human (or another agent) signs off on.
The agent didn't lie. It just never had to be right.
Register a requirement → start a continuous run → inspect the evidence → approve.
git clone https://github.com/horrible-gh/FlowGate.git
cd FlowGate
docker compose up -d --build
docker compose exec flowgate python create_dev_user.py \
--username admin --email admin@flowgate.local --password 'ChangeMe!' --admin
# → open http://localhost:8089/flowgate and log in as adminThat's the fastest taste. The full Quick start — local dev with auto-reload, plus MySQL/PostgreSQL — is further down.
Hand a coding task to an autonomous AI agent and you eventually hit the same wall: it tells you it's done when it isn't. The tests "pass," the bug is "fixed," the feature is "fully implemented" — and none of it is true. The agent isn't lying maliciously; it just has no structural reason to be accountable. There's no gate between "I claim I did X" and "X is accepted."
FlowGate is that gate.
It turns work into a typed document pipeline. An agent can't just say a task is finished — it has to register an artifact (a Task, a Task Report, a Requirement) through an authenticated API. That artifact enters an inbox, gets a review status, and can be approved, rejected with a reason, or sent back for revision. Nothing moves to the next stage until the current one clears its gate. The agent's claim and the verified state are no longer the same thing — which is the entire point.
The system has been dogfooding itself for its own development: the requirement and work order that produced this very README were filed, reviewed, and approved through FlowGate.
Each unit of work is a document with a type and a place in a sequence. Documents are grouped, numbered automatically, and chained: a Requirement (R) triggers a Task (T), which produces a Task Report (TR), and so on. Every transition is a reviewable gate.
- Typed documents & auto-numbering —
R(requirement),T(task),TR(task report), conversation docs, and more, each numbered and chained within a group. - Work plans & sequences — a Work Plan (
WP, approval not required) pours into candidate rows that seed the sequence edit dialog's starting state; the workflow sequence itself only changes once a human reviews it and presses Save, with per-step AI provider, note, and review configuration set at that point. - Review gates & rework — the default gate is approve / reject-with-reason / request-revision, with full rejection history kept on the document. Separately, an optional automated document review loop can be invoked to drive reviewer selection and AI-assisted correction through repeated rounds until the document passes review or reaches a configured review, retry, or total-time limit — it is an opt-in AI execution feature, not something every rejection triggers.
- Remote worker API — agents authenticate with scoped Bearer tokens and submit work over HTTP. A dry-run mode validates a submission (URL, token, fields, permissions) without consuming the token.
- Structured clarification (Q) — when an agent is unsure, it doesn't guess and it doesn't pop a dialog into the void: it registers a question bound to the document, which the system routes for a definite answer.
- Live updates — Server-Sent Events push status changes to every watcher in real time, with a notification feed and unread badge.
- Mentions & handoffs — generated, copy-ready mention blocks carry the exact context (references, predecessors) the next worker needs, including hop handoff between chained runs.
- AI execution & continuous (unmanned) work — direct AI invocation or a scoped continuation token that self-chains through the workflow toward a target stage: provider selection/pinning, pause/resume, per-step review, step timeouts, run diagnostics, and prompt audit, with optional human Q&A along the way.
- Git-backed branches & worktrees — a group branch explorer with live worktrees where available, file diffs, changed/untracked/deleted indicators, update-from-base, a merge conflict resolver, and finalize actions.
- Conversation documents — a dedicated chat-style document type (
CH) for back-and-forth that doesn't fit the requirement → task → report spine, with user-controlled, configurable AI source access — read-only, persistent edit, or one-time edit.
| Area | What's in the box |
|---|---|
| Backend | Python · FastAPI · v1 route modules for documents, workflow, RBAC, tokens, remote tools, SSE, dashboard, inbox, Q&A, and more |
| Database | SQLite / MySQL / PostgreSQL — 130+ ordered migrations per backend, one matching set in each of sqlite, mysql, and postgres, plus a runtime dialect-translation layer (db/dialect.py), clean module split (api / auth / db / rbac / workflow / numbering) |
| AI orchestration | A dedicated invoke engine (services/ai_invoke/) driving Claude, Copilot, Codex, custom-CLI, and API-based providers — continuous chains, pause/resume, provider pin, per-step review, step timeouts, run diagnostics, and prompt audit |
| Git integration | Group branch/worktree lifecycle, file diff/blob browsing, update-from-base, merge conflict resolution, and finalize actions (services/git_service.py, api/v1/git_routes.py) |
| Auth & security | JWT + bcrypt + TOTP 2FA (with backup codes) + refresh/blacklist · per-token action scopes · slowapi rate limiting |
| Frontend | Vue 3 · Pinia · vue-i18n (ko / ja / en) · vue-router · Vite |
| Testing | Focused backend and frontend regression tests around workflow, auth, documents, SSE, dashboard, Q&A, and review flows |
| Ops | Docker / docker-compose (one-command, SQLite or bundled Postgres/MySQL) · systemd unit (deploy/flowgate.service) · one-shot setup.sh (Linux) / setup.ps1 (Windows) · selectable DB backend · Redis-ready |
AI CLI integrations (such as Claude and Codex) and configured test runners are deliberately arbitrary-command execution surfaces: executing repository commands is the feature, not a capability FlowGate can safely remove. Treat anyone who can configure or launch them as having command-execution authority inside the FlowGate service account and its filesystem/container boundary, and isolate that boundary and grant it only the credentials and paths it needs. Newly registered providers keep Skip permission confirmation off by default; an operator must explicitly enable the warning-marked option. Leaving it off can pause unmanned work at an approval prompt, while enabling it allows the CLI to act without per-command confirmation.
FLOWGATE_AGENT_API_BASE is the canonical origin reachable by spawned CLI workers, not the browser-facing/operator URL. Set it to an HTTP(S) origin only; for a same-host default deployment the recommended value is http://127.0.0.1:8089. If it is absent, FlowGate keeps an explicit operator port or otherwise uses the trusted FLOWGATE_PORT fallback. Blank or malformed configured values stop CLI startup instead of silently sending a work token to a different origin.
Requires Python 3 and Node.js.
# 1. Backend
cd server
cp .env.sample .env # set SECRET_KEY, DB_TYPE=sqlite, CONTEXT=/flowgate
pip install -r requirements.txt
python dev.py # serves on http://0.0.0.0:8088 (auto-reload)
# 2. Frontend (separate terminal)
cd client
npm install
npm run dev # Vite dev server with HMRCreate the first user with server/create_dev_user.py, then open the client and log in.
For a one-command staging deploy on Linux (venv + .env + client build + systemd install + admin account), run ./setup.sh from the repo root. On Windows, run .\setup.ps1 (venv + .env + client build + generated run.bat launcher + admin account). Both default to SQLite; target MySQL/MariaDB or PostgreSQL by presetting DB_TYPE (e.g. DB_TYPE=postgres DB_HOST=… ./setup.sh, or .\setup.ps1 -DbType postgres -DbHost …).
Requires Docker with the Compose plugin. Builds the client and server into one image; persistent state (SQLite DB, document storage, generated secrets) lives in the
flowgate-datavolume.
# SQLite (default) — one container, state on a named volume
docker compose up -d --build
# → http://localhost:8089/flowgate
# Seed the first admin (idempotent; re-runs skip if it already exists)
docker compose exec flowgate python create_dev_user.py \
--username admin --email admin@flowgate.local --password 'ChangeMe!' --adminSECRET_KEY and the token pepper are generated once on first start and persisted to the data volume (never rotated on restart, so issued tokens keep working). To run against a bundled database instead, start with a profile and set DB_TYPE — the app waits for the DB and auto-migrates the schema on boot:
DB_TYPE=postgres docker compose --profile postgres up -d --build # + Postgres 16
DB_TYPE=mysql docker compose --profile mysql up -d --build # + MariaDB 11ALLOWED_ORIGIN now defaults to an empty value, which blocks all cross-origin browser requests while leaving the bundled same-origin client unaffected. Set it explicitly to the permitted origin or origins before a separately hosted frontend or another external web origin calls the API.
Stored AI provider API keys are encrypted with FLOWGATE_AI_ENCRYPT_KEY; FLOWGATE_AI_ENCRYPT_KEY_PREV is available temporarily when rotating that key. Docker, setup.sh, and setup.ps1 generate the active key automatically, so a normal installation does not require an operator to invent one.
Back up the secret material together with the database and storage volume. For Docker, include $FLOWGATE_STORAGE_DIR/.flowgate-secrets.env from the flowgate-data volume. For local or setup-script installations, include server/.env entries for SECRET_KEY, the FLOWGATE_TOKEN_PEPPER_* values, FLOWGATE_GIT_ENCRYPT_KEY, FLOWGATE_TOTP_ENCRYPT_KEY, and FLOWGATE_AI_ENCRYPT_KEY (plus any _PREV key present during rotation). Losing or replacing these values can make stored Git credentials, AI provider API keys, and enrolled TOTP secrets unreadable; a database-only backup is therefore incomplete.
# Submit an artifact (use dry_run:true first to validate without consuming the token)
curl -X POST http://<host>:8089/flowgate/api/v1/inbox \
-H "Authorization: Bearer <scoped-token>" \
-H "Content-Type: application/json" \
-d '{ "action":"new", "project":"flowgate", "module":"default",
"group_name":"flowgate.default.0072", "doc_type":"TR",
"prev_doc_id":"flowgate.default.0072.0002-T",
"title":"...", "content":"..." }'The API exposes typed help endpoints (GET /flowgate/api/v1/help/doc_type) so an agent can discover document types and required fields at runtime.
FlowGate/
├── server/ # FastAPI backend
│ ├── routers/ # app wiring (main.py mounts every sub-router)
│ ├── modules/flow_gate/ # the real domain
│ │ ├── api/ # inbox, tokens (top level) + v1/ routes: documents, workflow, git, AI invoke, conversation, remote tools, SSE, dashboard, Q&A…
│ │ ├── services/ # work_plan_* (plan → sequence), git_service, ai_invoke/ (chain, admission, provider_cli, provider_api, review, diagnostics…), conversation_*, mutation_policy…
│ │ ├── auth/ rbac/ # JWT + 2FA, role-based access
│ │ ├── workflow/ numbering/
│ │ ├── documents/ conversation.py process_service.py
│ │ └── db/ # multi-backend data access
│ ├── sql/migrations/ # 130+ ordered migrations in each of {sqlite, mysql, postgres}
│ ├── tools/ # maintenance/one-off scripts, incl. the dialect migration generator (regen_dialect_migrations.py)
│ └── tests/ # backend regression tests
├── client/src/main/ # Vue 3 + Pinia + Vite SPA
│ ├── components/ # WorkPlanEditor/ProposalDialog, AiInvokeDialog, Git* (status/diff/conflict/finalize), ConversationView, TimeMachineDialog…
│ └── stores/ composables/ router/ workflow/ views/
├── Dockerfile # multi-stage: build client → Python runtime
├── docker-compose.yml # one-command stack (SQLite / Postgres / MySQL profiles)
├── deploy/
│ ├── flowgate.service # systemd unit template (rendered by setup.sh)
│ └── docker-entrypoint.sh # container init: secrets, DB wait, admin seed
├── setup.sh # one-shot staging deploy (Linux)
├── setup.ps1 # one-shot staging deploy (Windows)
└── TESTING.md # how to run the suites (Fast/Standard/Full) and when to add a test
FlowGate is built as a working system, not a throwaway prototype — it runs the document pipeline that drives its own development, including this README's own update. What started as a document-approval pipeline is now an actively evolving orchestration workspace, with several fronts moving at once: workflow orchestration (Work Plans, sequence editing, per-step provider/review configuration), the AI execution lifecycle (direct invocation, continuous chains, pause/resume, provider pin, step timeouts, run diagnostics, prompt audit), review/rework automation (reviewer selection, AI-assisted correction, rework loops), Git/worktree operation (branch explorer, diff, update-from-base, conflict resolution, finalize), multi-dialect database support (SQLite / MySQL / PostgreSQL), and conversation-based source access control (read-only / persistent edit / one-time edit).
Future roadmap mockup — not a current product screen. This visual describes a possible v0.2 presentation of FlowGate's existing direction; it does not represent implemented features, UI, data, or availability.
The current-state dashboard image near the top of this README is labelled v0.1. This distinct v0.2 visual is a conceptual roadmap view only.
Roadmap:
- Workspace evolution — sharpen the existing SPA's operator UX and orchestration visibility (clearer AI/group execution management, run diagnostics surfaced more directly) rather than a ground-up GUI rebuild — FlowGate's primary surface is already this SPA, not a CLI.
- AI group orchestration — evolve the presentation of coordinated execution, review/rework, and handoffs so operators can understand group-level work more readily; this describes a v0.2 UX direction, not newly implemented runtime behavior.
- Deeper Git / hosting integration — build on the existing branch/worktree, diff, merge, and finalize support with pull-request hosting integrations and configurable transition policies.
- Agent protocol / integration evolution — more provider-aware orchestration and broader external agent interoperability beyond the current CLI/API invocation surface.
Released under the MIT License — © 2026 horrible-gh.



