This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady
Imagine an API provider releases v2. The route moves, request fields are rearranged, and the response uses a different status value. Your client has not changed, but checkout is suddenly broken.
Fixing this usually means comparing two contracts, writing a temporary adapter, testing it, patching the client, and remembering to remove the adapter later. It is repetitive work at exactly the moment when you are already under pressure.
I built ContractBridge to handle the repetitive parts while leaving the important decision with a person. Gemma suggests how the old and new contracts fit together. Regular code checks that suggestion, builds both fixes, and tests them. Nothing goes live until someone reviews and approves it.
What I Built
ContractBridge sits between an application and an API it depends on. Most of the time it simply passes requests through. When the provider stops matching the contract the client expects, it records the mismatch and starts a repair workflow.
One approved declarative mapping drives two outputs:
- a temporary compatibility bridge that can restore new requests;
- a permanent client patch, plus a draft pull request when GitHub is configured.
The temporary bridge does not disappear just because a patch was merged. ContractBridge waits until the matching version is actually deployed and a direct test succeeds without translation. Only then can it retire the workaround.
That cleanup is one of my favorite parts. The bridge has a clear exit instead of becoming another forgotten compatibility layer.
Figure 1. A scoped gateway detects drift. Local Gemma proposes a mapping, deterministic checks verify it, and a human controls activation. One approved mapping drives the temporary and permanent repairs.
Demo
Video demo:
The demo is intentionally local and synthetic. It contains no production traffic, customer data, or payment data. A small shopping client expects POST /v1/orders; the provider is switched to a v2 contract with POST /v2/purchases, nested buyer data, renamed array fields, a nested response, and a changed lifecycle enum.
From the repository root, the complete example starts with:
./scripts/bootstrap.sh --example shopping
Step 1: Prove the unchanged client works against v1
With examples/provider/provider.json set to {"version":"v1"}, the unchanged client placed synthetic order ord-7001 successfully.
Figure 2. The unchanged example client completes a real request against the synthetic v1 provider. No payment is collected.
Step 2: Switch only the provider to v2
I changed the provider configuration to:
{"version":"v2"}
The same checkout then failed. The cart stayed intact, and the failed POST was not automatically replayed.
Figure 3. Provider v2 breaks the unchanged client. ContractBridge records the failure instead of pretending the request is safe to retry.
Step 3: See what ContractBridge caught
The operator console showed the failed request and the 404 from the provider. Nothing had been repaired or rerouted yet. This was simply the starting point for the investigation.

Figure 4. The incident as it appeared before ContractBridge proposed a repair.
Step 4: Check the Sentry issue
The same failure also appeared in Sentry as UpstreamContractDrift. Sentry kept the useful context, including the monitored API transaction and the exact application frame, while ContractBridge's privacy policy withheld the exception details.

Figure 5. Sentry shows where the contract failure happened without exposing the request or response payload.
Step 5: Review Gemma's proposed repair
Gemma ran locally and suggested six mapping rules for the changed route, fields, arrays, and status value. ContractBridge turned that suggestion into a candidate and ran 12 checks in a locked-down container before showing it to me.

Figure 6. Gemma suggested the mapping, then regular code built and tested the candidate before review.
The test container had no network access or Docker socket, and it could not write to its root filesystem. This kept the model's suggestion inside a narrow, testable path.
Step 6: Send a correction back to Gemma
I rejected the first candidate because I wanted the PLACED to CONFIRMED status change called out clearly. ContractBridge saved my feedback and asked Gemma to revise the mapping.

Figure 7. Rejection is recorded feedback, not an override that bypasses verification.
The revision came back through the same review screen and had to pass the checks again.
Step 7: Approve the repair
Once the revised mapping looked right, I approved it. ContractBridge activated the temporary bridge and prepared a permanent application patch. I had not connected GitHub for this demo, so it produced the patch locally instead of pretending it had opened a pull request.

Figure 8. The approved mapping now powers the temporary bridge and the permanent patch.
Step 8: Retry with the unchanged client
With the provider still on v2, the unchanged client placed a new order through the active bridge. The application confirmed synthetic order ord-7002.

