Unified Monitoring System Architecture
This document describes the comprehensive architecture of the FSI-AgentGov monitoring system for detecting external changes that may require framework updates.
Executive Summary
Purpose: Proactively detect changes in external sources (Microsoft Learn documentation, regulatory notices) that may impact the FSI Agent Governance Framework, enabling timely documentation updates.
Implementation Status: Active and operational as of February 2026.
Coverage: - Microsoft Learn: ~207 URLs monitored daily - Regulatory Sources: Federal Register (SEC, CFTC, OCC, Federal Reserve) + FINRA notices monitored weekly
Key Principle: ONE unified monitoring system with multiple source adapters, not separate independent monitors.
System Overview
┌──────────────────────────────────────────────────────────────────────────┐
│ UNIFIED MONITORING ARCHITECTURE │
│ │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ SHARED INFRASTRUCTURE │ │
│ │ ┌─────────────────────────────────────────────────────────┐ │ │
│ │ │ monitoring_shared.py (Unified Framework) │ │ │
│ │ │ - State management │ │ │
│ │ │ - Report generation │ │ │
│ │ │ - Control mapping │ │ │
│ │ │ - Change classification │ │ │
│ │ └─────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ ┌────────────────┐ ┌──────────────────────────────┐ │ │
│ │ │ Shared State │ │ Shared Report Directory │ │ │
│ │ │ data/monitor- │ │ reports/monitoring/ │ │ │
│ │ │ state.json │ │ - learn-changes-*.md │ │ │
│ │ │ │ │ - regulatory-changes-*.md │ │ │
│ │ └────────────────┘ └──────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────┘ │ │
│ │ │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ SOURCE ADAPTERS │ │
│ ├────────────────────────────────────────────────────────────────┤ │
│ │ ┌─────────────────────┐ ┌─────────────────────────────┐ │ │
│ │ │ learn_monitor.py │ │ regulatory_monitor.py │ │ │
│ │ │ - Fetch Learn URLs │ │ - Fetch Federal Register │ │ │
│ │ │ - Hash content │ │ - Fetch FINRA notices │ │ │
│ │ │ - Classify changes │ │ - Keyword matching │ │ │
│ │ │ - Map to controls │ │ - Map to controls │ │ │
│ │ │ │ │ │ │ │
│ │ │ Schedule: Daily │ │ Schedule: Weekly │ │ │
│ │ │ 6:00 AM UTC │ │ Wednesday 6:00 AM UTC │ │ │
│ │ └─────────────────────┘ └─────────────────────────────┘ │ │
│ └────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ AI-ASSISTED REVIEW │ │
│ │ ┌──────────────────────────────────────────────────────────┐ │ │
│ │ │ .github/prompts/review-learn-changes.prompt.md │ │ │
│ │ │ - Learn reports: Auto-draft edits │ │ │
│ │ │ - Regulatory reports: Triage only │ │ │
│ │ │ │ │ │
│ │ │ Invocation: Manual (user runs /review-learn-changes) │ │ │
│ │ └──────────────────────────────────────────────────────────┘ │ │
│ └────────────────────────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Unified Framework
monitoring_shared.py
Location: scripts/monitoring_shared.py
Purpose: Core framework providing shared utilities for all monitoring sources
Key Functions:
| Function | Purpose |
|---|---|
load_state() |
Load monitoring state from unified state file |
save_state() |
Save monitoring state to unified state file |
classify_change() |
Classify changes (CRITICAL/HIGH/MEDIUM/NOISE) |
map_to_controls() |
Map changes to affected framework controls |
generate_report() |
Generate markdown change reports |
normalize_content() |
Clean and normalize content for comparison |
compute_hash() |
Generate SHA-256 content hashes |
Design Principle: Source adapters (Learn Monitor, Regulatory Monitor) are thin wrappers that fetch content and delegate to monitoring_shared.py for all common operations.
State File
data/monitor-state.json
Purpose: Unified state file tracking all monitored sources
Structure:
{
"last_updated": "2026-02-04T06:00:00Z",
"sources": {
"learn": {
"urls": {
"https://learn.microsoft.com/...": {
"hash": "sha256:abc123...",
"last_checked": "2026-02-04T06:00:00Z",
"title": "Managed Environments Overview",
"normalized_content": "..."
}
}
},
"regulatory": {
"federal_register": {
"last_checked": "2026-02-04T06:00:00Z",
"items": {
"2026-02228": {
"title": "SEC Rule Filing...",
"hash": "sha256:def456...",
"agency": "SEC",
"document_type": "Rule"
}
}
},
"finra": {
"last_checked": "2026-02-04T06:00:00Z",
"items": {
"trade-reporting-notice-20260114": {
"title": "Trade Reporting Notice...",
"hash": "sha256:ghi789...",
"notice_type": "Trade Reporting"
}
}
}
}
}
}
Benefits of Unified State: - Single source of truth for all monitoring - Cross-source correlation possible - Simplified backup and restore - Reduced state file management complexity
Report Directory
reports/monitoring/
Purpose: Unified directory for all monitoring reports
Report Types:
| Report Pattern | Source | Frequency | Purpose |
|---|---|---|---|
learn-changes-YYYY-MM-DD.md |
Learn Monitor | Daily (if changes) | Microsoft Learn documentation updates |
regulatory-changes-YYYY-MM-DD.md |
Regulatory Monitor | Weekly (if changes) | Federal Register + FINRA regulatory notices |
Report Format (Learn):
# Learn Monitor Report - YYYY-MM-DD
**Run Date:** YYYY-MM-DD
**URLs Monitored:** ~207
**Meaningful Changes:** N
## Summary
[Executive summary table]
## HIGH Priority Changes
### URL: [Microsoft Learn URL]
**Affected Controls:** 1.1, 1.5, 2.3
**Affected Playbooks:** 1.1/portal-walkthrough.md
**What Changed:**
[Diff showing before/after]
Report Format (Regulatory):
# Regulatory Monitor Report - YYYY-MM-DD
**Run Date:** YYYY-MM-DD
**New Items:** N
**Sources:** Federal Register (SEC, CFTC, OCC, Federal Reserve) + FINRA Notices
## Summary
[Executive summary table by category]
## HIGH Priority Items
### [Regulatory Item Title]
**Source:** SEC
**Potentially Affected Controls:** [keyword-matched controls]
[Summary of item]
Why Unified Directory: - Single location for all change reports - Simplified AI-assisted review workflow - Easier backup and archival - Clear organizational structure
Source Adapters
Learn Monitor
Script: scripts/learn_monitor.py
Workflow: .github/workflows/learn-monitor.yml
Schedule: Daily at 6:00 AM UTC
Data Source: docs/reference/microsoft-learn-urls.md (~207 URLs)
Process: 1. Load URLs from watchlist 2. Fetch each URL via HTTP 3. Extract meaningful content (remove headers, navigation, metadata) 4. Normalize content (whitespace, encoding) 5. Compute SHA-256 hash 6. Compare to previous hash in state file 7. If changed, classify change (CRITICAL/HIGH/MEDIUM/NOISE) 8. Map to affected controls via URL-to-control mapping 9. Generate report if meaningful changes detected 10. Update state file
Exit Codes:
- 0 - No meaningful changes
- 1 - Meaningful changes detected (triggers PR creation)
- 2 - Error during execution
PR Creation Logic: - Every Sunday (baseline run), OR - When exit code = 1 (changes detected)
Regulatory Monitor
Script: scripts/regulatory_monitor.py
Workflow: .github/workflows/regulatory-monitor.yml
Schedule: Weekly on Wednesday at 6:00 AM UTC
Data Sources: - Federal Register API (SEC, CFTC, OCC, Federal Reserve) - FINRA regulatory notices (web scraping)
Process: 1. Query Federal Register API for recent documents from target agencies 2. Scrape every page of FINRA's complete, unfiltered regulatory-notice listing. The selected-year taxonomy filter is advisory only and is never used as a completeness proof. The first complete pass finishes before a second independent session begins; the two cache-busted passes must agree on declared totals, page identities, ordered raw-row counts, and row digests. Each scoped row must resolve to a same-origin canonical notice or numeric node URL; unresolved or contradictory metadata fails closed. Raw rows are retained in the coverage proof. Stable cross-page duplicates are coalesced only after authoritative detail content hashes match and are recorded in a duplicate ledger. Listing-row formatting/title/date differences are retained as duplicate-ledger evidence when the authoritative node/detail agrees. Every duplicate node also retains a separate raw detail-date proof containing the canonical URL, numeric shortlink, node marker, title, and official date field. Its hash, exact node binding, normalized detail-content hash, and persisted entry hash must agree independently of the listing rows. A conflicting or missing listing date is cleared only when another retained occurrence normalizes exactly to that bound authoritative date. Missing or unverifiable authority, or no matching occurrence, fails closed. Conflicting detail payloads fail closed. Explicit one-page and zero-result shapes are the only permitted exceptions. 3. For each new item: - Extract title, abstract, document type - Compute content hash - Check if already seen in state file - If new, classify relevance (CRITICAL/HIGH/MEDIUM/NOISE) via keyword matching - Suggest potentially affected controls based on keywords 4. Generate report if new items detected 5. Update state file
Exit Codes:
- 0 - No new items; a maintenance PR is created only when the successful run
changed persisted state (for example, a refresh cursor, timestamp, or learned
FINRA fallback). A clean run stays silent.
- 1 - New items detected; creates a findings PR containing the report and state.
- 2 - Error during execution; fails closed and never creates a state PR.
Persistence and PR safety: Only a run on the default branch may mutate
state or create a state PR. Feature-branch and pull-request runs use a
separate read-only job (contents: read, persist-credentials: false) and
execute only --dry-run; they never receive the App/write token. The
mutating job checks out the trusted default branch with credentials persistence
disabled, and only requests the App token after monitor success and CAS
validation. Before creating a state PR, the workflow revalidates the captured
default-branch commit and state-file SHA; a changed base fails closed. The CAS
step publishes a manifest of every mutated path with both its git blob SHA and
its sha256 content hash. After PR creation, the workflow reads the immutable PR
head through the GitHub API, requires the PR base OID to equal the captured CAS
base, verifies every manifested blob and the exact file set, and fails to
needs-review if any binding is missing or changed.
The privileged workflow deliberately leaves the newest verified PR open. It
does not merge or enable auto-merge because no available merge primitive
atomically binds both the validated base and head. The existing external
guarded sweep or a human performs the final up-to-date merge gate.
REGULATORY_STATE_AUTOMERGE does not authorize merging; only after
verify_pr emits verified=true does it permit consolidation of older,
non-needs-review monitor PRs. Immediately before consolidation it re-reads
the PR base/head and the current default-branch SHA; any movement from the
verified CAS binding fails closed. A failed or skipped verification leaves
every older PR and branch untouched. Successful runs may change only
data/monitor-state.json, its atomic backup, or a regenerated regulatory
report.
Scheduled mutation also requires both regulatory source sections to be valid
objects with an entries map and a parseable last_run. Missing or corrupt
state fails before any fetch or write. Baseline initialization is an
explicitly approved local-only --initialize-baseline operation and is never
available from GitHub Actions. Each persisted regulatory watermark is bound to
a coverage proof containing the entry count, stable entry-map digest, source
identity, query/window metadata, declared and fetched page counts, and exact
page identities (plus FINRA listing/detail counts). The proof is validated
before the next fetch; a missing or mismatched proof cannot advance a
watermark. Each FINRA pass proof retains the raw listing-row payloads, and
every derived count and digest it carries (row counts, row digests, raw row
total, resolved/unresolved rows, unique nodes) is recomputed from those
payloads at validation time, so replacing the payloads while keeping the
duplicated evidence fields fails closed. Validation independently derives the
exact duplicate-occurrence multiset from both retained passes and binds each
ledger record's page/row occurrence, listing target, fetched node identity,
detail hash, raw payload, and payload digest. Missing, extra, fabricated, or
count-drifted duplicate records fail closed. Retained rows must use the exact
production text/links schema; synthetic metadata such as a persisted
listing_date field is rejected. Every duplicate node, including duplicates
whose listing dates agree, requires a separately hashed raw detail-date proof.
That proof must bind one canonical detail identity, the exact numeric node, and
one official publication date; the same date must occur in normalized
substantive content whose hash equals the persisted fetched entry. Listing-date
conflicts replay only against this authority and require a retained matching
occurrence. The 55 duplicate nodes recovered on 2026-08-09 are additionally
bound to the reviewed, code-held
scripts/regulatory_recovery_anchors.py v2 trust root. Each immutable anchor
record fixes the canonical URL, numeric node URL, normalized authoritative
publication date, raw authoritative-proof hash, and substantive-detail hash.
Validation recomputes those facts from the retained raw proof and detail
content, requires the state to name the exact reviewed version/digest, and
requires exact equality with the complete canonical anchor set. Missing,
extra, altered, duplicated, ambiguous, or reordered code-held records fail
closed even when every mutable row, flag, entry, and aggregate digest has been
coherently recomputed. The scope is deliberately limited to that reviewed
recovery duplicate set; later duplicate nodes remain governed by the live
proof validators without being silently frozen into this historical anchor.
FINRA also binds the sorted
fetched-detail identity set and digest
to the persisted entry identity set. Legacy identities are retained only in a
separate one-to-one alias ledger containing source-hash evidence; aliases do
not count as persisted entries or coverage. Every alias target must remain a
fetched canonical identity, and stale, cyclic, conflicting, or unverified
identities fail closed. Aliases are additionally bound to facts outside the
alias record. Each legacy identity requires a retained raw detail-page identity
envelope whose canonical link, numeric-node shortlink, page-node-* body class,
and authoritative node title agree, and whose canonical URL occurs in both
listing proofs. The complete derived alias-binding set must also match the
reviewed code-held recovery anchor, which a state-only monitor run cannot
rewrite. The v2 duplicate anchor carries the same URL-to-node binding digest,
so extending date/content provenance cannot weaken or replace the original
alias root. The mutable fallback_urls transport cache is never accepted as
alias evidence. A migration may never move between two different FINRA
notice numbers, and the alias must reach the hash the canonical entry actually
carries through an explicit, contiguous, append-only content-update chain.
Swapping aliases, fallback mappings, shortlinks, hashes, or aggregate digests
without rewriting the retained source envelope therefore fails validation.
When a canonical detail fetch is rate-limited and a /node/<id> URL is used as
a transport fallback, the notice keeps its listing/canonical identity rather
than adopting the transport URL. A known refresh target absent from both
complete listing passes makes the run incomplete; after all in-memory updates,
the complete regulatory state is validated again before any report or state
save. Recovery may admit a legacy proof only through the
explicitly approved local recovery mode, which rewrites the proof from a
successful complete crawl.
Keywords for Control Mapping:
| Keyword Category | Keywords | Maps To |
|---|---|---|
| AI/ML | artificial intelligence, machine learning, automated decision | 1.8, 2.6, 2.15 |
| Recordkeeping | records, retention, books and records, archive | 3.1, 3.2, 3.3 |
| Supervision | supervision, review, oversight, monitoring | 2.6, 2.15, 3.5 |
| Data Protection | privacy, data security, PII, confidential | 1.1, 1.2, 1.3 |
| Content Moderation | harmful content, content review, moderation | 1.27, 1.8 |
AI-Assisted Review
Prompt: .github/prompts/review-learn-changes.prompt.md
Invocation: Manual via /review-learn-changes in GitHub Copilot Chat
Learn Report Workflow
When a Learn change report is created:
- User invokes
/review-learn-changesin GitHub Copilot Chat - Prompt reads
reports/monitoring/learn-changes-*.md - For each HIGH priority change:
- Read affected control/playbook
- Analyze the diff from Microsoft Learn
- Draft specific edit
- Present summary to user:
- Proposed updates (auto-draftable)
- Flagged for human review (policy/regulatory language)
- Skipped (formatting/noise)
- User confirms: "Apply the N updates"
- Prompt applies edits using the Edit tool
- Runs
mkdocs build --strictvalidation - User reviews, commits, and pushes
Auto-Draft Eligible Changes: - UI navigation step updates - Date/deadline changes - Feature GA/deprecation notices - URL redirects - New documentation cross-references
Flagged for Human Review: - Policy language changes - New compliance requirements - Security guidance changes - Licensing changes
Regulatory Report Workflow
When a regulatory change report is created:
- User invokes
/review-learn-changesin GitHub Copilot Chat - Prompt reads
reports/monitoring/regulatory-changes-*.md - For each CRITICAL/HIGH item:
- Read suggested affected controls
- Assess relevance to AI agent governance
- Validate keyword-based suggestions
- Present triage summary:
- Requires human review (with relevance assessment)
- Out of scope (dismissible)
- User conducts detailed analysis
- User determines if framework updates are needed
IMPORTANT: Regulatory changes are NEVER auto-edited per CONTRIBUTING.md safety rules. The prompt provides triage assistance only.
Change Classification
4-Tier System:
| Classification | Criteria | Action |
|---|---|---|
| CRITICAL | Affects portal-walkthrough.md playbooks, breaking changes, security vulnerabilities | Immediate update required |
| HIGH | UI steps, policy language, deprecations, new capabilities | Review and update |
| MEDIUM | General content updates, minor documentation changes | Review optional |
| NOISE | Metadata, dates, formatting, out-of-scope regulatory items | Ignore |
Learn Classification Logic:
- Contains UI keywords (
click,navigate,portal,admin center) + affects playbook → CRITICAL - Contains policy keywords (
required,must,prohibited,compliance) → HIGH - Contains deprecation keywords (
deprecated,retired,no longer) → HIGH - Contains release keywords (
preview,GA,generally available) → HIGH - Substantive content change → MEDIUM
- Metadata/formatting only → NOISE
Regulatory Classification Logic:
- Contains AI/supervision/recordkeeping keywords → HIGH (if SEC/FINRA/OCC/Fed)
- Contains data protection keywords → HIGH (if GLBA-relevant agency)
- Trading rules, fee schedules, non-AI topics → NOISE
- Keyword matching to framework controls → Suggests affected controls
Maintenance Procedures
Weekly Maintenance (~30 minutes)
Monday Morning:
-
Check Learn Monitor PR (created Sunday baseline or when changes detected)
-
Review change report in
reports/monitoring/learn-changes-*.md - Check summary for HIGH/CRITICAL changes
-
Note number of affected controls
-
Run AI-assisted review (if HIGH priority changes exist)
-
Apply updates and validate
-
Commit and merge PR
Thursday Morning:
-
Check Regulatory Monitor PR (created Wednesday if changes detected)
-
Review change report in
reports/monitoring/regulatory-changes-*.md - Check summary for HIGH items
-
Note suggested affected controls
-
Run AI-assisted triage
-
Conduct detailed analysis for items flagged as "Requires Human Review"
- Read full regulatory text
- Assess applicability to AI agent governance
-
Determine if framework updates needed
-
Update framework if needed (separate work session)
- Create issue tracking regulatory change
- Plan documentation updates
-
Implement and test
-
Merge PR (updates state file even if no framework changes)
Adding New URLs to Learn Monitor
Process:
-
Add URL to watchlist
-
Map URL to controls
-
Run test
-
Commit changes
Next scheduled run will pick up the new URL automatically.
Adding New Regulatory Sources
Federal Register Agencies:
Edit scripts/regulatory_monitor.py around line 30:
FEDERAL_REGISTER_AGENCIES = [
"securities-and-exchange-commission",
"commodity-futures-trading-commission",
"comptroller-of-the-currency",
"federal-reserve-system",
# Add new agency slug here
]
FINRA Notice Types:
Edit scripts/regulatory_monitor.py around line 250:
Keyword Mapping:
Edit scripts/monitoring_shared.py around line 400:
REGULATORY_KEYWORDS = {
"ai_governance": {
"keywords": ["artificial intelligence", "machine learning", ...],
"controls": ["1.8", "2.6", "2.15"]
},
# Add new keyword category here
}
Troubleshooting
| Issue | Symptoms | Resolution |
|---|---|---|
| Workflow not running | No PRs created for days | Check GitHub Actions settings, verify GITHUB_TOKEN permissions |
| State file corrupted | JSON parsing errors | Restore from backup or delete and re-run monitor (establishes new baseline) |
| False positives | Too many NOISE changes classified as HIGH | Tune classification keywords in monitoring_shared.py |
| Missing changes | Known changes not detected | Verify URL in watchlist, check URL_TO_CONTROLS mapping |
| API rate limits | Federal Register API 429 errors | Workflow runs weekly to avoid limits; if persistent, add retry logic |
| FINRA scraping failure | Regulatory monitor fails | FINRA HTML structure changed; update scraping logic in regulatory_monitor.py |
| mkdocs build fails after updates | Broken links or syntax errors | Review AI-drafted edits manually, fix syntax, re-run build |
Monitoring Approach Evaluation
Requirement (MON-03): Assess monitoring approach with documented rationale.
Chosen Approach: Unified Monitoring with Source Adapters
Rationale:
Why unified framework: - Reduced code duplication: Common operations (state management, report generation, control mapping) implemented once - Consistent classification: All sources use the same 4-tier classification system - Simplified maintenance: Bug fixes and enhancements apply to all sources - Cross-source correlation: Future capability to detect related changes across sources - Single state file: Easier backup, restore, and troubleshooting
Why source adapters: - Separation of concerns: Each adapter focuses on its data source specifics - Independent schedules: Learn runs daily, Regulatory runs weekly (different change frequencies) - Extensibility: Adding new sources (e.g., Azure Updates, Microsoft Tech Community) is straightforward - Different workflows: Learn changes can be auto-drafted, regulatory changes require human review
Why manual AI-assisted review: - Cost control: User decides when to invoke AI assistance (not every run) - Human oversight: Critical for regulatory content per CONTRIBUTING.md - Flexibility: User can review subset of changes, skip low-priority items - Safety: Prevents automated commits of incorrect edits
Alternative Approaches Considered
Alternative 1: Separate Independent Monitors
Description: Maintain completely separate scripts, state files, and report directories for Learn vs. Regulatory.
Pros: - Complete independence (failure in one doesn't affect the other) - Simpler initial implementation
Cons:
- Code duplication: 60-70% of code is identical (state management, classification, reporting)
- Inconsistent classification: Hard to maintain consistent standards across monitors
- Multiple state files: data/learn-state.json + data/regulatory-state.json
- Multiple report dirs: reports/learn-changes/ + reports/regulatory-changes/
- Maintenance burden: Bug fixes need to be applied twice
Decision: Rejected. The duplication cost outweighs the independence benefit.
Alternative 2: Fully Automated with GitHub Actions
Description: GitHub Actions workflow automatically invokes Claude API to draft and commit edits when changes detected.
Pros: - Fully automated, no human invocation needed - Faster response to changes
Cons: - API costs: ~$0.14 per Learn Monitor run × 365 days = ~$51/year (plus regulatory runs) - Safety risk: Automated commits of incorrect edits - Authenticated model access in GitHub Actions: Security consideration - No human review gate: Violates CONTRIBUTING.md requirement for regulatory content
Decision: Rejected for now. Manual invocation provides better cost control and safety. Could revisit as "Phase 4" enhancement with proper guardrails.
Alternative 3: Polling vs. Push-Based
Description: Instead of polling external sources on a schedule, use webhooks or RSS feeds to get push notifications.
Pros: - More real-time detection - Lower polling overhead
Cons: - Microsoft Learn has no webhooks: Would need RSS feed or undocumented API - Federal Register has RSS: But still requires polling to fetch full content - FINRA has no RSS: Web scraping still required - Complexity: Managing webhook endpoints, authentication, security - Reliability: Push-based systems fail silently; polling failures are obvious
Decision: Rejected. Polling is reliable, simple, and sufficient for the framework's needs (daily/weekly cadence acceptable).
State AI Law Monitoring
Status: Manual monitoring (not automated)
Coverage: - Colorado AI Act (SB 24-205) - Effective June 30, 2026 (extended from February 1, 2026 via SB 25B-004) - California AI Transparency Act (AB 2013) - Signed September 2024 - New York City Local Law 144 - Effective July 2023 - Illinois Biometric Information Privacy Act (BIPA) - Relevant to AI - Texas Data Privacy and Security Act (HB 4) - Effective July 2024
Process: - Monthly review of state legislature tracking services - Quarterly review of framework for state law alignment - Ad-hoc updates when new laws enacted
Why not automated: - No unified API for state legislature tracking - High variance in relevance (most state bills not applicable) - Human judgment required to assess applicability to M365 AI agents - Low change frequency (quarterly review sufficient)
Future consideration: Add RSS feeds for key state legislature sites if change frequency increases.
Related Documentation
- Learn Monitor Guide: learn-monitor-guide.md - Learn Monitor user documentation
- AI-Assisted Review: learn-monitor-ai-enhancement.md - AI-assisted review implementation
- Copilot Prompt:
.github/prompts/review-learn-changes.prompt.md- User-invocable prompt - Microsoft Learn URLs: microsoft-learn-urls.md - Monitored URL watchlist
- Contributing Guide:
CONTRIBUTING.md- Language guidelines and safety rules
FSI Agent Governance Framework v1.6.2 - May 2026