quickstart-e2e) runs that exact sequence on a clean GitHub runner
every week and on every change to it, and fails unless the queued post reaches
awaiting_approval, and, once approved and published, can be read at
/site/. (A runner has no GPU, so the job stands one tiny model in for the
three large ones and zeroes the quality bar; every command is yours,
verbatim.) For what each step does under the hood, see
operations/local-development-setup.
Poindexter runs on Linux (Docker Engine), Windows (Git Bash or WSL2 with
Docker Desktop) and macOS (Docker Desktop). Linux needs one extra Ollama
setting, covered in step 3.
Prerequisites
Steps
1
Clone and install the CLI
Install the On Windows Git Bash, create the virtualenv with
poindexter CLI into a Python 3.13 virtualenv inside the
clone.py -3.13 -m venv .venv
and activate it with source .venv/Scripts/activate.2
Bootstrap
--auto generates the stack’s secrets into ~/.poindexter/bootstrap.toml
(the only config file on disk), starts the stack’s own Postgres (the
postgres-local service of the compose file the next steps launch), runs
the migrations, and provisions the CLI’s OAuth client. The CLI and every
container share that one database. Re-running with --force keeps the
secrets the file already holds.3
Pull the models
These are the models the default pipeline calls. The pulls happen once.That is about 31 GB: Firewall port 11434 if the machine sits on a network you don’t trust.
Docker Desktop on Windows and macOS needs none of this.
gemma3:27b (17 GB) is the writer, phi4:14b (9 GB) is
the critic that hard-gates every draft, llama3:latest (4.7 GB) drafts the
podcast and video scripts, and nomic-embed-text (274 MB) does the
embeddings. Nothing pulls a model on demand: a model Ollama does not have
fails the call that names it, so poindexter setup --auto prints this same
command from your database’s own model settings.Pull these only when you switch the feature on: qwen3-vl:30b-a3b-instruct
(image QA and captions, about 20 GB, called only when a post has images),
qwen2.5:32b (fallback critic), granite4.2:3b (the brain’s alert triage)
and qwen2.5:7b (console chat and the voice agent).Linux only: the containers call Ollama at host.docker.internal:11434,
which on Linux is the Docker bridge gateway, and a default Ollama install
listens on loopback only. Make it listen on every interface once:4
Start the stack
start-stack.sh exports bootstrap.toml as the environment the compose
file needs and launches docker-compose.consumer.yml: Postgres, the
worker API, the brain daemon, Prefect (server, services and worker),
Grafana, Prometheus, AlertManager and the backup jobs. The first run
builds the images, so allow several minutes. On its first start the
Prefect worker registers the content-generation deployment that turns a
queued task into a pipeline run.5
Queue a first post
--niche names the niche the post belongs to; a fresh install seeds
starter-blog, and poindexter topics niche list shows yours. A post can
only be published once its task has one.The command waits for the worker to finish booting (about a minute after
the stack starts). Prefect then picks the task up within two minutes and
runs it pending → in_progress → awaiting_approval. Follow along in
Prefect at http://localhost:4200, in Grafana at
http://localhost:3000 (the Pipeline dashboard),
or with docker logs -f poindexter-prefect-worker.When the draft lands, it waits for you with its QA scores attached:Next
Architecture overview
The kernel/module/capability structure, the LangGraph pipeline, the six QA
rails — how the parts fit.
Operations runbooks
Day-2 work: troubleshooting, incident response, backups, secret rotation.
CLI reference
Every
poindexter subcommand with flags and examples.Extend with plugins
Add a Stage, Reviewer, Publishing Adapter, Tap, or Module.