mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
* feat(ci-watch): config flags Default-off CI-watch config (mirrors self_heal_*): ci_watch_enabled, ci_watch_default_workflow (ci.yml), ci_watch_interval_seconds (1800), ci_watch_max_open_tasks (3), ci_watch_max_per_cycle (1). Registers ci_watch_enabled in the panel FEATURE_FLAGS. 4 tests. * feat(ci-watch): per-project ci_watch_enabled/workflow (migration 048) Adds projects.ci_watch_enabled (bool NOT NULL default false) + projects.ci_watch_workflow (varchar null) — the per-project opt-in for multi-repo CI-watch. ProjectTable + Pydantic Project fields + migration 048 (off 047_ws_single_active). Real upgrade->downgrade->upgrade chain verified against a throwaway Postgres; 2 ORM round-trip tests. * feat(runtime): prune dangling agent images in the background sweeper Every agent-image rebuild orphans the prior build's layers as an untagged <none> image; across deploys these pile up (the operator hit ~80). The sweeper now runs 'docker image prune -f --filter dangling=true' (dangling only — a tagged image or one backing a running container is never dangling), throttled to settings.image_prune_interval_seconds (default 6h) and gated by image_prune_enabled (default on). Best-effort: any failure is logged, never raised into the sweeper. Mirrors the transcript-retention prune. 4 tests. * feat(ci-watch): source tag + open-task dedupe query CI_WATCH_SOURCE='ci_watch' + TaskService.list_open_ci_watch_tasks(git_url=None): non-terminal ci_watch tasks (the dedupe + open-cap basis), optionally scoped to one repo by git_url — a monorepo registers several cell-projects on one git_url, so dedupe keys on the repo, not the slug. 2 real-PG tests. * feat(ci-watch): multi-project CI telemetry fan-out MultiProjectCITelemetrySource.fetch(projects) reuses the hardened per-project get_latest_ci_conclusion for each opted-in project (passing its ci_watch_workflow or the configured default). Per-project isolation: a GitHub error or absent signal yields NO sample (unknown, never read as green) and never aborts the sweep; only a real conclusion yields a sample (fail→breach, pass→non-breach). self-heal source untouched. 3 tests + self-heal regression green. * feat(ci-watch): engine — fan-out, originate, dedupe, cap CiWatchEngine.run_cycle(projects) mirrors SelfHealEngine: assess via MultiProjectCITelemetrySource, open one PENDING ci_watch fix task per red repo (team=main_pm, assigned_to=main-pm, confirmed_by_human=True so it dispatches without an Approve-&-Start — thefe029fe3lesson), never starts/approves/merges. Dedupe per git_url (monorepo → one fix task per repo) + per-cycle/rolling caps. Default-off; disabled → no-op. 5 real-PG tests (red→one task, dedupe, cap, green/none→nothing, disabled). * feat(ci-watch): orchestrator loop tick + watch-set loader _ci_watch_loop (registered in start(), cancelled in stop(), separate from the untouched self-heal loop): dormant unless ci_watch_enabled; each interval loads the watch set (ci_watch_enabled projects, collapsed one-per-repo via the existing _projects_one_per_repo) and runs CiWatchEngine.run_cycle, committing opened tasks. _run_ci_watch_cycle extracted for testing; loud warning when enabled-but-empty. confirmed_by_human=True on the originated task means it dispatches without an Approve-&-Start (no stranding, thefe029fe3lesson). 5 tests (disabled no-op, watch-set filter+one-per-repo, empty warn, engine run). * docs(ci-watch): CHANGELOG + CLAUDE.md for multi-repo CI-watch Document CI-watch (Added) in the CHANGELOG and the Self-Healing & Feature Flags section of CLAUDE.md — it generalizes self-heal to opted-in projects, reuses the hardened per-project CI lookup, never auto-merges, default-off. Adds the ci_watch_enabled flag to the feature-flags enumeration. * feat(dep-update): config flags Default-off dep-update config (mirrors self_heal_*/ci_watch_*): dep_update_enabled, dep_update_interval_seconds (604800 = weekly), dep_update_max_open_tasks (3), dep_update_max_per_cycle (1). Registers dep_update_enabled in FEATURE_FLAGS. 4 tests. * feat(dep-update): per-project dep_update_command/paths (migration 049) Adds projects.dep_update_command (varchar null) + dep_update_paths (varchar[] null) — the per-project opt-in for the dependency-update bot. ProjectTable + Pydantic Project fields + migration 049 (off 048_ci_watch_project_cols). Real upgrade->downgrade->upgrade chain verified on a throwaway Postgres; 2 ORM tests. * feat(dep-update): source tag + open-task dedupe query DEP_UPDATE_SOURCE='dep_update' + TaskService.list_open_dep_update_tasks(git_url=None): non-terminal dep_update tasks (dedupe + open-cap basis), optionally scoped to one repo by git_url (monorepo → one open dependency-update task per repo). 2 real-PG tests. * feat(dep-update): read-only lockfile-diff probe WorkspaceService.dry_upgrade_changes_lockfile(project): clones the project's read clone into a throwaway dir (--no-hardlinks, so the read clone is never mutated), runs project.dep_update_command (no shell, shlex.split), and reports whether any lockfile path (dep_update_paths or inferred uv.lock/pnpm-lock.yaml) is dirty. Fail-safe: null/failing command → False (don't originate on a broken probe), logged; throwaway always removed; never commits/pushes. 5 real-git tests. * feat(dep-update): engine — detect, originate, dedupe, cap DepUpdateEngine.run_cycle(projects) mirrors SelfHealEngine/CiWatchEngine: for each opted-in project (dep_update_command set) with updates available (the read-only probe), open one PENDING dep_update task (team=main_pm, assigned-to main-pm, confirmed_by_human=True), never starts/approves/merges. Cheap checks (command, per-git_url dedupe) before the expensive probe; per-cycle + rolling caps. Default-off; disabled → no-op. 6 real-PG tests. * feat(dep-update): weekly orchestrator loop tick _dep_update_loop (registered in start(), cancelled in stop(), separate from the self-heal + CI-watch loops): dormant unless dep_update_enabled; each interval (default weekly) loads projects with a dep_update_command (one-per-repo) and runs DepUpdateEngine.run_cycle, committing opened tasks. _run_dep_update_cycle extracted for testing; loud warning when enabled-but-no-commands. Refactored stop() to cancel background tasks via a shared _cancel_background_task loop (keeps it under xenon B as the loop count grows). 4 loop tests. Task 7 (anti-stranding dispatch guard) is satisfied by construction: no dispatcher skip targets source='dep_update', and the engine sets confirmed_by_human=True (thefe029fe3lesson), asserted in the engine tests — so the originated task dispatches via the assigned-PM path, never stranded. * docs(dep-update): CHANGELOG + CLAUDE.md for the dependency-update bot Document the dep-update bot (Added) in the CHANGELOG and the Self-Healing & Feature Flags section of CLAUDE.md — read-only lockfile-diff probe, never auto-merges, per-project opt-in via dep_update_command, default-off. Adds the dep_update_enabled flag to the feature-flags enumeration. * feat(ci-watch): route fix-task notification to the project's cell PM On opening a fix task, CiWatchEngine notifies the red project's own cell PM (resolved from project.assigned_cell via foundation AGENTS — e.g. BACKEND → be-pm), not the CEO, once per project per cycle. Best-effort: a notification failure never rolls back the origination. Adds _cell_pm_slug_for + _notify_cell_pm. 1 real-PG test (asserts to_agent='be-pm', not 'ceo'). * feat(ci-watch,dep-update): expose per-project opt-ins in the project API Add ci_watch_enabled/ci_watch_workflow + dep_update_command/dep_update_paths to ProjectUpdate, ProjectUpdateRequest, the PATCH route mapping, ProjectResponse, and project_to_response — so the panel edit-project dialog can read + set the per-project autonomy opt-ins (the columns were unreachable through the API before). Also threads the previously-dropped quality_command through the update route. 1 real-PG update round-trip test. * feat(ci-watch,dep-update): panel project-edit fields for the per-project opt-ins Adds an 'Autonomous Maintenance' section to the edit-project dialog: a CI-watch enable switch + workflow input, and a dependency-update command + lockfile-paths input (comma-separated → list). Threads the four fields through the Project / ProjectUpdate TS types and the mock-mode create fixture. The global on/off toggles already live in Settings → Feature Flags; these are the per-project opt-ins. panel tsc --noEmit + eslint green. * docs(0.12): CI-watch + dep-update bot + image-prune across user docs + RAG New docs/optional/autonomous-maintenance.md (mirrors self-heal.md) covering both engines; optional/index rows; panel settings + projects-and-products notes for the Feature Flags toggles + the edit-project Autonomous Maintenance fields; resilience note for the dangling-image prune; env-reference + RAG config-reference tables for all ROBOCO_CI_WATCH_* / ROBOCO_DEP_UPDATE_* / ROBOCO_IMAGE_PRUNE_* vars; mkdocs nav entry. reflow-check green; prompts unchanged (operator-facing, not agent-facing). * chore(release): 0.12.0 Cut [Unreleased] -> [0.12.0] (CI-watch + dep-update bot + image-prune housekeeping + the post-0.11.1 run-hardening fixes). Bumps all 8 canonical version refs to 0.12.0 (pyproject / uv.lock roboco pkg / panel package.json / __init__ / config.app_version + the README / deployment / agent-image-tag examples). * fix(pr-review): repo-scope external-PR dedupe (no duplicate review on a monorepo) external_review_task_exists keyed on (project_id, pr, head_sha), but a monorepo registers several cell-projects on one git_url and the poll already collapses to one canonical project per repo — so once a review task was re-pointed to a sibling project, the next poll (checking the canonical project) no longer saw it and opened a second review of the same PR (observed: PR #131 reviewed once on guard-core-saas-frontend, once on -backend). Dedupe now spans every project sharing the PR's repo (git_url); re-review on a new head SHA still works; a genuinely different repo with the same PR number is independent. 3 real-PG tests. --------- Co-authored-by: Renn F <rennf93@users.noreply.github.com>
129 lines
7.9 KiB
Markdown
129 lines
7.9 KiB
Markdown
# Configuration Reference
|
|
|
|
Environment variables for RoboCo (prefix: `ROBOCO_`).
|
|
|
|
## API Server
|
|
|
|
| Variable | Default | Description |
|
|
|----------|---------|-------------|
|
|
| `ROBOCO_HOST` | `127.0.0.1` | API host (0.0.0.0 for containers) |
|
|
| `ROBOCO_PORT` | `8000` | API port |
|
|
| `ROBOCO_DEBUG` | `false` | Debug mode |
|
|
| `ROBOCO_ENVIRONMENT` | `development` | development/staging/production |
|
|
|
|
## Database
|
|
|
|
| Variable | Default | Description |
|
|
|----------|---------|-------------|
|
|
| `ROBOCO_DATABASE_HOST` | `localhost` | PostgreSQL host |
|
|
| `ROBOCO_DATABASE_PORT` | `5432` | PostgreSQL port |
|
|
| `ROBOCO_DATABASE_USER` | `roboco` | Database user |
|
|
| `ROBOCO_DATABASE_PASSWORD` | `roboco` | Database password |
|
|
| `ROBOCO_DATABASE_NAME` | `roboco` | Database name |
|
|
|
|
## Redis
|
|
|
|
| Variable | Default | Description |
|
|
|----------|---------|-------------|
|
|
| `ROBOCO_REDIS_HOST` | `localhost` | Redis host |
|
|
| `ROBOCO_REDIS_PORT` | `6379` | Redis port |
|
|
| `ROBOCO_REDIS_DB` | `0` | Redis database |
|
|
|
|
## Workspaces
|
|
|
|
| Variable | Default | Description |
|
|
|----------|---------|-------------|
|
|
| `ROBOCO_WORKSPACES_ROOT` | `/data/workspaces` | Root for agent workspaces |
|
|
| `ROBOCO_WORKSPACE_AUTO_CLONE` | `true` | Auto-clone on first access |
|
|
| `ROBOCO_WORKSPACE_CLONE_TIMEOUT` | `300` | Clone timeout (seconds) |
|
|
|
|
## RAG/Embeddings
|
|
|
|
| Variable | Default | Description |
|
|
|----------|---------|-------------|
|
|
| `ROBOCO_DEFAULT_EMBEDDING_MODEL` | `qwen3-embedding:0.6b` | Embedding model |
|
|
| `ROBOCO_EMBEDDING_DIMENSIONS` | `1024` | Embedding dimensions |
|
|
| `ROBOCO_RAG_CHUNK_STRATEGY` | `fixed` | fixed/semantic/hierarchical/contextual |
|
|
| `ROBOCO_RAG_CHUNK_SIZE` | `512` | Base chunk size |
|
|
| `ROBOCO_RAG_CHUNK_SIZE_DOCS` | `1536` | Chunk size for docs |
|
|
| `ROBOCO_RAG_CHUNK_SIZE_JOURNALS` | `1024` | Chunk size for journals |
|
|
| `ROBOCO_RAG_CHUNK_OVERLAP` | `128` | Chunk overlap |
|
|
| `ROBOCO_RAG_USE_HYBRID_SEARCH` | `true` | BM25 + vector search |
|
|
| `ROBOCO_RAG_USE_CROSS_ENCODER` | `true` | Neural reranking |
|
|
| `ROBOCO_RAG_AUTO_UPDATE_ENABLED` | `true` | Auto-update indexes |
|
|
| `ROBOCO_RAG_AUTO_UPDATE_INTERVAL` | `300` | Update interval (seconds) |
|
|
|
|
## LLM
|
|
|
|
| Variable | Default | Description |
|
|
|----------|---------|-------------|
|
|
| `ROBOCO_LOCAL_LLM_MODEL` | `glm-5:cloud` | Local LLM for RAG |
|
|
| `ROBOCO_LOCAL_LLM_BASE_URL` | `http://roboco-ollama:11434/v1` | OpenAI-compat API |
|
|
| `ROBOCO_OLLAMA_BASE_URL` | `http://roboco-ollama:11434` | Native Ollama API |
|
|
|
|
## Grok provider (xAI)
|
|
|
|
Agents whose provider is `GROK` run xAI's official `grok` CLI. Auth is the host SuperGrok subscription (mounted `~/.grok`), not a metered API key.
|
|
|
|
| Variable | Default | Description |
|
|
|----------|---------|-------------|
|
|
| `ROBOCO_HOST_GROK_DIR` | `~/.grok` | Host dir holding `auth.json`, mounted into Grok agents; the orchestrator auto-refreshes the ~6h token in place. Set up once with `grok login`. |
|
|
| `ROBOCO_GROK_CLI_MODEL` | `grok-build` | Grok CLI model id |
|
|
| `ROBOCO_GROK_AGENT_IMAGE` | `roboco-agent-grok:latest` | Image for Grok delivery agents |
|
|
| `ROBOCO_GROK_REASONING_EFFORT` | (blank) | Per-run reasoning-effort override; blank = the grok CLI default |
|
|
| `ROBOCO_GROK_IDLE_KILL_SECONDS` | `900` | Kill + evict a Grok container that has been ACTIVE-yet-idle (no gateway verb) this long |
|
|
| `ROBOCO_GROK_MAX_COST_USD` | `0.0` | Per-agent Grok cost ceiling (USD); `0` disables |
|
|
|
|
## Feature flags
|
|
|
|
Env-gated subsystems, default-off except the overload break. Each takes effect on the next backend restart; the panel's Settings → Feature Flags card toggles them without hand-editing env.
|
|
|
|
| Variable | Default | Description |
|
|
|----------|---------|-------------|
|
|
| `ROBOCO_CONVENTIONS_ENABLED` | `false` | Architectural Conventions Standard: auto-scaffold `.roboco/conventions.yml`, inject the architecture map, attach baseline constraints, and block `i_am_done` / `pr_pass` on block-level placement and hygiene violations. Off = fully inert. |
|
|
| `ROBOCO_TOOLCHAIN_MATCH_ENABLED` | `false` | Provision each agent workspace with the target project's Python (resolved from its `requires-python` / `.python-version`) and block delivery gates when the suite cannot be executed under it. Off = today's behavior. |
|
|
| `ROBOCO_OVERLOAD_BREAK_ENABLED` | `true` | Park a provider on a persistent model-API overload (HTTP 529 / 500 / 503) the same way a 429 is parked — queue its spawns and probe until it recovers — instead of crash-retrying into the overload. Off = crash-retry behavior. |
|
|
|
|
The company-in-a-box subsystems toggle the same way and are all default-off: web research (`ROBOCO_RESEARCH_ENABLED`), the strategy engine (`ROBOCO_STRATEGY_ENGINE_ENABLED`), and pitch provisioning (`ROBOCO_PROVISIONING_ENABLED`).
|
|
|
|
## Self-Healing CI loop
|
|
|
|
RoboCo watching its own repo's CI. All default-off / dormant.
|
|
|
|
| Variable | Default | Description |
|
|
|----------|---------|-------------|
|
|
| `ROBOCO_SELF_HEAL_ENABLED` | `false` | Master switch (detect + notify the CEO); off = the loop never runs and no CI is fetched |
|
|
| `ROBOCO_SELF_HEAL_ORIGINATE_ENABLED` | `false` | Second opt-in: also open a PENDING fix task on a regression — CEO-gated, never auto-started/merged/deployed |
|
|
| `ROBOCO_SELF_HEAL_PROJECT_SLUG` | (empty) | The registered project that IS RoboCo itself — the only repo it watches and fixes; empty = no-op |
|
|
| `ROBOCO_SELF_HEAL_CI_WORKFLOW` | (empty) | GitHub Actions workflow to scope the CI signal to (e.g. `ci.yml`); empty = latest across all workflows |
|
|
| `ROBOCO_SELF_HEAL_INTERVAL_SECONDS` | `1800` | Seconds between assessment passes |
|
|
| `ROBOCO_SELF_HEAL_MAX_OPEN_TASKS` | `3` | Rolling cap on concurrently-open self-heal tasks |
|
|
| `ROBOCO_SELF_HEAL_MAX_PER_CYCLE` | `1` | Max fix tasks originated per cycle |
|
|
|
|
## Autonomous maintenance
|
|
|
|
The fan-out generalizations of self-heal — they watch any opted-in project, not just RoboCo's own. All default-off; neither ever auto-merges (every task rides the normal delivery + PR-review gate). Per-project opt-in lives on the project row (set in the panel's edit-project dialog), not in env.
|
|
|
|
| Variable | Default | Description |
|
|
|----------|---------|-------------|
|
|
| `ROBOCO_CI_WATCH_ENABLED` | `false` | Master switch for multi-repo CI-watch; off = the loop never runs. Per-project opt-in via `projects.ci_watch_enabled` |
|
|
| `ROBOCO_CI_WATCH_DEFAULT_WORKFLOW` | `ci.yml` | Workflow file the CI signal is scoped to when a project sets no `ci_watch_workflow` |
|
|
| `ROBOCO_CI_WATCH_INTERVAL_SECONDS` | `1800` | Seconds between CI-watch passes |
|
|
| `ROBOCO_CI_WATCH_MAX_OPEN_TASKS` | `3` | Rolling cap on concurrently-open ci_watch tasks |
|
|
| `ROBOCO_CI_WATCH_MAX_PER_CYCLE` | `1` | Max ci_watch fix tasks originated per cycle |
|
|
| `ROBOCO_DEP_UPDATE_ENABLED` | `false` | Master switch for the dependency-update bot; off = the loop never runs. Per-project opt-in via `projects.dep_update_command` |
|
|
| `ROBOCO_DEP_UPDATE_INTERVAL_SECONDS` | `604800` | Seconds between dependency-update passes (default weekly) |
|
|
| `ROBOCO_DEP_UPDATE_MAX_OPEN_TASKS` | `3` | Rolling cap on concurrently-open dep_update tasks |
|
|
| `ROBOCO_DEP_UPDATE_MAX_PER_CYCLE` | `1` | Max dep_update tasks originated per cycle |
|
|
| `ROBOCO_IMAGE_PRUNE_ENABLED` | `true` | Background sweep prunes dangling (`<none>`) Docker images from agent-image rebuilds (only dangling; ~6h throttle). Always-on safety net, not a feature flag |
|
|
| `ROBOCO_IMAGE_PRUNE_INTERVAL_SECONDS` | `21600` | Minimum seconds between dangling-image prune passes |
|
|
|
|
## Security
|
|
|
|
| Variable | Default | Description |
|
|
|----------|---------|-------------|
|
|
| `ROBOCO_ENCRYPTION_KEY` | (required) | Fernet key that encrypts secrets at rest (e.g. per-project git tokens). Generate with `Fernet.generate_key()`. |
|
|
| `ROBOCO_AGENT_AUTH_SECRET` | (required) | HMAC secret the orchestrator signs each agent's `X-Agent-Token` with. |
|
|
| `ROBOCO_AGENT_AUTH_REQUIRED` | `false` | When `true`, every request must carry a valid agent token (secure mode). |
|
|
| `ROBOCO_PANEL_AGENT_TOKEN` | (unset) | The control panel's CEO token, injected by nginx in secure mode. Get it with `make panel-token`. |
|