Skip to main content
Glama
SyakeerRahman

Credit Risk Copilot

README.md
# Credit Risk Copilot

A natural-language interface to a credit risk database. A user asks a question in English. The
service returns a validated answer, a chart, and the SQL it ran.

The point of the project is not the SQL generation. The point is the boundary that decides which
SQL is allowed to run.

## Status

Scaffolded 2026-08-05. No agent yet. No database yet. The preflight check runs.

## Requirements

| Need | Version | State on this machine |
|---|---|---|
| Python | 3.12 | installed |
| Docker Desktop | any current | installed |
| Terraform | 1.x | **not installed** |
| AWS CLI | v2 | **not installed** |

Use Python 3.12, not 3.13. The 3.13 interpreter is ahead of the ML ecosystem, and a package that
ships compiled wheels can lag the interpreter by a year.

## How to run it

1. Create the virtual environment:
   ```
   py -3.12 -m venv .venv
   ```
2. Activate it:
   ```
   .venv\Scripts\activate.bat
   ```
   Use the `.bat` file. PowerShell blocks `Activate.ps1` under the default execution policy.
3. Copy the example environment file:
   ```
   copy .env.local.example .env.local
   ```
4. Open `.env.local` and set `DEEPSEEK_API_KEY`.
5. Run the preflight check:
   ```
   py -3.12 -m app.doctor
   ```
   The check imports only the standard library, so it runs before step 6.
6. Install the dependencies:
   ```
   pip install -r requirements.txt
   ```

## Environment variables

`.env.local` holds every secret. The file is gitignored. Never commit it. If a key reaches a
commit, rotate the key, because removal of the commit does not undo the exposure.

| Variable | Required | Purpose |
|---|---|---|
| `DEEPSEEK_API_KEY` | yes, for DeepSeek | The API key |
| `DEEPSEEK_MODEL` | no | Defaults to `deepseek-v4-flash` |
| `LLM_PROVIDER` | no | `deepseek` or `ollama`. Defaults to `deepseek` |
| `OLLAMA_BASE_URL` | no | The local fallback. Needs no key |
| `DATABASE_URL` | yes | The Postgres connection string |
| `LANGSMITH_API_KEY` | no | Tracing. The app runs without it |

**The model names changed.** DeepSeek retired `deepseek-chat` and `deepseek-reasoner` on
2026-07-24. Calls to those names no longer route anywhere. Use `deepseek-v4-flash` or
`deepseek-v4-pro`. Both `app/doctor.py` and `app/llm/client.py` refuse a retired name and say why.

## The architecture rule

`app/guardrails/sql_check.py` runs on the tool side of the MCP boundary. The agent never calls it.

The agent writes SQL. The MCP tool owns the database connection. The tool validates the SQL before
it executes anything. This order matters: a check inside the agent's own code path is skipped by
any input that redirects the agent, so such a check is a suggestion and not a control.

The full reasoning is in `brain/decisions/2026-08-05-sql-guardrails-live-behind-the-mcp-boundary.md`.

## What the guardrail refuses

| Rule | Reason |
|---|---|
| Anything except one `SELECT` | A write reaches the database only through a migration |
| A table absent from the allowlist | A new table is denied by default, not allowed by oversight |
| A column absent from the allowlist | Column-level control, not table-level |
| `SELECT *` | The caller must name the columns it needs |
| A missing or oversized `LIMIT` | One question cannot return the whole table |

## Layout

```
app\
  doctor.py          preflight check, standard library only
  llm\client.py      one factory for DeepSeek and Ollama
  guardrails\        SQL validation, called by the tool, never by the agent
```

## Cost

`deepseek-v4-flash` costs $0.14 per million input tokens on a cache miss. A cache hit costs
$0.0028 per million, which is a 98% discount.

The schema prompt is identical on every call. Put the schema at the front of the prompt and never
reorder it, so every call after the first is a cache hit.

## Related notes

- `brain/projects/credit-risk-copilot.md` - status, open questions, and the log
- `brain/decisions/2026-08-05-sql-guardrails-live-behind-the-mcp-boundary.md`
- `brain/decisions/2026-08-05-python-for-credit-risk-copilot.md`