Skip to content

Agent Workflow Standards

Governing principle: One task = one branch = one worktree = one PR.

Every discrete piece of agent work follows the same end-to-end lifecycle: isolate, implement, verify, deliver via pull request. Work is not considered done until a PR exists.

Every agent task MUST follow these steps in order:

  1. Create worktree + branch.

    Terminal window
    git worktree add .claude/worktrees/<branch-name> -b <branch-name>
    cd .claude/worktrees/<branch-name>
  2. Write tests first (TDD). Red → Green → Refactor. No implementation code before a failing test.

  3. Implement. Write the minimum code to pass tests. Maintain ≥ 95% coverage in all modified modules. Python code must pass mypy --strict.

  4. Run make ci. The full pipeline must pass before proceeding.

  5. Push the branch.

    Terminal window
    git push -u origin <branch-name>
  6. Create a pull request. Link to the relevant issue. Include 🤖 Generated with [Agent Name] in the PR body.

    Terminal window
    gh pr create --title "type(scope): description" --body "..."
  7. Clean up after merge. Remove worktree, delete local branch, delete remote branch:

    Terminal window
    git worktree remove .claude/worktrees/<branch-name>
    git branch -D <branch-name>
    git push origin --delete <branch-name>
  • Requirement: AI agents MUST work in git worktrees, never the developer’s root checkout.
  • Location: Worktrees live in .claude/worktrees/ (Claude Code), .cursor/worktrees/ (Cursor), or equivalent per-agent directory.
  • Rationale: The root checkout is the developer’s active workspace. Agent modifications cause conflicts with IDE state (unsaved buffers, debug configurations, terminal sessions). Worktrees provide full isolation at near-zero cost.
  • Never modify files in the root checkout from an automated agent session.
  • Create a new worktree at the start of each feature/fix branch.

Agent branches MUST use the same type/description convention as human branches. Opaque IDs or numeric suffixes alone are not acceptable:

feat/preview-scroll-optimization ✓ descriptive
fix/sidebar-drag-crash ✓ descriptive
worktree-agent-a0939472 ✗ opaque, impossible to triage
copilot/sub-pr-7 ✗ meaningless without the PR

Before starting new work, verify no stale agent worktrees or branches remain:

Terminal window
git worktree list # should only show root checkout + active work
git branch --no-merged main # audit for abandoned branches