Figure 9. A new request succeeds through the approved bridge. This is not a replay of the failed POST.
The part I cared about most was the full sequence. The client worked on v1, failed when only the provider changed, and worked again after I reviewed the repair. The failed order was never replayed. Gemma never produced code for the system to execute. Rejecting the first suggestion led to a new suggestion, not a shortcut around the review step.
Because GitHub was not connected for this demo, ContractBridge produced a patch I could download and inspect. It did not claim to have opened a pull request.
I also tried cases that should not be repaired automatically. In one of them, v2 required a delivery method that the old client never supplied. ContractBridge left the incident waiting for a person instead of inventing a value to make the test pass.
When you are finished, stop the example with:
./scripts/stop.sh --example shopping
Code
The project is MIT licensed and available at github.com/mtwn105/contractbridge.
mtwn105
/
contractbridge
Self-healing API compatibility control plane: detects contract drift, verifies a local Gemma mapping, restores traffic, and prepares a permanent client fix.
ContractBridge
Recover now. Fix permanently. Remove the workaround when production is healthy.
ContractBridge is a plug-in control plane for API contract drift. A registered application sends an API call through its scoped gateway. When the upstream response no longer matches the contract that application expects, ContractBridge records an incident and asks a local open-weight Gemma model for a constrained declarative mapping.
One verified mapping drives two repairs:
- Temporary runtime repair: a deterministic compatibility proxy can restore traffic only after an operator approves the verified candidate, isolated tests pass, and the built artifact matches those approved inputs.
- Permanent code repair: the same mapping produces a reviewable client patch and, when configured, a real GitHub draft pull request.
The temporary rule remains active after merge. It is retired only after the registered deployment reports the matching commit and authorized synthetic probes show that the deployed client works with translation bypassed.
The core…
How I Built It
1. Detect drift without replaying the failed request
Every integration registers the client-expected OpenAPI contract, an operator-allowed upstream origin, and a selected operation. The gateway forwards calls directly until the response no longer matches what the client expects.
A failed business POST is not silently retried. ContractBridge records the mismatch and starts investigating, but it treats the original request as failed or unknown. A broken response does not prove that an upstream side effect never happened, so an automatic replay could create a duplicate order.
ContractBridge uses oasdiff to find structural breaking changes, then applies its own limited schema analysis. A diff can show that state became status, but it cannot decide whether PLACED and CONFIRMED mean the same thing to the business.
2. Ask Gemma for data, not executable code
The semantic step runs locally through Ollama. Gemma sees small excerpts from the two schemas and sanitized examples, then returns a structured transformation plan.
The plan can describe supported operations such as field copies, renames, nesting, flattening, array-item mappings, reviewed constants, and reviewed enum translations. It cannot include arbitrary Python, shell commands, or network instructions.
This boundary is deliberate: the model proposes data; trusted code interprets it. Generated model code is never executed.
3. Verify in an isolated container
The candidate must validate against both API schemas and independent synthetic fixtures. Trusted templates generate the adapter and tests. A worker builds the exact inputs and runs compile, fixture, and HTTP behavior checks in an isolated container.
Mocks and fixtures are still limited evidence. A passing fixture proves that one example works, not that every valid payload will work. That is why ContractBridge keeps the contract comparison, example fixtures, model suggestion, and build result as separate pieces of evidence.
Model behavior can change too. I keep the model details, validation results, artifact hashes, and failures so I can rerun the same cases after changing the model or its instructions.
4. Make review bind to the exact candidate
The review screen brings the contract changes, field mappings, fixtures, test result, and open questions together. Approval is tied to that exact candidate, so an old approval cannot activate a newly generated one.
Rejecting a candidate is useful feedback, not a dead end. The next Gemma attempt receives the review comment, but it still has to pass the same checks and return for approval.
5. Use Temporal for the long wait
The repair is not one quick request. It may wait for review, retry a temporary model failure, prepare a draft pull request, wait for deployment, and finally check whether the client works without the bridge. Temporal keeps that process moving even if a worker restarts.
The local Compose stack uses Temporal's persistent development server for demonstration. It is not presented as a production Temporal deployment.
6. Retire the bridge with evidence
The same approved mapping produces the runtime bridge and the permanent patch, keeping them from drifting into two unrelated interpretations. ContractBridge never merges or deploys the patch itself.
Merge is only intent. Retirement requires deployment evidence for the expected commit and successful synthetic probes with translation bypassed. If those checks fail, the bridge stays active and the failure remains visible.
Why Does Open Innovation Matter?
API contracts can describe private endpoints, internal field names, and business rules. Running Gemma locally through Ollama lets the semantic proposal happen without sending those contracts to a hosted inference API.
Local execution is only part of the value. The prompt schema, validator, interpreter, fixtures, and evaluation cases are inspectable. Another compatible model can be tested against the same dataset instead of being trusted because its name changed on an API endpoint.
I describe Gemma as open-weight. ContractBridge itself is MIT licensed, while the Gemma weights are downloaded separately under Gemma's terms. Keeping that distinction clear matters.
The Lazy Payoff
ContractBridge removes a sequence of mechanical chores from the incident path: collecting the two contracts, drafting mappings, generating two repair forms, building a test bundle, preserving evidence, and checking when the workaround can be retired.
One reviewed mapping becomes both the temporary bridge and the permanent patch. The operator still makes the semantic decision, but does not have to hand-write two translators or remember a cleanup ticket later.
The bridge adds an extra hop, so it is meant to be temporary. The permanent patch is what removes that cost and returns the application to a normal direct connection.
Prize Categories
- Best Use of Gemma: Gemma handles the part that needs semantic judgment while the rest of the repair stays testable and reviewable.
- Best Use of Temporal: Temporal keeps the repair moving through retries, human review, deployment, and eventual bridge removal.
- Best Use of Sentry: Sentry catches the contract failure and points back to the application code while ContractBridge keeps private payload details out of the event.
Limits I Want to Keep Visible
The current engine handles one selected JSON POST operation within a bounded OpenAPI 3.0/3.1 subset. Authentication changes, missing business data, undeclared semantics, arbitrary source rewriting, and unsupported schemas stop for human action.
Permanent repair currently targets a registered declarative Python client. The GitHub path creates a draft PR when configured; the demonstrated run did not configure GitHub and therefore did not create one.
Most importantly, this is a controlled local demonstration with synthetic fixtures. Passing those fixtures is not proof of universal compatibility, production reliability, or semantic correctness. The useful result is narrower: a repeatable way to let a local model help with the ambiguous part while deterministic checks and a human retain authority over production behavior.



Top comments (0)