An agent's legal exposure, from the first line of code to production
Author
Sean McDermottCo-Founder and CEO, UnGovr
Date
Series
Agents and the law they act under
Legal information, not legal advice. This paper describes the law as written and dated; it does not apply it to any system. The notice in the footer says what that means.
Abstract
No law requires an organisation to limit where its software operates. Many limit it anyway, for the reason companies decline to sell in some countries: a narrower legal exposure is one that counsel can read, verify and enforce. This paper describes that practice for agentic software. An organisation declares what an agent does and in which jurisdictions, has the declaration checked against the law, records a decision on each finding, and holds the software to the declaration while it is written, in continuous integration and in production. One sample application is followed throughout.
1Introduction
1.1 Why draw a boundary the law does not require
Software that can reach anyone is exposed to the law of every
jurisdiction it reaches. For an AGENT with a browser, a mail
tool and a payment tool, that is all of them by default. No legal team
can read, verify and keep current a position against the whole world's
law, and a position nobody has read is not one counsel can sign.
So counsel does for software what it has always done for products: it
narrows the exposure to something that can be managed. A company that
does not sell in a country has decided not to take on that country's
law. A declared profile is the same decision made for software. The
organisation chooses the jurisdictions in which its software, and the
parties it acts for and reaches, may be present, and the activities it
may perform there. Inside that boundary counsel has read the law and
recorded a position on it. Outside it nothing has been read, so the
software does not go there.
Optional in law, deliberate in practice
Nothing in this paper is required by law. It describes legal risk
management: trading reach for a compliance position small enough to
verify and to enforce, and then holding the software inside it.
The method has four steps, and the rest of the paper follows them.
Declare. Two lists, kept in the repository and versioned: what the software does, and the jurisdictions it operates in.
Audit. A lint matches the two lists against the law library and returns findings, each with its citation and its date.
Decide. Every finding gets one of four outcomes, with an author, a reason and a scope.
Hold. The same declaration is checked while the code is written, in continuous integration, and in production, where an action outside it is logged, alerted on or blocked.
1.2 Who should read this
If you maintain
You are asked to
Sections
An agent or application of your own
Declare what it does and in which jurisdictions, decide each finding with its scope, and agree what happens when the product moves
3 to 5
An agent gateway, proxy, policy engine or governance toolkit
Take a declared profile as a signed, versioned input, and offer log, alert and block for each rule
4, 5
An agent framework, harness or tool server
Say what kind of act each tool performs, and what a project does by default
Jurisdiction. A body of law together with the authorities and courts that apply it. LexLint keys every law to one jurisdiction at one of four levels: supranational (the EU), national, subnational (a US state, a province, a Land), or local (a city).
In principle a jurisdiction can be as small as any government body that
makes law. In practice the law that binds software is made at the
national and subnational levels, with the European Union above its
member states, and a declaration is written at that granularity. The
exceptions are a small number of cities with software law of their own,
which the law library lists by name.
Declaration, profile, finding. A declaration is the file. The
profile is what it states: a set of activities and a set of
jurisdictions. A finding is one instrument in the law library that the
profile matches.
1.4 What this paper depends on
A boundary drawn in jurisdictions can only be held by a system that
knows which jurisdiction each party to a call is in. That is the record
the companion paper, Whose law was that?,
argues the law's reporting deadlines already need. An operator who has
done that work for the sake of the deadlines has, as a by-product,
everything a runtime boundary needs.
2Background: the sample application
The example through this paper is Pennant, the sample app of
LexLint for legal teams.
Pennant is an invented Irish invoicing company. Its collections
AGENT chases late invoices by email and text message, drafts each
reminder with a language model, and answers the customer's replies in a
chat window. Its findings below are a real lint of that declaration.
Its people and their decisions are invented.
In the handbook's terms Pennant is an OPERATOR. Its model
provider is a MAKER, the people it chases are
USERS (affected persons and data subjects, not
principals), and the mail and phone networks it sends through are
COUNTERPARTYS. The
cheatsheet maps each
of those to the role a statute names: deployer and controller for
Pennant, provider for the model's maker, data subject for the
person chased.
3Method: declare, audit, decide
3.1 Declare what the software does, and in which jurisdictions
A declaration is two lists: what the software does, and the
jurisdictions it operates in. It is a statement by the people
responsible for the software, kept in the repository, versioned, and
never inferred from the code.
A declared jurisdiction brings its parents. Ireland brings the European Union, and Colorado brings the United States. It never runs downward: a declared country does not bring its states or its cities.
What is left out is part of the statement. Pennant's declaration covers Ireland, the United Kingdom and the United States, with California and Colorado. Every other jurisdiction is out, and counsel signs that as well. A jurisdiction left off is not passed. It is unlinted.
It has versions. Each one is the unit counsel agrees and the software is checked against. Pennant is on its third: the second added the United States and California, the third Colorado.
A lint matches the two lists against the law library and returns
findings. The match is fixed and rule-based. No model reasons about the
law at that step, so the same declaration against the same law library
always returns the same findings.
Pennant's run 3, on , returned
110 findings.
Kind
What it means
Findings
Obligation
A specific instrument binds the declared profile now
77
Pending
An instrument that cannot be said to be in force today: proposed, not yet in force, or blocked by a court
23
Coverage
A note about what was not reported. Never a pass
10
Jurisdiction
Findings
California
29
United States
26
European Union
20
Ireland
17
United Kingdom
9
Colorado
9
Three rules bound what a run can claim. A jurisdiction the law library
holds no current data for is a warning, never a silent pass. Every
finding carries its citation, its as-of date and a staleness flag. And
the passing state is "no basic issues found": the word "compliant" does
not appear in the output, because a lint cannot know that.
Each finding is structured, cited and specific enough for a coding
agent to map onto the code it is working in. That is the use of a lint
with a language model at the keyboard: the model is not asked what the
law is. It is handed the law that matched and asked where in the code
each finding lands, and whether the code already answers it.
One full run, end to end
shows that on a small crawler.
3.3 Decide: four outcomes for a finding
A list of 110 findings is not a plan. Triage turns it
into decisions, and there are four.
Figure 1. Each finding goes to one of four outcomes. Two set it aside, at different scopes. One records where the code already answers it. One is work.
Each outcome below is shown on one finding from Pennant's run, as
the lint returned it: the instrument, its jurisdiction and citation,
the declared activity it matched on, and the first thing it asks.
If you are a large frontier developer (a frontier developer whose group had annual gross revenues over $500,000,000 in the prior calendar year), write, implement and publish on your website a frontier AI framework describing how you define and assess catastrophic-risk thresholds for your frontier models and apply mitigations, and review that framework at least once a year
Decision. Pennant trains no models, so it is not a frontier developer. Dismissed, with that reason.
How far it reaches. Every app the company ships, because it is a fact about the company. It is reopened the day the fact changes.
If a reasonable person interacting with your companion chatbot could be misled into believing they are talking to a human, issue a clear and conspicuous notification that the chatbot is artificially generated and not human
Decision. Counsel's reading is that a chat about an unpaid invoice is not a companion chatbot. Dismissed, with the reason.
How far it reaches. This app only. The company's next app gets its own decision.
Obtain the called party's prior express consent before initiating any call or text to a wireless number using an automatic telephone dialing system or an artificial or prerecorded voice, and before delivering a prerecorded-voice message to a residential line, unless the call is for an emergency purpose.
Decision. An engineer confirms it: consent is taken when the invoice is created and a reply of "stop" ends texts, in agent/channels/sms.py. Acknowledged, with where it is handled.
How far it reaches. This app, as the code stands. The finding does not disappear. An obligation applies whether or not it has been met, so it returns on every run with its answer beside it.
Clearly and conspicuously disclose that the user is interacting with a bot, which is the statute's safe harbor
Decision. Counsel confirms the obligation. The reply chat does not say it is a machine, so its opening line changes before the United States launch.
How far it reaches. Open until the change ships. Then it becomes the third outcome, with the file that answers it.
The same outcomes take the rest of the run. Findings addressed to
public bodies and to law enforcement agencies are set aside for the
whole company, which is not a public body and sells to none; the first
public-sector customer undoes that. Colorado's
HB 24-1147, Candidate Election Deepfake Disclosures is set aside for this app, which
writes no election material. California's
text message law
is handled in the same file as the federal one. And AI Act, Article 50 (transparency obligations for AI systems and synthetic content)
asks for the same disclosure as the California finding, so one change
answers both.
"Needs work" has two other forms. One is a question of law, which is
counsel's: is a payment reminder direct marketing under the
United Kingdom's
and the European Union's
rules? It is marked as under investigation, routed to a person, and
acted on by nobody else. The other is a gap in the law library, stated
as one: Colorado's communications law has not been researched.
Unlinted is not clean, so it is checked by hand.
The fourth outcome is a workflow between two readers. Counsel sees each
item with the laws behind it and records a decision: investigating,
confirmed, or dismissed with a reason. Engineers see the same items as a
worklist grouped by where the work lives: a code change, a document to
draft, a question for counsel, or something a customer needs. A
decision is visible to everyone on the project, on that run and every
later one until it is changed, and the earlier decision stays in the
history.
Two limits on what a dismissal is. It is counsel's decision, signed, and
not a statement by the lint that a law does not reach the app. And it is
a recorded fact with a date, which is what lets it be changed later:
when the company, the app or the law moves, the decision is found and
reopened rather than rediscovered.
4Holding the software to the declaration
4.1 One declaration, checked three times
The declaration counsel and engineers agreed is one version of one
file. It can be checked at three moments, and the checks get stronger as
the software gets closer to a real person.
Figure 2. The first two checks read code and a declaration. The third reads each action as it happens, and needs every party's jurisdiction to do it.
When
What is checked
What a mismatch looks like
Status
While the code is written
The declaration against the law library, and the findings against the code
A finding with nothing in the code that answers it
Available today, as the lint in a coding agent
In continuous integration
Each commit against the declared activities
A commit adds voice calls, and voice processing is not in version 3
The first two are static analysis. They read code and a declaration,
and they need nothing from the running system.
The third is different in kind. A runtime check against declared
jurisdictions is only possible if every action arrives with its
parties' jurisdictions: the recipient's, the counterparty's, the
principal's. Those are the fields the companion paper says the record
must carry anyway, and it says why they cannot be worked out from a
network address.
4.2 An action outside the profile
Pennant's customers are small Irish businesses, and one of them has
invoiced a client in Brazil. The invoice goes unpaid. At 14:02 the
collections AGENT prepares a reminder text.
What the runtime sees
Value
How it was known
The tool
send_text
The tool's own manifest, which marks it as automated outreach
The activity
Automated outreach
Declared in version 3
The recipient's jurisdiction
Brazil
A declared fact: the client's country on the invoice. The phone number's country code agrees with it
The declared jurisdictions
The European Union, Ireland, the United Kingdom, the United States, California, Colorado
Declaration version 3
The verdict
Refused: Brazil is not in version 3
The declaration
The activity was declared. The jurisdiction was not. So nobody at
Pennant has ever read what Brazil's law asks of a company that
texts a person there about a debt.
The law library holds 7
privacy provisions in force for Brazil, the
Lei Geral de Proteção de Dados Pessoais
(the General Personal Data Protection Law, LGPD) among
them, with its own security-incident notification and its own rules on
international transfer.
None of that was in Pennant's 110 findings, because
none of it was asked for. Whatever the law library has not researched
for Brazil would come back as a coverage note, as Colorado's
communications law did in section 3.3.
The same check works on the other axis. An AGENT that tries
place_call to a debtor in Colorado is inside the declared
jurisdictions and outside the declared activities: a call is voice
processing, and version 3 does not include it.
Whether it is the jurisdiction or the activity that falls outside the
declaration, the refusal leaves evidence: the time, the version of the
declaration, the jurisdiction and how it was known, the tool, the work,
the decision. That is the record the companion paper describes, written
at the moment it is cheapest to write.
4.3 What a runtime boundary may claim
A runtime check that refuses an out-of-profile action has applied a
technical measure. It has not made anyone compliant.
The handbook's classification of requirement lines says how much of the
law a request path can touch at all. Of 2,430 lines in force
classified by , out of the
6,073 the law library holds in force across four
topics, a control on the request path can prevent the conduct in
37%, recognise the event in
15%, and supply the evidence in
13%. The remaining
35% attach to conduct the path never
sees: lawful-basis determinations, contracts, registrations, security
programmes, training. The classification is incomplete, so those
figures are a floor. How a runtime engine takes in legal constraint data has the reading.
Three limits are structural. Intent is not on the wire. A claim is
checked for its presence and its issuer, never for its truth: the
gateway knows a consent claim was carried, not that consent was given.
And the record the boundary keeps is itself evidence with duties of its
own.
5When a request leaves the profile
5.1 Three protocols, by legal risk
An out-of-profile action is not always an attack, and rarely one. More
often the product changed, a customer did something new, or the data
was wrong. The response should match the legal risk of the action, and
three protocols cover the range.
Figure 3. Three protocols in rising order of legal risk. Whatever happens to the task, every one ends in the same loop.
Protocol
When it fits
What happens to the task
What happens next
Log
The action does nothing to a person that cannot be undone, such as reading a public page published in a jurisdiction outside the profile
It proceeds, and the event is recorded with its evidence
Reviewed with the next declaration review
Alert
A declared activity reaches a new jurisdiction within tolerances counsel agreed in advance
It proceeds, and counsel and security are told the same day, with the event
Counsel answers within an agreed period: add the jurisdiction, or close the path
Block
The action contacts, decides about or moves data about a person in an undeclared jurisdiction; or the activity itself is undeclared; or the law library holds no research for that jurisdiction
It is refused and recorded. There is no override
A security and legal review: was this a product change nobody declared, a data error, or misuse?
Pennant's text to Brazil is the third kind. It is outreach to a
person, and a sent text cannot be recalled. It is blocked and reviewed.
5.2 What sets the level
What sets the level is the legal risk of the action, not its technical
shape. Five things move it.
Factor
Lower risk
Higher risk
What the action does to a person
Reads something public
Contacts them, decides about them, or moves their data
Whose jurisdiction is outside the profile
A COUNTERPARTY'S: a site that was read
A USER'S: a person who was reached
What is in the payload
No personal data
Sensitive categories, or a minor's data
What the law library holds for the jurisdiction
Researched law, already read for a neighbouring jurisdiction
Not researched, which is not the same as no law
Whether it can be undone
A draft, a queued job
A sent message, a payment, a published page
5.3 The loop every protocol ends in
Whatever happened to the task, an out-of-profile event is evidence that
the declaration and the product have drifted apart. At minimum, one
process follows, and it takes weeks, not minutes.
The event goes to counsel with its evidence: what was attempted, for whom, in which jurisdiction, and how the jurisdiction was known.
If the business wants the new jurisdiction, it is added to a draft of the next version of the declaration, and the lint is run on the draft. For Pennant that returns Brazil's findings for the first time.
The findings are triaged into the four outcomes of section 3.3.
Engineers ship the work the findings call for, and the checks in continuous integration run against the draft.
Counsel signs the new version.
Production loads the new version. The same text to Brazil now passes, and leaves the same evidence.
Until the last step, the rule for that jurisdiction stays where its
risk put it. A new version can be run in log mode first, recording what
it would refuse, before it is enforced. There is no path by which a
single engineer or a single request widens the boundary: a change goes
back to counsel and comes out as a version.
6Recommendations
The changes, by what you maintain.
If you maintain
Change
So that
An agent or application of your own
Declare activities and jurisdictions. Decide each finding as one of four outcomes, with its scope. Agree the protocols for an out-of-profile event
The organisation knows what it has decided, who decided it, and what happens when the product moves
An agent gateway, proxy, policy engine or governance toolkit
Take a declared profile as a signed, versioned input. Offer log, alert and block for each rule, and count out-of-profile verdicts
A boundary counsel agreed can be held in production, and its misses are visible
An agent framework, harness or tool server
Declare what kind of act each tool performs. State which activities a project performs by default and which record fields it writes
A policy can refuse an activity, and the people who deploy the project can answer for it
7Limitations
This paper does not say that any law requires a declared profile, a
triage record or a runtime boundary. It describes one way to manage
legal exposure once the parties and jurisdictions of a task are known.
It does not say that a declaration, a clean lint or a runtime boundary
makes software compliant. A lint passes as "no basic issues found". An
engine loaded from the same data should say no more than the lint does.
It does not describe only what exists. The lint in a coding agent and
the portal's record of counsel's decisions are available today. The
checks for continuous integration and production are in development,
and so is a decision that holds for a whole company and that later apps
inherit: today a decision is recorded for one project.
Pennant is invented. Its findings are a real lint of its
declaration; its people, their decisions and the text to Brazil are an
illustration. The dismissals in section 3.3 are written as its
counsel's reading and are not LexLint's view of what those statutes
reach.
LexLint's interest in this argument
LexLint publishes the law library and the lint this paper draws on,
and is developing the checks for continuous integration and production
described in section 4. The examples come from those tools for that
reason. The method does not depend on them.
8Conclusion
A declared profile turns an open-ended exposure into a bounded one that
counsel has read. The boundary is drawn in activities and
jurisdictions, each finding inside it carries a recorded decision, and
the software is checked against it at three moments. When a request
leaves it, the response follows the legal risk, and the boundary moves
only by a new version that counsel has signed.
None of this is required by law. It is how an organisation keeps its
legal position small enough to verify and to enforce, in the way a
company that declines to sell in a country keeps that country's law off
its desk. What it rests on is not optional: a system that knows the
parties to each task and the jurisdiction each one is in, which is the
subject of the companion paper,
Whose law was that?.
References
Every law named in this paper, then the handbook documents and other
sources it draws on.
Sean McDermott is
Co-Founder and CEO of
UnGovr, which publishes LexLint: a
library of the law that reaches software, and a lint that reads a project
against it. Corrections and comments are welcome at
hello@ungovr.org.
UnGovr is an Associate Member of the Linux Foundation, of the Agentic AI Foundation and of the Open Secure AI Alliance. While UnGovr supports the mission of all three, none of them reviews, certifies or endorses LexLint, its findings, or this paper.
Written by Sean McDermott (with AI assistance) using the LexLint law library, which supplied every legal instrument, status and date on these pages.
Every law named here links to its summary page on lexlint.io, translated to English (if needed) and restructured to a standard format for human and code use.