Using agent-orchestrator
The two repositories
This system always involves two separate GitLab repositories:
- agent-orchestrator — the engine itself. Generic, no knowledge of any specific target project.
- The target repository (e.g.
portfolio-sitein this project) — the codebase the agents actually modify. Containsmemory/*.mdat its root, read by every agent at runtime.
The orchestrator runs once, on one VPS, and is pointed at exactly one target repository via TARGET_REPO_URL in its .env.
Setting up a target repository
1. Add memory/*.md at the repo root — read in full by every LLM-backed agent on every run:
architecture.md— route structure, rendering strategy, component conventionscoding_rules.md— naming, TypeScript conventions, what counts as "done"decisions.md— a running log of settled choices, so agents don't reopen themfrontend.md— design system: colors, typography, motion patternsbackend.md— API surface, if anysecurity.md— project-specific security rules
2. Add issue templates under .gitlab/issue_templates/:
bug.md— for defects. Appliestype::bugautomatically via a/labelquick action.user_story.md— for new features. Appliestype::feature.chore.md— for tweaks or reworks of already-shipped pages. Appliestype::chore.
Each template's trailing /label line is what actually triggers a run — the webhook only reacts to issues carrying type::feature, type::bug, or type::chore.
3. Populate REVIEW_COMMANDS in the orchestrator's .env — the deterministic gate that runs before any LLM review. Semicolon-pair separated (;;), never newline-separated:
REVIEW_COMMANDS="gitleaks git .;;npm install;;semgrep scan --config p/default --error;;npm run lint;;npx tsc --noEmit;;npm run build"
Triggering a run
Open an issue on the target repo with one of the three templates. The webhook responds to GitLab in under a second regardless of how long the actual run takes (often several minutes) — it hands off to a background task, well within GitLab's ~10s webhook timeout.
The pipeline
Prepare → Plan → Develop → Review → Supervise → Git. See the Architecture page for the full diagram — this page focuses on how to operate it, not its internals.
Human-in-the-loop commands
/retryon the issue — re-runs the whole pipeline from scratch, reusing the existing branch. Useful after aBLOCKEDrun, or to try again with a different model./fix <feedback>on the merge request — re-runs the pipeline for the linked issue, seeding your feedback directly into the Development Agent's next attempt as a failed review verdict. The linked issue is resolved from the MR's branch name first (agent/issue-N), falling back to aCloses #Npattern in the description.- Merging the MR — closes the loop automatically: the issue's label advances to
workflow::done, and the merged branch is pruned from the shared workspace clone. - A blocked run still pushes its branch (best-effort) so the code is reachable on GitLab, without opening a merge request for work that didn't pass review.
Configuring model behavior
Every LLM-backed role can be tuned independently — model and reasoning effort — falling back to a shared default if unset:
ORCHESTRATOR_LLM_MODEL=gpt-5.6-terra
PLANNER_LLM_MODEL=
REVIEWER_LLM_MODEL=
COMMIT_MESSAGE_LLM_MODEL=gpt-5.6-luna
ORCHESTRATOR_REASONING_EFFORT=low
REVIEWER_REASONING_EFFORT=medium
The Development Agent's own model is separate, since it's driven by OpenCode rather than a direct OpenAI call:
OPENCODE_MODEL=openai/gpt-5.6-sol
Adjusting the retry budget
ORCHESTRATOR_MAX_REVISIONS=3
How many times the Development Agent gets to retry after a non-critical review failure before the run blocks and asks for manual review. A critical failure (a leaked secret, an injection pattern) blocks immediately regardless of this setting.