microsoft/regulation-monitor
Use when the user asks to set up, run, or check a scheduled regulation, law, or regulatory-guidance monitor or tracker — triggers include "set up a regulation tracker for X", "monitor [regulation] for me", "run my regulation monitor", "what changed on [regulation] this week", or an unattended scheduler invoking a saved profile. On first invocation walk interactive setup (topics, jurisdictions, cadence, delivery), auto-discover the top authoritative sources per topic, and STOP for user confirmation before any monitoring. On subsequent runs visit only the locked source list plus user seeds, classify items, flag team-relevant ones via a WorkIQ-derived keyword match, and render a self-contained HTML dashboard with client-side sortable columns. Do NOT use for one-off legal research, reading a single document, computing compliance liability or filing position, or non-regulatory news monitoring.
npx skills add https://github.com/microsoft/cat-agent-skills --skill regulation-monitor
This skill is deliberately bounded and confirmed. It does not run
open-ended web searches every run. Instead, at setup:
sources per watch topic (regulators, official trackers, reputable
trade press).
until the user has confirmed the list.
their own seed sources on top.
Every subsequent run visits only those sources. A tightly-bounded
fallback web search (at most one query per topic, capped result count,
allowlist-filtered) is used only when a locked source is silent for a
topic in the window.
If config.json for the requested profile does not exist, walk the user
through setup:
pillar-ii.keywords the sweeps should look for.
global.page, or "inline only".
**This is an interactive checkpoint. Run a small discovery pass to
identify candidate sources, then present them and stop. Do not start
the monitoring sweep (Step 5) until the user has explicitly confirmed
the source list.**
For each watch topic the user configured, propose up to **5 authoritative
sources** (default target 5; use fewer if the user asks or if the domain
has fewer canonical sources).
Preference order (pick the strongest 5 that exist for the topic):
Examples: OECD's Pillar Two page, the European Commission's page for
the AI Act, HHS OCR for HIPAA, EDPB for GDPR, ISSB for sustainability
disclosure.
jurisdictions in scope. Examples: Federal Register, EUR-Lex, UK
legislation.gov.uk, state legislature bill pages.
page for the topic. Examples: OECD, UN, BIS, ISO, NIST (AI RMF,
cyber), WHO/EMA (health), ILO (labor), FSB (financial stability).
domain. Examples: Tax Foundation and MTC/NCSL for tax; IAPP and
Future of Privacy Forum for privacy; Stanford HAI, Brookings AI, and
the Ada Lovelace Institute for AI; ISSB and EFRAG for sustainability;
SHRM and EPI for labor; KFF for healthcare policy.
firms that cover the domain (public URLs only, never subscriber
content). Examples: KPMG / EY / PwC / Deloitte / BDO insight pages
for tax and financial regulation; DLA Piper, Hogan Lovells, Wilson
Sonsini, Cooley for tech / privacy / AI; Ropes & Gray for healthcare;
Littler and Ogletree Deakins for labor.
Match the mix to the domain — do not force tax-style sources onto a
non-tax topic.
Trackers and firm alerts are pointers, not authoritative sources.
Sources in categories 4 and 5 are useful as indices to find primary
regulator/court/legislative material, but any item you record must cite
the underlying official document or announcement (regulator page,
official journal, court opinion) as its source_url — not the tracker
or firm alert that linked to it. If you only have the tracker link and
can't find the primary source, drop the item.
How to find them: for each topic, do a short bounded discovery
pass — one to three focused web searches against the reputable-domain
allowlist in references/sources-and-taxonomy.md — just enough to
identify canonical topic pages (not the regulator's home page). This
discovery pass is separate from the monitoring sweep and must be small.
Present them and STOP. Show the shortlist to the user and wait
before doing anything else:
> "Before I start monitoring, here are the 5 authoritative sources I'd
> watch for Pillar II:
> 1. OECD — Pillar Two: <url>
> 2. European Commission — Pillar Two implementation: <url>
> 3. HMRC — Multinational Top-up Tax: <url>
> 4. Tax Foundation — Global minimum tax tracker: <url>
> 5. KPMG — BEPS 2.0 tracker: <url>
>
> Want me to swap any out? And do you have any of your own sources
> (regulator pages, internal trackers, subscription-free trade alerts,
> etc.) you want me to add on top of these?"
Wait for the user's reply. The user may:
with the constraint they gave.
seed_sources_by_topicunder the appropriate topic key. Seed sources are not counted
against the "top 5" — a topic can end up with 5 auto-discovered plus
N user seeds. A seed that spans multiple topics is added under each
relevant topic key.
Do not skip this confirmation, even on a re-setup. If the user
later adds a topic, repeat this checkpoint for the new topic before
touching the sweep.
Derive a light org profile from WorkIQ and show it for confirmation:
workiq_get_my_profile → job title, department, officeworkiq_get_my_manager → manager and their department (context only)workiq_get_relevant_people (limit 10) → likely function-areacollaborators
Propose a function_area_keywords list (5–15 words: department name and
variants, the user's job function, key collaborator team names, obvious
topic proxies). The user edits and confirms.
If WorkIQ is unavailable on the current platform, ask the user for
function_area_keywords manually. The rest of the skill works unchanged.
Write config.json:
{
"profile_name": "pillar-ii",
"watch_topics": [
{ "key": "pillar-two", "name": "OECD Pillar II / GloBE",
"keywords": ["Pillar Two", "GloBE", "global minimum tax",
"IIR", "UTPR", "QDMTT", "DMTT", "top-up tax"] }
],
"jurisdictions": ["global"],
"sources_by_topic": {
"pillar-two": [
{ "name": "OECD — Pillar Two",
"url": "https://www.oecd.org/tax/beps/pillar-two-model-rules-in-a-nutshell.pdf",
"kind": "regulator" }
]
},
"seed_sources_by_topic": {},
"cadence": "weekly",
"window_days": 7,
"runtime_budget": {
"max_items": 40,
"max_fallback_searches": 2,
"max_fetches_per_source": 2
},
"delivery": { "type": "email", "to": ["[email protected]"] },
"workiq_context": {
"captured_at": "2026-07-23T11:00:00Z",
"department": "Global Tax Policy",
"job_title": "Director, International Tax",
"function_area_keywords": ["Pillar Two", "GloBE", "international tax",
"transfer pricing", "top-up tax"],
"collaborator_teams": ["Transfer Pricing", "Tax Controversy"]
},
"last_run_at": null
}
config.json for the profile.last_run_at (if set) to now, else the pastwindow_days.
if it looks wrong (interactive runs only).
Sweep proceeds in this order and stops when the budget is met:
sources_by_topic[topic] andseed_sources_by_topic[topic] for each topic.** web_fetch each URL.
Extract items dated within the window.
max_fetches_per_source (default 2). If a source's index pagelinks to individual items, follow at most that many per source.
(auto-discovered + user seeds) returned zero items in the window. At
most one web_search per topic, at most max_fallback_searches
total across the run (default 2). Filter results by the reputable-
domain allowlist. Discard non-matching results.
max_items is reached (default 40). Prefer regulatorsources > tracker sources > firm alerts when trimming.
Runtime budget defaults, all configurable in config.runtime_budget:
max_items: 40 — total items recorded per run.max_fallback_searches: 2 — web_search calls per run.max_fetches_per_source: 2 — items followed from one source's index.Rules that always apply:
more authoritative source (regulator > tracker > firm alert).
Record, for every item:
global /local: <name>.
proposed / in-consultation / passed /regulatory-guidance / in-force / litigation / withdrawn.
(http/https/mailto only; other schemes are dropped at render time).
Stage inference guidance is in references/sources-and-taxonomy.md.
For each item, set relevant_to_your_team to true if any
workiq_context.function_area_keywords phrase appears (case-insensitive)
in the item's title, summary, or matched topic keywords. Otherwise
false.
This is a soft highlight, not an impact rubric. The dashboard uses it
to sort and badge; the skill never says "this affects your business" —
that is a human judgment.
working/regulation-items.json as a JSON object with theshape {"items": [ ... ]} (not a bare array). Each entry follows the
Step 6 schema.
python scripts/build_dashboard.py --config config.json --items working/regulation-items.json --output output/regulation-dashboard.html
The dashboard is a single self-contained HTML file — KPI tiles (total
items, count per topic, team-relevant count), a table color-coded by
stage with client-side sortable columns (click any column header, or
focus and press Enter/Space, to sort), a team-relevant badge on flagged
rows, and every row linking to its primary source.
the top team-relevant items (title, jurisdiction, stage, date). If a
topic produced no items, say **"No significant developments this
period"** for that topic. Do not pad, do not speculate.
typeis email, send the HTML dashboard as an attachment to the addresses
in to. The pre-authorized recipient is the user themselves. Any
additional recipient requires explicit user confirmation on an
interactive run and is never added on an unattended run.
last_run_at = <now-ISO>.If a fact cannot be confirmed from a retrieved public source, mark it
[unverified] in the summary. Report gaps honestly.
items sourced from anonymous leaks, social-media speculation,
unattributed drafts, or "reportedly" / "expected to" claims without a
named official source. If an item cannot be tied to a specific
document or announcement from a source on the profile's locked list
(or the reputable-domain allowlist for fallback search), drop it.
Better silence than noise.
in the window, say "No significant developments this period" for
that topic in both the inline summary and the dashboard. Do not pad
with low-signal filler.
paywalled or copyrighted text. Summarize in the skill's own words and
link the source.
sources_by_topic and seed_sources_by_topic. That list is set at
interactive setup with explicit user confirmation — the skill cannot
start the monitoring sweep until the user has approved the sources.
Fallback search is bounded by runtime_budget.max_fallback_searches
and filtered by the reputable-domain allowlist. Do not add new
sources on an unattended run — that requires interactive re-setup.
a legal conclusion, or a business impact. relevant_to_your_team is
a soft keyword-match highlight.
user requires explicit confirmation on an interactive run; unattended
runs never add recipients.
confidentiality label or sensitivity marking (for example
"Confidential", "Internal Only", "Restricted", or an enterprise
information-protection label), or contains unreleased figures,
customer or partner identifiers, or names that aren't public yet,
drop it — this skill uses public sources only. Never add PII,
customer identifiers, or non-public attribution to the dashboard
beyond the function-area keywords the user confirmed at setup.
in the skill's own words.
reporting success. If the delivery block failed, report the failure.
requested window.
references/sources-and-taxonomy.md — reputable-domain allowlist,item classification taxonomy, stage-inference rules, and per-topic
search-query templates.
scripts/build_dashboard.py — self-contained dashboard generator(Python standard library only; embeds a small vanilla-JS sorter for
the items table).
Take microsoft/regulation-monitor from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.