Skip to content

Build1 publisher3 min readPublished

A compliance agent reads its permission table and stops one transition short of signing

The EU AI Act wants AI system logs kept for six months and the GDPR wants personal data dropped when it stops being necessary. A challenge project stores the workflow that settles that gap as content both an agent and a person query.

The Engineer · Build desk

Illustration accompanying A compliance agent reads its permission table and stops one transition short of signing

What happened

  • A compliance project targets two rules that conflict: the logs the AI Act requires hold personal data by construction, and the GDPR limits how long personal data may be kept.
  • Querying the dataset returns the workflow's own shape, reported as five states, two transitions an agent may make and three reserved for a person.
  • Every transition names the actor permitted to make it, with the agent allowed to start looking and to attach the sources, and the other three moves human only.
  • One function in the agent repo computes the permitted moves for whichever actor asks, so the agent and the person share one rule set.
  • The signing desk works straight off the dataset, listing whatever it says is in review with both clauses verbatim and the agent's steps timestamped and attributed.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • constraint Permissions are stored as content, so widening what the agent may sign takes no deploy and no code review; it is an edit in the same Studio as the clauses.
  • capability An auditor can pull the permission table from the public API and see which moves are human only, without being given the agent's source.
  • cost Adoption costs schema work up front: a human-only move is only enforceable if the dataset already lists the fields that move requires.

The table itself is four document types. `workflow` holds the states and transitions, and `workflowState` is a state. `transition` carries `from`, `to`, `actor` and the fields a move requires, and `transitionRecord` holds what actually happened. A conflict document carries its `state` and a `history[]` of records [10].

Run the gate as the agent and the review-to-decided move comes back refused, on the grounds that signing the decision is reserved for a person [7]. Run it as the human and the same transition comes back "CANNOT Sign the decision - needs rationale, decidedBy, decidedAt" [8]. The agent is refused for lack of authority; the person is refused for missing fields.

The two moves open to the agent are starting the search and attaching the sources [6], so the furthest it can push a conflict on its own is into review [1].

The author wrote that the boundary "is not a sentence in a system prompt that a model can reason its way around on a bad day. It is a row in the dataset the model queries, rendered in the same Studio a person uses, enforced the same way for both" [13]. The first half holds: a row survives a rewritten prompt, and an auditor can read it without reading any code. The second half is the part I would want to test. The check runs inside the agent's own repo [9], and the write-up does not say whether the dataset refuses a state change written with the agent's credentials. On the human side the post describes a different control: the signing app requires a Sanity login, deliberately, since it writes signed decisions and "an anonymous signature is not one" [12].

The signature is typed by hand, because the App SDK has no current-user hook [14]. The author calls that the right accident. They wrote that "a name that fills itself in is not a signature, and the whole reason the field exists is that a person chose to put their name against a reading of the law" [15]. I would still store the login identity next to the typed one. The record does hold both halves of the move in one write. Signing writes the decision and its transition record in a single edit, so the state cannot move without the evidence of who moved it [11].

The workflow exists to manage the gap, and what the compliance file has to hold is the period someone picked and the reasoning they put their name to [2].

This was built with Claude Code in the desktop app in one sitting [19], as a submission to the Sanity Challenge, Path Two [20]. It is aimed at whoever ends up holding the compliance file at a small company, usually a founder or a lone engineer rather than a legal department [18]. Two conditions have to hold for the pattern to carry into a larger shop. The forbidden moves have to be few enough to name as rows, and the store has to refuse a write by actor instead of trusting the caller to ask first. The repo runs with no credentials at all: `npm install && npm run ask -- --workflow` [17].

What to watch

  • Whether the project exposes an edit history for the workflow document, so a widened agent permission is visible after the fact.
  • Whether the signing desk gains a current-user hook, and whether it keeps the typed name alongside the login identity.
  • Whether any auditor treats a transitionRecord as evidence of who chose a retention period.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories