Skip to content

Repository files navigation

RepoMedic

Retrieval-grounded, guardrail-first remediation from incident evidence to verified draft PR.

CI Python 3.12 License: Apache-2.0

RepoMedic is a self-hosted AI remediation assistant for engineering teams that want AI help with production incidents without giving the model direct authority over their repositories. It ingests incidents from manual reports, logs, traces, or webhooks, retrieves repository-specific context, asks a configured LLM for a structured remediation plan, applies deterministic safety checks, optionally patches an isolated workspace, runs configured verification commands, and can open a controlled GitHub draft PR.

RepoMedic does not auto-merge, mutate production, or push to default branches. Its output is designed to be inspected by engineers.

Overview

AI code-fix tools are risky when they jump from an error message straight to a patch. RepoMedic adds the missing operational layers:

  • repository-specific retrieval before remediation
  • strict model output schemas
  • path, patch-size, and branch guardrails outside the model
  • isolated workspace patching
  • build/test/lint verification before PR-ready status
  • durable runs, jobs, incidents, PR records, and metrics
  • a server-rendered operations dashboard for normal use

It is useful for teams experimenting with guarded AI remediation, LLMOps, incident response automation, and draft-PR workflows over GitHub repositories.

Key Features

  • Operations dashboard for repositories, incidents, runs, jobs, PR attempts, collectors, signals, metrics, and knowledge status.
  • Automation preflight for repo and collector readiness before autonomous analysis, patching, or draft PR creation.
  • RAG knowledge base for runbooks, repository docs, fix summaries, and historical incidents.
  • Postgres + pgvector retrieval by default, with optional Qdrant support.
  • Optional LlamaIndex chunking for longer knowledge documents.
  • Observability intake from OpenSearch-compatible logs, Jaeger traces, signed OpenSearch webhooks, and signed GitHub webhooks.
  • Durable collector run history with signal counts, queued jobs, skipped reasons, warnings, cursor state, and errors.
  • Durable repo configuration for allowed paths, blocked paths, verification commands, local repo paths, and automation defaults.
  • Postgres-backed remediation queue processed by repomedic-worker.
  • Task-based LLM routing for incident analysis and patch generation.
  • LLM providers for Ollama, vLLM/OpenAI-compatible endpoints, Claude API, Codex CLI, and Claude Code CLI.
  • Patch guardrails for retrieval support, groundedness, confidence, risk, changed file count, patch size, allowed paths, and blocked paths.
  • Isolated workspace patching before any draft PR action.
  • Verification runner for configured build, test, and lint commands.
  • Controlled GitHub draft PR creation through GitHub CLI or GitHub App installation tokens for verified pr_ready runs.
  • MCP server runtime for Claude Code, Claude Desktop, Codex, Cursor, and other MCP-aware clients to call guarded RepoMedic tools directly.
  • Metrics and audit records for provider/model attribution, verification status, risk, confidence, draft PR success, and failure stages.

Screenshots / Product Tour

The screenshots below were captured from the real local dashboard at /dashboard against a clean database.

RepoMedic operations dashboard overview

Overview tab with first-run counters and empty states for incidents and runs.

RepoMedic pull request board

Pull Requests tab empty state, which points users to PR-ready run details.

Additional useful screenshots to capture later from a clean demo dataset:

  • incident detail with queued analysis action
  • run detail with verification output and changed files
  • collector setup tab with an OpenSearch or Jaeger config
  • knowledge tab after ingesting sample runbooks

How It Works

  1. A user registers a repository policy or submits inline policy with an incident analysis request.
  2. A manual incident, collector signal, or signed webhook creates or updates a durable incident record.
  3. The API queues a remediation job when requested or when repo/collector automation allows it.
  4. The worker retrieves relevant repository context from the selected vector backend.
  5. The incident analysis provider returns strict JSON with diagnosis, targets, risk notes, and a fix plan.
  6. If patching is enabled, a dedicated patch-generation task uses exact local file context to produce a focused diff.
  7. Guardrails decide whether the diff is safe enough to apply in an isolated workspace.
  8. Verification commands from repo config run without shell-control syntax.
  9. RepoMedic persists run metrics and exposes the result through the API and dashboard.
  10. A verified pr_ready run can create a GitHub draft PR against explicitly allowlisted safe branches.
