Controls and evidence

How controls carry their own evidence, what the freshness states mean, and how a control is audited from its own procedure's workflow.

<!-- Reviewed 2026-09-08 (no default team; team codes capped at three): the covered code lost one payload field (`isDefault` on `GET /api/teams?mine=true`, which no surface this page describes ever showed), renamed the team-less fallback helper, and had its comments corrected — the fallback itself is now the workspace's OLDEST team rather than its flagged one, which resolves to the same team on every workspace the app has made. New team codes are 2–3 characters; existing longer codes are untouched and keep numbering, because the numbers already issued cite them. Nothing this page states about behaviour changes. --> <!-- Reviewed 2026-08-30 (the control mirror retires): repos/controlAgents.ts stopped using the `control_agents.instructions` / `instructions_doc` columns — a control's definition now lives only in its backing document. This page's promises do not change; they become structurally true instead of maintained by a copy. "The audit judges the published definition" and "whenever a check runs, Alchex re-reads the note's current draft" were both kept by a mirror column written at publish, which is why the draft claim was the one that could drift. Two user-facing behaviours got MORE correct rather than different: the draft test-run and the standards advisor were reading the last published text while saying they read the draft, and now read the draft. Nothing this page states needed rewriting; the phase story is docs/CONTROLS-AS-DOCUMENTS.md. --> <!-- Reviewed 2026-08-30 (the workflow leaves the document body): the covered workspace/lifecycle files changed only in workflow-storage wiring — chips retired from the editor surface and the document_workflows store took over behind the same seams. Nothing this page describes moved; the workflow story itself is authoring/workflows.md, rewritten in the same change. --> <!-- Reviewed 2026-08-20 (the record lock): repos/evidenceRecords.ts gained assertRecordUnlockedTx on its user-edit writers. Check runs and source-identity stamps deliberately stay open (observations, not edits), so the freshness loop this page documents is unchanged; the lock on manual edits is documented under Library → Connected data. -->

A control is the unit of work in Alchex: one requirement, one owner, the evidence that proves it, and its own audit history. A control is a document with auditing — it lives in the Governance list like any other record, with its Type reading Control and a CTL-… code. It opens in the same editor, follows the same draft → review → publish flow, and is audited from its own procedure — see How an audit is started.

Where controls live

A standard certified as an extension of another has no controls of its own on this page: its controls are the base framework's, with the extension's additions layered onto them, so a control attached from either standard's tab is one control on one record.

Create one from Governance → New and choose the Control card: you name it, Alchex drafts its plan, and it opens as a draft where you pick the clauses it judges. See What a new control starts with.

In the Governance list a control is an ordinary row — lifecycle status (Draft, Current, and so on), owner, version, updated. The owner is the person who created it, shown by name exactly as on any document. Filter the Type column to Control to see a team's controls together. The audit verdict is not a list column; it lives on the compliance record, and the run that produced it is read from the control's Workflow panel.

The last run's verdict is one word:

VerdictMeaning
Not checkedNo audit has run yet
ConformThe last run found the requirement met
GapA shortfall was found
Serious gapA material shortfall was found
ObservationWorth noting, not a shortfall
No evidenceNothing was attached for the run to grade
InconclusiveThe run could not reach a verdict

Deleting a control removes its agent and wiring but keeps its audit history.

A control can also be handed to the assistant directly: in Ask Alchex, Focus the conversation has a Controls tab, and pinning one there keeps the answers to that control. Only controls your teams can reach appear, and archived ones are left out. See AI review and assistance.

Evidence

A control's evidence is what is attached to the control. Three kinds attach: a document — a policy, a procedure or a register already under governance; a connected source — a connector label pointing at one thing inside a system you have connected; and a file imported onto the control itself. Nothing sits between the control and its sources: the control reads the source, and the audit grades what comes back. The same source can be attached to several controls and cited from several documents at once, and removing it from one of them leaves the others alone.

Evidence reaches a control through its text. Open the control, type / in the definition, and the References group offers one door — Mention — which opens the reference form; its left rail does the narrowing. Every way through it ends the same way: a chip in the sentence that needed the proof, and the item attached to the control so the next audit grades it.

  • Reference — one search across everything the workspace already holds: documents, registers and logs, other controls, risks, and the connected sources your teams hold. Best when a published policy or procedure is the proof.
  • Import file — bring a file in from your machine. Nothing uploads until you save.

Evidence attached to a document follows the same rule, and deliberately so. A document says what backs it by referencing it in the text, and the list follows. Write a reference into the body and it appears as a backing; take the reference out and the backing is withdrawn — the item itself stays in the workspace, because removing a citation from one document says nothing about whether it is still worth holding. Anything you attached to a document by hand elsewhere is left alone. See References.

