Evidence-first Git integration investigations.
Find the bugs that only appear when two individually passing changes are merged, and keep the proof.
Product · Engineering · Architecture · Verification · Run locally · Creator
Change A passes its tests. Change B passes its tests. Merge them, and something breaks: a renamed key, a changed default, an assumption that only one side knew about. Code review rarely catches it, because each diff looks correct on its own.
MergeProof runs each change and the combined merge in clean, isolated clones, then records exactly what happened. It reports a confirmed interaction only when both independent runs pass and the combined run fails with real assertion evidence. Everything else is labeled for what it is.
| Capability | What you can do |
|---|---|
| Repository import | Validate and store a local Git checkout, list its branches, and inspect the merge-base of any two. |
| Isolated execution | Run your test command on branch A, branch B and the combined merge, each in its own temporary clone at an exact commit SHA. |
| Honest classification | Separate assertion failures from syntax errors, missing dependencies, timeouts, merge conflicts and other execution errors. |
| Background investigations | Queue an investigation, follow its progress, and cancel it cooperatively without marking it failed. |
| Evidence bundle | Download a ZIP with the JSON report, full logs, source diffs and a REPRODUCE.md with the exact commands. |
| Dashboard | A local web UI with live counts, recent activity, investigation history and a clearly labeled sample repository. |
Select two branches → run each alone → run the merge → classify → export the proof
| Engineering problem | Implementation | Inspect the code |
|---|---|---|
| A failing exit code is not proof of a broken test | Only assertion tracebacks, pytest assert failures or unittest's failure summary count as test_failure. Syntax, import and other errors are classified separately. |
classify_failure |
| A merge conflict must never look like a confirmed bug | summary.confirmed requires tests to run in all three roles, A and B to pass, and the combined run to fail with a test failure and a log. |
_confirmed |
| Runs must not leak state into each other | Every role gets a fresh git clone --no-local --no-hardlinks; remote-only commits are fetched into private refs and executed by SHA. |
_clone, run_branch, run_combined |
| Long or stuck test suites | Commands run with a deadline and poll a cancel event, so timeouts and user cancellations end cleanly with their own status. | run_command |
| Investigations should not block the UI | A single daemon worker thread consumes a queue and persists progress after each role. | InvestigationWorker |
| Results need to be reproducible by someone else | The report, logs, diffs and reproduction steps are packed into one downloadable bundle. | evidence_bundle |
MergeProof does not include runtime AI reasoning. Git and test evidence stay deterministic; an AI layer could later propose hypotheses or targeted regression tests whose claims remain unverified until executed.
flowchart LR
UI[web/index.html dashboard] --> API[ThreadingHTTPServer JSON API]
API --> STORE[(mergeproof-data.json)]
API --> Q[Investigation queue]
Q --> W[Daemon worker]
W --> A[Clone + test branch A]
W --> B[Clone + test branch B]
W --> C[Clone + merge + test A+B]
A & B & C --> R[Classification + report]
R --> STORE
R --> ZIP[Evidence bundle ZIP]
- Backend: one Python file (
app.py) using only the standard library:http.server,subprocess,threading,zipfile. - Frontend: a single static page (
web/index.html) served by the same process. - Storage: a local JSON file (
mergeproof-data.json, orMERGEPROOF_DATA_FILE). A labeledcheckout-service (sample)record is created with every new store. - Fixture:
demo_repo/holdschange_a,change_bandcombinedversions of a small service that reproduce a real interaction.
| Gate | Evidence |
|---|---|
| Regression suite | 20 tests passed locally (python -m unittest discover -s tests) |
| Linux rebuild | The rebuild workflow builds the image on Ubuntu, runs the suite with --network none and no personal Git config, then checks /api/health on a running container. |
| Sample investigation | Change A and Change B pass independently; the combined snapshot reproduces a failing assertion. The fixture is meant to fail inside its investigation, while the suite itself exits with OK. |
Scope and known limitations
- Local-only application: no hosted accounts, billing, teams or remote provider imports. Repository import means a path to a local Git checkout.
- Repository tests execute code with the privileges of the process or container. Only run trusted repositories.
- Hosted multi-user execution is out of scope for this prototype.
- A documented Dockerfile alone is not proof of a successful run; check the workflow result for the commit you are using.
- Python 3.11.17, pinned in
.python-versionand the Docker image. - Git on your
PATH. No personal Git identity is needed for temporary executions. - Docker Engine or Desktop for the clean Linux rebuild.
There are no third-party Python packages. requirements.lock is intentionally empty apart from comments; it locks the complete dependency set.
git clone https://github.com/Lingu17/MergeProof.git
cd MergeProof
python -m pip install --no-index --require-hashes -r requirements.lock
python app.pyOpen http://localhost:8000. The dashboard runs a real Python fixture analysis right away.
The server binds to 127.0.0.1 by default. Optional settings are documented in .env.example; the app reads environment variables, not .env files. In Bash: cp .env.example .env, then set -a; . ./.env; set +a. In PowerShell, set variables individually, for example $env:MERGEPROOF_PORT = '8765'.
| Variable | Purpose |
|---|---|
MERGEPROOF_PORT |
HTTP port (default 8000) |
MERGEPROOF_BIND_HOST |
Interface to bind (default 127.0.0.1) |
MERGEPROOF_DATA_FILE |
JSON store location (default mergeproof-data.json beside app.py) |
docker build -t mergeproof .
docker run --rm -p 127.0.0.1:8000:8000 -v mergeproof-data:/data mergeproofThe named volume keeps investigations when the container is recreated; container data lives at /data/mergeproof-data.json. To analyze a host repository, mount it read-only and use the mounted path in the Repositories screen:
docker run --rm -p 127.0.0.1:8000:8000 \
-v "$PWD/my-repository:/repos/my-repository:ro" \
-v mergeproof-data:/data \
mergeproofRun the offline regression suite inside the image:
docker run --rm --network none -e GIT_CONFIG_GLOBAL=/dev/null -e GIT_CONFIG_NOSYSTEM=1 mergeproof python -m unittest discover -s tests -vAll request and response bodies are JSON.
| Area | Routes |
|---|---|
| Health & overview | GET /api/health, GET /api/overview |
| Repositories | GET / POST /api/repositories, POST /api/repositories/validate, GET /api/repositories/:id/inspect?branch_a=…&branch_b=… |
| Investigations | GET / POST /api/investigations, GET /api/investigations/:id |
| Execution | POST /api/investigations/:id/start, POST /api/investigations/:id/cancel |
| Evidence | GET /api/investigations/:id/runs, /history, /progress, /report |
| Downloads | GET /api/reports/:id/download (JSON), GET /api/reports/:id/bundle (ZIP) |
| Sample | GET /api/analysis runs the bundled fixture |
POST /api/investigations accepts repository_id, branch_a, branch_b and an optional test_command (default python -m unittest discover -v).
- Open the
checkout-service (sample)repository and create thechange_a+change_bcomparison. - Review the base/change/combined table, then start the background analysis.
- See two passing independent checks and the combined assertion failure; open the saved diff and logs.
- Download the evidence bundle and open
REPRODUCE.md. - Add a real local Git repository, pick two branches and a test command, and repeat. The same engine reports an all-green result, a confirmed interaction, or a setup/merge/runtime result without conflating them.
MergeProof/
├── app.py HTTP API, Git execution, classification, worker, evidence bundle
├── web/index.html Single-page dashboard
├── demo_repo/ change_a, change_b and combined fixture versions
├── tests/
│ ├── test_analysis.py Fixture analysis regression
│ └── test_backend.py API, store, execution and classification tests
├── Dockerfile Pinned Python image with Git
├── requirements.lock Empty, hash-locked dependency set
├── .env.example Optional settings
└── .github/workflows/rebuild.yml Linux rebuild, offline tests and health check
Lingraj Malipatil · GitHub @Lingu17 · LinkedIn
Released under the MIT License. For a technical walkthrough, start with classify_failure, _confirmed and the backend tests.
MergeProof
Two green builds are not a green merge. Prove it.