This repo hosts roborev, a local daemon + CLI for AI-assisted code review. Use this guide to navigate the codebase quickly, understand subsystem boundaries, and avoid missing adjacent changes when working in a growing Go project.
- Product behavior and user-facing workflows:
README.md - CLI entry point and command registration:
cmd/roborev/main.go - Command discovery:
rg '^func .*Cmd\(' cmd/roborev - Daemon HTTP API and route wiring:
internal/daemon/server.go - Worker pool and job execution:
internal/daemon/worker.go - SQLite schema and migrations:
internal/storage/db.go - Config loading and resolution:
internal/config/config.go - Prompt construction:
internal/prompt/prompt.go - TUI entry point:
cmd/roborev/tui/tui.go
CLI (roborev) -> HTTP API -> Daemon -> Worker Pool -> Agent adapters
| |
| -> Hooks / Activity log / CI poller
|
-> SQLite DB <-> Sync worker <-> PostgreSQL (optional)
- The daemon is the long-lived control plane. Many CLI commands are thin HTTP clients.
- Background daemon work must not edit tracked source files in the user's checked-out working tree or apply agent changes there. Repo metadata is different:
roborev initmay update the usually tracked.gitignoreso the configuredsnapshot_dir(default.roborev/) is ignored, and daemon review work may create disposable ignored snapshot artifacts there so sandboxed agents can read oversized diffs. Runtime snapshot creation may also add a local.git/info/excludefallback when an existing checkout is missing the ignore rule. - Foreground agentic flows such as
roborev fixandroborev refinemay modify code. - Isolated background fix work uses temporary git worktrees and stores patches in the DB.
| Path | Purpose | Start with |
|---|---|---|
cmd/roborev/ |
Cobra CLI commands and daemon-facing client logic | main.go, review.go, fix.go, refine.go, analyze.go, daemon_cmd.go |
cmd/roborev/tui/ |
Bubble Tea terminal UI | tui.go, api.go, fetch.go, handlers.go, render_*.go |
internal/daemon/ |
HTTP server, handlers, worker pool, SSE, hooks, runtime, CI poller | server.go, worker.go, client.go, runtime.go, ci_poller.go |
internal/storage/ |
SQLite models/queries/migrations, sync logic, PostgreSQL mirror | db.go, models.go, jobs.go, reviews.go, sync.go, postgres.go |
internal/agent/ |
Agent interface, registry, command-backed implementations, ACP support | agent.go, codex.go, claude.go, acp.go, test_agent.go |
internal/config/ |
Global config, repo config, validation, key metadata, resolve helpers | config.go, keyval.go |
internal/prompt/ |
Review prompt builder and template loading | prompt.go, templates.go, prompt/analyze/ |
internal/review/ |
Daemon-free batch review, synthesis, comment sizing/formatting | batch.go, synthesis.go, result.go |
internal/git/ |
Shared git helpers for refs, diffs, branch logic, repo discovery | git.go |
internal/worktree/ |
Temporary worktree creation, patch capture/apply/check | worktree.go |
internal/skills/ |
Embedded Codex/Claude skill files and installer logic | skills.go, internal/skills/claude/, internal/skills/codex/ |
internal/streamfmt/ |
Formatting streamed agent output for CLI and TUI | streamfmt.go, render.go |
internal/githook/ |
Hook install/upgrade logic | githook.go |
internal/github/ |
GitHub REST helpers used by CI/comment flows | comment.go |
internal/ghaction/ |
GitHub Actions integration | ghaction.go |
internal/update/ |
Self-update logic and release fetches | update.go |
internal/testenv/ |
Test environment setup helpers | testenv.go |
internal/testutil/ |
Temp git repos and shared test helpers | git.go, testutil.go |
docs/plans/ |
Design notes for larger features | open the matching date/topic file |
skills/ |
Human-readable skill docs shipped to agents | README.md and roborev-*.md |
- Review queueing and results:
review.go,wait.go,status.go,list.go,show.go,comment.go,compact.go - Agentic fix flows:
fix.go,refine.go,run.go,analyze.go - Daemon lifecycle and transport:
daemon_cmd.go,daemon_client.go,stream.go,log_cmd.go - Repo/bootstrap/hooks:
init_cmd.go,hook.go,repo.go,remap.go - Configuration and maintenance:
config_cmd.go,skills.go,update.go,version.go,check_agents.go - Automation/integration:
ci.go,ghaction.go,sync.go - TUI entry command:
tui_cmd.go
roborev review typically flows through:
- CLI validation and repo/ref resolution in
cmd/roborev/review.go - Daemon startup/runtime lookup in
cmd/roborev/daemon_cmd.goandcmd/roborev/daemon_client.go POST /api/enqueuehandled byinternal/daemon/server.go- Job persistence in
internal/storage/ - Prompt building in
internal/prompt/prompt.go - Agent execution from
internal/agent/ - Review/result persistence plus broadcasts/hooks in
internal/daemon/
roborev fixruns agents synchronously in the foreground fromcmd/roborev/fix.go.- It often discovers candidate jobs through daemon APIs, but the actual code modification happens locally.
- When behavior changes, inspect both the CLI-side flow and the job state transitions in storage.
roborev refineis the automated review-fix-review loop incmd/roborev/refine.go.- It uses
internal/worktree/to keep agent work isolated before applying changes back. - If you touch refine behavior, also inspect branch validation, worktree patching, and re-review polling.
roborev analyzeuses prompt templates frominternal/prompt/analyze/.- It can enqueue analysis jobs, wait on them, and optionally pass results into a fix flow.
- Changes here usually need command tests plus prompt/template coverage.
- TUI state/model setup:
cmd/roborev/tui/tui.go - HTTP requests:
cmd/roborev/tui/api.go - Background fetch/update logic:
cmd/roborev/tui/fetch.go - Input handling:
cmd/roborev/tui/handlers*.go - Rendering:
cmd/roborev/tui/render_*.go - Filtering/search/tree state:
cmd/roborev/tui/filter*.go
- CLI flag or output changes usually require updates in the command file, its tests, and sometimes
README.md. - Daemon API changes usually require updates in
internal/daemon/server.go,internal/daemon/client.go, CLI callers, TUI callers, and API/integration tests. - Worker/job lifecycle changes usually affect
internal/daemon/worker.go,internal/storage/jobs.go, status/event broadcasting, cancellation, and rerun behavior. - Storage schema changes must stay minimal and need both SQLite and PostgreSQL consideration.
- SQLite changes live in
internal/storage/db.go; PostgreSQL schema/versioning lives ininternal/storage/postgres.goplusinternal/storage/schemas/postgres_v*.sql. - Config key changes usually touch
internal/config/config.go,internal/config/keyval.go,cmd/roborev/config_cmd.go, and related tests. - Agent changes usually touch the adapter file,
internal/agent/agent.goregistry/fallback logic, and tests that usetest_agent.go. - TUI changes rarely live in one file; expect to touch fetch, handlers, render, and tests together.
- Hook behavior spans
cmd/roborev/init_cmd.go,internal/githook/, and daemon hook execution ininternal/daemon/hooks.go. - CI/sync work often crosses daemon, storage, and config packages. Do not patch only one side.
- Daemon default address:
127.0.0.1:7373and auto-increments if busy. - Runtime info:
~/.roborev/daemon.json - SQLite DB:
~/.roborev/reviews.dbusing WAL mode - Data dir override:
ROBOREV_DATA_DIR - Color mode:
ROBOREV_COLOR_MODEenv var (auto,dark,light,none);NO_COLOR=1also supported - Global config:
~/.roborev/config.toml - Repo config:
.roborev.tomlat repo root - Config precedence is generally: CLI flags -> repo config -> global config -> defaults
- Reasoning defaults: review =
thorough, fix =standard, refine =standard - Repo config can include
review_guidelines; prompt building pulls these into reviews, falling back to a repo-rootREVIEW.mdwhen it is unset roborev initinstalls or upgrades git hooks; daemon startup warns about stale hooksroborev refineis agentic and may run with unsafe capabilities depending on flags/config; use only on trusted code
Use testify (github.com/stretchr/testify) for all test assertions. Use require.* for fatal preconditions and assert.* for non-fatal checks. Do not use raw if/t.Errorf/t.Fatalf patterns.
- Fast test pass:
go test ./... - Integration tests:
go test -tags=integration ./... - PostgreSQL tests:
go test -tags=postgres -v ./internal/storage/... -run Integration - ACP smoke tests: use the
make test-acp-integration*targets inMakefile - On Windows, repo-wide and daemon/CLI package tests can take several minutes.
Use command wrapper timeouts of at least 10 minutes for
go test ./...and at least 5 minutes forgo test ./internal/daemonorgo test ./cmd/roborev. - Pre-commit hooks in this repo are managed with
prek; runprek installafter cloning ormake install-hooksas a wrapper. - The local pre-commit hook is a
preksystem hook that runs the non-mutatingmake lint-citarget withalways_run, so it executes on every commit without rewriting files. - Format Zensical Markdown sources with
make markdown; prose wraps at 80 columns while tables remain unchanged. The non-mutatingmake markdown-cicheck runs inprekand CI. - Use
prek run --all-filesto execute the hooks manually. Runmake lintonly when you explicitly want golangci-lint to apply fixes. - Useful build/lint checks:
go build ./...,make lint,make lint-ci,prek run --all-files
Test conventions:
- Prefer fast, isolated tests that use
t.TempDir(). - Use the
testagent path to avoid calling real AI agents. - Integration tests use
//go:build integration. - PostgreSQL-only tests use
//go:build postgres. - ACP adapter integration tests use
//go:build integration && acp. - Shared helpers live in
internal/testenv/,internal/testutil/, and package-local*_test_helpers*.go. - In tests with more than three assertions, prefer
assert := assert.New(t)to make grouped assertions cleaner. - Test packages that run git or use git repo helpers from
internal/testutilmust defineTestMainand calltestenv.RunIsolatedMain; thetest-git-isolationpre-commit hook enforces this. assert.True*/require.True*/assert.False*/require.False*should only be used for actual boolean values (fields, return values); never use them as comparisons (e.g.,assert.True(t, x == y)should beassert.Equal(t, y, x)).- Do not use
assert.Fail/require.Failin tests. - Prefer
assert.Equalfor explicit expectations. - Convert redundant
ifwrappers around assertions into direct assertions (for example,if err != nil { require.NoError(t, err) }should becomerequire.NoError(t, err)). - Do not replace assertions with manual control-flow (
if,t.Fatal*,t.Error*) when a direct testify check covers the same condition. - Enforce a no-redundant-guards policy for assertions:
- replace
if err != nil { require.NoError(t, err, ...) }andif err == nil { ... } else { ... }with directrequire.Error/require.NoError/require.NotNilstatements. - avoid manual
ifprechecks such asif got != wantorif cfg != nil; convert to directassert.Equal/assert.NotNilassertions. - remove
assert/requirefail helpers andt.Fatal/t.Fatalf/t.Errorusage when a direct assertion provides the same check.
- replace
- Shell script tests must exercise observable behavior by running the script against controlled inputs and asserting outputs, side effects, or exit codes. Do not add bash tests that grep shell scripts, workflows, config files, or docs for expected implementation text; those checks are usually tautological and should be replaced with real execution, parser/tool-native validation, or a documented manual release check.
- Commands:
rg '^func .*Cmd\(' cmd/roborev - Daemon handlers:
rg 'handle[A-Z]' internal/daemon - Job state usage:
rg 'JobStatus|job_type|review_type' internal cmd/roborev - Build tags:
rg '^//go:build' . - Config resolution:
rg 'Resolve[A-Z]|LoadRepoConfig|LoadGlobal' internal/config - Agent capability methods:
rg 'WithReasoning|WithAgentic|WithModel' internal/agent - TUI view logic:
rg 'view[A-Z]|currentView|handle.*Key' cmd/roborev/tui
- Keep changes simple; avoid over-engineering.
- Prefer Go stdlib over new dependencies.
- No emojis in code or output (commit messages are fine).
- Do not include private review data or infrastructure details in tests, fixtures, commit messages, PR descriptions, PR comments, issue comments, or public docs unless the user explicitly asks for that disclosure. This includes real hostnames, usernames, local paths, daemon/service names, job IDs, review IDs, PR numbers from private queues, database rows, log excerpts, timestamps tied to incidents, config contents, auth state, and machine-specific behavior. Use synthetic identifiers, generic provider messages, and behavior-focused descriptions instead.
- Never amend commits; fixes should be new commits.
- Never push/pull unless explicitly asked.
- NEVER merge pull requests.
- NEVER change git branches without explicit user confirmation. Always ask before switching, creating, or checking out branches.
- NEVER run
make install,go install ./cmd/roborev, or any build/install command that writes aroborevbinary into a user PATH without explicit user permission. Installing a development build can replace the production local daemon binary, trigger schema migrations against~/.roborev/reviews.db, and damage the user's live review environment. - Release builds use
CGO_ENABLED=0. - Release workflow testing must not publish anything. Do not run any command, workflow mode, or release tool path that creates public releases, uploads release assets, publishes package repositories, updates taps, signs release artifacts for distribution, pushes tags, or writes to any external release channel. Use local, non-publishing validation that proves artifact names, checksums, and package contents. If a release tool cannot validate without publishing, stop and ask the user instead of approximating with a live publish.
- For multi-step tasks (for example: implement + commit + PR), complete the full requested sequence without stopping partway.
- Commit after completing each piece of work; do not wait to be asked.
- When committing, stage ALL modified files related to the work (including formatting-only and ancillary updates).
- Before committing, run
git diffandgit statusto verify nothing is unintentionally left unstaged. - When creating PRs, write a clean GitHub-facing summary with relevant context and links.
- Before opening a PR: update the zensical docs under
docs/for any user-facing behavior or config changes, and remove superpowers working documents (docs/superpowers/plans/specs) from the branch — unless the user explicitly asks to retain them. - Do not add navel-gazing PR sections for validation, testing, checks run, or lists of changes made. Keep PR bodies focused on reviewer-facing context, rationale, behavior changes, risk, and useful links; rely on the diff and CI/status checks for routine mechanics and validation evidence unless the user explicitly asks for those details.
- Never invoke the
roborev reviewCLI command in any form unless the user explicitly asks for it. Use all otherroborevCLI commands normally when they are appropriate for interacting with roborev. Never invoke a roborev skill (includingroborev-fixorroborev-design-review-branch) unless the user explicitly asks for that skill.
When reviewing or fixing issues:
- Focus on correctness, concurrency safety, and error handling in daemon/worker code.
- For storage changes, keep migrations minimal and validate schema and queries.
- For API changes, preserve HTTP/JSON conventions.
- For daemon changes, preserve the rule that background jobs must not edit tracked source files in the checked-out working tree or apply agent changes there. The repo metadata exception is snapshot ignore setup:
.gitignoremay be updated byroborev init, and daemon snapshot writes may add a local.git/info/excludefallback. Ignored repo-local snapshot artifacts are allowed only for oversized diff handoff and must stay under the configuredsnapshot_dir, remain gitignored, and be cleaned up best-effort. - When addressing review feedback, update tests if behavior changes.
- If the user pastes review findings or review text directly into the prompt, treat that as direct fix input and work from the pasted content.
- Do not invoke review-fetching skills for pasted review text unless the user explicitly asks for that skill or provides only a review/job ID that must be fetched first.
- If diffs are large or truncated, inspect with
git show <sha>.
When ending a work session, you MUST complete ALL steps below. Work is NOT complete until git push succeeds.
MANDATORY WORKFLOW:
- File issues for remaining work - Create issues for anything that needs follow-up
- Run quality gates (if code changed) - Tests, linters, builds
- Update issue status - Close finished work, update in-progress items
- PUSH TO REMOTE - This is MANDATORY:
git pull --rebase git push git status # MUST show "up to date with origin" - Clean up - Clear stashes, prune remote branches
- Verify - All changes committed AND pushed
- Hand off - Provide context for next session
CRITICAL RULES:
- Work is NOT complete until
git pushsucceeds - NEVER stop before pushing - that leaves work stranded locally
- NEVER say "ready to push when you are" - YOU must push
- If push fails, resolve and retry until it succeeds