On a control's definition the citation goes one step further: referencing evidence in the control's body also attaches the item to the control itself, so the next audit grades it — a proof named in the text is never silently missing from the run's bundle. The same law covers connected systems: cite one of your connection labels in the note and the audit may read from it — the citation is the grant, so a system named in the text is never silently missing from the run's allow-list either. This holds for the draft you are typing in, not only the published version: whenever a check runs, Alchex re-reads the note's current draft and attaches what it cites first — a citation saved moments ago already counts. Taking the citation out withdraws what the citation attached; anything attached to the control by another route stays.

To prove a control with something in a connected app, cite its connector label. The reference picker's Connectors row lists the labels your teams hold; citing one in the control's definition attaches that source to the control and is itself the grant that lets the audit read it. See Connectors as references.

A connected source is team property. A label belongs to a team, and every read follows the team you are in: with a team selected in the sidebar you see that team's labels; on All teams you see everything you can reach. Narrowing only ever narrows what you already had access to.

What you confirm when you pin a resource

Before anything is read, you can see what exactly is this? — the resource's own title, then Where it sits, its Owner, and when it was last Updated. Those identifying details are all that reach your browser — the resource's contents stay in the connected app, whose own permissions decide what you may see there. Alchex never widens them.

What a label pins is the resource's stable identifier, so the reference survives a rename in the source system. The label also keeps the resource's own name as its last passing check saw it, so what it points at stays readable on every later open without a live call to the source. To point a sentence somewhere else, double-click its chip in the text: the reference picker reopens on that chip, and picking another target re-points it without disturbing the chip's place in the sentence.

The state of a connected source

A label's last verdict is the health signal everywhere it renders: alive when the check reached the source, unreachable when the connection or the resource stopped answering — with the source's own reason — and not verified yet when nothing has checked. A check that merely could not complete changes nothing — proving nothing is not the same as finding something wrong, and recovery clears the state by itself on the next passing check.

Two behaviours are worth knowing:

  • A source that several things rely on is one label: re-pointing it re-points it everywhere it is cited.
  • Removing it from one place leaves it attached everywhere else.

Retiring something a control cites

Archiving a record retires it, and a retired record stops resolving in every document whose text cites it. The removal goes through anyway. It used to be refused while a citation stood — with the citing documents listed before the button and a workspace admin able to override — and none of that is there now. There is no list to clear, no refusal, and no override to write into an audit log.

What happens instead is that the citation states the problem where it is written: every chip citing the retired item picks up a red dot, keeps the item's title so you can see which proof was withdrawn, and carries Rebind for pointing that sentence at a live item. See References.

There is a second reason a red dot is the better answer for a connected source in particular. A chip pointing at one has three states, not two: a red dot means the label is gone, while an amber one means it is still there and only its last check failed — a connector down, access revoked at the source. Under the old scheme an outage and a deletion looked alike, so people re-pointed citations that had never broken.

Deleting a record outright

Archive retires a record; Delete removes it for good, from the record's own page or its row in the Governance list. Neither door is refused because something cites the record — a reference is not a lock, and the rule is the same for every kind of record in the workspace.

The two are not interchangeable, though, and the difference lands on whoever reads the citing document:

  • Archived — the record is still there, so every chip citing it goes red and keeps its name. A reader can see which proof was withdrawn, and Rebind points the sentence at a live one. Restoring the record clears the dots.
  • Deleted — there is nothing left to name, so those chips read as a restricted record: inactive, unopenable, and with no title to rebind from. That wording is not evasive, it is unavoidable: a citation is resolved for each reader in their own scope, and "destroyed" cannot be told apart from "belongs to a team you are not on" without leaking something about a record the reader may have no right to.

Deleting also detaches the record from everything it was backing, in the same act — a control never lists a proof that no longer exists.

Both doors follow the same rungs as every other record. Archiving and restoring a record takes author rights on its team; deleting it takes owner rights. One rule, on every kind. See Permissions.

A connected source is the one thing a member cannot always remove. A connector label that a control is reading as an audit source is refused to an ordinary member — detach it from the control first, or ask a workspace admin — so one team cannot quietly remove another team's audit input.

