ProjectOpen-source tool

Compliance Agent: Explainable Policy Copilot

A compliance tool should not pretend it can know yes or no.

Documented

Why I made it

I made this to explore a more honest compliance workflow: narrow the review, show the evidence, and leave the decision with the person accountable for it.

Most legal-tech tools answer yes or no, which is the one thing they cannot actually know. Compliance Agent screens instead: it reads a policy against written rules, flags the passages worth a second look, and shows the sentence behind every flag so a person can check its work.

Tools: LangChain · ChromaDB · Python · YAML Reasoner

Ask most legal-tech tools whether a policy is compliant and they answer yes or no. That is the wrong answer to give, because it is the one thing the tool cannot actually know — and it is the answer a lawyer is paid to make.There are narrow exceptions — a rule like "the policy must name a data protection officer" really is a yes-or-no question. Those are the minority, and they are the ones worth automating first.

Compliance Agent does something narrower. It reads a policy against a set of written rules, flags the passages that look like a problem, and shows you the text it based each flag on. A person still decides.

Why screening, not deciding

A compliance review is mostly reading. Someone opens a forty-page policy, holds a regulation in their head, and looks for the places where the two do not line up. It is slow, and it is slow in a boring way: the hard judgement calls are rare, and most of the time is spent finding the paragraphs worth judging.

That is the part worth automating. Not the decision — the search.

The distinction matters more than it sounds. A tool that answers "compliant: yes" has to be right, and you have no way to check it. A tool that says "this clause looks like it is missing a consent basis, here is the sentence, here is the rule" can be wrong and still save you an hour, because you can see immediately whether it is wrong.

How it works

Three steps, none of which involve asking a model for a verdict.

It reads the regulation. GDPR, the EU AI Act, whatever you point it at, chunked and indexed so passages can be retrieved by meaning rather than keyword.Retrieval by meaning finds "we may share your information with partners" when you search for third-party disclosure, even though the two share no words. Keyword search does not.

It compares versions. Policies are edited, not written. When a new version arrives, the agent checks whether the meaning moved or only the wording did — the same engine as LegalDrift. A rewritten paragraph that means the same thing is noise. One that quietly drops an obligation is not.This is the harder half, and it is a separate tool: LegalDrift runs a statistical test over the two versions rather than diffing the text.

It checks the rules. This is the part that stays deterministic.

The rules are written down

Instead of asking a model "is this GDPR compliant?", you write what you are checking for:

rules:
  - id: "GDPR-CONSENT-001"
    type: "obligation"
    description: "Consent must be obtained before processing personal data"
    predicates:
      - name: "has_consent"
        condition: "document contains explicit consent language"
        weight: 1.0

The model never sees the rule. It only answers one small question — does this passage match this condition — and returns a confidence score.weight decides how much one predicate counts toward its rule. A rule with three predicates at 1.0, 0.5 and 0.5 needs more than just the first to fire. The logic that turns those scores into a flag is ordinary code you can read.

That split is the whole design. When a flag looks wrong, you can tell whether the rule was badly written or the match was bad, and those have different fixes.

Every rule is one of three kinds, and the kind decides what a match means:

What a match meansThe same evidence means different things depending on the kind of rule it matched.
Rule typeEvidence foundEvidence missing
ObligationSatisfied — nothing to flagFlagged: the policy is missing something it needs
PermissionFine — the policy allows it explicitlyNoted, but not a violation on its own
ProhibitionFlagged: the policy allows something it should notClean

Rules live in version-controlled files, so a team's accumulated reading of a regulation becomes something they own and can review, rather than something locked in a prompt.The honest limit: two people can write the same rule and disagree about what counts as evidence for it. The file makes that disagreement visible, which is the most it can do.

What you get

Not a score. A report:

Every flag is a link back to the text. If you disagree with one, you can see why the tool thought it, which is the only way a screening tool earns a second use.

What it will not do

It does not give a legal opinion, and it will not be pushed into giving one.

It is deliberately cautious: it would rather flag something harmless than stay quiet about something real, because a false flag costs a minute and a missed one costs considerably more. Expect to dismiss some flags. That is the tool working, not failing.On the bundled sample it flags 5 of 10 rules. Two of those five are usually judgement calls rather than real gaps — which is roughly the ratio I would expect on a real policy.

And it is only as good as the rules you write. A rule pack that misreads a regulation will confidently screen against the wrong thing — which is exactly why the rules are plain text in a file you can review, rather than behaviour buried in a model.

Code and rule packs: OsamaMoftah/compliance-agent.


Related notes