Prüfstand — the test bench that proves an Agentforce agent is safe
I built an AI agent — then I built the thing that tries to break it: a pre-registered 30-case German red-team corpus, a deterministic verifier the model can't sweet-talk, a config linter that found real bugs on the live agent for zero credits, and a consent handshake a jailbreak cannot fake.
- Year
- 2026
- Role
- Salesforce Developer — Agent Evaluation & Red-Teaming
- Tech stack
- Agentforce (evals & red-teaming)Python (stdlib harness)ApexDeterministic verifier30-case German attack corpusStatic config linter (20 rules)Tooling APIConsent handshake (expiring token)DSGVO / EU AI Act traceability
Highlights
- The 'prove it' counterpart to HanseWatt: I built an AI agent — then I built the thing that tries to break it, and the tools that show it is safe before it ever talks to a customer
- A 30-case German-language red-team corpus (prompt injection, cross-customer fishing, authority spoofing, GDPR-rights abuse) — pre-registered as the repo's first commit, before the harness that scores it: git is the notary
- A deterministic verifier — the LLM is never in the pass/fail decision: trace-based checks read the AccountId an action actually ran with; canary checks survive homoglyph tricks (NFKC + Cyrillic folding)
- Consent a jailbreak cannot fake: the tariff change is a two-action handshake over an expiring Tariff_Change_Request__c record — the model can't fabricate the token only the propose action emits; every property has an Apex test
- The static linter ran against the live agent and found what the UI can't show: two orphan GenAiFunctions and a routing gap — 22 → 0 errors, closed loop, zero Flex Credits
- 69 meta-tests are the verifier's verifier: planted violations must be caught, clean inputs must stay clean — including two silent-pass bugs found in the harness itself, documented and regression-pinned
- Credit discipline as architecture: one transport interface (mock / replay / live), record-once-replay-forever, and a five-lock credit guard — credits buy evidence, never development
- Honest framing: the harness, linter, corpus and Apex are real and verified; the one paid live reference run is deliberately last, and no live pass-rate is claimed until it exists
Feature walkthrough
Git as the notary — the corpus came first
The 30-case attack corpus is the first commit in the repository, before the verifier that scores it. That ordering is a property anyone can check with git log — not a claim they have to trust. You can't quietly tune the exam to the answers if the exam is notarised first.

The linter, clean on the live agent — after finding real bugs
Pointed at the real HanseWatt agent, the 20-rule linter first surfaced two orphan GenAiFunctions (invisible in Agent Builder — an unlinked function belongs to no topic) and a routing gap in the topic description. Fixed on the live agent, re-linted: 0 errors, bound to the config's fingerprint. Found → fixed → confirmed, for zero credits.

The verifier's verifier — 69 meta-tests
A scorer is only trustworthy if it actually fires. The meta-suites plant known violations — a leaked canary, a cross-account action, an uncited number — and assert the verifier catches them, and that clean runs stay clean. This suite is also what caught the harness's own two silent-pass bugs: an evidence gap must read as a failure, never as a pass.

The problem
Anyone can make an agent demo well. Almost nobody publishes how they prove an agent is grounded, safe, and GDPR-compliant before it talks to a real customer — the verification gap. Three hard problems live in that gap: a model cannot grade its own homework, so the verifier must be independent of the LLM; the most expensive failures are silent (an evidence gap that reads as a pass); and the economics are upside down — red-teaming means many live conversations, which is exactly what a credit-metered org cannot afford.
The approach
Four pillars behind one interface. A 30-case German attack corpus (prompt injection, cross-customer fishing, authority spoofing, GDPR-rights abuse) committed as the repo's first commit — git is the notary that the exam predates the grading. A deterministic scorer: trace-based checks read the AccountId an action actually ran with, canary checks catch leaked facts even through homoglyph tricks; the LLM may explain a failure, never decide one. A fingerprint-bound report that stamps itself STALE if the agent later changes. And a 20-rule static linter over the agent config plus Apex — reachability, routing, guardrails, threat-to-control coverage — all on free Tooling API reads. On the Salesforce side, the tariff change itself is engineered against jailbreaks: consent is a two-action handshake over an expiring record, so the model cannot fabricate the token only the propose action emits — and the recommendation ranks tariffs by true annual cost at the customer's real consumption, where the naive lowest-price answer is provably wrong. 69 meta-tests plant violations and assert the verifier catches them. Credits are spent only on evidence: mock and replay transports carry all development, and a five-lock guard chokepoints any paid run.
The outcome
The harness met the real agent and earned its keep: the linter surfaced two orphan GenAiFunctions invisible in the Agent Builder UI and a routing gap that would have silently swallowed traffic — fixed on the live agent, re-linted to 0 errors, a closed CI-style loop at zero Flex Credits. It also earned something rarer: it caught two silent-pass bugs in itself, and the repo documents them instead of hiding them — the exact failure mode it hunts, found living in the hunter, fixed and pinned with regression tests. 69/69 meta-tests green, a 30/30 offline demo, committed reference reports, and seven documented Developer-Edition platform walls (three now auto-linted). Deliberately not claimed: any live pass-rate — the single paid reference run is the last step, and the reports say what they do and do not prove on their face.