sequenceDiagram
    participant User as Engineer or Collector
    participant API as FastAPI API
    participant DB as Postgres + pgvector
    participant Worker as repomedic-worker
    participant LLM as LLM provider
    participant Git as Local workspace + git
    participant GH as GitHub PR client

    User->>API: Register repo / submit incident / run collector
    API->>DB: Persist repo config, signal, incident, job
    Worker->>DB: Claim queued remediation job
    Worker->>DB: Retrieve top-k knowledge context
    Worker->>LLM: Incident analysis JSON request
    LLM-->>Worker: Structured remediation output
    Worker->>LLM: Patch generation request when enabled
    LLM-->>Worker: Unified diff or no diff
    Worker->>Git: Clone local repo into isolated workspace
    Worker->>Git: Apply patch and collect changed files
    Worker->>Git: Run configured build/test/lint commands
    Worker->>DB: Persist run, evaluation, verification
    Worker->>GH: Create draft PR when allowed and verified
    Worker->>DB: Persist draft PR record
    User->>API: Review dashboard, run, and PR detail
Loading

Architecture

flowchart LR
    subgraph UI["User interfaces"]
        Dashboard["FastAPI/Jinja dashboard"]
        REST["REST API"]
        MCP["MCP server"]
    end

    subgraph Intake["Incident intake"]
        Manual["Manual incident API/UI"]
        OpenSearch["OpenSearch collector/webhook"]
        Jaeger["Jaeger collector"]
        GitHubWebhook["GitHub webhook"]
    end

    subgraph Core["RepoMedic services"]
        API["repomedic-api"]
        MCPService["repomedic-mcp"]
        Collector["repomedic-collector"]
        Worker["repomedic-worker"]
        Knowledge["Knowledge service"]
        Guardrails["Guardrails + patch gate"]
        Verification["Verification runner"]
    end

    subgraph Storage["Persistence"]
        Postgres["Postgres"]
        Pgvector["pgvector embeddings"]
        Qdrant["optional Qdrant"]
    end

    subgraph External["External tools"]
        LLM["Ollama / vLLM / Claude / Codex CLI"]
        GitWorkspace["Local git workspace"]
        GHCLI["GitHub CLI"]
    end

    Dashboard --> API
    REST --> API
    MCP --> MCPService
    Manual --> API
    OpenSearch --> Collector
    Jaeger --> Collector
    GitHubWebhook --> API
    Collector --> API
    MCPService --> Postgres
    MCPService --> Knowledge
    MCPService --> GHCLI
    API -->|persist config, incidents, jobs| Postgres
    Worker -->|claim jobs| Postgres
    Worker --> Knowledge
    Knowledge --> Pgvector
    Knowledge --> Qdrant
    Pgvector --> Postgres
    Worker --> LLM
    Worker --> Guardrails
    Worker --> GitWorkspace
    Worker --> Verification
    Worker --> GHCLI
    Worker --> Postgres
Loading

Architecture Notes

  • FastAPI serves both JSON APIs and the Jinja2 dashboard.
  • Postgres is the durable store for repo configs, incidents, events, jobs, signals, runs, PR records, and knowledge documents.
  • pgvector is the default retrieval backend; Qdrant is available through a Docker Compose profile.
  • The queue is a Postgres table claimed by the worker with database locking.
  • Verification commands come from repo config, not model output.
  • Draft PRs require pr_ready, passing verification, a workspace diff, and allowlisted repository/base branch settings.
  • The dashboard shows warn-only setup readiness for repository policy, collectors, LLM provider credentials/tooling, knowledge indexing, workers, and draft PR safety. These warnings do not block saving configs.
  • Repo and collector preflight checks show blockers separately from warnings for analysis, patch, and draft-PR modes. The same service powers REST, dashboard, and MCP output.
  • repomedic-mcp exposes RepoMedic as an MCP server over local stdio or trusted-network Streamable HTTP. It reuses the same safety gates as REST.
  • Controlled MCP client tool-use can collect extra context during remediation only from explicit per-repo policies and global runtime allowlists.
  • Docker Compose is the only orchestration shipped in this repo. No Kubernetes manifests or Aspire app host are present.
  • RepoMedic does not expose arbitrary external tool execution, shell tools, production mutation, ready-PR conversion, auto-merge, or default-branch mutation.

Project Structure

apps/
  api/                 FastAPI app, REST routes, Jinja dashboard, static CSS
  worker/              Postgres-backed remediation worker
  collector/           Polling process for enabled collectors
  mcp/                 MCP server tools/resources for AI clients
