Agent Wranglers

Scope and ownership Required

Keep a register of every duty that applies

Keep one register in the repository of every law, standard and contract duty you screened. Give each its decision, reason, owner and next review date.

How to do it

Write the register as data, such as YAML. List every law you considered, also the ones that do not apply, with the fact that rules each one out. Link each entry to its official text, such as the EUR-Lex page. Give each entry a review date no more than 12 months ahead. Record who checked the decision, ideally a lawyer, and when.

Example

- id: gdpr
  name: General Data Protection Regulation (EU) 2016/679
  source: https://eur-lex.europa.eu/eli/reg/2016/679/oj
  applies: true
  reason: We process personal data of customers in the EU.
  owner: maria.lind
  reviewed_by: external counsel, 2026-09-14
  review_by: 2027-09-01
- id: cra
  name: Cyber Resilience Act (EU) 2024/2847
  source: https://eur-lex.europa.eu/eli/reg/2024/2847/oj
  applies: false
  reason: We sell only a hosted service and ship no app, agent or device.
  owner: maria.lind
  reviewed_by: external counsel, 2026-09-14
  review_by: 2027-09-01
import { readFileSync } from 'node:fs';
import { parse } from 'yaml';

const REQUIRED = ['id', 'name', 'source', 'applies', 'reason', 'owner', 'reviewed_by', 'review_by'];
const today = new Date().toISOString().slice(0, 10);
const latestReview = new Date(Date.now() + 365 * 86_400_000).toISOString().slice(0, 10);
const problems = parse(readFileSync('compliance/obligations.yaml', 'utf8')).flatMap(entry => [
  ...REQUIRED.filter(field => entry[field] === undefined || entry[field] === '').map(field => `${entry.id}: missing ${field}`),
  ...(entry.review_by < today ? [`${entry.id}: review overdue since ${entry.review_by}`] : []),
  ...(entry.review_by > latestReview ? [`${entry.id}: review more than 12 months ahead`] : []),
]);
if (problems.length) { console.error(problems.join('\n')); process.exit(1); }
import datetime, sys, yaml

REQUIRED = ["id", "name", "source", "applies", "reason", "owner", "reviewed_by", "review_by"]
today = datetime.date.today().isoformat()
latest_review = (datetime.date.today() + datetime.timedelta(days=365)).isoformat()
problems = []
for entry in yaml.safe_load(open("compliance/obligations.yaml")):
    problems += [f"{entry['id']}: missing {f}" for f in REQUIRED if entry.get(f) in (None, "")]
    if str(entry["review_by"]) < today:
        problems.append(f"{entry['id']}: review overdue since {entry['review_by']}")
    if str(entry["review_by"]) > latest_review:
        problems.append(f"{entry['id']}: review more than 12 months ahead")
sys.exit("\n".join(problems) or None)

How to check

A script in the build fails when an entry lacks a decision, reason, owner, source link, reviewer or review date. It also fails when a review date has passed or lies more than 12 months ahead.

For agents: if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in Based on the Agent Wranglers compliance playbook: https://agentwranglers.se/playbook/compliance/scope-and-ownership/obligations-register.