The compliance record

One page that says how ready you are — every clause of your standard, one verdict per clause, and a readiness number that reconciles against the rows below it.

<!-- Reviewed 2026-09-05 (delete the copies — the loop's item 5): the covered src/lib/server/compliance/loopTasks.ts and src/lib/server/repos/compliance.ts changed only in HOW they read the stored check result, not in what a reader gets. loopTasks dropped a local structural restatement of `lastCheck` and now reads the typed field defined in workflows/clauseCheck.ts; compliance.ts had a field description that still called the clause state "the document-audit verdict", a surface retired with fs_to_pg_199. No column, field, task or row moved, and nothing this page describes changed. -->

The compliance record is the page you point an auditor at: every clause of the standard you are working toward, each with one verdict, and a readiness percentage at the top that is the sum of what you see below it — nothing more, nothing less.

Some standards in your catalog are certified as an extension of another — a base framework plus a set of additional controls, never on its own. Adding one gives it its own tab, and that tab is the base framework's clause record: the same clauses, the same assignments, the same documents and the same verdicts, counted once for both, with what the extension adds layered onto the base framework's controls. The summary line names the framework it extends, so two tabs showing the same numbers read as what they are. Every standard in your catalog renders here the moment you add it, whether or not the assistant has control-level detail for it yet. A standard whose control detail is still being authored shows its full clause list and says so on the summary line — control detail not yet available — and its clauses are assigned, documented, excluded and audited exactly like any other. Readiness is clause-based, so the number at the top means the same thing for such a standard as for one with every control described.

One verdict per clause

Each clause row reads as exactly one state, folded from everything attached to it — its documents, their audit results, and its controls:

VerdictMeaning
ConformingThe clause's document audit passed, or every control on it is met
In progressDocumented, but not yet passing an audit
GapAn open non-conformity — in the document audit or on any control
Needs evidenceThe last check could not confirm the clause from what is attached — its finding says what it looked for
Not assessedIn scope, but no evidence of any kind yet
ExcludedTaken out of scope in your Statement of Applicability, with a reason

The worst state wins. A clause with a live gap never reads Conforming, even if an earlier audit passed — the record tells you where you stand today, not where you stood at your best.

A clause no team owns yet shows as Unassigned (a hollow dot) — it is outside your scope until someone takes it on.

How the readiness number is worked out

Conforming clauses count in full, in-progress clauses count half, over everything in scope. A document merely existing is progress, not compliance — which is why an unaudited policy can only ever carry a clause halfway.

The count line under the headline — so many conforming, so many in progress, so many gaps — is clickable: each count filters the list to exactly the clauses behind it. Those counts are the percentage's own terms, so the number always reconciles against the rows you can see; they are the same verdicts, counted once.

What a row shows

Each row carries the clause code and name, how many things are attached to it, the team that owns it as plain text, and the verdict. Open a row and the clause unfolds in place, right under it — there is no side panel to look across to and no separate page to visit. The detail is one list:

  • What is attached — the clause's documents and controls together, one line each: a small glyph tells the kind, a document carries its name, a control carries its name, its audit state and when it was last audited. Point at a line and a quiet × detaches it. There is no separate documents section and no separate controls section, because the clause does not care which kind satisfied it.
  • What the last check found, when one has run — the check's own words about this clause, above the list. Under them, a small line saying when it ran and which requirement it judged, and, where the check quoted something, what it cited. A link opens the run behind it, with its full receipts. This is the answer to why is this clause not passing — you are reading the finding itself, not a summary of it.
  • "This is fine — remember it for next time", on a clause where the check disagreed and quoted a passage. Some findings are wrong: the check read your evidence and asked for something your document already covers in its own way. Pressing this saves the passage the check quoted as an accepted example for that requirement, and the next check of the clause is shown it — so you settle the point once instead of re-arguing it every time your evidence is re-read. It saves what the check QUOTED, never the check's own wording, and it appears only where there is a quoted passage to accept. What happens next follows your workspace's change setting: where changes wait for approval it says so and waits for Apply rather than reporting success, and either way the acceptance is recorded with who made it. Accepted passages stay inside your workspace — they are never sent anywhere outside it.
  • One sentence, only when no check has run yet — what would change the verdict: the check has to pass, the gap has to be closed, or nothing is attached yet. Once a check has spoken, its finding replaces this sentence: a general statement and a specific finding on the same row would only compete. A conforming clause with no finding shows its attachments and nothing else.
  • + Attach… — the one door, which opens the one picker described under Attaching.

Nothing in the detail changes who owns the clause or takes it out of scope: the team is text, and Assign to team and Exclude… live in the action bar that rises when you select rows.

Following the roadmap

Where your framework has an authored implementation order, the record is also the map, drawn as one timeline. The line under the readiness number says where you are — Phase 3 of 9 — and each phase is a node on the timeline: a tick and one line of what it produced for a phase you have completed, a thin line with its progress for one still to come, and the phase you are in open.

The open phase reads top to bottom. First the next step: one clause, chosen for you as the first in this phase that does not yet conform, with a sentence written from the record itself — which document is attached, what its audit said, how many controls are met, what the phase produces — and, after it, what comes next and which phase opens when these conform. It carries the page's one button, Continue with AI, and a quiet Work on a different clause for when you want another of the open clauses first. Then why this phase now, the consultancy's reason for its place in the order. Then the phase's clauses as rows.

Click any other phase to open it and see its rows; click again to fold it. A count-filter or a search is a lens over the whole standard: every phase with a matching clause opens, the others fold away, and the next step steps aside until the lens is cleared. The bulk bar's select all means the rows on the page.

A phase counts as complete when every one of its in-scope clauses is conforming — excluded clauses do not count either way, and a phase with nothing in scope yet is work not started, not work done. The risk phase has one more condition: your Risks register must hold at least one record, because a documented method nobody has run is not a completed assessment. The order and its reasons are authored by the consultancy practice and reviewed like any other content; an order that has not been reviewed yet is marked Draft order · pending review, and the assistant says the same when asked.

Continue with AI opens the assistant with the standard, the phase, the next clause and the other open clauses already in hand. It reads the record, audits the clause against what is attached, explains what is missing in the chat, and proposes the fixes as changes you accept — the row's verdict then updates here. The record is where the assistant resumes from, so it never asks you what you were working on.

A framework with no authored order shows the clause list grouped by section — the product never invents a sequence.

Scope and exclusions

Not every clause applies to every organisation. Excluding a clause asks for a reason, drops it from the readiness denominator, and shows it struck through with the reason kept — the record of what is in scope, what is out, and why is your Statement of Applicability, kept live on this page.

Attaching

Attaching is how a clause earns its first credit: link the policy, procedure, form, record or uploaded file that satisfies it, or the control that proves it, and the clause moves from Not assessed to In progress — half credit toward readiness.

There are three doors to the same picker:

  • On the row — a clause with nothing attached shows + Attach… when you point at it.
  • In the clause detail+ Attach… under the list of what is attached.
  • In bulk — select several clauses and choose Attach… from the action bar: everything you pick gains every selected clause in a single step, the way one manual legitimately covers a whole chapter of your standard.

The picker holds documents and controls in one list. Each line is a checkbox showing the item's name and the team that owns it, nothing more: tick as many as you want — a document, a control, several of each — and one button attaches them all. A Suggested section leads with the items likely to satisfy the clause you're on (they already cover a neighbouring clause, or their name matches the clause's subject), with Select all to tick the whole section at once. Suggestions never attach themselves.

The picker offers what your library already holds. A document that does not exist yet is written in Governance, or by the assistant from the roadmap's next step, and attached from here once it does.

Attaching a document declares its audit scope — the same link the document's own scope picker edits — and attaching a control adds the clause to the control's own clause list, so the record and its sources can never disagree about what covers what. Every attach and detach is a line in the activity ledger, with who did it.

Working on, and the work that is left

Under the header, the record says what you are working on: the one item the assistant and you last touched, which step it is at — reading, change proposed, checking — and a button to carry on with Alchex from exactly there. If nothing has been started yet, the strip names the first thing on the list and offers to start it instead. This is what makes "where were we?" answerable: your position is on the record, not in somebody's memory.

The record is the list. There is no separate to-do page to keep up to date, and nothing to reconcile: the work left is read from this record every time you open it, and it appears on the rows it is about.

  • Clauses to satisfy — every clause that is not conforming yet is already a row here, with its verdict and, when a check has run, what that check actually said. The one you are working on is the clause Do this next names; nothing else marks it, because saying it twice only adds noise.
  • Documents to produce — the phase that produces a document says whether you have it: "This phase produces a written scope statement — not written yet." A document you do have but have not linked to this standard is named too, and the sentence tells you to extend its scope rather than write a second copy. A phase you have not opened still says how many it owes, so closing a phase never hides work.
  • Promises — what you or your consultant said you would do, as one line under the readiness counts that opens when you click it. A promise belongs to no clause and no phase, so it is the one thing here with a place of its own.

Any of them can be parked. Parking is how you say not now — the row stays where it is, dimmed, with your reason where its attachments normally read, sorted to the end, and the assistant will not raise it again until you unpark it. Nothing is ever hidden, because work that disappeared would simply be derived again and asked again.

Only a promise can be ticked off by hand. A clause is done when its check passes and a document is done when it exists — so the record decides those, and the product will refuse to let anyone mark them complete instead of doing them. That refusal is the point: a list you can tick without changing anything is a list that lies. That is also why Done appears in exactly one place on this page.

Asking Alchex to "find the weaknesses" and asking it to "start the journey" are the same work read two ways — the clause rows in the first case, the phase's documents in the second.

The activity ledger

The Activity tab is the record's memory, and it holds three kinds of line. Audit runs — what the audits found — carry status dots. Scope changes — what people did — carry a neutral dot: controls removed or restored, clauses excluded or returned to scope, standards added or removed, each with who did it and when. That second kind exists because a compliance record must be able to answer an auditor's first question — who changed this, and when? — about itself. The third kind is workflow runs — what your procedures did: each run of a document workflow appears with a dot for how it ended, one sentence naming the procedure and what it ran for, and a muted line carrying the run's own last receipt. Workflow lines appear whichever standard is selected — a procedure's run is not owned by one framework.

The ledger is append-only: nothing in the product can rewrite or delete a line.

When controls are removed, the removal line carries its own Restore — one click brings back exactly the controls that line recorded, statuses and audit history intact, and writes the restore as its own line. Removed controls are never destroyed; they are retired, and the ledger is the door back.

Stalled decisions and controls that did not operate

Two states are pinned above the feed and never sort away. A run parked on a person is a stalled decision — the card names what is waiting, on whom, and since when, with Open run beside it. A run that failed is a control that did not operate — the card says what did not happen in plain words, with Raise a risk beside it, which opens the risk form already filled in from the run's own receipt. On a clean day the band shows nothing; that emptiness is the product working.

Open run — on a pinned card or any workflow line — opens the run's receipts over the page: each step's sentence, any AI call it made shown as a suggestion with its token cost, and two doors out, to the record the run was about and the procedure that ran it. Every run is kept against the procedure exactly as it stood when it fired, which is what makes a run readable as audit evidence.

The same run lines and pinned band also appear on each team's home page, scoped to that one team, where each line also names the process that ran (a document can hold several) — this page is where everything adds up; a team's page is where its own share of it lives, and it is the team's run history.