application/           Shared use cases used by API and MCP adapters
core/                  Settings, LLM task selection, structured logging
domain/
  collectors/          Collector result and severity domain logic
  incidents/           Incident normalization
  knowledge/           RAG models, ports, indexing, and knowledge service
  metrics/             Run metric domain models and ports
  remediation/         Analysis service, prompts, guardrails, patch gate
  repositories/        Repository policy rules
  verification/        Verification result models
infrastructure/
  collectors/          OpenSearch, Jaeger, webhook normalization, intake runner
  db/                  SQLAlchemy models, sessions, operations, run metrics
  embeddings/          sentence-transformers embedding provider
  git/                 Local workspace and GitHub draft PR clients
  indexing/            Optional LlamaIndex adapter
  llm/                 Ollama, OpenAI-compatible/vLLM, Claude, Codex providers
  retrieval/           pgvector and Qdrant knowledge repositories
  verification/        Command runner
schemas/               Pydantic API request/response models
migrations/            Alembic migrations
prompts/               Incident analysis and patch-generation prompt templates
examples/              Sample incidents, policies, runbooks, and repo docs
docs/                  Architecture, API, safety, demo, and operations docs
docs/images/           README screenshots captured from the running dashboard
tests/                 Unit and integration-style tests

Visual Flow / Animated Architecture

No GIFs are committed. The lightweight Mermaid flow below shows the real runtime path from observability signal to draft PR.

flowchart TD
    A["Log, trace, webhook, or manual incident"] --> B["Incident record"]
    B --> C{"Auto queue enabled or user queues analysis?"}
    C -- No --> D["Incident stays reviewable in dashboard"]
    C -- Yes --> E["remediation_jobs row"]
    E --> F["Worker claims job"]
    F --> G["Retrieve knowledge context"]
    G --> H["Structured incident analysis"]
    H --> I{"Patch requested?"}
    I -- No --> J["Suggestion-only run"]
    I -- Yes --> K["Patch generation with local file context"]
    K --> L{"Guardrails and patch gate pass?"}
    L -- No --> J
    L -- Yes --> M["Apply diff in isolated workspace"]
    M --> N["Run configured verification"]
    N --> O{"Verification passed?"}
    O -- No --> J
    O -- Yes --> P["pr_ready run"]
    P --> Q{"Draft PR allowed?"}
    Q -- No --> R["Review run in dashboard/API"]
    Q -- Yes --> S["GitHub draft PR"]
Loading

Getting Started

Prerequisites

  • Python 3.12 (.python-version is 3.12)
  • Docker and Docker Compose
  • uv for the same local workflow used by CI
  • Git
  • GitHub CLI gh or GitHub App credentials if you want draft PR creation
  • Optional: Ollama, vLLM-compatible serving, Qdrant, Codex CLI, Claude Code CLI, or an Anthropic API key depending on the provider/backend you choose

Installation

git clone https://github.com/mecemis/repo-medic.git
cd repo-medic
cp .env.example .env

If local port 5432 is already used, set POSTGRES_PORT in .env before starting the stack. Host-side commands must use the same port in DATABASE_URL.

Running Locally With Docker

Set the host folder that contains the repos RepoMedic may patch. Compose mounts that folder at /host-repos in the API, worker, collector, and MCP containers:

printf '\nREPOMEDIC_HOST_REPOS_ROOT=%s\n' "$HOME/code" >> .env

For Docker-first use, set each repository config local_repo_path to the container path, for example /host-repos/example-service. If a config already contains a host path such as /Users/me/code/example-service, RepoMedic uses REPO_PATH_MAPPINGS to resolve it to /host-repos/example-service inside the containers. Compose fills that mapping from REPOMEDIC_HOST_REPOS_ROOT; advanced users can set comma-separated mappings manually, for example:

REPO_PATH_MAPPINGS=/Users/me/code=/host-repos,/srv/repos=/repos

Model providers run where the worker runs. In the default Docker image, ollama, vllm, openai_compatible, and claude_api are the practical container-friendly choices. If you do not have provider API keys and want to use authenticated local CLIs, set CLI_RUNTIME=host_worker, do not rely on the Docker worker for remediation jobs, and run the worker from the host where codex, claude, and gh are installed.

For local CLI mode:

