Business-rule verification for pull requests

Proof, not opinions.

Bracel checks on every pull request, before merge, that the rules guarding your money, permissions and access still hold, by executing them. If it can’t establish the result, it doesn’t pass the change.

  • Runs in your own GitHub Actions
  • Rules from your base commit
  • No seat limits
PR #482 · Refund flow cleanup customer-ci
  1. http.auth-required@1 GET /admin/refunds without credentials → 401 PASS
  2. http.auth-required@1 DELETE /admin/users/:id without credentials → 403 PASS
  3. refund.amount-cap@1 Refund 50.01 after 50.00 of a 100.00 payment → accepted · 201 FAIL
Result FAIL Advisory · no merge settings changed

Chapter 01 · The run

A pull request touches the refund flow.

PR #482 changes how refunds are validated. In your own runner, Bracel starts the application and executes every approved rule that applies.

Chapter 01 · The run

Three rules apply. Two hold. One does not.

Both authentication checks are refused, as expected. The refund rule fails: a refund beyond the remaining captured amount was accepted.

What changed ↓

The gap

The gap between review and proof

Code ships faster than ever, and it is reviewed faster too. But a review is an opinion: it reads the change, it does not run it. So a rule that guards money or access can break quietly, pass review, and reach your customers.

A review is an opinion. Bracel runs the rule.

Chapter 02 · The change

A clean refactor. One missing word.

The new guard compares each refund to the captured amount, not to what is left of it. It reads well, the tests that existed still pass, and the review approves it.

A review reads the change. Bracel runs the rule.

