Self-Hosted AI Code Reviewer for a Swiss Private Bank
Designed and built a clickable AI code review agent for the engineering team of a Zurich private bank: it reviews every merge request on GitLab and GitHub Enterprise with models hosted in the bank's own tenancy, masks client data and secrets before any model sees the diff, posts inline findings with rule, CWE and suggested patch, and never approves or merges.
Most of our work is under NDA. Per agreement, we can share the work but not the company details - all names and identifying information shown here have been changed.
Dashboard, review runs, review detail, findings and secret exposures. Every one of the 24 demo review runs opens its own detail page with diff, summary, checks, context and timeline.
Lektor posts discussions and inline comments, never an approval. Every summary ends with "Lektor comments only. A human reviewer must approve this merge request.", so the four-eyes rule stays with people.
8 security rules, from SQL injection (CWE-89) to deserialisation of untrusted data (CWE-502), each with an OWASP Top 10 category, plus bug, performance and style rules from the bank's own guidelines, such as BigDecimal for money.
14 repositories on GitLab and GitHub Enterprise, 36 findings, 12 secret exposures and 3 model endpoints, two on premises in Zurich and one in the bank's own Azure tenancy in Switzerland North.
Brunnacher's four-eyes rule means every change to production code needs a human reviewer, and the median merge request waited 19 working hours for its first comment. Senior engineers kept pointing out the same missing input validation, string-built SQL and logged account numbers, and two teams that pasted diffs into a public chatbot were stopped at once because test fixtures held real client names and IBANs.
Lektor is a first reviewer that answers in minutes and keeps every byte inside the bank. It reads the diff and its repository context, runs secret, static and client-data checks first, masks what it finds, asks a model hosted in the bank's tenancy for a review, and posts inline comments with severity, category, rule and suggested patch. Developers rate every comment, and a human still approves every merge.
A code review agent at a Swiss private bank has to be useful to developers, but it also sits inside banking secrecy, FINMA's expectations for ICT and AI, Swiss data protection and the bank's own change process.
Source code is not client data in itself, but diffs, test fixtures, SQL migrations, logs and configuration can contain client-identifying data, and disclosing it is an offence under Art. 47 of the Banking Act. Nothing may reach an endpoint outside the bank's tenancy, and any such call must be blocked and logged.
Lektor is itself an ICT system in the change process under FINMA Circular 2023/1. It must not hold merge or approve rights, its commit status is informational, and the bank must be able to keep releasing code when it is down.
FINMA Guidance 08/2024 expects clear ownership, an inventory and risk classification, testing, monitoring and documentation for AI applications. Every model, prompt and policy change needs a regression run, and every target is the bank's own policy, approved by the AI system owner.
Commit authors and feedback are employee data under the revised FADP, and Swiss labour law generally prohibits systems built to monitor employee behaviour. Quality has to be measured per rule and per team with a minimum group size, never by ranking developers.
Mapped 10 user roles, from developer and AppSec engineer to AI system owner and internal audit, and 35 screens with 5 slide-over panels. Defined the data model for repositories, policy packs, rules, review runs, findings, feedback, suppressions, secret exposures, model endpoints, routing and the egress log. Wrote down the rules the design follows: banking secrecy, FINMA Circular 2023/1 and Guidance 08/2024, the four-eyes principle, the revised FADP, the ban on employee monitoring, and OWASP Top 10 and CWE tagging.
Built 5 key screens on a production dashboard kit: the dashboard with time to first review, acceptance, false positive rate and cost per merge request against client targets, review runs with skip reasons and re-run, the review detail with inline comments, suggested patches, deterministic checks and the context inspector, findings by rule with suppression, and secret exposures with the rotation checklist. A platform filter switches between GitLab and GitHub Enterprise. All actions run on local state.
Webhooks and comment posting on GitLab Self-Managed and a GitHub Enterprise Server App, self-hosted models on vLLM or NVIDIA NIM, an optional Azure OpenAI endpoint in Switzerland North for non-CID repositories, gitleaks, Semgrep and tree-sitter, SSO through Entra ID or AD FS, Splunk, Jira and Teams. Plus the remaining staff and developer screens: policy pack editor, model routing, regression set, data egress log, AI system record, incidents and a tamper-evident audit log.
gitleaks, Semgrep and client-data detectors for IBANs and client numbers run before any model call, and the review shows what was masked by type and position only. Revealing masked content needs a reason, shows "Unmasked view - logged" and locks again after 15 minutes. Secret values are never shown.
Each inline comment carries a severity, category, rule id and CWE, and where it can a suggested patch as a mini diff. The context inspector lists which files, symbols and guidelines were retrieved and why, with the token count for each, so a reviewer can see why Lektor said what it said.
Every finding records thumbs up or down and its outcome. Findings group by rule with acceptance and false positive rates, and a rule above the bank's 15% target is flagged on the dashboard. Suppressions need a reason, and security suppressions need an AppSec engineer who is not the requester.
A secret that reaches a branch becomes an exposure with its type, a truncated hash, file, line and commit. Age turns amber after 4 hours and red after 24, the panel shows whether it reached a shared branch or was merged, and rotation is confirmed only with a ticket reference once the checklist is complete.

Designed and built a clickable document processing platform for a Rotterdam freight forwarder and customs representative: it classifies commercial invoices, packing lists, bills of lading, air waybills and certificates of origin, extracts each field with a confidence score, checks it against business rules and sends only the uncertain fields to a person in a side-by-side review workspace.

Designed and built a clickable back-office agent for a Dubai mainland distributor: it reads the AP and vendor mailboxes, matches invoices to POs and goods receipts, checks UAE tax invoice fields, drafts replies and posts to the ERP, while people approve by amount, see every tool call and handle every bank detail change themselves.
Enterprise Software Engineering - Human + AI
Contact Us
© 2026 - Copyright. All Rights reserved Oceanlab
Location
Global Headquarters
21 Merchant Road, 3rd Floor, Singapore 058267
Main corporate office and leadership operations
North America Office
548 Market Street, PMB 12345, San Francisco, CA 94104
Client operations and business development
India Office
402 Shivalik Shilp II, SG Highway, Ahmedabad 380015
Engineering and delivery center
Enterprise Software Engineering - Human + AI
Contact Us
Locations
Global Headquarters
21 Merchant Road, 3rd Floor, Singapore 058267
Main corporate office and leadership operations
North America Office
548 Market Street, PMB 12345, San Francisco, CA 94104
Client operations and business development
India Office
402 Shivalik Shilp II, SG Highway, Ahmedabad 380015
Engineering and delivery center
© 2026 - Copyright. All Rights reserved Oceanlab