Home
Documentation

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-site in this project) — the codebase the agents actually modify. Contains memory/*.md at 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 conventions
  • coding_rules.md — naming, TypeScript conventions, what counts as "done"
  • decisions.md — a running log of settled choices, so agents don't reopen them
  • frontend.md — design system: colors, typography, motion patterns
  • backend.md — API surface, if any
  • security.md — project-specific security rules

2. Add issue templates under .gitlab/issue_templates/:

  • bug.md — for defects. Applies type::bug automatically via a /label quick action.
  • user_story.md — for new features. Applies type::feature.
  • chore.md — for tweaks or reworks of already-shipped pages. Applies type::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

  • /retry on the issue — re-runs the whole pipeline from scratch, reusing the existing branch. Useful after a BLOCKED run, 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 a Closes #N pattern 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.