# Add these to .env:
# CLI_RUNTIME=host_worker
# LLM_PROVIDER=codex_cli
# INCIDENT_ANALYSIS_LLM_PROVIDER=codex_cli
# PATCH_GENERATION_LLM_PROVIDER=codex_cli
# PULL_REQUEST_CLIENT=gh_cli

docker compose up -d postgres api collector mcp
docker compose stop worker

codex --version
claude --version
gh auth status -h github.com
gh auth setup-git -h github.com

set -a
source .env
set +a

DATABASE_URL="postgresql+asyncpg://repomedic:repomedic@localhost:${POSTGRES_PORT:-5432}/repomedic" \
uv run python -m apps.worker.main

In this mode, queued jobs and automatic draft PR creation run through the host worker. Direct dashboard/API draft PR creation still runs in the API process; if the API is inside Docker, use auto PR creation from the host worker or run the API on the host too.

The dashboard Overview tab includes an AI Runtime table that shows whether each provider is usable from the current API/worker runtime, which model it will use, and the Docker-specific action needed when it is blocked. Use Test provider to run an active probe: Ollama checks /api/tags, OpenAI-compatible/vLLM checks /v1/models, Claude API checks /v1/models, and CLI providers run --version in the same runtime that would execute jobs. The same data is available for scripts:

curl http://localhost:8000/api/v1/runtime/providers
curl "http://localhost:8000/api/v1/runtime/providers?provider=ollama"
curl -X POST http://localhost:8000/api/v1/runtime/providers/ollama/probe

The Repos tab includes Queue smoke for each registered repository. It creates a synthetic incident and queued job through the same queue used by collectors. The worker still uses the repository's stored provider, patch, verification, guardrail, and draft-PR settings.

docker compose up --build -d
docker compose exec api alembic upgrade head
curl http://localhost:8000/api/v1/healthz

Open:

http://localhost:8000/dashboard

The default Compose stack includes:

  • repomedic-api
  • repomedic-worker
  • repomedic-collector
  • repomedic-mcp
  • repomedic-postgres

Start optional services only when you need them:

docker compose --profile ollama up --build -d
docker compose exec ollama ollama pull ${OLLAMA_MODEL:-deepseek-coder:33b}

RETRIEVAL_BACKEND=qdrant docker compose --profile qdrant up --build -d
LLM_PROVIDER=vllm docker compose --profile vllm up --build -d

Running Locally Without Docker

Use Docker for Postgres, then run the API from the host:

docker compose up -d postgres
uv sync --extra dev --extra embeddings --frozen
uv run alembic upgrade head
uv run uvicorn apps.api.main:app --host 0.0.0.0 --port 8000 --reload

Run a one-shot worker from the host:

uv run python -m apps.worker.main --once

Run the MCP server over local stdio:

uv run python -m apps.mcp.main

Run the MCP server over Streamable HTTP:

MCP_TRANSPORT=streamable-http MCP_HOST=127.0.0.1 MCP_PORT=8100 \
  uv run python -m apps.mcp.main

Run the worker continuously:

uv run python -m apps.worker.main

MCP Runtime

RepoMedic includes a first-class MCP server for agent clients that need a standard tool interface. It exposes guarded tools for repo config, knowledge, incident intake, job queueing, collector runs, run/PR inspection, and draft PR creation.

RepoMedic can also act as a controlled MCP client during remediation, but only for predeclared context calls in a repo config. The remediation model does not choose arbitrary tools. Repo policy names the server, tool, arguments, and allowlist; runtime settings then enforce server URL/stdio allowlists, timeouts, call limits, output caps, and redaction. Tool results are added to the prompt as extra evidence and persisted in each run under evaluation.mcp_tool_use.

Local stdio clients can launch RepoMedic directly:

{
  "mcpServers": {
    "repomedic": {
      "command": "uv",
      "args": ["run", "python", "-m", "apps.mcp.main"],
      "cwd": "/absolute/path/to/repo-medic",
      "env": {
        "DATABASE_URL": "postgresql+asyncpg://repomedic:repomedic@localhost:5432/repomedic"
      }
    }
  }
}

Claude Code can connect to the HTTP transport after docker compose up -d mcp:

claude mcp add --transport http repomedic http://localhost:8100/mcp

Codex or other MCP-aware clients can use the same command/args for stdio or http://localhost:8100/mcp for Streamable HTTP. The HTTP endpoint has no auth in this release; bind it to localhost or a trusted network only.

Example repo policy for controlled MCP context collection:

