How the IQ series was built
ImpactIQ, SupplierIQ and GovernIQ are working demonstrators, not client deployments. Each one shows how we would turn a piece of AI governance, an impact assessment, a supplier review or a statement of applicability, into a record that a person authors and a reviewer can follow. This page sets out why each exists, what it is built with and why, and how it is tested, with the current results.
Test results last checked: 23 September 2026.
Status at a glance
Every figure below comes from a test run, not an estimate. Continuous integration (CI) re-runs the automated checks on every change.
- Automated tests
- 334 passed
- Browser tests
- 8 passed
- Engine coverage
- 99.4%
- Accessibility
- 0 issues
- CI
- Passing
- Automated tests
- 114 passed
- Browser tests
- 14 passed
- Engine coverage
- 99.2%
- Accessibility
- 0 issues
- CI
- Passing
- Automated tests
- 19 passed
- Browser tests
- 20 passed
- Dependencies
- None
- Accessibility
- 0 issues
- CI
- Passing
"Browser tests" run each app's end-to-end tests in Chromium and WebKit (the engines behind Chrome, Edge and Safari), so each test counts twice. "Engine coverage" is the share of each app's rules engine and record schema run by its tests.
Why they exist
Governance standards say what a good record contains. They do not show what it looks like when a real team fills one in, where it goes wrong, or how a board member should read it.
We built the three apps to show that working, end to end, on one fictional case: a UK lender, Northbridge Credit, using a supplier's model (Meridian Decisioning, also fictional) to decide personal loans. GovernIQ records what applies, SupplierIQ examines the supplier, and ImpactIQ assesses the effect on customers. They are separate apps and deliberately do not share data; the links between them are references a person writes, as they would be in a real organisation.
They are also how we test our own method. If a record cannot be explained on one screen, or a gap cannot be traced back to the field that caused it, the design is wrong, and building the app makes that visible faster than a document would.
Design decisions that apply to all three
These choices come from what a governance tool should never do, rather than from technical preference.
- A person writes every judgementThe apps structure the work and show what is missing. No field that carries a judgement is pre-filled, and nothing is scored as compliant or non-compliant.
- No AI model at runtimeGaps and views come from fixed, readable rules, so every flag can be traced to the field that caused it. Nothing is invented, and the same record always gives the same result.
- Your data stays in your browserNo accounts, no server storage and no calls to other services. Records are saved in the browser and can be exported as JSON, Markdown or PDF. There is nothing to breach because nothing is sent.
- Evidence before assuranceA harm or control cannot be shown as handled without an evidence reference. Claims without evidence are flagged, not accepted.
- Fictional, and labelled as suchThe worked examples use invented companies and invented control references, never licensed standard text. Every screen that shows them says so.
- Hosted like any static siteEach app is a set of static files behind strict security headers (a content security policy that only allows its own files, HSTS, no framing). Unlisted apps also tell search engines not to index them.
How we built them
The same loop for each app, whatever the stack.
- Specification first. Each app starts from a written specification: what the record contains, which views it produces and what the app must refuse to do. In ImpactIQ, tests name the specification clause they encode, so a drift between the specification and the code fails a test rather than waiting to be noticed.
- AI-assisted build, human-owned decisions. We built the code with AI coding assistants. A person set the specification, reviewed the changes and made every call on regulatory wording, scope and what the app is allowed to claim.
- Human checkpoints on anything that sounds like compliance. Work stops wherever a change touches a regulatory claim or a judgement field. ImpactIQ's regulatory statements are checked against published sources, and CI fails if any is marked unverified. SupplierIQ's example wording had its own review against primary sources.
- Tested from the outside, too. Beyond the automated tests, scripted browser checks run over every key screen at desktop and phone width: an automated accessibility audit (axe-core), a keyboard-only pass, and checks that nothing overflows a small screen.
- Watched by people. We ran a facilitated first-look test and fixed what it found. Confusion that automated tests cannot see, such as a button that means different things in different apps, is found this way.
The apps in detail
What each one is built with, why, and exactly what its tests cover.
ImpactIQ
Open ImpactIQ →One assessment record, structured to ISO/IEC 42005, produces several views: an executive brief, a risk matrix, an EU AI Act fundamental rights view and a UK regulatory mapping. The views are filters over one record, not separate documents, so they cannot disagree with each other.
| Part | Technology | Why we chose it |
|---|---|---|
| Interface | React 19, TypeScript | A guided, multi-step form with live gap counts needs predictable state. TypeScript catches schema drift at build time. |
| Record schema | Zod | One schema validates the record, imported files and the worked example, so a bad import is rejected with a reason. |
| Rules engine | Plain TypeScript rules | Small, composable rules, each with a readable trace of why a field was tagged or flagged. |
| Exports | React PDF, Markdown | PDF and Markdown are produced in the browser, so an export never leaves the device. |
| Build and style | Vite, Tailwind CSS | Fast builds and a small static bundle; one shared design system with SupplierIQ. |
| Hosting | Netlify, static files | No server to run or secure; each change deploys automatically once pushed. |
| Test layer | Tool | What it checks | Result |
|---|---|---|---|
| Unit and component | Vitest, Testing Library | Schema rules, each rules-engine evaluator, gap detection, every view generator, exports, storage and the main screens, including the replace-record confirmation. | 334 passed |
| Coverage | V8 coverage | Share of the rules engine and schema exercised by tests. | 99.4% lines, 98.2% branches |
| End-to-end | Playwright: Chromium, WebKit | On the production build: the home page and mandatory disclaimer, entries surviving a reload, Settings locked in the public demo, and a Markdown and PDF export of the EU view. | 8 passed |
| Regulatory claims | Custom check | Every regulatory statement the app makes is recorded with its source and must be marked verified. | 4 of 4 verified |
| Static checks | ESLint, TypeScript, Prettier | Lint, type errors and formatting, run in CI before tests. | Clean |
SupplierIQ
Open SupplierIQ →A due-diligence record for one third-party AI supplier: who is responsible for what, which documents were requested and obtained, how the supplier is monitored and what is still open. Its completeness measure describes how much of the record is written and evidenced. It is not a rating of the supplier, and the page says so beside the number.
| Part | Technology | Why we chose it |
|---|---|---|
| Interface | React 19, TypeScript | The same stack as ImpactIQ, so the two share a design system, dialogs and form patterns. |
| Record schema | Zod | Validates the record and imported bundles; the responsibility matrix is typed row by row. |
| Rules engine | Plain TypeScript rules | Gap detection and the completeness measure are small functions over the record, each testable on its own. |
| Exports | React PDF, JSON | A printable record and a portable bundle, both produced in the browser. |
| Build, style, hosting | Vite, Tailwind CSS, Netlify | As ImpactIQ. |
| Test layer | Tool | What it checks | Result |
|---|---|---|---|
| Unit and component | Vitest, Testing Library | Schema, gap detection, the completeness figure (an empty record is 0%, the example matches the engine exactly), each wizard step, the results page and the home-screen actions. | 114 passed |
| Coverage | V8 coverage | Share of the rules engine and schema exercised by tests. | 99.2% lines, 93.8% branches |
| End-to-end | Playwright: Chromium, WebKit | On the production build: home actions and disclaimer, the example opening at its results with the fictional label and completeness figure, a gap link and the way back, the in-app replace dialog, persistence across a reload, Markdown export and phone-width layout. | 14 passed |
| Static checks | ESLint, TypeScript, Prettier | Lint, type errors and formatting, run in CI before tests. | Clean |
GovernIQ
Open GovernIQ →A working statement of applicability: the scope, each control with its applicability decision, the reasoning, the owner and the evidence, then a work plan of open items grouped by owner and a printable statement. It contains no licensed control text; the example uses invented references.
| Part | Technology | Why we chose it |
|---|---|---|
| Whole app | HTML, CSS and JavaScript modules | Deliberately the smallest thing that works: no framework, no build step and no third-party code shipped. Anyone can read every line that runs. |
| Record logic | One plain JavaScript module | Validation, gap detection, the work plan and Markdown export are pure functions, kept apart from the page so they can be tested directly. |
| Printing | Browser print with a print stylesheet | A clean paper or PDF statement without a PDF library. |
| Hosting | Netlify, static files | A content security policy that only allows the app's own scripts, styles and font. |
| Test layer | Tool | What it checks | Result |
|---|---|---|---|
| Record logic | Node's built-in test runner | Record validation and size limits, gaps per control, the work plan's ordering (unowned items first), the numbered suggested order and its stated rule, Markdown export and that the example keeps its honest gaps. | 19 passed |
| End-to-end | Playwright: Chromium, WebKit | The real page: the example's scope and counters, counters that open their tab, the cross-reference to SupplierIQ, keyboard tabs, the work plan and suggested order, in-app confirmations, adding, deleting and exporting a control, the print sheet, persistence and phone width. Playwright is installed only for the test run, so the app still ships no dependencies. | 20 passed |
| Static checks | Node syntax check | Every script parses, run in CI before tests. | Clean |
Checks across all three
Scripted browser checks that run against every app, at desktop (1440 pixels wide) and phone (390 pixels) sizes.
| Check | What it covers | Result |
|---|---|---|
| Accessibility | axe-core audit of each app's home, worked example, results and settings screens, plus GovernIQ's work plan and edit dialog. | 0 issues |
| Keyboard | Visible focus, skip link, dialogs that trap and return focus, tabs that work with arrow keys. | Passing |
| Behaviour | 29 checks on the live apps: no browser pop-ups, the example loads in one click, the back link stays on screen, nothing overflows at phone width, no script errors. | 29 of 29 |