Cadence
Audit

The AI inventory

Where AI attaches, who owns each attachment, how it classifies under the AI Act, and what runs when the model is unavailable.

Control test CO1 failed until this page existed. The test now reconciles this list against the instrumented call sites in source, so a fourth attachment added without being declared here fails CO1.

This is layer 4 of 4. The 3 layers underneath it, meaning the decision itself, the model attachments and the quality and observability work, are on the layer overview.

The decision is deterministic code

The credit decision is deterministic code. Affordability, the debt-to-income test and the bureau rule are ordinary arithmetic and thresholds an auditor can re-perform by hand. No model makes, scores or ranks the decision. The models attach to the inputs and to the explanation.

Control tests
7 / 10

7 pass, 2 partial, 1 fail. Last run 2026-09-07.

Findings open
8 of 14

Each carries a condition, the evidence for it, and what was done about it.

AI attachments
3

Reconciled against the instrumented call sites in source on every test run.

Risk classification
High

Annex III 5(b), with the Article 6(3) derogation tested and rejected.

Where AI attaches

Transaction categorisation

categorise-transactions
Attaches at
Account information, before the affordability calculation
What the model does
Assigns a category and three boolean flags to each statement line
Owner
Product owner, lending decisioning
Source
src/lib/llm.ts
Classification
Minimal risk standing alone. It becomes a component of the affordability decision the moment its output feeds the Haushaltsrechnung, and classification follows purpose rather than architecture.
If it is unavailable
Deterministic rules categoriser, always available, no API key required
Threshold, owner and breach action
Metric
Overall accuracy against the 1,067-case evaluation set
Threshold
95.0% overall. The measured figure is 96.1%.
Owner of the threshold
Product owner, lending decisioning
Measured by
The evaluation harness at /eval, run by hand
On breach
The deploy is held and the deterministic rules categoriser carries the traffic until accuracy is restored.
Enforced by
Manual. The owner runs the evaluation from /eval before a deploy and reads the result, and the hold happens when the owner stops the push. A push to main deploys whatever the branch holds. Automating the check is open work.

Decision rationale drafting

build-rationale
Attaches at
Loan officer console, after the decision is made
What the model does
Writes a short grounded explanation of a decision the rules engine has already taken
Owner
Product owner, lending decisioning
Source
src/lib/llm.ts
Classification
Does not make the decision. Bears on Article 26 human oversight and Article 86 explanation, because it is the reasoning a reviewer and an affected person actually read.
If it is unavailable
Deterministic grounded template, which is also the baseline the grounding checks score against
Threshold, owner and breach action
Metric
The 5 deterministic grounding checks, scored today on the deterministic template rather than on the drafted text (F10)
Threshold
All 5 pass on every persona case
Owner of the threshold
Product owner, lending decisioning
Measured by
scripts/verify-rationale.ts, which needs no API key
On breach
The deterministic template is served in place of the drafted rationale. A person runs the check, reads the result and makes that change by hand.
Enforced by
Manual. A person runs scripts/verify-rationale.ts from the command line and it computes a pass or fail. The repository carries no CI workflow and no git hooks, and the Vercel build command is the default next build, so a push to main deploys whatever the branch holds.

Rationale judge

judge-rationale
Attaches at
Evaluation harness only, never in the request path
What the model does
Scores relevance, balance and tone of a drafted rationale
Owner
Quality owner, evaluation harness
Source
src/lib/llm.ts
Classification
An AI system evaluating an AI system. Informational and never blocking, so it cannot gate a deploy. Its own validity has never been measured against human labels.
If it is unavailable
5 deterministic checks, which are what decides the pass or fail the harness reports
Threshold, owner and breach action
Metric
Groundedness the judge returns for a drafted rationale, on a 5-point scale
Threshold
3 of 5
Owner of the threshold
Quality owner, evaluation harness
Measured by
The judge score recorded on each rationale in the harness
On breach
The run is reported to the owner for review. The judge does not block a deploy, because its own agreement with human labels has never been measured.
Enforced by
Reviewed by a person. It is the weakest of the 3: the other 2 at least have a script that computes a pass or fail, and this one rests on the owner's reading.

Providers

RoleModelNote
Primaryopenai/gpt-oss-120bGroq runs the inference; the model is GPT-OSS 120B, open weights published by OpenAI. No request reaches OpenAI. Free tier, 8,000 tokens per minute, and the rate limit is the binding constraint. Cost has always been zero.
Fallbackgemini-2.5-flashGoogle runs the inference and made the model. Also free tier, 20 requests a day. Absorbs the work whenever the primary is rate-limited, and a daily quota does not recover inside a run.

Who runs the inference and what is running are 2 different questions, and the model ids hide it. GPT-OSS 120B is an open-weight model published by OpenAI and served here by Groq, so no request reaches OpenAI and there is no account there. The namespace in the id names who made the weights.

Any attachment may run on either provider. The model that answered varies per call and is recorded on the trace and on each row. See F6.