Archiving a control works the same way — the same act, at the same author rung, as retiring a document or a register, and everything the control holds (its evidence, its audit history, every run) stays with it and comes back on restore. A control that a document's text cites can be archived, and every chip citing it picks up a red dot, keeping the control's name. The one moment Alchex stops to ask is a control that already carries an audit verdict: retiring it clears that verdict from the compliance record, so you are told which control and which status before it happens, and the removal is written into the compliance Activity ledger — which is also where a batch of retired controls is restored from. See Activity and archive. Deleting a control takes three things with it — the agent, the control record and the control's own definition document — and it, too, is never refused on account of what cites any of the three; the confirmation no longer lists them, because there is nothing there for you to act on before pressing the button. A control chip carries either no dot or a red one: a control has no source behind it, so it never goes amber.

A control cited in a document renders as a chip that resolves the control's current name, live, for each reader — rename the control and every chip follows on the next open. The lookup is scoped to the reader: a control outside the teams you belong to renders as a restricted record rather than naming something you cannot open. See References.

If a connected app drops out, everything bound through it becomes unverifiable at once and its checks stop passing. Settings → Connections names the connector and offers Reconnect — or says to ask an admin, if you do not hold that permission.

Pinning a connector resource here names it — that name is a label, and every label a connection holds is listed on the connection's own Configure page. When a source moves or is renamed beyond recognition, re-aim the label there once and every control and document citing it keeps working. See Connections.

A label belongs to a team, and a control reads only its own team's. The connection itself stays workspace-wide — every team can connect through the same door — but the labels on it are team property. A control may be backed by, and audited against, the labels of the team that owns the control, and nothing else. Attaching another team's label is refused exactly as attaching a deleted one is: it reads as not found, with no hint that it exists somewhere else.

This matters most when a control's instructions name a connector source. If the label named there is not the control's team's, the run does not quietly find something else to read: the source does not resolve, it is left out of the run's evidence bundle, and the requirement it was meant to prove comes back as No evidence. That is the same honest answer a deleted label, or a label pointing at nothing, already gives — Alchex would rather tell you a requirement is unproven than prove it with something you did not mean.

The control's audit agent

Every control can have an audit agent: a written instruction for what to check, wired to the control's evidence. Agents added from the marketplace arrive as drafts — you attach your own evidence sources and publish before the agent will run.

A run is graded against the latest published version, so a verdict that changed usually means the procedure changed — the document's own Version history is where to look, since the procedure is a document like any other.

What a new control starts with

A new control is never blank. Alchex writes its plan first — the checklist the control will be audited against — and the plan is what you edit. Plan changes apply to the control's definition document like any other edit, including while that document has a review pending: what an approver is deciding on is the copy submitted to them, so an applied plan change rides the next version rather than being refused.

A plan always has the same four parts:

  • What this control checks — a numbered list. Each check names one thing to verify, what evidence proves it, the red flag that gives it away, and when a shortfall is minor rather than serious. The numbering matters: it is what an audit run maps the gathered evidence onto, so an unnumbered check is a check no run can grade.
  • Benchmarks — the numeric defaults a check falls back on. Your own rules win wherever you have defined them; the benchmarks only fill the gaps.
  • Scope — what this control judges, and what a neighbouring control judges instead, so one gap is one finding rather than three.
  • Evidence to request — the records the audit will ask for.

Where the control was started from a clause in your framework, the plan is drafted from that requirement and the clause is recorded at the top of the definition. Where it was started from Governance → New with a name and nothing else, the plan is drafted from the name — the same four parts, written more generally, for you to narrow.

Drafting takes a few seconds and the page says so while it works. If it cannot be drafted — no allowance left, or the service is briefly unavailable — the control is still created, with the same four-part plan as a skeleton to fill in. You are never dropped into an empty editor.

Nothing here is fixed. The plan is a starting point, and the wording you leave in it is the wording the audit judges against, so edit anything that does not match how your organisation actually works.

The plan is written for people. It reads as a checklist an owner can review, not as an instruction addressed to a model — the audit run frames the model separately.

Changing the plan by asking

You can edit the plan by hand like any document. You can also ask for one part of it to change, with the assistant docked beside the control, and get a proposal about that part rather than a rewritten section.

Because the plan has named parts, the assistant can address them: "break-glass reviews should be within 1 business day, not 2" changes that benchmark and nothing else; "an unreviewed use should be a serious gap" changes that check's shortfall rule and leaves what it verifies, what proves it and its red flag exactly as written. Checks are counted the way you read them — the third check on the page is check 3, whatever number is typed beside it.

Six changes can be proposed this way: adding a check, changing one field of a check, removing a check, setting a benchmark, changing a scope line, and naming a source on the Evidence to request list. Anything else — reshaping several parts at once, rewriting the plan's prose — stays an ordinary document edit.