{
  "mcp_tool_policy": {
    "enabled": true,
    "servers": {
      "observability": {
        "transport": "streamable-http",
        "url": "http://localhost:8100/mcp"
      }
    },
    "allowed_tools": ["observability/repomedic_search_knowledge"],
    "context_calls": [
      {
        "name": "related-knowledge",
        "server": "observability",
        "tool": "repomedic_search_knowledge",
        "arguments": {
          "repository": "{{repository}}",
          "query": "{{raw_error}}",
          "limit": 3
        }
      }
    ],
    "max_calls": 3,
    "timeout_seconds": 30,
    "max_output_chars": 12000
  }
}

For Docker-to-Docker calls use http://mcp:8100/mcp in the repo policy and keep that URL in MCP_CLIENT_ALLOWED_SERVER_URLS.

Running Tests

uv sync --extra dev --frozen
uv run ruff check .
uv run mypy .
uv run pytest
uv run playwright install chromium
uv run pytest -m e2e
uv lock --check
docker compose config
docker compose --profile qdrant config
docker compose --profile vllm config

The default uv run pytest command excludes browser E2E tests. Run the API against a migrated database, install Chromium once with uv run playwright install chromium, then run uv run pytest -m e2e to exercise dashboard flows in a real browser. The E2E suite also includes an autonomous smoke harness that uses test doubles for analysis and PR creation to prove the persisted path from collector signal to incident, job, run, and draft PR record without calling a real LLM or GitHub.

Configuration

.env.example contains the full local configuration template. The table below summarizes the variables that materially change runtime behavior.