src/payments/refunds.ts +1 −1
  1. 41 export async function refund(paymentId: string, amount: number) {
  2. 42 const payment = await payments.get(paymentId);
  3. 43- if (payment.refunded + amount > payment.captured) {
  4. 43+ if (amount > payment.captured) {
  5. 44 throw new RefundExceedsCapture(paymentId);
  6. 45 }
  7. 46 return payments.addRefund(paymentId, amount);
  8. 47 }
Line 43 no longer counts what was already refunded. A 50.01 refund after 50.00 on a 100.00 payment now passes the guard.

Review · approved

Nice simplification, much easier to read. Ship it.

Illustrative story · not customer data

Chapter 03 · The rule

01 / 05Payments

A refund cannot pass the cap.

A rule your team approved, read from your base commit. Pay 100.00, refund 50.00, then try 50.01 more: the over-refund is refused and the total does not move.

Available · refund.amount-cap@1

02 / 05Access control

Every door asks for a key.

Each protected route gets a request without credentials. Every one must be refused. One open door is a FAIL.

Available · http.auth-required@1

Chapter 04 · The evidence

Your tests passed. The rule did not.

Tests check what someone thought to test. Bracel executes the rule your team approved, next to the checks you already have, with the evidence one click away.

Refund flow cleanup #482

Openwants to merge 3 commits into main from refund-cleanup

Some checks were not successful3 successful · 1 failing

  • buildSuccessful in 1m 12s your CI
  • unit-tests412 passed your CI
  • lintSuccessful in 21s your CI
  • Bracel VerifyFAIL · refund.amount-cap@1 · a 50.01 refund after 50.00 of 100.00 was accepted customer-ci Details

This branch has no conflicts with the base branch

Bracel is not a required check here. The FAIL is advisory; merging stays possible.

Merge pull request

Merging is blocked

Your administrators made Bracel Verify a required check, so a failing result blocks merging.

Merge pull request
Illustrative · names, counts and timings are examples

Branch protection, set by your administrators

Bracel changes no merge settings. If your administrators make the check required, a failing result blocks merging.

Run it yourself. Point a rule at a route, choose how the app answers, read the verdict.
  1. 01

    Runs next to your build and tests, as one more check on the pull request.

  2. 02

    States the rule, what was expected, what was observed and why the verdict follows.

  3. 03

    Shows the release and code digest it ran with, and that it ran in your own CI.

03 / 05Tenant isolation

One customer never reaches another.

Acting as tenant A, the check reaches for a record that belongs to tenant B. The wall has to hold.

Business-rule scenario

Every check ends in one of four verdicts: PASS, FAIL, UNKNOWN or NOT_APPLICABLE. Only PASS means the rule held.

Chapter 05 · The fix

Then Fix proposes the change. Verify judges it.

Bracel Fix reads the failure, writes one patch, and lets Verify run it in a clean environment with values it never saw. You get a draft pull request, never a merge.

Session replay bracel fix · PR #482 · refund.amount-cap@2 00:19 / 00:20

Session

  1. Verify · PR #482 · refund.amount-cap@2FAIL · a 50.01 refund after 50.00 of 100.00 was accepted
  2. Fix job startedattempt 1 of 3 · estimate shown before start
  3. Reading the failing behaviourrule, scenario, observed response

Why it failed

The refund adds the amount to the refunded total without looking at the capture. The update now applies only while the new total stays within the capture, in one atomic statement, so concurrent refunds cannot both pass.

  1. Changed: src/payments/refunds.tsapplication code
  2. Tests, fixtures, rules and workflowsuntouched

src/payments/refunds.ts

  1. 41export async function refund(id: string, amount: number) {
  2. 42 const updated = await db.affected(
  3. 43 'UPDATE payments SET refunded = refunded + $2' +
  4. 44 ' WHERE id = $1 AND refunded + $2 <= captured', [id, amount]);
  5. 45 if (updated === 0) throw new RefundExceedsCapture(id);
  6. 46 return payments.get(id);
  7. 47}

Verify · clean environment · rules from the base commit · hold-out values

  1. POST /payments · 74.00201
  2. POST refund · 37.00 (control)201
  3. POST refund · 37.01422
  4. GET refunded total37.00
  5. 2 concurrent refunds · 37.00 each201 · 422
  6. Other approved rule · admin-authholds

PASS · the listed behaviours were executed and held

Draft pull request #483 bracel-fix/482-refund-cap → the branch of #482

Fix: refunds never exceed the captured amount

Proposed by AI. AI can be wrong. Review it like any other change.

Merge · your decision Bracel never merges and never writes to main.
Example repair · independently verified before human review
  • Draft pull request on its own branch
  • Never writes to main, never merges
  • Stops at your rules, workflows and tests
  • Your model key, your provider
How Bracel Fix works

04 / 05Subscriptions and billing

A plan change charges what the pricing says.

Upgrade in the middle of a cycle, then read the invoice. The amount has to match the pricing rules, to the cent.

Business-rule scenario

Chapter 06 · Where it ran

Your CI. Not ours.

In customer-CI mode, Bracel runs entirely inside your own GitHub Actions, from a pinned, checksummed release that you install into a private repository you own. No part of the check runs on Bracel’s servers.

A pull request triggers the check in your GitHub Actions runner. Rules load from the base commit, dependencies follow the selected language profile, your application starts in an isolated environment without network access, the rules execute, and the verdict is written back to the pull request. No connection goes to Bracel.

Telemetry none · data sent to Bracel none · token read-only · secrets none · network during build and run none Every claim and its scope →

05 / 05Webhooks and events

The same event, applied once.

Deliver an event, then deliver it again. One effect, one record, however many times it arrives.

Business-rule scenario

Business-rule verification

Critical behavior.
From every angle.

Seven verification areas. One evidence contract. A controlled path from finding a violation to reviewing a repair.

01Sequence & state

Only valid transitions may change a record.

Execute
Refund a payment before it is captured.
Observe
Reject the transition; preserve the original state.
02Concurrency & races

Competing requests must preserve the same invariant.

Execute
Two requests reserve the last available unit together.
Observe
One reservation succeeds; stock never becomes negative.
03Retries & duplicate effects

Repeating a request must not repeat its business effect.

Execute
Deliver the same payment event twice.
Observe
One ledger entry, one effect, one stable response.
04Authorization & tenancy

Access must respect ownership, roles and revoked permissions.

Execute
A tenant requests another tenant’s record after access is revoked.
Observe
Deny access; leave the other tenant’s data unchanged.
05Partial failure & recovery

A failed operation must not leave an invalid partial result.

Execute
Interrupt a transfer after debit, before credit.
Observe
Roll back or complete the defined compensation; conserve the balance.
06Evaluation integrity

The change under test must not redefine its own judge.

Execute
A pull request edits the rule and disables its assertion.
Observe
Use the approved base-commit rule; detect incomplete execution.
07Reproduction & diagnosis

A finding must include enough context to reproduce it.

Execute
Replay a failure with the same input, schedule and fault point.
Observe
Reproduce the observation, or explain the mismatch without claiming a pass.

Five language tracks · two database tracks

Node / TypeScript · Python · Java / JVM · Go · C# / .NET

PostgreSQL and MySQL for each track. Defined Redis scenarios. Explicit execution profiles keep support precise.

Explore verification

From observation to decision

Know what changed.
Know what held.

A verdict is the beginning. The evidence tells you what failed, whether the change introduced it, and what a repair actually preserves.

01

Find what this change actually broke.

Compare base and head in equivalent environments. Separate a new violation from a pre-existing defect, a resolved issue, an unchanged outcome or an incomparable run.

Explore the mechanism
02

Observe the effect, not just the response.

Inspect committed state, balances, stock, permissions and emitted effects. A rejected request that still writes unauthorized data is a violation.

Explore the mechanism
03

Control the conditions that expose the bug.

Exercise admitted overlapping schedules, lost responses, duplicate deliveries, restarts and fault points. Record the schedule and the convergence window.

Explore the mechanism
04

Replay the counterexample.

Carry the code and policy revisions, image and dependency digests, seed, initial state, schedule and fault point into a clean replay. Keep original and minimized evidence distinct.

Explore the mechanism
05

Keep incomplete coverage visible.

Retain an observed violation even when another scenario cannot finish. Separate verdict, coverage, applicability and execution state; a successful job alone is not PASS.

Explore the mechanism
06

Repair without weakening the check.

Protect the approved rules and evaluator. Run the original failure, held-out neighboring behavior, legitimate paths and required customer checks against the actual patched commit.

Explore the mechanism
07

Control sharing, spending and writes.

Approve outgoing file names, snippets and tool results. Bound attempts, tokens, time and cost. Review the diff and residual risks; a changed target commit requires revalidation.

Explore the mechanism

Integrations

Fits the stack you already run.

Five language tracks. PostgreSQL and MySQL. Redis where the scenario needs it. One rule and evidence contract, inside your GitHub workflow.

  • GitHub Actions
  • TypeScript
  • Python
  • OpenJDK
  • Go
  • .NET
  • PostgreSQL
  • MySQL
  • Redis
  • Docker
  1. GitHub Actions Required

    GitHub Actions

    Where every check runs

    The pull_request trigger on GitHub-hosted ubuntu-24.04 runners, in your own account. The action is pinned by full commit SHA.

  2. GitHub Required

    Pull requests

    Where the verdict appears

    The check summary lands on the pull request: approved rule, why it ran, expected, observed, why, next step and provenance.

  3. GitHub Actions Supported

    Workflow artifacts

    Optional evidence file

    An opt-in JSON evidence file with the same fields as the summary, kept 7 days in your repository.

  4. GitHub Recommended

    Code owners

    Protects the rules

    Protect .github/workflows/ and the rules file with CODEOWNERS, so changes to Bracel itself always get review.

  5. GitHub Supported

    Branch protection

    Optional merge gate

    Bracel changes no merge settings. Your administrators decide whether the check is required.

  6. TypeScript Supported · defined profile

    Node.js / TypeScript

    Node.js 24 · Express 5 · TypeScript 7

    JavaScript and TypeScript applications on Node.js 24 with Express 5, installed from package-lock.json. Approved business rules run through a pinned runtime, build and application profile.

  7. Python Supported · defined profile

    Python

    Python 3.13 · FastAPI · Uvicorn

    Python 3.13 applications on FastAPI and Uvicorn, with hash-pinned requirements. Behaviour is verified through a versioned runtime, dependency and observation profile.

  8. OpenJDK Supported · defined profile

    Java / JVM

    Java 21 · Spring Boot 4.1 · Maven

    Java 21 applications on Spring Boot 4.1, built with Maven against a checksum-verified dependency list.

  9. Go Supported · defined profile

    Go

    Go 1.26 · net/http

    Go 1.26 services on the standard net/http library, built from go.mod and go.sum.

  10. .NET Supported · defined profile

    C# / .NET

    .NET 10 · ASP.NET Core

    .NET 10 applications on ASP.NET Core minimal APIs, restored from a locked packages file.

  11. PostgreSQL Supported · defined profile

    PostgreSQL

    PostgreSQL 18

    Persisted state, transaction boundaries, concurrent writes and recovery, across all five language profiles.

  12. MySQL Supported · defined profile

    MySQL

    MySQL 8.4

    Business invariants against MySQL persistence and the transaction semantics declared by the profile, across all five language profiles.

  13. Redis Supported · defined profile

    Redis

    Redis 8 · with PostgreSQL

    The defined cache, session, deduplication and asynchronous side-effect scenarios, with PostgreSQL as the system of record. Redis use is declared per profile.

  14. npm Supported · defined profile

    npm

    Node.js · package-lock.json

    Installed with npm ci from package-lock.json, with install scripts disabled.

  15. Python Supported · defined profile

    pip

    Python · hash-pinned requirements.txt

    Installed with --require-hashes from binary wheels only; every package must match its recorded hash.

  16. OpenJDK Supported · defined profile

    Maven

    Java · dependency checksum list

    Resolved with strict checksums and compared with the repository’s dependency-checksums.txt, including on a cache hit.

  17. Go Supported · defined profile

    Go modules

    Go · go.mod and go.sum

    Downloaded against go.sum and built read-only, so the module graph cannot change during the build.

  18. .NET Supported · defined profile

    NuGet

    .NET · packages.lock.json

    Restored in locked mode from packages.lock.json.

  19. Docker Built in

    Docker

    Isolated execution

    Images pinned by digest. Dependencies are fetched only while preparing, through a per-run proxy limited to the package registries; the application then runs with no network route out, a read-only file system and bounded memory, CPU and processes.

  20. See every requirement.

    All integrations and execution profiles →

Chapter 07 · Plans

Per organization. Never per seat.

The same verification engine in every plan. Pay for shared evidence, approvals and team coordination. Model and CI costs remain separate.

  1. Free

    $0

    self-managed verification

    Prove the rule in your own workflow.

  2. Team

    $119

    / org / month, annual

    Keep the rule, its owner and its evidence connected.

  3. Business

    $399

    / org / month, annual

    Coordinate critical rules across services and teams.

  4. Enterprise

    Custom

    by agreement

    Agree deployment, identity and assurance requirements.

Compare plans

Questions

Asked, answered.

How do you pronounce Bracel?

BRAY-sel.

Is Bracel an AI code reviewer?

No. Bracel does not comment on style or guess at intent. It executes the rules your team approved and reports what happened. The verdict comes from execution, not from a language model’s text.

Does it block merging?

Your administrators control merge policy. Bracel reports the observed result; your required checks decide whether a change can merge.

Where does my code run? Is anything sent to Bracel?

It runs in your own GitHub Actions runner. In our tests on GitHub-hosted runners, the action sends no telemetry and no data to us. Every data path is listed on the security page. An optional evidence file stays in your repository as a workflow artifact for 7 days; nothing reaches us unless you send it.

What if no rule applies to a pull request?

The result is NOT_APPLICABLE: 0 checks executed and no verification claim. It succeeds, so a pull request that changes none of a rule’s paths merges without that rule running. Omit paths to run a rule on every pull request.

What does UNKNOWN mean?

Bracel could not establish the result: the project is outside the supported profile, a rule could not run, or the pull request changes Bracel’s own rules or workflow. UNKNOWN is never shown as a pass. The summary says why and what to do next.

Which stacks are supported?

Node.js/TypeScript, Python, Java/JVM, Go and C#/.NET, with PostgreSQL and MySQL for each track and defined Redis scenarios. Each execution profile specifies versions, framework, dependencies, observation and fault capabilities. See integrations for the scope.

What behaviors does Bracel verify?

Sequence and state transitions, concurrency, retries and duplicate effects, authorization and tenancy, partial failure and recovery, evaluation integrity, and reproduction. Each rule publishes its scenario, observations and outcome conditions.

Does it replace code review or tests?

No. Review and tests keep doing their jobs. Bracel adds an executed check for the specific rules you name.

How is Bracel priced?

Free evaluation access and organization plans are shown on the pricing page. Fix inference uses your own model key and an explicit budget. Provider costs are separate; no payment is collected in this preview.

What is Bracel Fix?

A controlled repair workflow. Start from a reproduced FAIL, approve model sharing, inspect a bounded patch and its independent validation, then review the draft pull request. PASS is necessary, never sufficient; a human decides whether to merge.

How do I start?

Check your repository on the compatibility page, then follow the quickstart: approve a rule, add the workflow, and open a pull request.

How do I report a security issue?

Email security@bracel.dev. That includes a suspected incorrect PASS, which we treat as a security issue.

Proof,
not opinions.

Protect the rules that move money and control access. Start with one.

Request access