Three things hold, whatever is proposed:

  • It lands in the draft. Every card says so. Publishing is untouched: the change reaches the definition the audit reads only when you publish, from the control's page, exactly as above.
  • A part that moved is not written over. Each proposal carries the wording it saw. If a colleague changed that part first, the proposal is refused, you are shown what the control says now, and the assistant is offered the chance to re-read and propose again.
  • Older controls degrade honestly. A control written before plans existed has no numbered checks to name, so the assistant proposes an ordinary edit and says why, rather than addressing a structure that is not there.

The full behaviour of proposal cards — how they are decided, batched and commented — is in AI review and assistance.

The audit judges the published definition

This is the one thing to keep in mind while you write a control: a run reads the published version, not the draft in front of you. Editing the procedure and running it grades what was published last — nothing runs from a draft, and the Workflow panel says so if you try. Publishing follows the ordinary rules on Publishing — there is no separate route for controls.

What gets graded is the published version itself. A run reads the definition out of the version you published — the same one Version history opens and the same one a reader sees — rather than a separate copy kept for the auditor. There is nothing in between that could fall behind it, so what a run judges and what the published version says can only ever be the same words.

How an audit is started

A control is audited from its own procedure. Give the control's document a workflow: Check a requirement steps — one per obligation you want judged, in your own words, at the depth you want proved — and a Run on demand step. Press Build from the text in the Workflow panel and the builder proposes those steps from the procedure's own sentences, exactly as on any other document. Publish it. Then press Run now in its Workflow panel, and those checks are graded and filed as a report against this control. See Workflows in documents.

There is no separate audit surface on the control's page any more — no Run audit button and no audit rail. The workflow is the audit: each run's verdicts are read in the run's own receipts, on the Workflow panel's Runs tab, one finding per check step. A run you start also records a draft audit report on the control's record, and a check that names a clause updates where you stand on that clause on your compliance page — see A check that answers for a clause. A workflow decides nothing beyond that on its own.

Two limits are worth knowing. Only a run you start files a report: a workflow triggered by a record event never does, or it would file a fresh one every time a record passed through the procedure. And if the report cannot be written, the run itself is unaffected — its receipts are already saved.

Attaching a document does not turn it into a second record. Behind the attachment there is a pointer the audit reads the document through, and that pointer is plumbing rather than something you own: it does not appear in your Governance list, it is not something to name or curate, and your policy stays one row in one place. What you see on the control is the document itself.

Citing works exactly as it does in any document: the / palette's one Mention entry opens the reference picker, and you can pick several things — a document, a register, a rolling set — and insert them with one press of Insert N references, each landing as its own chip. See References.

Linked evidence is optional, never a prerequisite — a check can judge the control's own document with nothing attached. When you do want the checks to read further, know which reference kinds count: what a check can read is a document, an imported file, or a connector. A register or control reference is a perfectly good link — it just isn't something a check can pull records through, so on its own it will not widen what the checks can read.

Every run is kept: the Workflow panel's Runs tab lists them newest first, each with its outcome, the document version it ran from, and per-step receipts — a check step's receipt carries its verdict in full. The audit reports and evidence bundles earlier runs recorded remain on the control's record.

A control's instructions can also cite a rolling set of records — for example, everything a team holds — as one reference. Nothing about the set is stored: the audit expands it on the day it runs, judges what the set holds at that moment, and freezes the member list into the run's evidence bundle, each member marked with the set it came from. Two runs a week apart can therefore honestly record different members — that is the point of citing a set rather than the records one by one.

A record raised by an audit links back to the control that raised it. Open the non-conformity in the register and follow From audit in its properties — the control opens, with its procedure and its runs. See Risk records.

Deleting a control never destroys its verdict

Deleting a control removes its agent, its instructions and its wiring — not its audit history. A control that has been audited keeps its verdict on the compliance record: the clause it judged still shows the status, and the run records stay on the record. Removing an audited control's status from the record is a separate, deliberate act, and the product warns you with the consequence — which clauses lose their status — before it happens. Removed controls can be brought back from the compliance record's Activity ledger, where the removal is logged with who did it and a Restore that returns exactly what was removed. See The compliance record.

<!-- Reviewed 2026-08-26 (workflow manager P2 — the executor): the covered record routes gained post-commit workflow dispatch hooks (record created / submitted → runs; decisions → resume). No editor can place a workflow chip yet, so no published document declares a trigger and every documented flow behaves exactly as before. Nothing this page documents changed. --> <!-- Reviewed 2026-08-28 (fs_to_pg_203, evidence onto the versions spine): the covered code's evidence-version reads/writes now go through record_versions (snapshot.sourceRef) instead of the frozen evidence_versions table. Same rows, same answers — nothing this page documents changed. -->