The root checkout is the human’s volatile workspace — it auto-pulls mainline and its branch gets switched out from under you. These rules keep agent work from landing on the wrong branch or failing on phantom errors:

  • Do all multi-commit work in a worktree, never the root checkout. If you must touch the root, run git branch --show-current immediately before every commit — a background pull may have flipped HEAD to main or another branch.
  • gh pr create infers the head branch from the current directory. Run it from inside the feature worktree, or pass --head <branch> explicitly. Running it from the root opens a PR for whatever branch the root is on — your title/body on the wrong diff, a silent outward-facing mistake. Verify after: gh pr view <n> --json headRefName. (gh pr merge <number> is safe — it takes an explicit PR number.)
  • Install from the lockfile in a fresh worktree before running gates. A new worktree shares the repo but not node_modules/target; a plain install can resolve versions that differ from the committed lock and produce phantom lint or type failures on files you never touched. Use the frozen/locked mode (pnpm install --frozen-lockfile, npm ci, cargo build --locked). When a gate fails on an untouched file, check the installed toolchain version against the lock before “fixing” the file.
  • Repair git hooks after switching worktrees. Hook installers can leave .git/hooks/* pointing at a deleted worktree’s path. If hooks misbehave, run the repo’s hook-repair target (e.g. make hooks) to rewrite them for the current checkout.

Every project SHOULD have a CLAUDE.md (or equivalent agent guide) at the repository root. This file is distinct from .cursorrules or .github/copilot-instructions.md — it documents project-specific context that evolves during development.

Section Purpose
Project Summary One paragraph describing what the project does
Key Commands make check, make lint, make test, make ci, make fmt, make ls
Workspace Layout Directory tree with purpose annotations
Architecture Rules Dependency direction, critical invariants, “never do X” items
Error Handling Library vs. app error patterns
Testing Structure, coverage baselines, per-package commands
Key Source Files Table mapping files to responsibilities
Commit Message Format Conventional Commits reference with project-specific scopes
What NOT To Do Explicit anti-patterns discovered during development
Agent Workflow Worktree requirement, permission model
  • Keep it under 300 lines. Link to detailed docs rather than inlining everything.
  • Include concrete examples of invariants and how they break.
  • Update it as the project evolves — it is a living document, not a one-time artifact.

Define what agents can do autonomously vs. what requires human confirmation.

Action Permission
Read files, search code Autonomous
Edit/create source files Autonomous
Run tests (make test, cargo test) Autonomous
Run linters/formatters (make lint, make fmt) Autonomous
Run full CI (make ci) Autonomous
Git commit (in worktree) Autonomous
Git push Requires confirmation
Git force push, reset –hard Requires explicit approval
Delete files/branches Requires confirmation
Modify CI/CD pipelines Requires explicit approval
Send messages (PR comments, emails) Requires confirmation

Permission models should be defined in agent-specific configuration files:

  • Claude Code: .claude/settings.json
  • Cursor: .cursorrules
  • Copilot: .github/copilot-instructions.md

For projects with a graphical interface, expose an HTTP API that enables agents to build, inspect, and iterate on the UI autonomously.

Endpoint Purpose
POST /rebuild Trigger a build, block until complete, return build status
GET /snapshot Return screenshot (PNG base64) + widget/component tree (JSON)
GET /snapshot?diff=true Same as above, plus diff from previous snapshot

The snapshot response should include a structured representation of the UI hierarchy:

  • Element ID, type/kind, bounding rectangle, visibility
  • Style properties (background color, font size, etc.)
  • Interactive state (focused, hovered, selected)

This enables agents to reason about UI changes semantically rather than relying solely on pixel-level screenshot comparison.

setup-devloop: ## Install devloop dependencies
devloop: ## Start devloop HTTP server for agent-driven UI iteration

When an agent (typically Google Antigravity) starts work on a major feature, it sets the active Mission URL in .gemini/active_mission.log. Other agents (Claude Code, Cursor, Aider, Codex, Gemini CLI) read this file and stay aligned with the Mission’s scope.

  • One Mission per major feature. Don’t lump multiple features into one Mission — the cost is review confusion and Mission scope drift.
  • Cross-reference issue/PR. The Mission URL should resolve to a Mission that links the work back to a GitHub Issue or PR.
  • Don’t run two Missions in the same project simultaneously — they will overwrite each other’s active_mission.log.
Terminal window
./scripts/mission-set.sh https://antigravity.google.com/missions/<id> # at start
./scripts/mission-clear.sh # on completion
Phase Action
Set Before the first agent action on the feature. Validates HTTPS-only, writes URL + UTC timestamp atomically.
Active Other agents reading .gemini/active_mission.log will see the URL on first line; treat as authoritative scope.
Clear Immediately on completion — PR merge, Mission close, or abandonment. Do not leave stale entries.
Stale A non-empty active_mission.log whose timestamp is more than ~7 days old. Treat as forgotten clear; verify with the Mission owner before assuming it’s still valid.

Before starting work in a project, agents SHOULD check the file:

Terminal window
[ -s .gemini/active_mission.log ] && head -1 .gemini/active_mission.log

If a Mission URL is present, agents SHOULD reference it in commit messages and PR descriptions. Scope creep beyond the Mission’s stated goals SHOULD trigger a new issue rather than expanded edits.

Agent-authored commits MUST include a Co-Authored-By trailer identifying the agent:

feat(core): add validation for email addresses
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Agents MUST open a pull request for every discrete piece of completed work. Work is not considered done until a PR exists.

Agent-created PRs MUST:

  • Include 🤖 Generated with [Agent Name] in the PR description.
  • Follow the same title/body format as human-authored PRs.
  • Link to the relevant issue or design document (Closes #N, Fixes #N, or Part of #N).

Agents MUST create GitHub Issues (or the project’s configured tracker) when they:

  • Discover bugs or failing edge cases during implementation.
  • Identify tech debt or shortcuts taken to meet scope.
  • Encounter out-of-scope work that should be addressed later.
  • Add TODO or FIXME comments to the codebase — every such comment MUST reference an issue number.

Agents must NOT silently defer work. If something needs to be done, it needs to be tracked. Check CLAUDE.md, README.md, or .github/CONTRIBUTING.md for the project’s configured tracking tool. Default is GitHub Issues.

For projects with a graphical interface, agents that modify UI files MUST validate the rendered output against a reference design before claiming the change is complete. This complements the Devloop Pattern — devloop enables agents to iterate; UI Change Validation enforces that the iteration converges on design intent.

Agents SHOULD apply this protocol when modifying files matching any of the following patterns:

Stack Patterns (globs)
Web **/*.tsx, **/*.jsx, **/*.vue, **/*.svelte, **/*.html, **/*.css, **/*.scss
Mobile / desktop **/*.dart, **/*.swift, **/*.kt (Compose), **/*.xaml
Style tokens / theme **/tokens.json, **/theme.*, **/design-tokens/**, **/*.tokens.{json,yml,yaml}

