Inspiration

A client writes: "$500, three pages, online ordering, live next week." The freelancer replies with a number, the client agrees, and two weeks later both discover they agreed on different things. Freelance money is lost in the gap between a vague request and a signed scope.

We wanted an AI assistant that closes that gap without becoming the dangerous kind of "AI quoting tool" — one that confidently invents a price and a delivery date. So ScopeBridge runs on one rule: the model may propose, but only a program prices, only a human reviews, and only the client confirms.

What it does

  • The client submits a plain-language brief and gets a private portal link.
  • The model reads the brief and returns exactly five facts — pages, budget, deadline, assets, features. It never prices anything.
  • The server builds at most two candidate scopes and prices them against versioned service rules. The over-budget option stays on screen with its exact violation instead of being hidden.
  • The studio turns a scope into a quote where every line references the rule that priced it and the client message that justified it, then reviews and issues it.
  • The client compares options and confirms one exact version. Confirming freezes it: the quote turns read-only, and any new client message creates a new revision with a line-by-line diff — history is never edited.
  • Payment runs on PayPal Orders v2 (create → approve → capture) in the sandbox. The quote locks before the first external call, and the amount is read from the confirmed quote on the server — the client never sends an amount.

How we built it

A FastAPI modular monolith (SQLAlchemy, Alembic, PostgreSQL 18 in Docker) with a React + TypeScript

  • Vite + Tailwind front end. Pricing and feasibility are pure functions with zero IO, so model output passes through the same gate as a hand-typed scope. 78 pytest tests cover the rules, state machine, auth and payment flows.

The model boundary was the interesting engineering. On our gateway, asking for nested JSON with candidate scopes matched the schema 0/5 times and response_format: json_schema was accepted but not enforced; a five-key fact sheet with a plain-text brief succeeded 5/5. We later found the gateway was dropping the system message entirely — moving the contract into the user message took parse rate from 47% to 100% on the same 19 cases. Both decisions are written up as notes in the repo.

Challenges

  • Payments that never answer. A browser return is not proof of payment. Captures with unknown outcomes park in RECONCILING, the original order is queried, and recovery retries with the same PayPal-Request-Id — or a human closes the attempt with a written reason. We demoed this with a real injected fault (1 ms timeout), not a mock.
  • Honest evaluation. A 19-case comparative run pits the facts-and-rules pipeline against letting the model quote directly, with call counts as denominators and unsafe releases recomputed at runtime: pipeline parsed 19/19 with 0 rule violations released; the baseline parsed 18/19 and twice called rule-rejected scopes feasible (evals/reports/20261030T151055Z-facts-v7-inline-both.md, 30 Oct 2026).

Accomplishments

A real sandbox payment ($500.00, order 26R58752UG7226808) end to end, plus a recovery run where PayPal never answered — and every paid order freezes into a read-only snapshot.

What we learned

"Who is allowed to set a price" is an architecture decision, not a prompt. Once amounts can only come from a pure rules layer, the model's job becomes small, testable and safe to fail.

What's next

Webhooks with unattended reconciliation, refunds and partial captures, a hosted demo, and a real user trial.

Built With

Share this project:

Updates

Submission history