Project Info
Inspiration
Every repo we've worked on has thirty outdated dependencies, a few unpatched CVEs, and a test suite nobody trusts enough to run before merging a fix. We wanted to see if an agent could own that whole loop, not just suggest a diff, so we built Repo Surgeon on Codex.
What it does
Point Repo Surgeon at a GitHub repo and a five-stage pipeline runs unattended inside an isolated Docker sandbox: Scout clones the repo, detects the stack, and records a pass/fail baseline plus a security scan (OSV-Scanner, pip-audit, npm audit). Researcher uses GPT-5.6 with web search to pull real changelogs and migration guides for each outdated or vulnerable dependency. Surgeon dispatches upgrades to Codex running headless, editing code and re-running affected tests after each change. Verifier re-runs the full suite against baseline, loops failures back to the Surgeon, then runs mutation testing on any new tests to prove they'd actually catch a regression. Reviewer splits the work into small, risk-ordered PRs with evidence and a confidence grade, then watches CI and pushes fix commits on failure.
How we built it
Orchestrator: Python/FastAPI state machine, plus GPT-5.6 for planning, risk ordering, and PR writeups. Agent runtime: Codex CLI headless (codex exec), with subagents for parallel upgrades and a post-edit hook that re-runs affected tests. Sandbox: one Docker container per job, network locked to allow-listed registries. Verification: full suite re-run plus mutmut (Python) and Stryker (JS/TS) for mutation testing. GitHub layer: GitPython + GitHub REST API for branches, risk-graded PRs, and CI polling. Dashboard: Next.js + Tailwind with a live SSE feed. One owner per layer, nightly 20-minute syncs.
Challenges we ran into
Token blowup on research calls. Input tokens dominated output roughly 20:1 with web search on. Capping output tokens broke generation, since reasoning tokens share that budget. Fixed by batching 3 packages per call plus a pacing gate. Four people, one sequential pipeline. Solved by defining shared Pydantic contracts and Protocol interfaces up front, so real implementations swapped in for mocks without touching the orchestrator or dashboard. One-shot Codex edits were unreliable. Built a bounded retry loop (edit, re-test, diff against baseline, retry with failure context) capped at 5 attempts, then flagged needs_human instead of force-merging. Generated tests can pass trivially. Added mutation testing scored against mutation score, coverage, and stability, so green means the tests would actually catch a regression. Sandboxing untrusted code. Docker with resource/capability/mount limits plus phase-based network policy (network during install, none during execution). Python 3.9 compatibility gap surfaced mid-integration and was fixed during the Researcher/Reviewer/CI-watcher pass. Multi-job dashboard state. Fixed cross-job SSE leakage and a stale-job-ID crash after backend restart, both found through manual end-to-end testing. Real mode is opt-in. Mock mode is default everywhere; live GitHub/OpenAI calls need explicit opt-in and credentials. CI repair is capped at 2 fix commits per PR. At submission: 58 passing backend tests, all four production stages enabled in real mode, dashboard verified end-to-end, and a live Codex smoke test on a real bump (requests==2.31.0 to 2.32.3).
What we learned
Token cost is an input problem once web search is involved, not an output one. Profile where tokens actually go before optimizing. Never trust a single LLM edit. A verify-and-retry loop with a hard cap and an honest needs_human state beats one-shot generate-and-merge. Passing tests isn't evidence of correctness. Mutation testing is the cheapest way to check if generated tests would catch a real regression. Contracts before implementations was the biggest unlock for four people building in parallel against a sequential pipeline. Default to the safe mode and make risk explicit. Sandboxing untrusted code has to be designed alongside the pipeline, not bolted on. Cap everything that could loop, or a stubborn failure becomes an unbounded cost sink instead of a clean signal. Manual end-to-end testing surfaces bugs unit tests don't; some things only show up when you use the product like a user would.
What's next
Scoped from what's explicitly still open at submission time, not aspirational ideas. Immediate: pick and authorize 2 to 3 demo-fork repos (enabled but not yet exercised), build the Docker sandbox images (docker/python/Dockerfile, docker/node/Dockerfile exist but weren't built as of 2026-07-20), and get the real demo fork URL into the video walkthrough. Near-term hardening: wider language/stack detection beyond Python and JS/TS, hostname-level network policy (currently phase-based), broader mutation testing coverage, and guaranteeing scanner tools are present rather than silently degrading. Product direction: multi-repo batch mode, a review UI for needs_human items, per-job cost/token visibility on the dashboard, and graduating Planner.from_openai() to the default (behind the same real-mode gate). If this became a real product: persistent job storage (currently in-memory), auth/multi-tenant support, and rate-limit-aware scheduling extended across the whole pipeline.
Repo Surgeon
Repo Surgeon is an autonomous codebase-modernization pipeline built for OpenAI Build Week 2026. Point it at a repo and it establishes a test baseline, researches real breaking changes, executes dependency upgrades and security fixes inside a sandbox, proves its own generated tests actually catch bugs, and opens small, risk-graded pull requests — unattended.
Status
| Component | Owner | Status |
|---|---|---|
| Orchestrator, job state machine, Surgeon self-correction loop, Codex runner, FastAPI/SSE endpoints | Vasu | Done |
| Sandbox, Scout (stack detection, baseline, coverage), security scanners, Verifier (baseline diff, affected tests, mutation testing) | Faiz | Done |
| Dashboard (Next.js) | Anubhav | Done |
| Evidence-backed Researcher, GitHub Reviewer/PR creation, CI watcher + bounded repair loop | Mayank | Done — enabled in real mode; demo forks need selected targets |
The pipeline runs end to end in mock mode by default. Real mode enables each production stage when its required credentials and local tools are available.
What it does once every piece is real
- Submit. A user pastes a repo URL into the dashboard.
- Scout (Faiz, real) clones the repo into a Docker sandbox, detects the stack, runs the existing test suite/build for a baseline, and scans dependencies with OSV-Scanner/pip-audit/npm audit.
- Researcher (Mayank) asks GPT-5.6 with web search to fetch primary changelog, migration-guide, and issue-tracker evidence for every outdated or vulnerable dependency. It validates the returned JSON against the detected dependencies and records source URLs in the breaking-change map.
- Planner (Vasu, real) turns the profile and breaking-change map into a risk-ordered upgrade plan: security fixes first, then patch, minor, major.
- Surgeon (Vasu + Faiz, real) runs Codex headless per item with the breaking-change context injected, then Faiz's Verifier re-runs affected and full tests, diffs against baseline, and feeds failures back to Codex (capped at 5 attempts before flagging
needs_human). It also mutation-tests any new/changed tests to score how many injected bugs they actually catch. - Reviewer (Mayank) splits green items into small, risk-graded PRs. Each PR contains its evidence link, verification record, confidence grade, and rollback note.
- CI watcher (Mayank) polls GitHub check runs; on failure it extracts the failing check output, asks Codex for a focused repair on the PR branch, pushes a fix commit, and rechecks (capped at two repairs).
- Dashboard (Anubhav, real) shows all of this live: a pipeline stepper, the scout report, the upgrade plan, per-item attempt/score cards with a diff viewer, and the resulting PR links.
Mock and real implementations share the same contracts, so the dashboard and orchestrator do not change when switching modes.
LLM Architecture: Codex & GPT-5.6
Repo Surgeon relies on a specialized, dual-model architecture rather than a single monolithic LLM. We explicitly chose to split responsibilities to maximize reliability and minimize token waste:
- GPT-5.6 (Researcher & Planner): We use GPT-5.6 for the high-level orchestration tasks. Extracting actionable migration paths from unstructured markdown changelogs requires deep semantic reasoning and the ability to parse dense, technical prose. GPT-5.6's superior structured JSON adherence ensures that the Researcher strictly returns valid schemas instead of hallucinating dependencies, while the Planner can reliably rank upgrades by accurately analyzing security-risk vectors.
- Codex (The Surgeon): Code modification is handled exclusively by Codex. While general-purpose models tend to rewrite entire files or inject unnecessary formatting (often breaking brittle legacy code), Codex is uniquely tuned for surgical, unified diff generation. It acts like a true developer—applying focused, isolated patches to exactly the lines that need changing. This precise scope drastically reduces unexpected side effects during the Verifier's regression tests.
Pipeline
QUEUED -> SCOUTING -> RESEARCHING -> PLANNING -> OPERATING
-> REVIEWING -> WATCHING_CI -> DONE
Terminal states: NEEDS_HUMAN, FAILED
For each upgrade item, the Surgeon follows this loop:
Codex edit -> verify -> green
\-> pass failure logs back to Codex -> retry (max 5)
An item that is still failing after five attempts becomes needs_human; the pipeline never forces a broken upgrade.
Repository layout
repo_surgeon/
contracts.py Shared Pydantic schemas; source of truth for integrations
interfaces.py Protocols for all teammate boundaries
orchestrator.py Pipeline state machine
planner.py Mock fallback and OpenAI Responses planner
surgeon.py Codex/verify self-correction loop
codex_runner.py Real and mock Codex runners
events.py Async event bus used by SSE
jobstore.py In-memory job registry
app.py FastAPI application
researcher.py GPT-5.6 web-search research with source validation
github_layer.py Git branch/worktree management and GitHub PR creation
ci.py Check-run watcher and bounded Codex repair loop
mocks/ Mock services used by the safe default mode
sandbox/ Docker sandbox manager, command runner, network policy
scout/ Stack detection, baseline runner, coverage, dependency collection
security/ OSV-Scanner / pip-audit / npm audit parsing and normalization
verifier/ Regression-aware verification, affected tests, mutation testing, quality score
dashboard/ Next.js dashboard (submit a repo, watch the live pipeline, view diffs/PRs/scores)
docs/ Implementation plans
tests/ Backend test suite (pytest)
Setup
Prerequisites:
- Python 3.12+
- Node.js/npm (dashboard, and to install the Codex CLI)
- Git
- Docker (only needed for real-mode sandbox execution)
Install the backend:
py -m pip install -e ".[dev]"
If py is not on PATH, use the bundled Python runtime:
$py = "C:\Users\MSI1\.cache\codex-runtimes\codex-primary-runtime\dependencies\python\python.exe"
& $py -m pip install -e ".[dev]"
Run the backend tests:
& $py -m pytest -q
Run the mock demo
Start the API:
& $py -m uvicorn repo_surgeon.app:app --host 127.0.0.1 --port 8000
In another terminal, create a job:
$job = Invoke-RestMethod -Method Post `
-Uri "http://127.0.0.1:8000/jobs" `
-ContentType "application/json" `
-Body '{"repo_url":"https://example.invalid/demo.git"}'
Invoke-RestMethod "http://127.0.0.1:8000/jobs/$($job.job_id)"
The default application uses mocks, so this demo does not call OpenAI or modify a repository.
Dashboard
The dashboard lives in dashboard/ (Next.js 16 + Tailwind). It proxies every API call through /api/backend/* to the FastAPI backend, so no CORS configuration is needed.
cd dashboard
npm install
npm run dev
Open http://localhost:3000 with the backend running on :8000 (set BACKEND_URL in dashboard/.env.local to point elsewhere). Submitting a repo URL creates a job and opens its live page: a pipeline stepper, the scout report, the upgrade plan, per-item cards with live test counts and a diff viewer, mutation/test-quality scores (populated in real mode; mock mode shows placeholders), and PR links. See docs/DASHBOARD_IMPLEMENTATION_PLAN.md for the full design.
API
| Endpoint | Purpose |
|---|---|
POST /jobs | Create and asynchronously run a job. Body: { "repo_url": "..." }. |
GET /jobs | List all jobs (id, repo URL, state, error). |
GET /jobs/{job_id} | Read the current state, results, PRs, error, repo profile, and upgrade plan. |
GET /jobs/{job_id}/events | Server-sent event stream for the dashboard. |
Live Codex runner
Install the standalone CLI:
npm install --global @openai/codex
codex --version
Set these environment variables in the terminal that will run the live command:
$env:OPENAI_API_KEY = "your-api-key"
$env:CODEX_API_KEY = $env:OPENAI_API_KEY
RealCodexRunner invokes codex exec --sandbox workspace-write, supplies migration and failure context, captures the resulting Git patch, and removes any temporary AGENTS.md it created. The live smoke test has been verified by updating an isolated fixture from requests==2.31.0 to requests==2.32.3.
Live GPT planner
Planner() intentionally defaults to a mock-safe fallback plan. To use the OpenAI Responses API, construct the planner with:
planner = Planner.from_openai()
It uses REPO_SURGEON_MODEL when set, otherwise gpt-4o. The OpenAI key must be available as OPENAI_API_KEY.
Real-mode credentials and safety
Copy .env.example to .env, then set REPO_SURGEON_MODE=real, OPENAI_API_KEY, and GITHUB_TOKEN. The GitHub token needs repository contents and pull-request read/write access; Actions/check-run read access is needed for CI watching. GITHUB_TOKEN is not required to construct the application, but jobs cannot open or watch live PRs without it.
The Python application reads standard environment variables; load the local .env file into your shell before starting it:
cp .env.example .env
# Edit .env with your credentials, then:
set -a && source .env && set +a
.venv/bin/python -m uvicorn repo_surgeon.app:app --host 127.0.0.1 --port 8000
On PowerShell, set the same values with $env:VARIABLE = "value" before running Uvicorn. .env is ignored by Git, so credentials are not committed.
Real mode is deliberately opt-in: it creates remote branches and pull requests only for the repository URL submitted to that job. The reviewer creates one branch per green upgrade, and the CI repair loop is capped at two fix commits per PR; a persistent failure is reported as needs_human rather than silently retried forever.
The plan's separate demo-fork task is not performed automatically: it needs the team to choose 2–3 source repositories and authorize forks in the GitHub account. This repository contains the pipeline needed to seed and process those chosen demos, but does not create external forks on startup.
Beyond choosing demo sources, remaining product work is limited to optional live GPT planning and dashboard visual polish.
Faiz services and real mode
Faiz's production Sandbox, Scout, security, and Verifier services integrate through Vasu's existing protocols. The default remains safe mock mode. Set REPO_SURGEON_MODE=real to construct the real services; imports never start Docker or scanners.
RealSandbox -> RealScout -> RepoProfile -> Surgeon edits
-> affected-test hook -> RealVerifier -> mutation score
Build and run the isolated runtimes with:
docker build -t repo-surgeon-python -f docker/python/Dockerfile .
docker build -t repo-surgeon-node -f docker/node/Dockerfile .
$env:REPO_SURGEON_MODE = "real"
python -m uvicorn repo_surgeon.app:app
Real mode expects Docker and Git. OSV-Scanner, pip-audit, mutmut, npm audit, and project-local Stryker are classified as unavailable when absent. Sandbox execution applies memory, CPU, PID, capability, privilege, mount, timeout, and phase-based network controls. Dependency installation may use the network; execution defaults to no network. Hostname allow-list enforcement requires an external proxy and is not provided by native Docker bridge mode. Host execution is disabled unless explicitly enabled for development.
Scout detects Python and JavaScript/TypeScript manifests, lockfiles, package managers, commands, and root workspaces. It captures baseline failures, dependency trees, coverage JSON, and normalized scanner findings. A deterministic repo_profile.json is written in the Repo Surgeon temporary output directory, outside the inspected repository. Its main fields include schema_version, repository, stack, commands, baseline, coverage_result, dependencies, and security_report.
Verifier loads the workspace-scoped profile, runs affected tests before the original full suite/build, and treats only new failures or a build regression as fatal. Targeted mutmut or project-local Stryker runs occur only when tests changed and are non-fatal when unavailable. Quality scoring reweights mutation, changed-code coverage, and stability when inputs are absent.
Current limits: Python and JavaScript/TypeScript only; root-level monorepo commands only; phase-based rather than hostname-based network rules; external scanner availability varies; mutation testing is targeted and capped.
python -m pytest -q
python -m compileall repo_surgeon
Current verification status
- Backend: 46/46 tests pass (
python -m pytest -q), covering the mock pipeline end to end (QUEUED→DONE), Surgeon retry behavior (fail-then-pass and five-iterationneeds_humanpaths), and the job-list/profile/plan API additions. - Real
codex exec: smoke-tested with a writable sandbox and a captured Git patch. - Dashboard: manually verified end to end against the mock pipeline — live stepper, scores, diff viewer, and PR panel render correctly; a stale job ID after a backend restart shows a friendly "not found" page instead of crashing; two concurrent jobs in separate tabs don't cross-contaminate events;
npm run buildandnpm run lintboth pass clean.
Analysis
View
Metric
- 1
Figures cover GitHub contributors during the hackathon window. A co-authored commit counts in full for each author, so per-member totals add up to more than the whole-team figures.
Technology
- CSSIn code
- FastAPIIn code
- Next.jsIn code
- OpenAIIn code
- PythonIn code
- ReactIn code
- Tailwind CSSIn code
- TypeScriptIn code
- DockerClaimed
- JavaScriptClaimed
8 of 10 appear in the indexed code. 2 claimed on Devpost could not be matched to code, which may simply mean the tool leaves no trace in the repository.
AI coding agents
- Claude CodeConfig
- CodexConfig
Detected from committed agent config files and commit authorship. Absence of a signal is not proof an agent was unused.
Codebase size
Source size
356 KB
Source files
94
Counts recognized source files only; vendored directories, binaries and lockfiles are excluded, so this is smaller than the repository on disk.
Repository
mayanks0ni/reposurgeon
110 files · 642 KB · @ 8a934d8
Structure
Interface
19 files · 17%Screens, components and styles rendered to the user.
Application logic
55 files · 50%Domain rules, services and shared utilities.
+2 moreBackground jobs
1 file · 1%Work run outside a request: tasks, workers and schedules.
Supporting
Layers are inferred from where files sit in the tree, not from reading the code. A project that names its directories unconventionally will read oddly here — open the file browser to check anything the diagram implies.
Languages
- Python64%
- TypeScript22%
- Markdown13%
- CSS1%
Share of indexed source by file size. Binary and vendored files are excluded.
Dependencies
dashboard/package.json
npm · 11- next
- react
- react-dom
- +8 more
pyproject.toml
pypi · 7- fastapi
- openai
- pydantic
- uvicorn
- +3 more
Declared in the repository’s manifests at the indexed commit. A declared package is not proof it is used, and runtime dependencies are listed first.
This project’s features have not been analysed yet.
Export this project's context (description, README, evidence, key source files) to chat with an AI agent elsewhere.