Patterns are globs evaluated against repo-relative file paths. For changes that don’t trip a pattern (e.g., copy edits in a Markdown-driven CMS that affect rendered UI), the PR author MAY opt in by writing ui-validation: required in the PR body.

  1. Render. Spin up the dev server (or use the project’s /rebuild devloop endpoint).
  2. Capture. Take a screenshot of the changed surface using the agent’s browser tool — see “Cross-agent invocation” below.
  3. Compare. Diff the screenshot against the reference design in assets/designs/<route-or-component>/<state>.png.

The agent surfaces the diff; a human approves whether intent is met. Pixel-diff alone is not gating: font rendering, anti-aliasing, sub-pixel layout, and OS-level smoothing produce noise that swamps real design changes. Use one of:

  • Side-by-side: reference and rendered output adjacent. Best for layout-driven changes.
  • Overlay: rendered output 50% opacity over reference. Best for spacing and alignment.
  • Per-region delta: cropped diffs for changed components only. Best for token / theme changes that touch many pages.

The agent’s output is a diff artifact + a summary of what changed. Approval is human-gated unless the project explicitly opts into pixel-diff gating (rare; document the threshold in assets/designs/NOTES.md).

UI PRs are not auto-mergeable without sign-off

Section titled “UI PRs are not auto-mergeable without sign-off”

When a UI change has no reference design for the surface (a brand-new view, an exploratory layout), the agent MUST open the PR, attach the rendered screenshots, and wait for human visual sign-off — even when CI is green. Do not auto-merge. This is an explicit exception to the otherwise-autonomous merge loop in proc-03_code_review_expectations.md §1. State it in the PR body (e.g. “UI — needs visual sign-off, do not auto-merge”).

Visual-regression baselines must be regenerated on the CI runner, not locally. Even a matching local container renders fractionally differently (font hinting, anti-aliasing) from the CI host, so locally-generated baselines fail the CI visual gate. Regenerate via the pipeline’s own mechanism (e.g. a workflow_dispatch with an update_snapshots input that uploads the regenerated baselines as an artifact), then commit those. Visual changes remain human-gated.

For products that ship the same UX on multiple platforms, a UI change is assumed to apply to every platform unless scoped otherwise. Scope the issue/PR to cover web and each native shell, and keep shared data/logic single-sourced in the core. See arch-07_cross_platform_shared_core_standards.md §4.

Agent Browser tool
Google Antigravity Built-in Browser Agent
Claude Code Playwright MCP server (@modelcontextprotocol/server-playwright)
Cursor Built-in browser tool
Aider, Codex No native browser — projects exposing the Devloop GET /snapshot endpoint normalize this across all agents

Reference designs live in assets/designs/<route-or-component>/<state>.{png,svg}. Each project SHOULD include a copy of the templates/assets-designs-README.md.example template at assets/designs/README.md to document its specific naming conventions and breakpoint coverage.

The directory is opt-in per projectsetup.sh does not auto-create it. Add it manually when the project takes on UI work.

When design intent changes (designer ships a new mock, accessibility audit changes spacing, etc.):

  1. Update the reference in the same PR as the UI change.
  2. Note the intentional reference change in the PR body so reviewers know the diff is expected.
  3. Update assets/designs/NOTES.md if the change requires explanation (e.g., “Reduced primary CTA size to meet WCAG 2.5.5 target-size requirements”).

When agent work spans multiple architectural layers:

  • Reference specific file paths when discussing code (e.g., packages/domain/user.py).
  • Summarize changes in the current layer’s context before moving to the next layer.
  • Keep conversation context focused: avoid loading full files when only a section is relevant.