From 01e082ff63292fb50b8ffc645e06d025159602df Mon Sep 17 00:00:00 2001 From: Renn F Date: Fri, 19 Jun 2026 10:23:49 +0200 Subject: [PATCH] chore(release): 0.7.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Roll up everything since 0.6.0 into the 0.7.0 CHANGELOG and bump the version (pyproject / __init__ / config.app_version). Rewrite the stale Unreleased Grok entry — which described the now-deleted opencode runtime — to the shipped reality: Grok agents on xAI's official grok CLI on a SuperGrok subscription, plus the token auto-refresh, the self-healing CI loop, the Company Scorecard, and the pr-reviewer / observability / usage / path-injection fixes. Also folds the uv.lock claude-agent-sdk spec sync (>=0.2.105) merged via #216. --- CHANGELOG.md | 13 +++++++++++-- README.md | 2 +- deployment.md | 2 +- panel/package.json | 2 +- pyproject.toml | 2 +- roboco/__init__.py | 2 +- roboco/config.py | 4 ++-- uv.lock | 2 +- 8 files changed, 19 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b2ec2449..b3c1afc7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,11 +4,20 @@ All notable changes to RoboCo are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] +## [0.7.0] - 2026-06-19 ### Added -- **Pluggable agent providers + a Grok (xAI) backend.** A new `roboco/llm/providers/` seam (an `AgentProvider` lifecycle ABC + a `ProviderRegistry` keyed by `ModelProvider`) lets the orchestrator drive agent backends other than Claude Code. The first is `GrokProvider` for xAI's `grok-build-0.1`: xAI is OpenAI-compatible only (no Anthropic-Messages endpoint), so a Grok agent runs an OpenAI-protocol runtime pointed at `https://api.x.ai/v1` rather than the `ANTHROPIC_BASE_URL` injection the other providers use — and it reuses the orchestrator's existing mount/auth assembly, so it gets the same MCP gateway + tool-manifest wiring as every other agent by construction (and passes its prompt via env, never an argv positional). The change is purely additive: only `GROK` routes through the registry; Anthropic / Ollama Cloud / self-hosted spawns are untouched. Includes the `grok` enum value (migration 038), a seeded Grok provider row (migration 039), a `grok-build-0.1` catalog entry, and `GET/PUT /api/providers/grok-key` + a Settings panel card to store the xAI key (Fernet-encrypted, reusing the existing provider-key machinery). Ships the full native runtime: a first-class `roboco-agent-grok` image (built `FROM` agent-base, adds opencode; wired into both compose files, the registry compose, and the release workflow) whose entrypoint renders an `opencode.json` at spawn — translating RoboCo's MCP gateway servers into opencode's config and declaring the xAI provider — then runs opencode. KNOWN PARITY GAP: RoboCo's bash-guard (PAT-scrub) and transcript-based usage/cost capture are Claude Code hooks that do not transfer to the opencode runtime; the `bash` permission is operator-tunable so a deployment can fail closed until a security/usage-parity opencode plugin lands. That plugin and live end-to-end validation are the remaining work to finalize with xAI. +- **Grok agents on xAI's official `grok` CLI, on a SuperGrok subscription.** A new `roboco/llm/providers/` seam (an `AgentProvider` lifecycle ABC + a `ProviderRegistry` keyed by `ModelProvider`) lets the orchestrator drive agent backends other than Claude Code, and the first is Grok — running xAI's official `grok` CLI authenticated by a **SuperGrok subscription** rather than a metered API key, so a Grok workforce can't stall mid-task on out-of-credits. It reaches parity with the Claude path by construction: the same MCP gateway + tool-manifest wiring, per-role tool removal and git-operation deny rules, a prompt-injection guard on the task prompt, headless tool auto-approval, and per-agent token/cost capture from the grok session store. It covers both one-shot delivery roles and the interactive Intake (Prompter) and Secretary chats (per-turn `grok -p` with session resume, streamed turn-by-turn). The change is purely additive — only `GROK` routes through the registry; Anthropic / Ollama Cloud / self-hosted spawns are untouched — and ships migration 038 (the `grok` enum) + 039 (the seeded provider row), first-class `roboco-agent-grok` / `-prompter` / `-secretary` images wired into all three compose files and the release workflow, and a Settings provider card. +- **SuperGrok token auto-refresh.** The grok access token has a fixed ~6h server-set TTL and the CLI cannot refresh it headlessly — on an expired token it hangs forever at an interactive login prompt — so the orchestrator now mints a fresh token from the offline-access refresh token (xAI's OIDC `refresh_token` grant) before expiry and rewrites the shared `auth.json` in place, keeping every Grok agent's credential live with no recurring manual `grok login`. As a backstop the agent entrypoint refuses to start (exit 78) on a missing or expired token instead of hanging. +- **Self-healing CI loop (default-off).** RoboCo can now watch its own repository's CI and, on a detected regression, open a fix task that is held out of dispatch until the CEO approves it — then dispatch it through the normal delivery flow, so the company repairs its own breakages. It is dormant by default and armed from two Feature-Flags panel toggles; the CI signal is scoped to a single named workflow, and task origination is bounded by rolling and per-cycle caps so it can't flood the backlog. +- **Company Scorecard.** A company scorecard on the panel's Business Goals tab. + +### Fixed + +- **The PR-reviewer is no longer wedge-killed before it can post a review.** `pr_review_claim` now seeds the claim heartbeat like every other claim path; without it a Grok reviewer was treated as a silent (NULL-heartbeat) wedged container and killed before it could call `post_pr_review`, churning the task back to pending in a respawn loop. +- **Grok one-shot runs are observable, and their usage is captured.** The entrypoint streams agent activity to the container log live (`--output-format streaming-json`) instead of buffering it to a file until the run ends, and per-agent token/cost is read from the grok session store's actual cumulative-total field (it was silently reading `$0`). +- **Path-injection hardening of the Grok usage directory.** The agent id is validated and reduced to a single safe path component before it is used to build the per-agent usage path, on both the write/mount and finalize-read sides. ## [0.6.0] - 2026-06-17 diff --git a/README.md b/README.md index 12973904..df2aa32f 100644 --- a/README.md +++ b/README.md @@ -120,7 +120,7 @@ Choose the registry and version with two env vars (defaults shown): ```bash ROBOCO_REGISTRY=ghcr.io/rennf93 # or docker.io/renzof93 -ROBOCO_VERSION=latest # or a pinned release, e.g. 0.6.0 +ROBOCO_VERSION=latest # or a pinned release, e.g. 0.7.0 ``` The orchestrator spawns the matching pre-built agent images on demand — no build toolchain or source compile on your host. diff --git a/deployment.md b/deployment.md index a41ecaf7..947534ba 100644 --- a/deployment.md +++ b/deployment.md @@ -41,7 +41,7 @@ docker compose -f docker-compose.registry.yml up -d docker compose -f docker-compose.registry.yml logs -f orchestrator ``` -Choose the registry and version with `ROBOCO_REGISTRY` (`ghcr.io/rennf93` or `docker.io/renzof93`) and `ROBOCO_VERSION` (`latest` or a pinned release such as `0.6.0`). The orchestrator pulls and spawns the matching pre-built agent images on demand. +Choose the registry and version with `ROBOCO_REGISTRY` (`ghcr.io/rennf93` or `docker.io/renzof93`) and `ROBOCO_VERSION` (`latest` or a pinned release such as `0.7.0`). The orchestrator pulls and spawns the matching pre-built agent images on demand. ### Option B — Build from source diff --git a/panel/package.json b/panel/package.json index 9995fc73..307965ca 100644 --- a/panel/package.json +++ b/panel/package.json @@ -1,6 +1,6 @@ { "name": "roboco-panel", - "version": "0.6.0", + "version": "0.7.0", "private": true, "packageManager": "pnpm@10.25.0", "scripts": { diff --git a/pyproject.toml b/pyproject.toml index 2ca5fb45..2b6813aa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "roboco" -version = "0.6.0" +version = "0.7.0" description = "AI Agents Company - A virtual organization of AI agents functioning as a software development workforce" authors = [ {name = "Renzo Franceschini", email = "rennf93@users.noreply.github.com"} diff --git a/roboco/__init__.py b/roboco/__init__.py index 8b12550f..56f85c9d 100644 --- a/roboco/__init__.py +++ b/roboco/__init__.py @@ -5,7 +5,7 @@ A virtual organization of 22 AI agents + 1 human CEO, designed to operate as a complete software development workforce. """ -__version__ = "0.6.0" +__version__ = "0.7.0" # Core exports from roboco.config import settings diff --git a/roboco/config.py b/roboco/config.py index 3bf721a5..47ff77a1 100644 --- a/roboco/config.py +++ b/roboco/config.py @@ -28,7 +28,7 @@ class Settings(BaseSettings): # ========================================================================== # Application # ========================================================================== - app_version: str = "0.6.0" + app_version: str = "0.7.0" debug: bool = False environment: str = Field( default="development", pattern="^(development|staging|production)$" @@ -488,7 +488,7 @@ class Settings(BaseSettings): agent_image_tag: str = Field( default="", description=( - "Tag for pre-built agent images (e.g. 'latest' or '0.6.0'). Empty " + "Tag for pre-built agent images (e.g. 'latest' or '0.7.0'). Empty " "leaves the tag implicit (':latest'); only meaningful with " "agent_image_registry set." ), diff --git a/uv.lock b/uv.lock index e452ba3b..269419c1 100644 --- a/uv.lock +++ b/uv.lock @@ -3056,7 +3056,7 @@ requires-dist = [ { name = "anthropic" }, { name = "asyncpg" }, { name = "bandit", marker = "extra == 'dev'" }, - { name = "claude-agent-sdk", specifier = ">=0.2.101" }, + { name = "claude-agent-sdk", specifier = ">=0.2.105" }, { name = "cryptography" }, { name = "deptry", marker = "extra == 'dev'" }, { name = "factory-boy", marker = "extra == 'dev'" },