Gemini DevOps Agent
This is the dev-only execution layer for using the Gemini plan where it is most useful: bounded build, test, deploy, log, and replay work with external truth in exit codes, reports, screenshots, traces, metrics, and rollout status. Codex and Claude remain the architects and engineers. Antigravity CLI runs constrained DevOps recipes and reports evidence back.
The practical change from the original Gemini CLI idea is now mandatory:
use Antigravity CLI (agy), not Gemini CLI, and pin the session to
Gemini 3.5 Flash (High).
Implementation evidence
The scan covered the current BestBuds checkout and the adjacent Reaktor framework checkout. These are the source-of-truth surfaces the tool references:
| Surface | Source files | What it contributes |
|---|---|---|
| Product map | bestbuds/README.md, bestbuds/AGENTS.md | Repo layering, deploy surfaces, target ownership, standing docs deploy rule |
| Build graph | bestbuds/settings.gradle.kts, bestbuds/build.gradle.kts, reaktor/settings.gradle.kts, reaktor/build.gradle.kts | Composite build, Gradle modules, dependeasy, Kotlin/JVM/JS/native target shape |
| CI/CD | bestbuds/.dagger/src/index.ts, .github/workflows/ci.yml, dagger.json | Dagger PR gate, worker bundle/deploy functions, Linux-safe vs host-runner boundaries |
| Worker deploys | bestbuds/DEPLOY.md, bestbuds/package.json, targets/*/package.json, targets/*/wrangler.json | Worker fleet order, Wrangler deploy scripts, log scripts, Cloudflare binding merge |
| Mobile release | bestbuds/fastlane/README.md, fastlane/Fastfile, package.json | Android/iOS debug/release/distribution lanes and Maestro lanes |
| Tests | bestbuds/tests/README.md, target-owned tests/** | Playwright, Maestro, Karate, k6, Keploy, performance budgets |
| k3s ops | bestbuds/cloud/k3s/README.md, status.sh, deploy.sh, apply.sh, targets/reaktorServer/deploy.sh | k3s status, VM/kubeconfig tooling, app-server rollout, Memgraph, ClickHouse, Keploy capture |
| Reaktor shared runners | reaktor/tools/maestro, reaktor/tools/karate, reaktor/tools/k6 | Shared runner contracts and artifact directories |
| Observability | reaktor/reaktor-cloud/README.md, reaktor/reaktor-performance/README.md, performance-observability.md | Pulumi/Grafana stack, OTel direction, Lighthouse/performance reports |
| Data backups | scripts/README-supabase-dump.md, scripts/dump-supabase.sh | Read-only Supabase dump contract and PII handling |
Two older memory paths have drifted in the current checkout: n8n/BUILD_MATRIX.md
and cloud/observability/README.md are not present. The replacement source of
truth is the set above.
Execution model
Codex / Claude
solutioning, architecture, source edits, final judgment
|
| bounded handoff packet
v
tools/gemini-devops/handoff.mjs
recipe catalog + prompt pack + safety class + model pin
|
| agy --model "Gemini 3.5 Flash (High)" --add-dir ../reaktor
v
Antigravity DevOps Executor
reads source-of-truth docs, runs recipe commands, classifies failures
|
v
Gradle / Dagger / npm / Wrangler / Fastlane / Maestro / Playwright /
Karate / k6 / Keploy / k3s / Pulumi / Supabase
|
v
evidence report: exit codes, logs, screenshots, traces, reports, URLs
This is intentionally not a general coding agent. Antigravity should not invent architecture, edit unrelated files, add dependencies, push git state, or decide production safety. It should run a known recipe and return evidence.
Repo tooling
The checked-in tool lives at:
tools/gemini-devops/
README.md
handoff.mjs
recipes.json
agent-card.json
prompts/system.md
The wrapper resolves agy from /Users/ovd/.local/bin/agy if the shell PATH
does not include it. It pins Gemini 3.5 Flash (High) by default and adds the
sibling Reaktor repo with --add-dir /Users/ovd/dev/reaktor.
If any other model is requested, the wrapper refuses the run.
List recipes:
node tools/gemini-devops/handoff.mjs list
Generate a prompt packet without starting Antigravity:
node tools/gemini-devops/handoff.mjs prompt web.reaktor.checks \
--goal "Validate the current Reaktor Web docs and workbench changes."
Run Antigravity:
node tools/gemini-devops/handoff.mjs run web.reaktor.checks \
--goal "Validate the current Reaktor Web docs and workbench changes." \
--timeout 30m
Run interactively when human approval will be needed:
node tools/gemini-devops/handoff.mjs run mobile.ios.smoke \
--interactive \
--goal "Run the iOS dev-login smoke after the chat persistence changes."
Mutating recipes are blocked unless the caller passes --allow-mutating after
operator approval. That includes Cloudflare deploys, k3s rollouts, mobile
distribution, live fixture writes, load tests, Keploy capture, and docs deploy.
Test the handoff layer:
npm run test:gemini-devops
The test suite uses Node's built-in test runner and a fake local agy binary. It
validates the recipe catalog, approval gates, prompt generation, pinned-model
rejection, A2A discovery/message/JSON-RPC packets, and the exact Antigravity
argument shape without spending Gemini tokens.
A2A orchestration
A2A helps at the boundary between the high-quality solutioning agents and the cheap routine executor. Codex or Claude can hand a structured A2A task to the Gemini-backed DevOps executor instead of spending its own context watching Gradle, Wrangler, Maestro, Karate, k6, Keploy, or k3s loops.
The local shape is packet generation, not a long-running server:
node tools/gemini-devops/handoff.mjs a2a-card
That command generates an A2A agent card with one skill per checked-in recipe.
It declares local HTTP+JSON and JSON-RPC interfaces, the Gemini 3.5 Flash (High) model pin, and a Reaktor-specific recipe extension that carries safety
class and approval metadata.
Codex or Claude can then generate a task request:
node tools/gemini-devops/handoff.mjs a2a-message k3s.status \
--client claude \
--goal "Report node, pod, and service health. Do not mutate anything."
For clients that prefer JSON-RPC:
node tools/gemini-devops/handoff.mjs a2a-jsonrpc web.reaktor.checks \
--client codex \
--goal "Run the Reaktor Web browser regression checks and return artifacts."
The A2A message has two parts:
- a text prompt that Antigravity can run directly with
agy; - structured JSON containing the recipe id, safety class, allowed commands, expected artifacts, model, cwd, sibling Reaktor path, and approval state.
production-write and staging-write recipes are intentionally blocked from
A2A packet generation unless the caller passes --allow-mutating after operator
approval. This keeps A2A from becoming an unreviewed deploy tunnel.
When this moves into Reaktor Desktop, the same contract should be hosted as:
GET /.well-known/agent-card.jsonfor discovery;POST /message:sendfor blocking task execution;POST /message:streamonce the run history panel can consume streaming status and artifact updates;- a task store where each DevOps recipe run has a context id, task id, status, terminal result, and immutable artifact list.
The production executor should still call the same recipe catalog. A2A gives Claude/Codex a stable delegation interface; it does not expand what Gemini is trusted to decide.
Recipe matrix
| Recipe | Safety | Use it for |
|---|---|---|
changed.validate | read-only | Inspect the current diff and choose a smaller recipe |
dagger.pr | local-build | Dagger PR gate: Reaktor verify, app checks, architecture checks |
gradle.app-jvm | local-build | Shared BestBuds app compile and JVM tests |
gradle.architecture | local-build | Architecture and actor invariant tests |
gradle.desktop | local-build | Engine and Reaktor Desktop compile/test |
gradle.desktop-package | local-build | Compose Desktop distributable |
reaktor.framework-jvm | local-build | Reaktor core, graph, and performance JVM tests |
reaktor.graph-editor | local-build | compose-flow and reaktor-flow compile loops |
reaktor.native-ffi-flexbuffer | local-build | Android native FFI/FlexBuffer smoke build |
worker.bundle | local-build | KMP JS bundle for Cloudflare Workers |
worker.deploy-fleet | production-write | Worker deploys in service-binding order |
worker.tail | live-read | Cloudflare Worker tail logs |
web.reaktor.checks | local-build | Reaktor Web Playwright suite |
web.reaktor.perf | local-build | Bundle, Playwright perf, and Lighthouse budgets |
web.bestbuds.checks | local-build | BestBuds Web Playwright suite |
web.all | local-build | BestBuds Web, Reaktor Web, and CompanyOS Playwright |
mobile.android.smoke | device | Android Maestro dev-login smoke |
mobile.android.full | device | Android Maestro full suite |
mobile.ios.smoke | device | iOS build plus Maestro dev-login smoke |
mobile.ios.full | device | iOS build plus full Maestro suite |
fastlane.lanes | read-only | Inspect release lanes |
fastlane.android-debug | local-build | Signed Android debug build |
fastlane.ios-debug | device | iOS debug build |
fastlane.distribute | production-write | Firebase App Distribution |
karate.auth-smoke | live-read | Auth contract smoke tests |
karate.auth-live | staging-write | Live auth fixtures and full contract suite |
k6.auth-smoke | live-read | Small auth load smoke |
k6.auth-load | staging-write | Larger live auth pressure test |
keploy.replay | local-build | Pull R2 corpus and replay locally |
keploy.record | production-write | k3s Keploy capture and R2 archive |
k3s.status | live-read | k3s node, pod, service, and Radar status |
k3s.logs | live-read | Focused app-server, Memgraph, or ClickHouse logs |
k3s.apply | production-write | Apply k3s manifests |
server.deploy-k3s | production-write | Build, push, and roll out the JVM server |
observability.preview | live-read | Build Reaktor Cloud and run Pulumi preview |
supabase.dump | live-read-sensitive | Read-only Supabase dump with PII safeguards |
docs.reaktor-web-build | local-build | Docusaurus build validation |
docs.reaktor-web-deploy | production-write | Reaktor Web docs deploy and live check |
Safety classes
| Class | Meaning | Antigravity authority |
|---|---|---|
read-only | Local inspection only | Can run without mutation approval |
local-build | Builds/tests on local files | Can run, but no dependency installs without approval |
device | Uses connected Android/iOS device or simulator | Can run with operator present; classify WDA/adb state separately |
live-read | Reads live logs/status/endpoints | Can run, but redact secrets and user data |
live-read-sensitive | Reads live data into sensitive artifacts | Can run only with explicit data-handling awareness |
staging-write | Writes disposable fixtures or applies pressure | Requires explicit approval |
production-write | Deploys, distributes, rolls out, captures live traffic, or changes infra | Requires explicit approval and --allow-mutating |
Prompt constraints
The system prompt in tools/gemini-devops/prompts/system.md forces these
rules:
- run only the selected recipe or harmless read-only inspection;
- do not edit files unless a recipe explicitly permits it;
- never run git commit/push/stash/reset;
- do not install dependencies without approval;
- do not run production deploys, rollouts, distributions, migrations, or secret changes without explicit approval;
- redact secrets and user identifiers in summaries;
- classify failures as environment/tooling, missing dependency, missing secret, device/simulator state, compile/typecheck, test regression, performance budget, live infra, flaky timeout, or needing Codex/Claude solutioning.
The output contract is fixed:
Recipe:
Goal:
Model:
CWD:
Sources read:
Commands:
Artifacts:
Result:
Failure class:
Next action for Codex/Claude:
That report shape is intentionally easy to lift into Reaktor Desktop run history later.
Handoff examples
Validate docs locally:
node tools/gemini-devops/handoff.mjs run docs.reaktor-web-build \
--goal "Validate the new Gemini DevOps Agent docs page."
Ask Antigravity to gather live cluster status:
node tools/gemini-devops/handoff.mjs run k3s.status \
--goal "Report node, pod, and service health. Do not mutate anything."
Prepare a prompt for a risky deploy without executing it:
node tools/gemini-devops/handoff.mjs prompt server.deploy-k3s \
--goal "After Codex confirms the server fix, deploy the JVM server to k3s."
Run an approved docs deploy:
node tools/gemini-devops/handoff.mjs run docs.reaktor-web-deploy \
--allow-mutating \
--goal "Deploy this documentation page and verify the live route."
Productionization path
This dev-only layer is deliberately boring so it can become a Reaktor Desktop feature without redesign:
| Phase | Desktop shape | Reuse from this tool |
|---|---|---|
| D0 | CLI and A2A handoff packets | recipes.json, system.md, prompt output, A2A message output |
| D1 | Run history panel | fixed output contract, A2A task ids, artifact paths |
| D2 | Operation nodes in the system graph | recipe id, safety class, cwd, command list |
| D3 | Permission-gated command queue | requiresHumanApproval from agent-card.json |
| D4 | Artifact browser | Playwright traces, Maestro screenshots, k6 JSON, Keploy bundles, Dagger traces |
| D5 | A2A delegation pane | Codex/Claude creates A2A task packet, Antigravity executes, Critic reviews report |
| D6 | Reaktor-native executor | replace shell prompt packets with typed GraphOperation calls |
The first production version should not expose arbitrary shell. It should import this recipe catalog as a set of typed operation nodes with safety classes, inputs, expected artifacts, and permission gates. The "free-form agent" remains outside the trusted boundary.
What Antigravity should not own
Antigravity should not own:
- source architecture decisions;
- broad refactors;
- dependency upgrades;
- schema design;
- production deploy judgment;
- secret management;
- git state;
- final incident calls.
It should own:
- choosing the right checked-in recipe after a diff scan;
- running approved commands;
- watching logs;
- classifying failures;
- collecting artifacts;
- retrying only safe flaky steps;
- handing a tight diagnosis back to Codex or Claude.
That is the token-saving boundary: Antigravity burns the repetitive operational cycles, while Codex and Claude spend their context on design, source changes, and judgment.
Related docs
- DevOps - Use before changing the build/deploy/ops pipeline, the Kotlin platform model, deployment partitioning, gated deploy operations, or the reaktorDesktop Deploy pane; pairs with reaktor-cloud-pane (operator view) and secrets-management.
- Control Plane - Use when exposing Reaktor safely to humans and agents.
- Koog Workbench - Use before wiring real agent behavior into reaktorDesktop.
- Security Plan - Use before enabling deploy actions, remote agents, or privileged commands.
- Shadow Dev - Use before building production-like test and replay environments.
- Auth Architecture - Use before changing reaktor-auth or request authorization boundaries.
References
- Google Developers Blog, Transitioning Gemini CLI to Antigravity CLI (May 19, 2026).
- Google Antigravity, CLI migration documentation.
- A2A Protocol, specification: agent card discovery,
supportedInterfaces,SendMessage, task status, artifacts, and.well-known/agent-card.json. - Local verification:
/Users/ovd/.local/bin/agy --versionreturned1.0.5;/Users/ovd/.local/bin/agy modelslistedGemini 3.5 Flash (High).