// an experimental semantic edit protocol for Go workspaces

Agentic Goa language for agents

Weak local models become effective repo-scale Go editors when raw file editing is replaced by semantic queries and validated mutations with typed rejections.

Get started Op catalog

curl -fsSL https://ago.aeryx.ai/install.sh | sh

One binary, the whole protocol

ago runs a per-workspace daemon over a typechecked snapshot. Queries answer in milliseconds. Mutations validate against the in-memory type graph before anything touches disk.

ago
$ ago --help
semantic edit protocol for Go: query the typechecked workspace, submit compiler-checked mutations

Usage:
  ago [command]

reads and setup:
  help        the versioned op catalog: args, examples, ceilings
  init        scaffold an agent-first module: MCP wiring, AGENTS.md
  inspect     kind, signature, position, doc for one symbol
  query       semantic questions by --kind (callers, implementations, ...)
  refs        every reference, tests included
  search      name fragment to exact symbol addresses
  status      load or refresh the snapshot: packages, files, errors
  view        declaration as annotated text with node handles

mutations (validated before anything touches disk):
  add-param   add a parameter, call sites updated with --default
  patch       ordered multi-op edit, atomic and generation-checked
  rename      rename a symbol, every reference proven to resolve
  set-body    replace a function body, typechecked first
  test        go test, scoped, structured pass/fail
  upsert      add or replace a whole declaration

lifecycle:
  daemon      run the workspace daemon in the foreground
  mcp         serve the MCP tools over stdio
  skill       install or print the embedded agent skill

Additional Commands:
  completion  Generate the autocompletion script for the specified shell
  help        Help about any command

Flags:
  -C, --dir string   workspace directory (default ".")
  -h, --help         help for ago

Use "ago [command] --help" for more information about a command.

Rejections are data, not errors

A bad edit changes nothing on disk and comes back as the compiler's own diagnostics, ready for the next attempt. The agent loop is query → mutate → (rejection → adjust → retry).

rejected
{
  "status": "rejected",
  "reason": "edit does not typecheck",
  "diagnostics": [
    {"pos": "config.go:114:29", "msg": "undefined: slices"},
    {"pos": "config.go:9:2", "msg": "\"reflect\" imported and not used"}
  ]
}

One handle per statement

Edits address the compiler's own syntax tree, not lines of text. The tree below is parsed with go/parser from the op catalog's set_body example on every build. Every node is real.

func Double(v int) int { return v + v }

FuncDecl Double FuncType FieldList Field v int FieldList Field int BlockStmt ReturnStmt + v v

Claims