{"id":48527739,"url":"https://github.com/tinkrtailor/nautiloop","last_synced_at":"2026-04-21T21:00:53.681Z","repository":{"id":348319638,"uuid":"1194439113","full_name":"tinkrtailor/nautiloop","owner":"tinkrtailor","description":"Push a spec, get a clean PR. Convergent loop where AI models review each other's work until the code is right.","archived":false,"fork":false,"pushed_at":"2026-04-18T09:43:07.000Z","size":1845,"stargazers_count":1,"open_issues_count":8,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-18T11:39:27.368Z","etag":null,"topics":["ai","claude","code-review","developer-tools","devops","kubernetes","llm","openai","rust","terraform"],"latest_commit_sha":null,"homepage":"https://nautiloop.dev","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tinkrtailor.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-28T11:05:36.000Z","updated_at":"2026-04-18T09:43:09.000Z","dependencies_parsed_at":null,"dependency_job_id":"dbfc0b95-3d73-45de-9d47-8ffa46411e22","html_url":"https://github.com/tinkrtailor/nautiloop","commit_stats":null,"previous_names":["tinkrtailor/nemo","tinkrtailor/nautiloop"],"tags_count":43,"template":false,"template_full_name":null,"purl":"pkg:github/tinkrtailor/nautiloop","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tinkrtailor%2Fnautiloop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tinkrtailor%2Fnautiloop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tinkrtailor%2Fnautiloop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tinkrtailor%2Fnautiloop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tinkrtailor","download_url":"https://codeload.github.com/tinkrtailor/nautiloop/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tinkrtailor%2Fnautiloop/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32110137,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-21T11:25:29.218Z","status":"ssl_error","status_checked_at":"2026-04-21T11:25:28.499Z","response_time":128,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","claude","code-review","developer-tools","devops","kubernetes","llm","openai","rust","terraform"],"created_at":"2026-04-07T23:00:47.480Z","updated_at":"2026-04-21T21:00:53.672Z","avatar_url":"https://github.com/tinkrtailor.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Nemo\n\n**Push a spec, get a clean PR.** Nemo runs a convergent loop where AI models review each other's work until the code is right.\n\nClaude implements. OpenAI reviews. Findings go back to Claude. Claude fixes. OpenAI reviews again. Repeat until clean. Different models have different blind spots. Claude never reviews its own work.\n\n```bash\nnemo start spec.md       # implement + PR\nnemo ship spec.md        # implement + auto-merge\nnemo harden spec.md      # harden the spec itself\n```\n\n## The loop\n\n```\nRound 1: Claude implements  --\u003e  tests run  --\u003e  OpenAI reviews  --\u003e  3 issues\nRound 2: Claude fixes       --\u003e  tests run  --\u003e  OpenAI reviews  --\u003e  1 issue\nRound 3: Claude fixes       --\u003e  tests run  --\u003e  OpenAI reviews  --\u003e  clean\n--\u003e PR created\n```\n\nThe exit condition is quality, not iteration count.\n\n## How it works\n\n`nemo` is the CLI. A **nautiloop** is the server environment where convergent loops run. You provision a nautiloop on any Linux server using the Terraform module, then `nemo` talks to it.\n\n```\nYour machine                         Nautiloop (k3s server)\n+----------+                         +-----------------------------+\n| nemo CLI | -------- HTTPS -------\u003e | API Server                  |\n|          |                         | Loop Engine                 |\n+----------+                         | Postgres                    |\n                                     |                             |\n                                     |  +----------+ +----------+  |\n                                     |  |Implement | | Review   |  |\n                                     |  |  (Claude)| | (OpenAI) |  |\n                                     |  +----------+ +----------+  |\n                                     +-----------------------------+\n```\n\nYour agents keep working when you close your laptop.\n\n## Deploy a nautiloop\n\nThe nautiloop Terraform module installs on any Linux server with SSH access. You provision the server, the module handles k3s, Postgres, and the control plane.\n\n```hcl\nmodule \"nautiloop\" {\n  source = \"github.com/tinkrtailor/nautiloop//terraform/modules/nautiloop\"\n\n  server_ip       = \"100.64.0.1\"                          # any server with SSH\n  ssh_private_key = file(\"~/.ssh/id_ed25519\")\n  git_repo_url    = \"git@github.com:you/your-repo.git\"\n  git_host_token  = var.github_pat\n}\n```\n\nFour required variables. Single `terraform apply`. No extra provider configuration needed.\n\nThe module auto-generates a deploy key (or accepts yours). After apply, add the public key to your repo's deploy keys with write access.\n\nSee [docs/deploy.md](docs/deploy.md) for the full guide, examples, and all options.\n\n## Set up your repo\n\n```bash\nnemo init                    # generates nemo.toml\nnemo auth                    # pushes Claude + OpenAI + SSH credentials\n\nnemo start spec.md           # PR appears when it converges\nnemo status                  # watch progress\nnemo logs \u003cid\u003e               # stream agent output\n```\n\n## Three verbs\n\n| Command | What happens | Result |\n|---------|-------------|--------|\n| `nemo harden spec.md` | OpenAI audits the spec, Claude revises. Loop until clean. | Hardened spec merged |\n| `nemo start spec.md` | Hardens the spec first, then Claude implements, tests run, OpenAI reviews. Loop until clean. | PR created |\n| `nemo ship spec.md` | Same as start + auto-merge when the loop converges | Code shipped |\n\n`nemo start` hardens by default (cheap on already-clean specs, high-value on soft ones). Add `--no-harden` to skip the harden phase.\n\n## Watching loops\n\n```bash\nnemo status                  # list your running loops\nnemo helm                    # K9s-style TUI with rounds table, diff pane, live logs\nnemo logs \u003cid\u003e               # stream agent output (SSE)\nnemo ps \u003cid\u003e                 # live process table inside the agent pod\nnemo inspect \u003cbranch\u003e        # full round history + per-round verdicts\n```\n\nDashboard (web, Tailscale-native): `/dashboard` on the control plane. Card grid on mobile, loop detail with rounds table + token/cost + actions. See [docs/dashboard-setup.md](docs/dashboard-setup.md).\n\n## Recovery\n\n```bash\nnemo approve \u003cid\u003e            # unblock a PENDING or AWAITING_APPROVAL loop\nnemo resume \u003cid\u003e              # resume a PAUSED or AWAITING_REAUTH loop\nnemo extend \u003cid\u003e --add 10     # bump max_rounds on a FAILED loop, resume where it stopped\nnemo cancel \u003cid\u003e              # terminate a running loop\n```\n\nLLM-friendly CLI: `nemo help ai` prints a comprehensive primer an agent can read to operate the system; every command has `--json` output for scripting.\n\n## Configuration\n\n```toml\n# nemo.toml (repo root, checked in)\n[repo]\nname = \"my-project\"\ndefault_branch = \"main\"\n\n[models]\nimplementor = \"claude-opus-4\"    # who writes the code\nreviewer = \"gpt-5.4\"            # who reviews it\n\n[services.api]\npath = \"api/\"\ntest = \"cd api \u0026\u0026 cargo test\"\n\n[services.web]\npath = \"web/\"\ntest = \"cd web \u0026\u0026 npm test\"\n```\n\n```toml\n# ~/.nemo/config.toml (per engineer)\nserver_url = \"http://nautiloop:8080\"   # Tailscale hostname or IP\napi_key = \"your-api-key\"\nengineer = \"alice\"\nname = \"Alice\"\nemail = \"alice@example.com\"\n```\n\n## Security model\n\nAgent containers get open internet but **no direct access to secrets**. Model API auth and git push go through a localhost sidecar that injects credentials at the network level.\n\n- **Auth sidecar** proxies model API calls and git pushes, injecting credentials without exposing them as env vars or files\n- **Read-only reviewer** mounts the worktree read-only in review stage\n- **Shared API key** (V1): all authenticated users have full access. Designed for single-tenant / small-team deployments. Per-engineer RBAC is planned for V2.\n- **Session data**: implement/revise jobs mount Claude session data (`.claude/`) into the agent container for session continuity. This is internal tool state, not user secrets.\n- **Egress logging** on all outbound traffic from agent pods\n- **Tailscale recommended** for private API access (no public endpoints)\n\n## Architecture\n\n- **`nemo`** (Rust CLI): runs on your machine, talks to the nautiloop\n- **Nautiloop** (k3s server): API server (axum) + loop engine, Postgres, Traefik\n- **Agent jobs** (K8s pods): each stage runs as a separate pod with an auth sidecar\n- **Auth sidecar** (Go): credential injection + git push proxy + egress logging\n- **Terraform module**: `terraform/modules/nautiloop/` -- installs on any Linux server\n\n```\ncontrol-plane/          Rust: API server + loop engine\n  src/api/              REST endpoints (axum)\n  src/loop_engine/      Convergent loop driver + reconciler\n  src/state/            Postgres state store (sqlx)\n  src/git/              Git operations (bare repo, worktrees)\n  src/k8s/              Job builder + K8s client (kube-rs)\n  src/config/           Three-layer config (cluster, repo, engineer)\n  migrations/           SQL migrations\n\ncli/                    Rust: nemo CLI\n  src/commands/         start, ship, harden, status, logs, auth, init\n\nimages/\n  base/                 Agent base image (Claude Code + OpenCode + tools)\n  sidecar/              Auth sidecar (Go, ~10MB static binary)\n  control-plane/        Control plane image (Rust, multi-stage build)\n\nterraform/\n  modules/nautiloop/    Reusable module (k3s + control plane + Postgres)\n  examples/hetzner/     Reference: Hetzner VPS + Tailscale + nautiloop\n\n.nautiloop/prompts/          Agent prompt templates\n```\n\n## Built with Nemo\n\nNemo was built through the exact process it automates. Three parallel implementation lanes, each hardened by cross-model adversarial review:\n\n| Lane | What | Rounds | Findings |\n|------|------|--------|----------|\n| A | Core loop engine | 28 | 124 |\n| B | Infrastructure (k8s, terraform) | 25 | 88 |\n| C | Agent runtime (sidecar, entrypoint) | 21 | 107 |\n| Integration | Cross-lane compatibility | 7 | 12 |\n| **Total** | | **81 rounds** | **331 findings** |\n\n331 production bugs caught by cross-model review before first deploy.\n\n## Documentation\n\n- [Local dev quickstart](docs/local-dev-quickstart.md) — 10-min k3d setup, no cloud required\n- [Deployment guide](docs/deploy.md) — production setup, terraform module reference, examples\n- [Dashboard setup](docs/dashboard-setup.md) — Tailscale-native web dashboard\n- [Architecture](docs/architecture.md) — system design and component interaction\n- [Design document](docs/design.md) — product decisions and rationale\n- [Convergence data](docs/convergence-learnings.md) — what we learned from 81 rounds\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md). TL;DR: conventional commits, clippy clean, tests pass, no placeholders.\n\n## License\n\n[Apache 2.0](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftinkrtailor%2Fnautiloop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftinkrtailor%2Fnautiloop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftinkrtailor%2Fnautiloop/lists"}