Bring Your Own Agents (BYOA) — Robot Dev Team is a containerized FastAPI service that consumes GitLab webhooks, enriches events with the GitLab CLI, and dispatches context-rich prompts to any CLI-based LLM agent via YAML routing rules. Ships with adapters for Claude Code, Google Gemini, and OpenAI Codex, but any tool that accepts prompts on stdin can be wired in simply by replacing CLI command strings. No need for separate pay-as-you-go API keys, use the command line agents you already have.
Using more than one agent provider (i.e. Claude, Codex, Gemini...) allows you to pit multiple language models against each other. You can fine-tune roles, get multiple opinions, and have them review each other. Huge level up for workflows.
This platform follows a BYOA philosophy: it is not locked to any specific provider. Go ahead and have Kimi review Codex. Make Qwen handle merge requests. You could also just use a single agent for everything, if you're old fashioned like that.
Here's an essay espousing the philosophy.
GitLab is open source, and can be hosted locally in a docker container. This provides you with a private, self-managed project repository with all the features you would expect from a modern SCM. But most importantly, GitLab's issue tracking, merge request, and conversation interface provides a rich infinite context platform on which to work with your coding agents. Track ideas, plans, work status, history...all without worrying about losing your state, blowing context windows, or misplacing sessions. All of your agents have access to the same working knowledge, in perpetuity. You can create as many agent dev accounts as you want without TOS risk. You can even allow your agents to @ each other, if you're token-uninhibited.
Containerizing the webhook server and agent CLI tools provides agent isolation from the host system without the need for the agents to aggresively sandbox themselves. What this means: agents can run in YOLO mode with access to only the tools they need and the codebase. They can get their job done without approval, and without risk.
Each agent CLI authenticates using your host account credentials, bind-mounted into the container. Agent operations bill to your existing subscription -- no separate API keys, no open-ended usage-based billing, and your plan's rate limits act as natural spending guardrails. If you're already authenticated in the host CLI, your agents are ready to work, using their own native harnesses that were already purpose-built to produce.
- BYOA — Agent-agnostic by design. Route GitLab webhooks to Claude, Gemini, Codex, or any custom CLI agent (OpenCode, Goose...) using flexible, first-match YAML routing rules.
- Event-driven agent orchestration — GitLab webhooks triggered by repository events are processed by the router; mentioning an agent in issue or MR comments dispatches it with full event context, and multi-mention comments (or
@all) fan out into separate, independent dispatches with per-mention event tracking. - On-demand project cloning — Projects are cloned automatically on first webhook trigger, with namespace-aware paths and concurrent-clone protection — no manual repo setup required.
- Automatic branch resolution — The system detects the relevant branch from the webhook payload and checks it out before the agent starts work, including divergence handling, backup branch creation, and stale branch auto-cleanup.
- Filesystem-enforced write protection — Projects are dual-mounted (read-only and read-write); routes select which mount the agent receives, enforcing access control at the OS level rather than by convention.
gitlab-connectCLI wrapper — An agent-aware wrapper aroundglabthat handles per-agent authentication, credential rotation, git identity setup, and file-based content input for issues, MRs, and comments.- Template-based prompt injection — Prompt templates with
${VARIABLE}substitution pull real-time context from GitLab (issue body, MR diff, branch info) and inject it into agent task prompts. - Live streaming dashboard — A real-time web UI with WebSocket-backed panes for agent stdout, thinking output, prompts, and system logs, plus a kill switch for runaway processes.
- Structured run logging — Every agent execution is captured as a JSON file (prompt, stdout, stderr, return code, branch context) with configurable retention and automatic pruning.
- Webhook deduplication and queue management — UUID-based event tracking with configurable TTL prevents duplicate processing; an in-memory async queue serializes dispatches.
- Features
- Quick Start
- Overview
- System Architecture
- Key Components
- Project Layout
- Prerequisites
- Configuration
- Local Development
- Routing & Prompts
- Testing
- Dependency Management
- Docker Deployment
- Logging & Observability
- Security Considerations
- Troubleshooting
- Additional Documentation
This project has been heavily documented to make it agent-friendly. Clone it, point your agent at it, have it help you set it up. Shortcut!
Before you begin: This assumes you already have a self-hosted GitLab CE instance. If you need to stand one up, see
gitlab/readme-gitlab.mdandgitlab/docker-compose.gitlab.ymlfor a reference deployment — it includes an entrypoint wrapper that automatically creates an admin token and configures webhook delivery on first boot. Create GitLab user accounts for each agent you plan to use (claude,gemini,codex, etc.), generate a Personal Access Token (PAT) withapiscope for each, and invite the agent accounts to your target project(s) with Developer role (Project > Members > Invite member). For multi-project setups, add agents at the Group level so access is inherited automatically -- seedocs/GROUP_SETUP.md. Agents cannot interact with projects they are not members of, even if webhooks are configured correctly.
- Install Node.js using
nvm(ensures a modern LTS build) and then install the agent CLIs:The CLIs will be available ascurl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" nvm install --lts npm install -g @anthropic-ai/claude-code @google/gemini-cli @openai/codex
claude,gemini, andcodexon yourPATH.
note1: some of these agent CLIs are migrating to native installers. Consult the latest installation guides for each.
note2: you can omit any of these agents from your config, just remove all references to that agent from your routing rules. - Authenticate each agent CLI under your user account so their configs live in
~/.claude,~/.gemini, and~/.codex:Run each command interactively once to seed credentials; Docker mounts the same directories so automation reuses your local auth. Using your personal subscription means agent operations stay under your existing plan limits. Requires a paid subscription for each provider you intend to use (or locally-hosted models if you're a cowboy).claude # follow the interactive prompts (Anthropic) gemini # sign in with your Google account codex # authenticate with your OpenAI account
- Clone the repository and change into it:
git clone https://github.com/mcknly/robot-dev-team.git cd robot-dev-team - Copy
.env.exampleto.envand populate the required values:cp .env.example .env nano .env
- Set the agent GitLab PATs (
CLAUDE_AGENT_GITLAB_TOKEN,GEMINI_AGENT_GITLAB_TOKEN,CODEX_AGENT_GITLAB_TOKEN) generated from the agent accounts created in the prerequisite step above. - Set
GLAB_TOKENto your own PAT withapiscope for the app process — used for procedural GitLab tasks (context enrichment, auto-unassign, termination comments) and is separate from the per-agent tokens. - Set
GLAB_HOSTto your GitLab instance hostname. - Set
GITLAB_WEBHOOK_SECRETto a shared secret token (this must match the value configured in the GitLab webhook settings in step 9) - optionally leave blank. - Set
CLAUDE_MODEL,GEMINI_MODEL, andCODEX_MODELto the desired default model for each agent (e.g.,claude-opus-4-6,gemini-3.1-pro-preview,gpt-5.4). These are required when the defaultroutes.yamlreferences${..._MODEL}placeholders -- if your routes hard-code the model value or omit--model, the corresponding variable can be skipped. - Set
LOCAL_UID/LOCAL_GIDto your local user/group ID (useid -u/id -g- docker-compose defaults to 1000; mismatches will cause bind-mount permission errors). - See
docs/ENVIRONMENT.mdfor the full variable reference. - To omit a default agent, remove its route entries from
routes.yaml, remove it fromALL_MENTIONS_AGENTS(if set), and optionally remove its env vars and Docker volume mounts. See the "Removing an Agent" section indocs/ADDING_AN_AGENT.mdfor details.
- Set the agent GitLab PATs (
- Edit
docker-compose.ymlto set the project volume mount paths (the./projects:/work/projectslines) to a local directory that will serve as the working directory for project repositories. This directory can start empty — withENABLE_AUTO_CLONE=true, projects are cloned automatically on first webhook trigger using the<namespace>/<project-name>structure. You can also pre-clone repositories here if preferred. - Configure routing rules for your GitLab username. Copy
config/routes.yamltoconfig/routes.local.yaml, replaceyour-usernamewith your GitLab username, and addROUTE_CONFIG_PATH=config/routes.local.yamlto your.env. This keeps your local configuration separate from the shipped defaults. - Ensure your account can run Docker without
sudo:sudo usermod -aG docker "$USER" newgrp docker # or log out/in docker info # verify access works without sudo
- Start the containerized stack:
docker compose up --build
- Configure the GitLab webhook to point at
http://localhost:8080/webhooks/gitlab(or your tunnel URL) and send a test event. Seedocs/GITLAB_WEBHOOKS.mdfor detailed webhook configuration including event selection and secret token setup, ordocs/GROUP_SETUP.mdfor automated webhook provisioning via File Hooks. SetLIVE_DASHBOARD_ENABLED=truein.envto enable the live dashboard at/dashboard. SetDEBUG_RELOAD_ROUTES=true, configure a route in your routes file (e.g.,config/routes.local.yaml), trigger the event, confirm a run log appears on the dashboard and inrun-logs/.
- Install Node.js via Homebrew and add the agent CLIs (follow latest guides)
- Authenticate each CLI so credentials live under
~/.claude,~/.gemini, and~/.codex(as above). - Install Docker Desktop for Mac and ensure it is running (
docker infoshould succeed in a new terminal). - Clone the repository, configure
.env, and edit volume mount paths as in steps 3-6 of the Linux section. - Launch the stack from the terminal:
docker compose up --build
- Configure & test the GitLab webhook as in step 9 of the Linux section. See
docs/GITLAB_WEBHOOKS.mdfor full webhook setup details.
- Install WSL2 (
wsl --install -d Ubuntu) and Docker Desktop, enabling Docker WSL integration for your distribution. - Inside the WSL shell, install Node.js with
nvmas in the Linux section. - Install & authenticate the agent CLIs as above.
- Install Git and clone the repository inside the WSL filesystem (e.g.,
/home/<user>/robot-dev-team). Configure.envand edit volume mount paths as in steps 3-6 of the Linux section. - Make sure your WSL user belongs to the
dockergroup (sudo usermod -aG docker "$USER"andnewgrp docker), then start the stack:docker compose up --build
- Configure the GitLab webhook to call
http://localhost:8080/webhooks/gitlab(accessible from Windows via Docker Desktop) or point it at a tunnel URL. Seedocs/GITLAB_WEBHOOKS.mdfor full webhook setup details. Send a test event and verify a run log is written.
GitLab projects can be configured to emit webhook events (merge requests, issues, comments). This service receives those events, optionally enriches them via glab, renders prompts from templates, and shells out to one or more agent CLIs configured per event type. Each agent can authenticate to GitLab via the bundled glab-usr helper and then post results back through the GitLab API via gitlab-connect, a custom helper script for wrapping glab and making it more agent-friendly.
- Webhook listener: FastAPI endpoint validates secrets, deduplicates events, and normalizes metadata.
- Event router: Matches incoming events against YAML rules that specify which agents to invoke and determines whether the payload should fan out per user mention.
- Trigger queue: Buffers mention-level trigger jobs in FIFO order before invoking agents, smoothing bursts of webhook traffic.
- Context builder: Retrieves additional GitLab data via
glaband renders prompt templates. - Agent runner: Streams prompts into CLI processes, captures outputs, and logs results to disk.
- FastAPI application (
app/main.py) — hosts/webhooks/gitlaband/healthendpoints. - Routing engine (
app/services/routes.py) — loadsconfig/routes.yaml, supports optional hot reloads. - Context enrichment (
app/services/context_builder.py) — fetches merge request/issue data throughglabhelpers. - Agent execution (
app/services/agents.py) — runs CLI commands, recording stdout, thinking (stderr), and prompt payloads inrun-logs. - Trigger queue (
app/services/trigger_queue.py) — serializes mention-level trigger jobs before delegating to the agent runner. gitlab-connecthelper — unified wrapper that authenticates for the active agent and proxies common issue/MR workflows (create/edit/comment/view) with structured logging.glab-usrhelper — low-level credential switch retained for direct authentication control.- Live dashboard (
app/api/dashboard.py,app/services/dashboard.py) — real-time web UI with WebSocket-backed streaming of agent stdout, thinking output, prompts, and system logs; includes a kill switch for terminating runaway agent processes (seedocs/DASHBOARD_GUIDE.md). - Docker assets —
Dockerfile,docker-entrypoint.sh, anddocker-compose.ymlreproduce the runtime described indocs/SYSTEM_DESIGN.md.
app/
api/ # FastAPI routers
core/ # Settings & logging utilities
services/ # Routing, context building, agent orchestration, glab helpers
config/
routes.yaml # Sample routing rules
header_guard.toml.example # Sample overrides for header guard coverage
docs/ # Contributor, environment, and operations guides
prompts/ # Prompt templates consumed by agents
scripts/
header_guard.py # Header compliance checker
generate-sbom.sh # SBOM extraction helper
tests/ # Pytest suite (mocked glab/agent subprocesses)
run-logs/ # Per-event agent output (populated at runtime)
npm-cache/ # Shared npm cache volume for agent CLIs
gitlab/ # Reference GitLab CE deployment & File Hook script
docker-entrypoint.sh # Container entrypoint (credentials, CLI install)
docker-compose.yml
Dockerfile
gitlab-connect # Agent-aware glab wrapper
glab-usr # Low-level credential switch
launch-uvicorn-dev # Local dev server launcher
pyproject.toml
.env.example
SECURITY.md
LICENSE
When running outside Docker:
- Python 3.12 or newer
- Node.js + npm (installs agent CLIs during startup)
- GitLab CLI (
glab) - Agent CLIs (
claude,gemini,codex, etc.) accessible on$PATH - Git access to repositories referenced by incoming events
- Copy
.env.exampleto.envand set the required values:GLAB_HOST— GitLab instance hostname (e.g.,gitlab.example.com).GLAB_TOKEN— a PAT withapiscope for the app process, used for procedural GitLab tasks such as context enrichment, auto-unassign, and termination comments (separate from the per-agent tokens). Seedocs/ENVIRONMENT.mdfor scope details.GITLAB_WEBHOOK_SECRET— shared token configured in GitLab project webhook settings (leave empty if GitLab and the listener share a trusted network/host).CLAUDE_AGENT_GITLAB_TOKEN,GEMINI_AGENT_GITLAB_TOKEN,CODEX_AGENT_GITLAB_TOKEN— personal access tokens for each agent account. On startup the entrypoint mirrors these into~/.claude/glab-token,~/.gemini/glab-token, and~/.codex/glab-token(with0600permissions) so sandboxed agent subprocesses can still authenticate even if environment variables are stripped.CLAUDE_MODEL,GEMINI_MODEL,CODEX_MODEL— default model for each agent (e.g.,claude-opus-4-6,gemini-3.1-pro-preview,gpt-5.4).LOCAL_UID/LOCAL_GID— set toid -u/id -gso the container remapsappuserto your host identity (defaults to 1000 if unset).- See
docs/ENVIRONMENT.mdfor the full variable reference including optional settings (timeouts, log pruning, branch switching, dashboard, etc.).
- Edit the project volume mount paths in
docker-compose.yml(the./projects:/work/projectslines) to a local directory that will serve as the working directory for project repositories. This can start empty — withENABLE_AUTO_CLONE=true, projects are cloned automatically on first webhook trigger using the<namespace>/<project-name>structure. The container mounts the directory to/work/projects(read-write) and/work/projects-ro(read-only); routes use theaccessfield to determine which mount the agent receives. - Maintain prompt templates under
prompts/(plain text processed viastring.Template).
- Create or designate GitLab user accounts for each agent (
claude,gemini,codex). These accounts should have:- Developer (or higher) access to every project the automation will interact with.
- Profile name and avatar matching the agent persona for clarity in activity feeds.
- Email (can be fake) - must match the variable in
.env.
- Generate a Personal Access Token (PAT) for each agent with
apiscope. Agents interact with GitLab through the API (commenting, creating issues/MRs, updating assignments) and push code via git, soapiis the recommended minimum.- Keep token lifetimes reasonable and rotate on a schedule that matches your security policy.
- Store the PATs in
.env:The entrypoint mirrors these values into agent-specific credential files so CLI subprocesses can authenticate.CLAUDE_AGENT_GITLAB_TOKEN=glpat-xxx GEMINI_AGENT_GITLAB_TOKEN=glpat-yyy CODEX_AGENT_GITLAB_TOKEN=glpat-zzz
- Invite each agent account to the required repositories with Developer role (Project → Members → Invite member). Confirm they appear in the member list before sending webhooks.
- Optionally create dedicated GitLab groups for agents to simplify project access management. Add the group to projects at the desired role level and manage tokens centrally.
- Configure a webhook on each project (or group) to send events to the automation service. Navigate to Settings > Webhooks, set the URL to your listener endpoint (e.g.,
http://localhost:8080/webhooks/gitlabor your tunnel URL), paste theGITLAB_WEBHOOK_SECRETvalue as the secret token (if used), and enable Issues events, Merge request events, and Note (comments) events. Seedocs/GITLAB_WEBHOOKS.mdfor the full walkthrough including event selection, mention routing, local development tips, and troubleshooting. - For multi-project self-managed GitLab deployments, deploy the File Hook script (
gitlab/file_hooks/add_webhooks.rb) to automate webhook creation on new projects within a GitLab group. This eliminates the need to manually configure webhooks each time a project is added. Seedocs/GROUP_SETUP.mdfor the complete guide including environment variables, validation, and the GitLab CE File Hook setup.
Install dependencies with uv, run the API, and tail logs (refer to docs/AGENT_ONBOARDING.md for platform-specific checklists):
python -m venv .venv
source .venv/bin/activate
pip install uv
uv pip install --editable .
./launch-uvicorn-devSet GITLAB_WEBHOOK_SECRET in .env (or environment) and start a tunnel (e.g., ngrok) if GitLab needs to reach your local machine.
launch-uvicorn-dev loads variables from .env and docker-compose.yml, checks that .venv contains python and uvicorn, and then starts Uvicorn with --reload. Pass additional flags (e.g., --log-level debug) after the command if needed.
config/routes.yamldefines an ordered list of rules. Each rule specifies the event/action/author/labels/mentions to match, anaccessmode (readonlyorreadwrite), and the agents to execute (seedocs/ROUTES.mdfor the full schema and examples).- When a webhook names multiple users, any rule that lists exactly one
mentionsvalue is evaluated separately for each username so agents receive individualized triggers. Rules without amentionsfilter (or with multiple values) still resolve once using the full mention list. agents[].optionsmay override the executable (command), arguments (args), or inject environment variables.- Prompt templates default to
{task}.txtwhen not explicitly provided. The globalprompts/system_prompt.txtfile is prepended to every task prompt so shared guidance (available tools, safety notes, etc.) is always included. - Context values available to templates include
${PROJECT},${TITLE},${DESCRIPTION},${AUTHOR},${URL},${EXTRA},${JSON}(full payload JSON),${SOURCE_BRANCH},${TARGET_BRANCH}, and${CURRENT_BRANCH}.
Agents interact with GitLab via the gitlab-connect wrapper, which automatically authenticates using the current agent context (CURRENT_AGENT) before delegating to glab. This also allows passing a description body file to directly to glab which does not handle this natively, avoiding agent tool use issues.
Common flows:
gitlab-connect issue create --title "Bug" --file body.mdgitlab-connect issue comment 42 --file reply.mdgitlab-connect issue view 42(includes comments and activities)gitlab-connect mr comment 17 --file feedback.mdgitlab-connect mr view 17
Pass additional glab issue/glab mr flags after --.
The automated test suite in tests/ exercises route resolution, context enrichment, agent dispatch logging, and webhook handling (with mocked glab and agent executions). To run the tests locally:
python -m venv .venv
source .venv/bin/activate
pip install uv
uv pip install --editable .[dev]
pytestKey coverage areas:
tests/test_routes.py— routing resolution against event metadata.tests/test_context_builder.py— context assembly and prompt rendering with mockedglabdata.tests/test_agents.py— agent subprocess orchestration and structured log output.tests/test_webhooks.py— webhook authentication, deduplication, and dispatch via FastAPI test client.tests/test_glab.py— GitLab CLI helpers, token resolution, and fallback behaviour.tests/test_trigger_queue.py— trigger queue FIFO processing and mention hold/promotion.tests/test_dashboard.py— dashboard endpoints and WebSocket streaming.tests/test_branch_resolver.py— branch detection and checkout logic.tests/test_branch_pruning.py— stale branch auto-cleanup.tests/test_mention_hold.py— mention hold buffer timing and cancellation.tests/test_config.py— settings loading and validation.tests/test_project_paths.py— project path resolution and namespace handling.tests/test_log_pruning.py— run-log retention and automatic pruning.
Dependency pinning, lockfile workflows, SBOM handling, and supported toolchain versions live in docs/DEPENDENCY_MANAGEMENT.md. Review that guide—and run scripts/generate-sbom.sh when dependency footprints change—before bumping packages or base images.
Build and run the stack:
docker compose up --buildKey volume bindings in docker-compose.yml:
~/.claude,~/.gemini,~/.codexmount directly into the container user's home. Because the container remapsappuserto your host UID/GID, the CLIs reuse the same credentials and the entrypoint writes token mirrors (glab-token) back onto the host for sandboxed agent use. SetLOCAL_UID/LOCAL_GIDin.env(typicallyid -u/id -g) so the container remapsappuserto your host identity before startup;docker-compose.ymlfalls back to 1000 when unset../npm-cache— caches global npm installs for agent CLIs../projects(configurable indocker-compose.yml) — parent directory containing all project repositories. Mounted twice: read-write at/work/projectsand read-only at/work/projects-ro. Projects should be organized as<namespace>/<project-name>to match GitLab's path structure. Routes withaccess: readonlyuse the read-only mount (default), whileaccess: readwriteroutes use the writable mount.
The entrypoint verifies that the npm cache directory is writable, falling back to /tmp/npm-cache if not. If the bind-mount is owned by the host user, ensure it is group/world writable (e.g., chmod 777 npm-cache) or point NPM_CONFIG_CACHE at a writable path so CLI installation succeeds. Run-log writes fall back to /tmp/run-logs automatically if the primary directory is not writable.
The container runs as a non-root appuser, installs agent CLIs on startup via docker-entrypoint.sh, and launches FastAPI with Uvicorn. Update environment variables in .env or compose overrides before deployment.
- Source code is released under the MIT License. Keep the license notice with redistributed copies and note that dependencies reuse permissive MIT/BSD/Apache terms (see table below).
- Every tracked source, documentation, and script file carries a structured header that mirrors the license, SPDX identifier, and copyright owner.
- Run
uv run python scripts/header_guard.pyduring CI or before commits to ensure new files retain the header tokens; add the header template shown indocs/CONTRIBUTING.mdwhen creating files manually. - Extend coverage without editing the script by copying
config/header_guard.toml.exampletoconfig/header_guard.tomland listing extra suffixes, filenames, or exclusion prefixes. - When introducing new direct dependencies, confirm they ship with permissive obligations and update the dependency table accordingly.
Verified against uv.lock on March 15, 2026.
| Dependency | Version | License | Notes |
|---|---|---|---|
| fastapi | 0.135.1 | MIT | Includes Starlette and Pydantic under the same permissive terms. |
| uvicorn | 0.41.0 | BSD-3-Clause | Redistribute with attribution notice retained. |
| pydantic-settings | 2.13.1 | MIT | Shares the Pydantic license terms. |
| pyyaml | 6.0.3 | MIT | No additional obligations beyond notice preservation. |
| mypy | 1.19.1 | MIT | Development-only static analysis. |
| pytest | 9.0.2 | MIT | Development-only testing. |
| httpx | 0.28.1 | BSD-3-Clause | Requires attribution when distributed. |
| pytest-asyncio | 1.3.0 | Apache-2.0 | Provides async test support; keep notice if packaged. |
| ruff | 0.15.6 | MIT | Development-only linting. |
| types-PyYAML | 6.0.12.20250915 | Apache-2.0 | Type stubs consumed during development. |
- Structured logs emit to stdout in
timestamp | LEVEL | logger.name | messageformat. Control verbosity withAPP_LOG_LEVEL(defaultINFO). Seedocs/ENVIRONMENT.mdfor a level guide anddocs/SYSTEM_DESIGN.md(section 9) for the full logging reference including key logger names, dashboard mirroring behavior, and troubleshooting recipes. - Agent outputs (prompt, stdout, stderr) are written to
run-logs/as JSON files named<event_uuid>-<project>-<route>-<agent>.out.json(project and route segments are optional and sanitized). - When
LIVE_DASHBOARD_ENABLED=true, visit/dashboardto watch real-time stdout/thinking/prompt streaming plus system logs. Dashboard system logs primarily mirror events controlled byAPP_LOG_LEVEL(plus a small number of dashboard-originated events such as kill-switch notifications) and use a simplified payload format (message, level, logger name). - Active agents appear in the dashboard header; click the red Kill button to terminate the running subprocess and cancel the remaining agent queue for that event.
GET /healthreturns{ "status": "ok" }for liveness probes.- Webhook responses include a
triggersarray describing each queued mention-level trigger (event id, route name, mentions list, and agent results).
- Review the SECURITY.md guidance for container hardening, supply-chain controls, and operational checklists.
- Webhook requests must include the configured
X-Gitlab-Tokenheader; terminate TLS at a trusted proxy and enforce rate limiting/IP allowlists where possible. - Store GitLab personal access tokens with least privilege (typically comment or note creation only) and inject them with a secret manager.
- Host token mounts (
~/.claude,~/.gemini,~/.codex) remain read/write so the entrypoint can refreshglab-tokenfiles; lock down host directory permissions to keep tokens safe. - For production hardening, consider running the container with dropped capabilities (
--cap-drop ALL --security-opt no-new-privileges) and a dedicated UID/GID (LOCAL_UID/LOCAL_GIDor--user). These options are not set in the defaultdocker-compose.yml.
- Invalid webhook token — confirm
GITLAB_WEBHOOK_SECRETmatches GitLab hook settings. - No matching routes — enable
DEBUG_RELOAD_ROUTES=trueand inspectconfig/routes.yamlfor event/action mismatch. - Agent command not found — verify CLI executables exist on the host or inside the container and update
agents[].options.commandif using custom wrappers. glabfailures — confirmGLAB_HOSTand tokens are configured; runglab auth statusinside the container to debug.- Permission issues accessing repositories — make sure compose volume paths map to directories accessible by the Docker daemon and align with the
appuserUID (LOCAL_UID, defaults to 1000 indocker-compose.yml). - npm cache permission errors — adjust permissions on the host cache directory or set
NPM_CONFIG_CACHE=/tmp/npm-cachebeforedocker compose up. - Run-log write failures — ensure
run-logs/is writable by the container user or remove the bind mount to fall back to/tmp/run-logs. - Inotify watcher exhaustion — heavy file watchers (Claude’s dev server, VS Code, Expo, etc.) can consume the host inotify budget and trigger
Too many open files. Inspect usage withsudo inotifywatch -r .orfind /proc/*/fd, bump the host sysctls (sudo sysctl fs.inotify.max_user_watches=262144 fs.inotify.max_user_instances=512), and restart the services. The FastAPI container inherits these limits; usesysctls:in compose if you need to lower them per container. - Queued triggers backing up — check application logs for slow agent runs; the trigger queue processes mention-level jobs sequentially, so one long task can delay others.
- Missing agent responses on GitLab — often times this is a server issue - either the cloud providers have capacity constraints or you have hit a usage cap. Check
run-logs/files for raw output.
docs/ADD_NEW_PROJECT.md— checklist for adding a new project to an existing deployment.docs/ENVIRONMENT.md— environment variables,.envsamples, and Compose overrides.docs/AGENT_ONBOARDING.md— setup checklist for Linux and Windows (WSL) operators.docs/GITLAB_WEBHOOKS.md— step-by-step GitLab webhook configuration and tunnel tips.docs/GROUP_SETUP.md— GitLab group setup with automatic webhook provisioning.docs/DASHBOARD_GUIDE.md— live dashboard usage and kill switch behaviour.docs/CONTRIBUTING.md— issue workflow, branching strategy, and MR expectations.docs/CHANGELOG.md— release notes beginning with v0.1.0.docs/SYSTEM_DESIGN.md— canonical architecture reference and container expectations.docs/DEPENDENCY_MANAGEMENT.md— dependency pinning policy, update cadence, and SBOM workflow.docs/ADDING_AN_AGENT.md— step-by-step guide for onboarding a custom agent CLI (BYOA).docs/ROUTES.md— routing rule schema, field reference, and configuration examples.docs/SANITIZATION_REPORT.md— pre-release sanitization audit results.gitlab/readme-gitlab.md— reference GitLab CE deployment and upgrade path.