Variable Required Description Example
APP_NAME No FastAPI application name. RepoMedic
ENVIRONMENT No Runtime environment label used in health/logging. local
LOG_LEVEL No Logging level. INFO
API_PREFIX No Prefix for JSON API routes. /api/v1
API_PORT No Host port for the API container. 8000
MCP_TRANSPORT No MCP server transport for host runs. Compose forces HTTP for the mcp service. stdio or streamable-http
MCP_HOST No MCP HTTP bind host. Use localhost unless on a trusted network. 127.0.0.1
MCP_PORT No MCP HTTP port. 8100
MCP_PATH No MCP Streamable HTTP path. /mcp
MCP_ALLOW_MUTATIONS No Enables MCP tools that write RepoMedic state. true
MCP_ALLOW_DRAFT_PRS No Enables MCP draft PR tool; existing PR safety policy still applies. true
MCP_MAX_LIST_LIMIT No Max list size returned by MCP tools. 100
MCP_CLIENT_ENABLED No Enables controlled MCP client context calls during remediation. false
MCP_CLIENT_ALLOWED_SERVER_URLS No Comma-separated allowlist for streamable HTTP MCP servers. http://localhost:8100/mcp
MCP_CLIENT_ALLOW_STDIO No Allows repo policies to use stdio MCP servers. Keep false unless commands are globally allowlisted. false
MCP_CLIENT_ALLOWED_STDIO_COMMANDS No Comma-separated executable allowlist for stdio MCP servers. empty
MCP_CLIENT_MAX_CALLS No Global cap for controlled MCP calls per remediation run. 3
MCP_CLIENT_TIMEOUT_SECONDS No Global timeout cap for each controlled MCP tool call. 30
MCP_CLIENT_MAX_OUTPUT_CHARS No Global output cap persisted and sent to the remediation prompt. 12000
DATABASE_URL Yes for host runs Async SQLAlchemy database URL. Compose overrides this inside containers. postgresql+asyncpg://repomedic:repomedic@localhost:5432/repomedic
POSTGRES_USER No Local Postgres user. repomedic
POSTGRES_PASSWORD No Local Postgres password; change outside local demos. repomedic
POSTGRES_DB No Local Postgres database. repomedic
POSTGRES_PORT No Host port mapped to Postgres. 5432
LLM_PROVIDER Yes for model-backed analysis Default provider for LLM tasks. ollama
OLLAMA_BASE_URL If using Ollama Ollama API URL for host runs. http://localhost:11434
OLLAMA_MODEL If using Ollama Default Ollama model. deepseek-coder:33b
VLLM_BASE_URL If using vLLM/OpenAI-compatible OpenAI-compatible base URL. http://localhost:8001
VLLM_API_KEY If using vLLM/OpenAI-compatible API key for the OpenAI-compatible endpoint. repomedic-local-dev-key
VLLM_MODEL If using vLLM/OpenAI-compatible Model name sent to the endpoint. Qwen/Qwen2.5-Coder-7B-Instruct
ANTHROPIC_API_KEY If using Claude API Anthropic API key for claude_api. empty
CLAUDE_API_BASE_URL If using Claude API Anthropic Messages API base URL. https://api.anthropic.com
CLAUDE_API_VERSION If using Claude API Anthropic API version header. 2023-06-01
CLAUDE_API_MODEL If using Claude API Claude model for native API requests. claude-sonnet-4-6
CLAUDE_API_MAX_TOKENS If using Claude API Maximum response tokens. 4096
CODEX_CLI_COMMAND If using Codex CLI Executable used for Codex CLI provider. codex
CODEX_CLI_MODEL If using Codex CLI Model string passed to Codex CLI. gpt-5.4
CODEX_CLI_SANDBOX If using Codex CLI Codex CLI sandbox mode. read-only
CLAUDE_CLI_COMMAND If using Claude Code CLI Executable used for Claude Code CLI provider. claude
CLAUDE_CLI_MODEL If using Claude Code CLI Model string passed to Claude Code CLI. claude-sonnet-4-6
CLAUDE_CLI_TIMEOUT_SECONDS If using Claude Code CLI Timeout for non-interactive Claude CLI JSON runs. 900
CLI_RUNTIME No same_process checks CLI tools in the API/worker runtime. host_worker is for Docker API/dashboard plus host-run worker CLIs. same_process
PROVIDER_PROBE_TIMEOUT_SECONDS No Timeout for dashboard/API provider readiness probes. 5
INCIDENT_ANALYSIS_LLM_PROVIDER No Task-specific provider override. ollama
PATCH_GENERATION_LLM_PROVIDER No Task-specific patch provider override. codex_cli
PULL_REQUEST_CLIENT No Draft PR backend: gh_cli local default or github_app. gh_cli
GITHUB_TOKEN No Alternative to mounted gh auth when using gh_cli. empty
GITHUB_APP_ID If using github_app GitHub App ID used to mint installation tokens. empty
GITHUB_APP_PRIVATE_KEY If using github_app Inline PEM private key. Prefer secret injection, never commit it. empty
GITHUB_APP_PRIVATE_KEY_PATH If using github_app Path to the GitHub App PEM private key. empty
GITHUB_APP_INSTALLATION_ID No Optional installation ID override; otherwise RepoMedic looks it up per repo. empty
GITHUB_APP_API_BASE_URL No GitHub REST API base URL. https://api.github.com
GITHUB_APP_API_VERSION No GitHub REST API version header. 2022-11-28
GITHUB_APP_REQUEST_TIMEOUT_SECONDS No GitHub App API request timeout. 30
COLLECTOR_WEBHOOK_SECRET For webhooks HMAC secret for OpenSearch/GitHub webhook verification. change-me
COLLECTOR_POLL_INTERVAL_SECONDS No Poll interval for repomedic-collector. 60
OPENSEARCH_BASE_URL If using OpenSearch collector Default OpenSearch-compatible URL. https://opensearch.example.com
OPENSEARCH_INDEX If using OpenSearch collector Default log index pattern. logs-*
OPENSEARCH_USERNAME No Basic auth username. empty
OPENSEARCH_PASSWORD No Basic auth password. empty
OPENSEARCH_API_KEY No API key auth value. empty
JAEGER_BASE_URL If using Jaeger collector Jaeger query API URL. http://localhost:16686
RETRIEVAL_BACKEND No Knowledge retrieval backend. pgvector or qdrant
KNOWLEDGE_INDEXER No Document indexing strategy. direct or llamaindex
QDRANT_URL If using Qdrant Qdrant base URL. http://localhost:6333
QDRANT_COLLECTION If using Qdrant Qdrant collection name. repomedic_knowledge
EMBEDDING_MODEL If using local embeddings sentence-transformers model name. sentence-transformers/all-MiniLM-L6-v2
EMBEDDING_DIMENSIONS If using local embeddings Expected embedding vector size. 384
PATCH_GATE_MIN_RETRIEVAL_SCORE No Minimum average retrieval score for patch readiness. 0.25
PATCH_GATE_MAX_RISK_SCORE No Maximum risk score for patch readiness. 0.2
PATCH_GENERATION_MAX_FILES No Max local files included in patch-generation context. 2
PATCH_GENERATION_MAX_FILE_CHARS No Max characters per file context. 6000
WORKSPACE_ROOT No Isolated patch workspace root. .repomedic-workspaces
REPOMEDIC_HOST_REPOS_ROOT Docker Host folder mounted into containers at /host-repos. /Users/me/code
HOST_REPOS_ROOT No Runtime path for mounted host repositories. /host-repos
REPO_PATH_MAPPINGS No Comma-separated host_path=runtime_path mappings for stored repo paths. /Users/me/code=/host-repos
VERIFICATION_MAX_COMMANDS No Maximum repo-configured verification commands per run. 10
VERIFICATION_MAX_COMMAND_LENGTH No Maximum length of each verification command string. 500
VERIFICATION_MAX_OUTPUT_CHARS No Max stdout or stderr characters persisted per command after redaction. 12000
VERIFICATION_ALLOWED_ENV_VARS No Comma-separated environment allowlist passed to verification commands. PATH,HOME,...
VERIFICATION_SECRET_ENV_NAME_PATTERNS No Env-name patterns whose values are redacted from command output. TOKEN,SECRET,...
VERIFICATION_BLOCKED_EXECUTABLES No Direct executables blocked in repo verification commands. bash,sh,curl,...
VERIFICATION_REQUIRE_WORKSPACE_CWD No Require verification cwd to be inside WORKSPACE_ROOT. true
DRAFT_PR_ALLOWED_REPOSITORIES For draft PRs Comma-separated owner/name allowlist. Blank disables PR creation. owner/safe-test-repo
DRAFT_PR_ALLOWED_BASE_BRANCH_PATTERNS For draft PRs Allowed base branch patterns. repomedic-safe/*
DRAFT_PR_SAFE_BASE_BRANCH_PREFIX No Safe base branch prefix. repomedic-safe/
DRAFT_PR_SAFE_HEAD_BRANCH_PREFIX No Safe head branch prefix. repomedic/

Do not commit real secrets in .env.

Usage Examples

1. Ingest And Search Knowledge

curl -X POST http://localhost:8000/api/v1/knowledge/ingest \
  -H 'content-type: application/json' \
  -d '{
    "repository": "acme/example-service",
    "source_type": "runbook",
    "source_ref": "runbooks/payment-webhook.md",
    "title": "Payment webhook runbook",
    "content": "Missing payment metadata should return a 4xx response, not a 500.",
    "metadata": {"owner": "payments"}
  }'
curl -X POST http://localhost:8000/api/v1/knowledge/search \
  -H 'content-type: application/json' \
  -d '{
    "repository": "acme/example-service",
    "query": "webhook metadata missing causes 500",
    "top_k": 5
  }'

2. Analyze A Manual Incident Without Patching

curl -X POST http://localhost:8000/api/v1/incidents/analyze \
  -H 'content-type: application/json' \
  -d @examples/incident-analysis-request.json

This returns retrieval matches, structured remediation output, guardrail decisions, verification status, evaluation scores, and PR-ready text. With apply_patch=false, the result is suggestion-only.

3. Register A Repository For Queued Remediation

curl -X POST http://localhost:8000/api/v1/repos \
  -H 'content-type: application/json' \
  -d '{
    "repository": "acme/example-service",
    "service_name": "payment-api",
    "default_branch": "main",
    "allowed_paths": ["src/payment", "tests/payment"],
    "blocked_paths": [".github/workflows", "infra", "secrets"],
    "build_commands": [],
    "test_commands": ["pytest tests/payment"],
    "lint_commands": ["ruff check src tests"],
    "local_repo_path": "/host-repos/example-service",
    "apply_patch_default": true,
    "auto_queue_analysis_default": true,
    "auto_create_draft_pr_default": false,
    "mcp_tool_policy": {
      "enabled": false,
      "servers": {},
      "allowed_tools": [],
      "context_calls": []
    }
  }'

Then create an incident:

curl -X POST http://localhost:8000/api/v1/incidents \
  -H 'content-type: application/json' \
  -d @examples/incident.json

Queue analysis for that incident from the dashboard or through:

curl -X POST http://localhost:8000/api/v1/incidents/<incident-id>/analyze \
  -H 'content-type: application/json' \
  -d '{"apply_patch": true, "top_k": 6}'

Inspect jobs and runs:

curl http://localhost:8000/api/v1/jobs
curl http://localhost:8000/api/v1/runs

Check autonomous readiness before enabling patch or PR automation:

curl "http://localhost:8000/api/v1/repos/acme/example-service/preflight?mode=draft_pr"

The response includes status, capabilities, structured checks, blockers, and warnings. Missing local checkout, allowed paths, verification commands, LLM credentials/tooling, draft PR allowlists, collector source config, and repo/collector auto-mode mismatches are surfaced before a signal is allowed to drive a patch or draft PR.

4. Run Collectors

Create OpenSearch and Jaeger collectors from the dashboard, or use the API:

curl -X POST http://localhost:8000/api/v1/collectors \
  -H 'content-type: application/json' \
  -d '{
    "name": "payment-jaeger-errors",
    "repository": "acme/example-service",
    "collector_type": "jaeger",
    "enabled": true,
    "query": {
      "base_url": "http://localhost:16686",
      "service": "payment-api",
      "tags": {"error": "true"}
    },
    "auto_queue_analysis": true,
    "auto_apply_patch": true,
    "auto_create_draft_pr": false,
    "min_severity": "medium"
  }'

Run enabled collectors once:

curl -X POST http://localhost:8000/api/v1/collectors/run \
  -H 'content-type: application/json' \
  -d '{"limit": 50}'

Inspect collector readiness and run history:

curl "http://localhost:8000/api/v1/collectors/<collector-id>/preflight?mode=draft_pr"
curl http://localhost:8000/api/v1/collectors/runs
curl http://localhost:8000/api/v1/collectors/runs/<run-id>

Collector run and webhook responses include auto_queue_skipped, auto_queue_skip_reasons, and auto_queue_warnings. Incident detail events also record auto_queue_decision or auto_queue_skipped, so you can see whether an observability signal queued remediation, skipped because repo/collector policy was off, or queued with setup warnings such as missing verification commands. Collector poll history is also persisted in collector_run_records, so the dashboard and API keep the last poll status even after the immediate response is gone.

5. Create A Controlled Draft PR

Draft PR creation is disabled until DRAFT_PR_ALLOWED_REPOSITORIES and safe base branch patterns allow the target. The local default backend is gh_cli, using mounted GitHub CLI auth or GITHUB_TOKEN. For server-style operation, set PULL_REQUEST_CLIENT=github_app plus GITHUB_APP_ID and either GITHUB_APP_PRIVATE_KEY or GITHUB_APP_PRIVATE_KEY_PATH. The App needs repository Contents write permission to push RepoMedic branches and Pull requests write permission to open draft PRs. This is GitHub App installation authentication, not user login or RepoMedic dashboard authentication.

curl -X POST http://localhost:8000/api/v1/runs/<run-id>/draft-pr \
  -H 'content-type: application/json' \
  -d '{
    "repository": "owner/safe-test-repo",
    "base_branch": "repomedic-safe/demo-base",
    "head_branch": "repomedic/demo-head",
    "title": "Draft: RepoMedic remediation",
    "body": "Draft PR opened by RepoMedic after verification.",
    "commit_message": "Apply RepoMedic remediation",
    "create_base_branch": true,
    "draft": true
  }'

Development

  • Use uv run ruff check . before committing.
  • Use uv run mypy . for type checks.
  • Use uv run pytest for the test suite.
  • Use uv run pytest -m e2e for browser dashboard checks against a running local server.
  • Use docker compose config after editing Compose files.
  • Put domain rules in domain/; keep framework and external-service code in infrastructure/.
  • Add API schemas in schemas/ and route handlers in apps/api/routes/.
  • Add migrations under migrations/versions/ for database changes.
  • Keep verification commands in repo config; never accept shell commands from model output.
  • Prefer deterministic guardrails over prompt-only safety rules.

Useful docs:

Roadmap

No issue, milestone, TODO, or roadmap file is present in this repository. The README therefore does not claim planned features as committed work.

Operational publication checks are documented in docs/release-checklist.md.

Contributing

  1. Create a branch.

  2. Keep changes scoped and covered by tests.

  3. Run:

    uv run ruff check .
    uv run mypy .
    uv run pytest
  4. Open a PR with a short summary, test results, and any operational notes.

Security-sensitive changes should also be checked against docs/security-safety.md.

License

Apache-2.0. See LICENSE.

About

AI remediation assistant for repositories with logs/traces intake, RAG, guardrails, verification, MCP, and controlled draft PR workflows.

Topics

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages