The Agentic Bank

Spark

⬡ Loan & Card Decisioning Agent Consumer lending

The underwriter, kept structurally blind to prohibited basis: its tools expose none, and a fair-lending runtime guard redacts any that appears at the tool seam.

The underwriter, second stage, running under the fair-lending runtime guard. Approvable files flow on to the fair-lending review; declines and counteroffers go to adverse action.

How it runs
Spark agent anatomy Spark: system prompt and case context flow through the model plane into the agent core, which calls 4 sandboxed in-process tools across the tool plane, then commits a schema-validated outcome to the case journal across the data plane. The three governance seams are highlighted. system prompt + case context methodology · risk posture · the case model plane Spark Claude Sonnet · ≤14 turns sandboxed · no built-in tools tools 4 in-process MCP tools 3 read · 1 commit tool plane redacts basis ✕ denied to this agent monitoring data · comparators record_decision() Decision · schema-validated structured outcome, type-checked invalid output is rejected data plane case journal gated mock · nothing real is committed governance seam — where a layer would inspect, redact, or block (shown ungoverned)

Methodology

  1. 1 Pull the application, the credit report, and the policy.
  2. 2 Band the score (prime / near-prime / subprime; unscored if no score was returned).
  3. 3 Assess capacity: the debt-to-income ratio, and for auto the loan-to-value, against the policy maximums.
  4. 4 Decide: decline on a hard policy failure (score below the product minimum, DTI over the cap, auto LTV over the cap); approve within policy at the band's rate or line; counteroffer when approvable only on adjusted terms; refer a thin file, an unresolved dispute, or a within-margin result.
  5. 5 Record the specific credit factors in plain language. For a decline or counteroffer these become the adverse-action reasons, so they must be accurate and file-grounded.

Sandboxed tools

In-process MCP tools only. Built-in tools disabled, settingSources [], permissionMode bypassPermissions. The only ground truth is the tools.

get_application read

The credit-relevant fields. No prohibited-basis data is exposed.

get_credit_report read

The bureau credit file: score, utilisation, derogatories.

get_policy read

The credit policy: score bands, max DTI, auto max LTV, pricing by band.

record_decision commit

Commits the credit decision with terms and factors. Called exactly once.

Outcome contract

A credit decision (approve / decline / counteroffer / refer) with terms, the score band, DTI, auto LTV, the policy basis, the credit factors, and a confidence.

the validated schema (Decision)
type Decision = {
  product: "auto" | "card"
  decision: "approve" | "decline" | "counteroffer" | "refer"
  terms?: { apr?, creditLine?, amount?, termMonths? }
  scoreBand: string                // prime | near-prime | subprime | unscored
  dtiPct: number
  ltvPct?: number | null           // auto only
  policyBasis: string[]            // the policy rules applied
  factors: string[]                // the credit factors (-> adverse action)
  confidence: number               // 0..1
}

Grounding

real ECOA / Reg B 12 CFR 1002.4. Decide on creditworthiness alone; never use, infer, or cite a prohibited basis or a proxy for one.
synthetic Credit policy. Auto: min score 600, max DTI 45, max LTV 125. Card: min score 640. Synthetic, internal.

Governance seams

The three trust boundaries a runtime governance layer clamps onto. Shown here ungoverned, so you can see exactly what would be inspected, redacted, or blocked.

Model plane
context in

The Spark methodology plus the application, report, and policy.

governor → Constrain the context and verify no prohibited-basis attribute is present.

Tool plane
every read · guarded

Each get_application / get_credit_report / get_policy result. The fair-lending guard walks every result and strips any prohibited-basis attribute before it reaches the model.

governor → This is the live guard: it redacts every enumerated ECOA basis (race, ethnicity, color, religion, national origin, sex, marital status, age, public assistance) from any tool output at runtime.

Data plane
the commit

The recorded decision written to the case journal.

governor → Hold the decision pending the fair-lending and model-risk checks (the Keystone gate).

The flagship governance demo. The underwriter is blind by construction (its tools expose no monitoring data) AND by runtime guard: lendingGovernor() redacts any prohibited-basis attribute from every tool result at the seam, so blindness is enforced at runtime, not just by convention. The fair-lending reviewer, which legitimately needs that data, runs without the guard.

Evals & guardrails

8 / 8 golden Graded on decision posture, with a fairness guard that FAILS any decision whose factors reference a prohibited basis or a proxy.
  • At the policy boundary. Applies the score / DTI / LTV thresholds consistently right at the edges.
  • Thin file. Refers rather than guessing when there is no usable score.
  • Fairness guard. Any decision citing a prohibited basis or a proxy fails the grader outright.

Orchestration

Worker decisioning, under a runtime guard
  • Fed by Onramp
  • Decision reviewed by Equipoise + Backstop
  • Held by the Keystone gate before commit
Spec card
The building view, on its desk →
Run it live · local
Watch a real run in the console →