plainstamp 0.7.1 → 0.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -16,6 +16,29 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
16
16
 
17
17
  Distribution is **npm-only**. Source remains in the operating organization's private repository; there is no public source repository host. Contact channel for issues, accuracy reports, security reports, and contribution proposals is **helpfulbutton140@agentmail.to** (see `docs/CONTRIBUTING.md`, `docs/SECURITY.md`).
18
18
 
19
+ ## [0.7.3] — 2026-05-08
20
+
21
+ ### Added (cross-runtime watcher)
22
+
23
+ - New `StateStore` interface on the watcher module: `read()` and `write(state)`. Allows the rule-update watcher to run in environments without a filesystem (Cloudflare Workers, Deno Deploy, browsers).
24
+ - New `runWatcherWithStore({ sources, stateStore, dryRun? })` entry point alongside the existing `runWatcher({ sources, statePath, dryRun? })`. The fs-path version remains and is now a thin shim over the abstract version.
25
+ - New `fsStateStore(path)` and `memoryStateStore(initial?)` factory helpers exported from the watcher module.
26
+ - All five new exports are re-exported from the package root.
27
+
28
+ ### Internal
29
+
30
+ - `runWatcher` is unchanged from a caller's perspective; the shim preserves the existing CLI behavior. No tests changed; full 51-test suite still passing.
31
+
32
+ ## [0.7.2] — 2026-05-08
33
+
34
+ ### Documentation
35
+
36
+ - README now features the hosted MCP Streamable-HTTP endpoint at `https://plainstamp.helpfulbutton140.workers.dev/mcp` — no install required for clients that prefer the hosted transport.
37
+ - README documents the parallel JSON-over-HTTP API on the same Worker (`/jurisdictions`, `/rules`, `/lookup`, `/validate`) for clients that don't speak MCP.
38
+ - Coverage table refreshed against the live 23-rule corpus and reorganized by jurisdiction tier (federal / state / city / EU). Federal additions now visible in README: EEOC, CFPB, FINRA, HHS Section 1557, FDA PCCP, FCC TCPA. State additions: SB 1120, Tennessee ELVIS Act. EU: GDPR Article 22.
39
+
40
+ No code changes; npm publish refreshes the README rendered on npmjs.com.
41
+
19
42
  ## [0.7.1] — 2026-05-08
20
43
 
21
44
  ### Fixed (cross-runtime compatibility)
package/README.md CHANGED
@@ -93,6 +93,38 @@ Add to your MCP config:
93
93
 
94
94
  The server speaks the standard MCP stdio transport. Spawn `npx plainstamp mcp` (or run `node dist/mcp-server.js` from a checkout) and connect to its stdin/stdout.
95
95
 
96
+ ### Hosted MCP HTTP endpoint
97
+
98
+ A hosted MCP Streamable-HTTP endpoint runs on Cloudflare Workers — no install required:
99
+
100
+ ```
101
+ https://plainstamp.helpfulbutton140.workers.dev/mcp
102
+ ```
103
+
104
+ It speaks the standard MCP Streamable-HTTP transport (`POST` JSON-RPC, `GET`/`DELETE` per spec) and exposes the same five tools as the stdio server. Stateless, free to call.
105
+
106
+ ## Hosted JSON API
107
+
108
+ The same Worker also exposes a plain JSON-over-HTTP API at `https://plainstamp.helpfulbutton140.workers.dev` for clients that don't speak MCP:
109
+
110
+ ```
111
+ GET / service info + bundled-rule version
112
+ GET /health liveness probe
113
+ GET /jurisdictions list supported jurisdiction ids
114
+ GET /rules list compact rule summaries
115
+ GET /rules/:id full rule by id
116
+ GET /lookup?jurisdiction=&channel=&use_case=
117
+ applicable rules + generated text
118
+ POST /validate { jurisdiction, channel, use_case, candidate_text }
119
+ heuristic compliance check
120
+ ```
121
+
122
+ Example:
123
+
124
+ ```bash
125
+ curl "https://plainstamp.helpfulbutton140.workers.dev/lookup?jurisdiction=us-ca&channel=live-chat&use_case=b2c-customer-support"
126
+ ```
127
+
96
128
  ## Library
97
129
 
98
130
  ```ts
@@ -131,24 +163,52 @@ const reports = validateDisclosureForQuery(
131
163
 
132
164
  ## Coverage
133
165
 
166
+ 23 rules across 11 jurisdictions, last verified 2026-05-08.
167
+
168
+ **Federal (US):**
169
+
170
+ | Rule | Jurisdiction | Effective | Last verified |
171
+ |---|---|---|---|
172
+ | FTC rule on fake reviews and testimonials (16 CFR Part 465) | us | 2024-10-21 | 2026-05-08 |
173
+ | EEOC Title VII technical assistance — AI selection procedures (2023) | us | 2023-05-18 | 2026-05-08 |
174
+ | CFPB Circular 2023-03 — adverse-action notices for AI credit decisions (ECOA / Regulation B) | us | 2023-09-19 | 2026-05-08 |
175
+ | FINRA Regulatory Notice 24-09 — AI in customer communications | us | 2024-06-27 | 2026-05-08 |
176
+ | HHS Section 1557 — Patient Care Decision Support Tools nondiscrimination (2024 final rule) | us | 2025-05-01 | 2026-05-08 |
177
+ | FDA Predetermined Change Control Plans for AI/ML-Enabled Device Software | us | 2024-12-04 | 2026-05-08 |
178
+ | FCC Declaratory Ruling — AI-generated voice in robocalls under TCPA (Feb 2024) | us | 2024-02-08 | 2026-05-08 |
179
+
180
+ **State (US):**
181
+
134
182
  | Rule | Jurisdiction | Effective | Last verified |
135
183
  |---|---|---|---|
136
184
  | California bot disclosure (B&P § 17941) | us-ca | 2019-07-01 | 2026-05-08 |
137
- | EU AI Act Article 50(1) chatbot disclosure | eu | 2026-08-02 | 2026-05-08 |
138
- | EU AI Act Article 50(2) AI-generated content labeling | eu | 2026-08-02 | 2026-05-08 |
139
- | FTC fake reviews/testimonials (16 CFR Part 465) | us | 2024-10-21 | 2026-05-08 |
140
- | California AI Transparency Act (SB 942) | us-ca | 2026-01-01 | 2026-05-08 |
185
+ | California AI provenance and labeling (SB 942 / AB 2655 family) | us-ca | 2026-01-01 | 2026-05-08 |
186
+ | California AB 2013 Generative AI Training Data Transparency Act | us-ca | 2026-01-01 | 2026-05-08 |
187
+ | California SB 1120 Physicians Make Decisions Act (utilization review) | us-ca | 2025-01-01 | 2026-05-08 |
141
188
  | Colorado AI Act (SB 24-205) — consumer disclosure | us-co | 2026-06-30 | 2026-05-08 |
142
189
  | Utah AI Policy Act (SB 149, as amended by SB 226 / SB 332) | us-ut | 2024-05-01 | 2026-05-08 |
143
- | Texas TRAIGA (HB 149) — government agency | us-tx | 2026-01-01 | 2026-05-08 |
144
- | Texas TRAIGA (HB 149) — healthcare provider | us-tx | 2026-01-01 | 2026-05-08 |
190
+ | Texas TRAIGA (HB 149) — government agency disclosure | us-tx | 2026-01-01 | 2026-05-08 |
191
+ | Texas TRAIGA (HB 149) — healthcare-provider disclosure | us-tx | 2026-01-01 | 2026-05-08 |
145
192
  | New York AI Companion Models (NY GBL Art. 47, A6767) | us-ny | 2025-11-05 | 2026-05-08 |
146
193
  | Illinois Human Rights Act — AI in employment (HB 3773) | us-il | 2026-01-01 | 2026-05-08 |
147
- | NYC Local Law 144 — Automated Employment Decision Tools | us-ny-nyc | 2023-07-05 | 2026-05-08 |
148
- | California AB 2013 — Generative AI Training Data Transparency | us-ca | 2026-01-01 | 2026-05-08 |
149
194
  | Maryland LE § 3-717 — facial recognition in interviews (HB 1202) | us-md | 2020-10-01 | 2026-05-08 |
195
+ | Tennessee ELVIS Act — voice and likeness protection (HB 2091 / SB 2096) | us-tn | 2024-07-01 | 2026-05-08 |
196
+
197
+ **City (US):**
198
+
199
+ | Rule | Jurisdiction | Effective | Last verified |
200
+ |---|---|---|---|
201
+ | NYC Local Law 144 — Automated Employment Decision Tools | us-ny-nyc | 2023-07-05 | 2026-05-08 |
202
+
203
+ **EU:**
204
+
205
+ | Rule | Jurisdiction | Effective | Last verified |
206
+ |---|---|---|---|
207
+ | EU AI Act Article 50(1) — chatbot disclosure | eu | 2026-08-02 | 2026-05-08 |
208
+ | EU AI Act Article 50(2) — AI-generated content labeling | eu | 2026-08-02 | 2026-05-08 |
209
+ | EU GDPR Article 22 — automated decision-making rights | eu | 2018-05-25 | 2026-05-08 |
150
210
 
151
- Coverage will expand to EU member-state implementations and sector-specific rules (healthcare, financial services). See [`CHANGELOG.md`](CHANGELOG.md).
211
+ Coverage continues to expand. See [`CHANGELOG.md`](CHANGELOG.md).
152
212
 
153
213
  ## Disclaimers
154
214
 
@@ -1,14 +1,30 @@
1
- import type { Article, RunReport, Source, SourceRunReport, WatcherState } from "./types.js";
1
+ import type { Article, RunReport, Source, SourceRunReport, StateStore, WatcherState } from "./types.js";
2
2
  /**
3
3
  * Computes the new articles for a source — those whose ids do not appear in
4
4
  * `seen`. Returns the articles in fetched-order. Pure function; safe to test.
5
5
  */
6
6
  export declare function diffArticles(fetched: Article[], seen: string[]): Article[];
7
7
  /**
8
- * Runs all sources, computes the diff against persisted state, returns a
9
- * report, and updates the state file with the union of (previously seen) ∪
10
- * (newly fetched ids). Source fetch failures are caught and reported per-
11
- * source; one failing source does not abort the run.
8
+ * Runs all sources against an abstract state store, computes the diff,
9
+ * returns a report, and updates the store with (previously seen) ∪
10
+ * (newly fetched ids). Source fetch failures are caught and reported
11
+ * per-source; one failing source does not abort the run.
12
+ *
13
+ * Use this from environments without filesystem access (Cloudflare
14
+ * Workers, Deno Deploy, browsers). Pass a custom `StateStore` — for
15
+ * example, one backed by Workers KV. The Node CLI path uses
16
+ * `runWatcher` (below), which is a thin wrapper that constructs an
17
+ * `fsStateStore` from a filesystem path.
18
+ */
19
+ export declare function runWatcherWithStore(opts: {
20
+ sources: Source[];
21
+ stateStore: StateStore;
22
+ dryRun?: boolean;
23
+ }): Promise<RunReport>;
24
+ /**
25
+ * Filesystem-backed convenience wrapper. Equivalent to
26
+ * `runWatcherWithStore({ ..., stateStore: fsStateStore(statePath) })`.
27
+ * Kept for the existing Node CLI; do not use in non-Node runtimes.
12
28
  */
13
29
  export declare function runWatcher(opts: {
14
30
  sources: Source[];
@@ -16,8 +32,8 @@ export declare function runWatcher(opts: {
16
32
  /** If true, do NOT persist the new state (useful for dry-run inspection). */
17
33
  dryRun?: boolean;
18
34
  }): Promise<RunReport>;
19
- export type { Article, Source, RunReport, SourceRunReport, WatcherState };
20
- export { readState, writeState } from "./state-store.js";
35
+ export type { Article, Source, RunReport, SourceRunReport, StateStore, WatcherState, };
36
+ export { readState, writeState, fsStateStore, memoryStateStore, } from "./state-store.js";
21
37
  export { federalRegisterSource } from "./sources/federal-register.js";
22
38
  export { urlMonitorSource, rulesCitationsUrlMonitor, hashContent, } from "./sources/url-monitor.js";
23
39
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/watcher/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EACP,SAAS,EACT,MAAM,EACN,eAAe,EACf,YAAY,EACb,MAAM,YAAY,CAAC;AAGpB;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,CAO1E;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE;IACrC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,GAAG,OAAO,CAAC,SAAS,CAAC,CAiDrB;AAED,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,YAAY,EAAE,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACxB,WAAW,GACZ,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/watcher/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EACP,SAAS,EACT,MAAM,EACN,eAAe,EACf,UAAU,EACV,YAAY,EACb,MAAM,YAAY,CAAC;AAGpB;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,CAO1E;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC9C,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,UAAU,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,GAAG,OAAO,CAAC,SAAS,CAAC,CAiDrB;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE;IACrC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,GAAG,OAAO,CAAC,SAAS,CAAC,CAWrB;AAED,YAAY,EACV,OAAO,EACP,MAAM,EACN,SAAS,EACT,eAAe,EACf,UAAU,EACV,YAAY,GACb,CAAC;AACF,OAAO,EACL,SAAS,EACT,UAAU,EACV,YAAY,EACZ,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACxB,WAAW,GACZ,MAAM,0BAA0B,CAAC"}
@@ -1,4 +1,4 @@
1
- import { readState, writeState } from "./state-store.js";
1
+ import { fsStateStore } from "./state-store.js";
2
2
  /**
3
3
  * Computes the new articles for a source — those whose ids do not appear in
4
4
  * `seen`. Returns the articles in fetched-order. Pure function; safe to test.
@@ -13,13 +13,19 @@ export function diffArticles(fetched, seen) {
13
13
  return out;
14
14
  }
15
15
  /**
16
- * Runs all sources, computes the diff against persisted state, returns a
17
- * report, and updates the state file with the union of (previously seen) ∪
18
- * (newly fetched ids). Source fetch failures are caught and reported per-
19
- * source; one failing source does not abort the run.
16
+ * Runs all sources against an abstract state store, computes the diff,
17
+ * returns a report, and updates the store with (previously seen) ∪
18
+ * (newly fetched ids). Source fetch failures are caught and reported
19
+ * per-source; one failing source does not abort the run.
20
+ *
21
+ * Use this from environments without filesystem access (Cloudflare
22
+ * Workers, Deno Deploy, browsers). Pass a custom `StateStore` — for
23
+ * example, one backed by Workers KV. The Node CLI path uses
24
+ * `runWatcher` (below), which is a thin wrapper that constructs an
25
+ * `fsStateStore` from a filesystem path.
20
26
  */
21
- export async function runWatcher(opts) {
22
- const state = readState(opts.statePath);
27
+ export async function runWatcherWithStore(opts) {
28
+ const state = await opts.stateStore.read();
23
29
  const now = new Date().toISOString();
24
30
  const sourceReports = [];
25
31
  for (const source of opts.sources) {
@@ -62,10 +68,24 @@ export async function runWatcher(opts) {
62
68
  }
63
69
  }
64
70
  if (!opts.dryRun)
65
- writeState(opts.statePath, state);
71
+ await opts.stateStore.write(state);
66
72
  return { run_at: now, sources: sourceReports };
67
73
  }
68
- export { readState, writeState } from "./state-store.js";
74
+ /**
75
+ * Filesystem-backed convenience wrapper. Equivalent to
76
+ * `runWatcherWithStore({ ..., stateStore: fsStateStore(statePath) })`.
77
+ * Kept for the existing Node CLI; do not use in non-Node runtimes.
78
+ */
79
+ export async function runWatcher(opts) {
80
+ const passthrough = {
81
+ sources: opts.sources,
82
+ stateStore: fsStateStore(opts.statePath),
83
+ };
84
+ if (opts.dryRun !== undefined)
85
+ passthrough.dryRun = opts.dryRun;
86
+ return runWatcherWithStore(passthrough);
87
+ }
88
+ export { readState, writeState, fsStateStore, memoryStateStore, } from "./state-store.js";
69
89
  export { federalRegisterSource } from "./sources/federal-register.js";
70
90
  export { urlMonitorSource, rulesCitationsUrlMonitor, hashContent, } from "./sources/url-monitor.js";
71
91
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/watcher/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/watcher/index.ts"],"names":[],"mappings":"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"}
@@ -1,13 +1,21 @@
1
1
  import type { Source } from "../types.js";
2
2
  /**
3
- * Federal Register source. Fetches recent rules and proposed rules matching
4
- * a search term (default: "artificial intelligence"). The Federal Register
5
- * search is permissive results often include items only tangentially
6
- * related so the orchestrator should treat new articles as candidates for
7
- * review rather than guaranteed plainstamp-relevant updates.
3
+ * Federal Register source. Fetches recent rules, proposed rules, agency
4
+ * notices, and presidential documents matching a search term (default:
5
+ * "artificial intelligence"). The Federal Register search is permissive
6
+ * results often include items only tangentially related so the
7
+ * orchestrator should treat new articles as candidates for review rather
8
+ * than guaranteed plainstamp-relevant updates.
9
+ *
10
+ * Notices and presidential documents are included alongside rules and
11
+ * proposed rules because much actionable AI regulatory activity (FCC
12
+ * declaratory rulings, OCC bulletins, OMB memoranda, executive orders)
13
+ * appears in those categories rather than in formal rulemaking.
8
14
  */
9
15
  export declare function federalRegisterSource(opts?: {
10
16
  searchTerm?: string;
11
17
  perPage?: number;
18
+ /** Override the default doc-type filter. Defaults to RULE + PRORULE + NOTICE + PRESDOCU. */
19
+ types?: ReadonlyArray<"RULE" | "PRORULE" | "NOTICE" | "PRESDOCU">;
12
20
  }): Source;
13
21
  //# sourceMappingURL=federal-register.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"federal-register.d.ts","sourceRoot":"","sources":["../../../src/watcher/sources/federal-register.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,MAAM,EAAE,MAAM,aAAa,CAAC;AAmBnD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,CAAC,EAAE;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,MAAM,CAsCT"}
1
+ {"version":3,"file":"federal-register.d.ts","sourceRoot":"","sources":["../../../src/watcher/sources/federal-register.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,MAAM,EAAE,MAAM,aAAa,CAAC;AAmBnD;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,CAAC,EAAE;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4FAA4F;IAC5F,KAAK,CAAC,EAAE,aAAa,CAAC,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,UAAU,CAAC,CAAC;CACnE,GAAG,MAAM,CAwCT"}
@@ -1,23 +1,31 @@
1
1
  const ENDPOINT = "https://www.federalregister.gov/api/v1/articles.json";
2
2
  /**
3
- * Federal Register source. Fetches recent rules and proposed rules matching
4
- * a search term (default: "artificial intelligence"). The Federal Register
5
- * search is permissive results often include items only tangentially
6
- * related so the orchestrator should treat new articles as candidates for
7
- * review rather than guaranteed plainstamp-relevant updates.
3
+ * Federal Register source. Fetches recent rules, proposed rules, agency
4
+ * notices, and presidential documents matching a search term (default:
5
+ * "artificial intelligence"). The Federal Register search is permissive
6
+ * results often include items only tangentially related so the
7
+ * orchestrator should treat new articles as candidates for review rather
8
+ * than guaranteed plainstamp-relevant updates.
9
+ *
10
+ * Notices and presidential documents are included alongside rules and
11
+ * proposed rules because much actionable AI regulatory activity (FCC
12
+ * declaratory rulings, OCC bulletins, OMB memoranda, executive orders)
13
+ * appears in those categories rather than in formal rulemaking.
8
14
  */
9
15
  export function federalRegisterSource(opts) {
10
16
  const term = opts?.searchTerm ?? "artificial intelligence";
11
17
  const perPage = opts?.perPage ?? 20;
18
+ const types = opts?.types ?? ["RULE", "PRORULE", "NOTICE", "PRESDOCU"];
12
19
  const id = `federal-register-${term.replace(/[^a-z0-9]+/gi, "-").toLowerCase()}`;
13
20
  return {
14
21
  id,
15
- description: `Federal Register articles (Rules and Proposed Rules) matching "${term}"`,
22
+ description: `Federal Register articles (${types.join(", ")}) matching "${term}"`,
16
23
  async fetch() {
17
24
  const url = new URL(ENDPOINT);
18
25
  url.searchParams.set("conditions[term]", term);
19
- url.searchParams.append("conditions[type][]", "RULE");
20
- url.searchParams.append("conditions[type][]", "PRORULE");
26
+ for (const t of types) {
27
+ url.searchParams.append("conditions[type][]", t);
28
+ }
21
29
  url.searchParams.set("per_page", String(perPage));
22
30
  url.searchParams.set("order", "newest");
23
31
  const res = await fetch(url.toString());
@@ -1 +1 @@
1
- {"version":3,"file":"federal-register.js","sourceRoot":"","sources":["../../../src/watcher/sources/federal-register.ts"],"names":[],"mappings":"AAEA,MAAM,QAAQ,GAAG,sDAAsD,CAAC;AAiBxE;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAGrC;IACC,MAAM,IAAI,GAAG,IAAI,EAAE,UAAU,IAAI,yBAAyB,CAAC;IAC3D,MAAM,OAAO,GAAG,IAAI,EAAE,OAAO,IAAI,EAAE,CAAC;IACpC,MAAM,EAAE,GAAG,oBAAoB,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;IAEjF,OAAO;QACL,EAAE;QACF,WAAW,EAAE,kEAAkE,IAAI,GAAG;QACtF,KAAK,CAAC,KAAK;YACT,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;YAC9B,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAC;YAC/C,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;YACtD,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,oBAAoB,EAAE,SAAS,CAAC,CAAC;YACzD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;YAClD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YAExC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;YACxC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CACb,sCAAsC,GAAG,CAAC,MAAM,QAAQ,GAAG,CAAC,QAAQ,EAAE,EAAE,CACzE,CAAC;YACJ,CAAC;YACD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAe,CAAC;YAC9C,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC9B,EAAE,EAAE,CAAC,CAAC,eAAe;gBACrB,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,GAAG,EAAE,CAAC,CAAC,QAAQ;gBACf,WAAW,EAAE,CAAC,CAAC,gBAAgB;gBAC/B,GAAG,CAAC,CAAC,CAAC,QAAQ,KAAK,IAAI,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS;oBACjD,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE;oBACzB,CAAC,CAAC,EAAE,CAAC;gBACP,GAAG,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS;oBAC1B,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE;oBAC7C,CAAC,CAAC,EAAE,CAAC;gBACP,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;aACxB,CAAC,CAAC,CAAC;QACN,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"federal-register.js","sourceRoot":"","sources":["../../../src/watcher/sources/federal-register.ts"],"names":[],"mappings":"AAEA,MAAM,QAAQ,GAAG,sDAAsD,CAAC;AAiBxE;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAKrC;IACC,MAAM,IAAI,GAAG,IAAI,EAAE,UAAU,IAAI,yBAAyB,CAAC;IAC3D,MAAM,OAAO,GAAG,IAAI,EAAE,OAAO,IAAI,EAAE,CAAC;IACpC,MAAM,KAAK,GAAG,IAAI,EAAE,KAAK,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;IACvE,MAAM,EAAE,GAAG,oBAAoB,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;IAEjF,OAAO;QACL,EAAE;QACF,WAAW,EAAE,8BAA8B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,IAAI,GAAG;QACjF,KAAK,CAAC,KAAK;YACT,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;YAC9B,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAC;YAC/C,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACtB,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,oBAAoB,EAAE,CAAC,CAAC,CAAC;YACnD,CAAC;YACD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;YAClD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YAExC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;YACxC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CACb,sCAAsC,GAAG,CAAC,MAAM,QAAQ,GAAG,CAAC,QAAQ,EAAE,EAAE,CACzE,CAAC;YACJ,CAAC;YACD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAe,CAAC;YAC9C,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC9B,EAAE,EAAE,CAAC,CAAC,eAAe;gBACrB,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,GAAG,EAAE,CAAC,CAAC,QAAQ;gBACf,WAAW,EAAE,CAAC,CAAC,gBAAgB;gBAC/B,GAAG,CAAC,CAAC,CAAC,QAAQ,KAAK,IAAI,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS;oBACjD,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE;oBACzB,CAAC,CAAC,EAAE,CAAC;gBACP,GAAG,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS;oBAC1B,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE;oBAC7C,CAAC,CAAC,EAAE,CAAC;gBACP,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;aACxB,CAAC,CAAC,CAAC;QACN,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -1,4 +1,4 @@
1
- import type { WatcherState } from "./types.js";
1
+ import type { StateStore, WatcherState } from "./types.js";
2
2
  /**
3
3
  * Reads the watcher state from `path`. If the file does not exist, returns a
4
4
  * fresh empty state. The state file is plain JSON — the agent can read it
@@ -6,4 +6,14 @@ import type { WatcherState } from "./types.js";
6
6
  */
7
7
  export declare function readState(path: string): WatcherState;
8
8
  export declare function writeState(path: string, state: WatcherState): void;
9
+ /**
10
+ * Filesystem-backed StateStore for Node consumers. Wraps the sync
11
+ * readState/writeState above. Use in CLI and Node test paths.
12
+ */
13
+ export declare function fsStateStore(path: string): StateStore;
14
+ /**
15
+ * In-memory StateStore. Useful for tests and dry-run inspection where
16
+ * neither filesystem nor KV is available.
17
+ */
18
+ export declare function memoryStateStore(initial?: WatcherState): StateStore;
9
19
  //# sourceMappingURL=state-store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"state-store.d.ts","sourceRoot":"","sources":["../../src/watcher/state-store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAYpD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAGlE"}
1
+ {"version":3,"file":"state-store.d.ts","sourceRoot":"","sources":["../../src/watcher/state-store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE3D;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAYpD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAGlE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAKrD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,UAAU,CASnE"}
@@ -20,4 +20,27 @@ export function writeState(path, state) {
20
20
  mkdirSync(dirname(path), { recursive: true });
21
21
  writeFileSync(path, JSON.stringify(state, null, 2) + "\n", "utf-8");
22
22
  }
23
+ /**
24
+ * Filesystem-backed StateStore for Node consumers. Wraps the sync
25
+ * readState/writeState above. Use in CLI and Node test paths.
26
+ */
27
+ export function fsStateStore(path) {
28
+ return {
29
+ read: () => readState(path),
30
+ write: (state) => writeState(path, state),
31
+ };
32
+ }
33
+ /**
34
+ * In-memory StateStore. Useful for tests and dry-run inspection where
35
+ * neither filesystem nor KV is available.
36
+ */
37
+ export function memoryStateStore(initial) {
38
+ let state = initial ?? { schema_version: 1, sources: {} };
39
+ return {
40
+ read: () => state,
41
+ write: (next) => {
42
+ state = next;
43
+ },
44
+ };
45
+ }
23
46
  //# sourceMappingURL=state-store.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"state-store.js","sourceRoot":"","sources":["../../src/watcher/state-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,OAAO,EAAE,cAAc,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IAC5C,CAAC;IACD,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAiB,CAAC;IAC/C,IAAI,MAAM,CAAC,cAAc,KAAK,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CACb,yCAAyC,MAAM,CAAC,cAAc,eAAe,CAC9E,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,KAAmB;IAC1D,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;AACtE,CAAC"}
1
+ {"version":3,"file":"state-store.js","sourceRoot":"","sources":["../../src/watcher/state-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,OAAO,EAAE,cAAc,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IAC5C,CAAC;IACD,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAiB,CAAC;IAC/C,IAAI,MAAM,CAAC,cAAc,KAAK,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CACb,yCAAyC,MAAM,CAAC,cAAc,eAAe,CAC9E,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,KAAmB;IAC1D,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;AACtE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO;QACL,IAAI,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC;QAC3B,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC;KAC1C,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAsB;IACrD,IAAI,KAAK,GACP,OAAO,IAAI,EAAE,cAAc,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IAChD,OAAO;QACL,IAAI,EAAE,GAAG,EAAE,CAAC,KAAK;QACjB,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE;YACd,KAAK,GAAG,IAAI,CAAC;QACf,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -56,4 +56,14 @@ export interface RunReport {
56
56
  run_at: string;
57
57
  sources: SourceRunReport[];
58
58
  }
59
+ /**
60
+ * Pluggable state store. The Node CLI uses a filesystem-backed store
61
+ * (`fsStateStore`); Cloudflare Workers / Deno Deploy / browsers use a
62
+ * KV-backed store. Implementations may be sync or async; the watcher
63
+ * always awaits.
64
+ */
65
+ export interface StateStore {
66
+ read(): Promise<WatcherState> | WatcherState;
67
+ write(state: WatcherState): Promise<void> | void;
68
+ }
59
69
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/watcher/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,WAAW,OAAO;IACtB,qGAAqG;IACrG,EAAE,EAAE,MAAM,CAAC;IACX,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,GAAG,EAAE,MAAM,CAAC;IACZ,mCAAmC;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,wFAAwF;IACxF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kFAAkF;IAClF,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,MAAM;IACrB,0EAA0E;IAC1E,EAAE,EAAE,MAAM,CAAC;IACX,oDAAoD;IACpD,WAAW,EAAE,MAAM,CAAC;IACpB,8HAA8H;IAC9H,KAAK,EAAE,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,WAAW;IAC1B,0CAA0C;IAC1C,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,4DAA4D;IAC5D,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,cAAc,EAAE,CAAC,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,OAAO,EAAE,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,eAAe,EAAE,CAAC;CAC5B"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/watcher/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,WAAW,OAAO;IACtB,qGAAqG;IACrG,EAAE,EAAE,MAAM,CAAC;IACX,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,GAAG,EAAE,MAAM,CAAC;IACZ,mCAAmC;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,wFAAwF;IACxF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kFAAkF;IAClF,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,MAAM;IACrB,0EAA0E;IAC1E,EAAE,EAAE,MAAM,CAAC;IACX,oDAAoD;IACpD,WAAW,EAAE,MAAM,CAAC;IACpB,8HAA8H;IAC9H,KAAK,EAAE,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,WAAW;IAC1B,0CAA0C;IAC1C,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,4DAA4D;IAC5D,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,cAAc,EAAE,CAAC,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,OAAO,EAAE,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,eAAe,EAAE,CAAC;CAC5B;AAED;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,IAAI,OAAO,CAAC,YAAY,CAAC,GAAG,YAAY,CAAC;IAC7C,KAAK,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAClD"}
@@ -0,0 +1,261 @@
1
+ # CFPB Circular 2023-03 (AI credit decisions): a builder's guide
2
+
3
+ > **Informational only — not legal advice.** Verify against the cited
4
+ > regulator-published text and consult counsel for production deployments.
5
+ > See `AI-DISCLOSURE.md` in this package.
6
+
7
+ If your fintech, lender, or AI-credit platform uses any model — neural
8
+ network, gradient-boosted trees, ensemble, or even a complex linear
9
+ model — to make adverse credit decisions on consumer applications, the
10
+ **Consumer Financial Protection Bureau's Circular 2023-03** is the
11
+ single most important federal regulatory guidance you need to comply
12
+ with. The headline rule, in one sentence: *the technological complexity
13
+ of an AI/ML model is not a defense for failing to provide ECOA-compliant
14
+ adverse-action reasons.* This guide covers what that means in
15
+ production, why generic reason codes are now legal liability, the
16
+ relationship to FCRA's parallel notice obligations, and what
17
+ explainability discipline a creditor needs in place before deploying an
18
+ AI/ML credit model at all.
19
+
20
+ ## What CFPB Circular 2023-03 actually says
21
+
22
+ On September 19, 2023, the CFPB issued [Circular 2023-03](https://www.consumerfinance.gov/compliance/circulars/circular-2023-03-adverse-action-notification-requirements-and-the-proper-use-of-the-cfpbs-sample-forms-provided-in-regulation-b/),
23
+ titled *"Adverse action notification requirements and the proper use of
24
+ the CFPB's sample forms provided in Regulation B."* The Circular
25
+ clarifies how the long-standing adverse-action obligations of the **Equal
26
+ Credit Opportunity Act** (15 U.S.C. § 1691(d)) and **Regulation B**
27
+ (12 CFR § 1002.9) apply when a creditor uses AI/ML models in credit
28
+ decisions.
29
+
30
+ The two operative holdings:
31
+
32
+ 1. **Specific, applicant-specific reasons are required.** When a creditor
33
+ takes adverse action against a credit applicant, the creditor must
34
+ provide a statement of the *specific principal reasons* that
35
+ adversely affected *the applicant's specific situation*. Generic
36
+ model-level explanations ("failed credit-decision model", "score
37
+ below cutoff", "credit application incomplete") are insufficient.
38
+ 2. **Technological complexity is not a defense.** A creditor cannot
39
+ evade the specific-reasons obligation by claiming that the underlying
40
+ AI/ML model is "too complex to explain." If the creditor cannot
41
+ accurately identify the specific reasons that drove the model's
42
+ adverse decision in this applicant's case, *the creditor likely
43
+ cannot lawfully use the model* for credit decisions at all.
44
+
45
+ The Circular is interpretive — it does not amend ECOA or Regulation B —
46
+ but it is the CFPB's authoritative position and has been treated as
47
+ binding in subsequent supervisory examinations.
48
+
49
+ ## Statutory teeth: ECOA penalties
50
+
51
+ The CFPB Circular interprets ECOA. The penalties for ECOA violations
52
+ come straight from the statute (15 U.S.C. § 1691e):
53
+
54
+ - **Actual damages** to the affected applicant.
55
+ - **Punitive damages** up to **$10,000 per individual action** or, in
56
+ class actions, the lesser of **$500,000 or 1% of the creditor's net
57
+ worth**.
58
+ - **Attorney's fees and costs** for prevailing applicants.
59
+ - **Equitable and declaratory relief** (e.g., orders to revise
60
+ adverse-action notice templates).
61
+
62
+ The CFPB also exercises **supervisory and enforcement authority** under
63
+ 12 U.S.C. § 5514 and § 5515, including civil money penalties under 12
64
+ U.S.C. § 5565 (up to $1,375,406 per day for knowing violations, in
65
+ 2026 dollars adjusted for inflation). ECOA enforcement remains a
66
+ declared CFPB priority through 2026.
67
+
68
+ ## Required elements of the adverse-action notice
69
+
70
+ Under Regulation B (12 CFR § 1002.9) as interpreted by Circular 2023-03,
71
+ an adverse-action notice on an AI-driven credit decision must include:
72
+
73
+ | Element | What it is | Examples |
74
+ |---|---|---|
75
+ | Specific principal reasons | Applicant-specific factors that drove this decision — not generic model-level language. | "(1) recent delinquencies on existing accounts; (2) high ratio of unsecured debt to monthly income; (3) short length of credit history" |
76
+ | Right-to-statement notice | Notice that the applicant may request a written statement of the specific reasons within 60 days, and the creditor will respond within 30 days. | (Statutory language, see CFPB sample forms) |
77
+ | ECOA equal-credit notice | Standard ECOA prohibited-bases statement and federal compliance agency identification. | (Standard language from Regulation B Appendix C) |
78
+ | Creditor name and address | Identity of the creditor making the decision. | — |
79
+
80
+ Plus the **governance-side** obligation that does not appear in the
81
+ notice but is essential to lawful deployment:
82
+
83
+ - **Model explainability sufficient to support per-applicant reason
84
+ codes.** This is the core compliance burden of Circular 2023-03 for
85
+ AI/ML credit models.
86
+
87
+ ## Why "specific principal reasons" is harder than it sounds
88
+
89
+ Most AI/ML credit models do not natively produce reason codes. A
90
+ gradient-boosted tree returns a score. A neural net returns a
91
+ probability. To extract per-applicant reasons, creditors typically use
92
+ **post-hoc explainability methods** — most commonly **SHAP** (SHapley
93
+ Additive exPlanations) or **LIME** (Local Interpretable Model-agnostic
94
+ Explanations).
95
+
96
+ The CFPB's position, in supervisory guidance and Circular 2023-03's
97
+ commentary, is that post-hoc explainability is **acceptable** as a
98
+ source of reason codes — *if* the creditor has validated that the
99
+ explanations actually reflect what drove the decision in each case.
100
+ Three traps:
101
+
102
+ 1. **Plausibility is not accuracy.** SHAP values can produce
103
+ plausible-sounding reason codes that don't match the model's actual
104
+ decision logic, especially for highly correlated features. The
105
+ creditor must validate that the generated reasons are *correct*, not
106
+ just *coherent*.
107
+ 2. **Feature aggregation matters.** A creditor often has many
108
+ correlated features (e.g., 15 different debt-utilization features).
109
+ If the SHAP attribution gets spread across all 15, no single one
110
+ crosses the threshold for "principal reason." The creditor needs a
111
+ feature-grouping policy that produces reportable reason codes.
112
+ 3. **The number of reason codes.** Regulation B's official commentary
113
+ suggests up to **four reason codes** is a typical maximum for one
114
+ adverse-action notice. The model needs a pipeline that produces a
115
+ ranked list of specific factors limited to that count.
116
+
117
+ ## The "lawfully use the model" trap
118
+
119
+ Circular 2023-03's most aggressive language is:
120
+
121
+ > *"If a creditor cannot accurately identify the specific reasons for
122
+ > the adverse action, the creditor likely cannot lawfully use the model
123
+ > for credit decisions."*
124
+
125
+ This is consequential. It implies a **per-model gating decision**: a
126
+ creditor must affirmatively determine, before deploying any AI/ML
127
+ credit model, that the model's decisions can be explained at the
128
+ per-applicant level with accuracy adequate to support reason codes. If
129
+ the model is a black box (opaque deep-learning ensemble with no
130
+ explainability layer, third-party scoring API that does not provide
131
+ reason codes, etc.), deploying it for credit decisions is itself an
132
+ ECOA violation — *independent* of any specific notice the creditor
133
+ sends.
134
+
135
+ This shifts the compliance burden upstream into model governance:
136
+ - Vendor due diligence: any third-party model must provide
137
+ per-applicant reason codes that the creditor has validated.
138
+ - Internal model approval: the model risk management framework
139
+ (consistent with SR 11-7 if the creditor is a federally-supervised
140
+ bank, or its functional equivalent for non-bank lenders) must
141
+ include explainability verification.
142
+ - Production monitoring: ongoing checks that explanations remain
143
+ accurate as the model is retrained.
144
+
145
+ ## Where the FCRA stacks
146
+
147
+ Many adverse credit actions are based "in whole or in part on a
148
+ consumer report" — which triggers a **parallel** notice obligation
149
+ under the **Fair Credit Reporting Act**, 15 U.S.C. § 1681m(a). The FCRA
150
+ notice has its own required elements:
151
+
152
+ - The name, address, and toll-free phone number of the consumer
153
+ reporting agency that provided the report.
154
+ - A statement that the CRA did not make the adverse decision and
155
+ cannot explain it.
156
+ - Notice of the consumer's right to obtain a free copy of the report
157
+ within 60 days.
158
+ - Notice of the consumer's right to dispute information in the report.
159
+
160
+ Under 12 CFR § 1002.9(b)(2) and FCRA practice, both sets of obligations
161
+ can be satisfied in **one combined notice** — but both sets of required
162
+ elements must appear. AI/ML credit models that consume CRA data
163
+ (virtually all consumer-credit AI models) fall under both regimes.
164
+
165
+ ## Adverse-action timing under Regulation B
166
+
167
+ Independently of content, Regulation B (12 CFR § 1002.9(a)) imposes
168
+ **timing** requirements:
169
+
170
+ - **30 days** from receipt of a completed application to send adverse-
171
+ action notice.
172
+ - **30 days** from taking adverse action on an existing account.
173
+ - **90 days** from notifying the applicant of a counter-offer if the
174
+ applicant did not accept the counter-offer.
175
+
176
+ AI/ML credit decisions are typically faster than these limits, but
177
+ batch-pipeline architectures need to ensure the notice-generation
178
+ service runs within the deadline even when the model retrains, model
179
+ serving fails over, or compliance review queues create delay.
180
+
181
+ ## Common compliance failure patterns
182
+
183
+ - **Boilerplate reason codes.** "Application did not meet underwriting
184
+ criteria" or "score below threshold." Per Circular 2023-03, these
185
+ are insufficient on their face. Each notice must reference
186
+ applicant-specific factors.
187
+ - **Reason codes derived from the wrong model layer.** A creditor
188
+ whose production model is an XGBoost ensemble but whose reason codes
189
+ are pulled from a separate "explainer" linear model trained on the
190
+ same data is at risk: the reason codes don't reflect the actual
191
+ model's decision logic.
192
+ - **Unvalidated SHAP outputs.** Using raw SHAP values as reason codes
193
+ without any validation that the high-attribution features actually
194
+ drove the decision in this case.
195
+ - **Missing FCRA notice elements.** Adverse-action notices that meet
196
+ ECOA but omit FCRA's CRA identification and dispute-rights language.
197
+ - **No model-governance gate.** Deploying a third-party scoring API
198
+ without validating that the API's reason codes meet ECOA's
199
+ specificity requirement.
200
+ - **Late notice on AI-batch decisions.** A weekly scoring batch that
201
+ produces decisions on day 0 but doesn't generate notices until day
202
+ 35 — past the 30-day deadline.
203
+
204
+ ## How plainstamp helps
205
+
206
+ `plainstamp` ships a `us-cfpb-circular-2023-03-ai-adverse-action` rule
207
+ that returns the live disclosure-element checklist for AI-driven
208
+ adverse-action notices, plain-language and formal-language templates,
209
+ citation back to ECOA + Regulation B + Circular 2023-03, and a
210
+ `last_verified` date. Lookup:
211
+
212
+ ```bash
213
+ npx plainstamp lookup --jurisdiction us \
214
+ --channel email-transactional \
215
+ --use-case financial-services
216
+ ```
217
+
218
+ Returns the CFPB rule alongside any other federal financial-services
219
+ rules that apply (e.g., FINRA RN 24-09 on AI in customer
220
+ communications). For US-based lenders also operating in EU markets,
221
+ query `--jurisdiction eu` to layer the GDPR Article 22 automated-
222
+ decision-making obligations on top.
223
+
224
+ ## The minimum viable compliance posture
225
+
226
+ If your AI-credit deployment is starting from zero on Circular 2023-03
227
+ compliance, ship these four artifacts in order:
228
+
229
+ 1. **Per-applicant reason-code pipeline.** A documented pipeline that
230
+ produces ≤4 specific reason codes for every adverse decision, with
231
+ evidence the codes reflect applicant-specific factors.
232
+ 2. **Model explainability validation.** Documentation that the
233
+ reason-code pipeline produces accurate explanations — not merely
234
+ plausible ones. SHAP / LIME / counterfactual-based methods are
235
+ acceptable; what matters is the validation evidence.
236
+ 3. **Combined ECOA + FCRA adverse-action notice template.** A single
237
+ template that satisfies both regimes' required elements when CRA
238
+ data was used.
239
+ 4. **Notice-generation SLA.** Production monitoring that adverse-
240
+ action notices are generated and delivered within Regulation B's
241
+ 30-day deadline, with escalation when the SLA is at risk.
242
+
243
+ Then layer the higher-fidelity work — fairness testing, disparate-
244
+ impact analysis, ongoing model performance review — onto the higher-
245
+ risk products first.
246
+
247
+ ## Source-of-truth links
248
+
249
+ - **CFPB Circular 2023-03** ([consumerfinance.gov](https://www.consumerfinance.gov/compliance/circulars/circular-2023-03-adverse-action-notification-requirements-and-the-proper-use-of-the-cfpbs-sample-forms-provided-in-regulation-b/))
250
+ - **Equal Credit Opportunity Act, 15 U.S.C. § 1691(d)** ([uscode.house.gov](https://uscode.house.gov/view.xhtml?req=granuleid:USC-prelim-title15-section1691&num=0&edition=prelim))
251
+ - **Regulation B, 12 CFR § 1002.9 (adverse-action notices)** ([ecfr.gov](https://www.ecfr.gov/current/title-12/chapter-X/part-1002/section-1002.9))
252
+ - **Fair Credit Reporting Act, 15 U.S.C. § 1681m (FCRA adverse-action notices)** ([uscode.house.gov](https://uscode.house.gov/view.xhtml?req=granuleid:USC-prelim-title15-section1681m&num=0&edition=prelim))
253
+ - **CFPB sample adverse-action forms (Regulation B Appendix C)** ([ecfr.gov](https://www.ecfr.gov/current/title-12/chapter-X/part-1002/appendix-Appendix%20C%20to%20Part%201002))
254
+
255
+ `plainstamp` is maintained by an autonomous AI agent operating under
256
+ KS Elevated Solutions LLC. Accuracy reports, rule-update suggestions,
257
+ and security disclosures: [helpfulbutton140@agentmail.to](mailto:helpfulbutton140@agentmail.to).
258
+
259
+ ---
260
+
261
+ [`← Back to plainstamp`](https://plainstamp.pages.dev/)
@@ -0,0 +1,301 @@
1
+ # FINRA Regulatory Notice 24-09 (AI in customer communications): a builder's guide
2
+
3
+ > **Informational only — not legal advice.** Verify against the cited
4
+ > regulator-published text and consult counsel for production deployments.
5
+ > See `AI-DISCLOSURE.md` in this package.
6
+
7
+ If your broker-dealer, registered representative platform, or
8
+ fintech-with-securities-business uses generative AI or large-language
9
+ models for any customer-facing purpose — chatbots that respond to
10
+ client questions, AI-drafted research summaries, AI-generated email
11
+ templates sent to clients, AI-suggested portfolio actions, AI-powered
12
+ voice agents on the phone with retail customers — **FINRA Regulatory
13
+ Notice 24-09** applies to you. It does not create new rules. It
14
+ clarifies that the existing FINRA rulebook applies, in full, to
15
+ AI-driven communications and AI-driven recommendations. This guide
16
+ covers what that means in production, the six existing rules that
17
+ matter most, the third-party-vendor responsibility doctrine, and what
18
+ written supervisory procedures (WSPs) need to cover before deployment.
19
+
20
+ ## What FINRA Regulatory Notice 24-09 actually says
21
+
22
+ On June 27, 2024, FINRA issued [Regulatory Notice 24-09](https://www.finra.org/rules-guidance/notices/24-09),
23
+ *"FINRA Reminds Member Firms of Their Obligations When Using Generative
24
+ Artificial Intelligence and Large Language Models."*
25
+
26
+ The Notice has two operative parts:
27
+
28
+ 1. **Existing FINRA rules apply to AI tools.** Member firms using
29
+ generative AI in their securities business remain subject to all
30
+ existing FINRA rules — supervision (Rule 3110), communications with
31
+ the public (Rule 2210), suitability (Rule 2111), KYC (Rule 2090),
32
+ books-and-records (Rule 4511), and gifts and gratuities (Rule 3220).
33
+ 2. **Member firms remain responsible even when the tool is
34
+ third-party.** Outsourcing AI tool development or operation to a
35
+ vendor does not shift the firm's obligations. Vendor due diligence
36
+ and ongoing oversight are part of Rule 3110 supervision.
37
+
38
+ Notice 24-09 also flags risk areas — hallucination, bias, data privacy,
39
+ intellectual-property exposure — that firms should address in their
40
+ written supervisory procedures.
41
+
42
+ The Notice is "reminder-and-clarification" guidance: no new rule, no
43
+ new compliance date, no new penalty. The binding obligations come from
44
+ the existing rule text. But by issuing the Notice, FINRA established
45
+ that AI use without WSP coverage of these rules is, at minimum, a
46
+ **Rule 3110 supervision deficiency** by definition.
47
+
48
+ ## The six rules that matter
49
+
50
+ ### Rule 2210 — communications with the public
51
+
52
+ **The standard.** All communications with the public must be fair,
53
+ balanced, and not misleading. Communications cannot omit material
54
+ information that would render them misleading. Specific communication
55
+ categories (retail communications, correspondence, institutional
56
+ communications) have specific principal-review, filing, and approval
57
+ requirements.
58
+
59
+ **How it applies to AI.** Any output of an AI tool that is delivered
60
+ to a customer or prospective customer is a "communication with the
61
+ public." That includes:
62
+
63
+ - Chatbot responses to customer questions.
64
+ - AI-generated email templates sent to clients.
65
+ - AI-drafted market commentary, research summaries, or "explainers."
66
+ - AI-suggested replies that a human rep then sends.
67
+
68
+ The Rule 2210 categorization (retail vs. correspondence vs.
69
+ institutional) and the corresponding pre-approval / filing workflow
70
+ applies on the same terms as for human-generated communications. An
71
+ AI-generated retail communication still needs principal pre-approval
72
+ under Rule 2210(b)(1)(A) before delivery.
73
+
74
+ ### Rule 3110 — supervision
75
+
76
+ **The standard.** A member firm must establish and maintain a
77
+ supervisory system, including written supervisory procedures, that is
78
+ reasonably designed to achieve compliance with applicable securities
79
+ laws and FINRA rules.
80
+
81
+ **How it applies to AI.** Any AI tool used in the firm's securities
82
+ business — internally developed, third-party SaaS, fine-tuned model,
83
+ agentic system — must be brought under the firm's supervisory system.
84
+ That means:
85
+
86
+ - Identification of AI tools in use (inventory).
87
+ - WSPs that address AI tool review, monitoring, and exception
88
+ handling.
89
+ - Designated principal responsible for AI-tool oversight.
90
+ - Vendor due diligence for any third-party AI tool, with ongoing
91
+ monitoring.
92
+
93
+ A firm using AI without WSP coverage of these elements has a Rule
94
+ 3110 deficiency on the face of it.
95
+
96
+ ### Rule 2111 — suitability
97
+
98
+ **The standard.** Recommendations to retail customers must be
99
+ suitable based on the customer's investment profile. Reg BI extends
100
+ the standard to a "best interest" obligation for broker-dealers
101
+ recommending to retail customers.
102
+
103
+ **How it applies to AI.** AI-generated investment recommendations are
104
+ subject to Rule 2111 (and Reg BI where applicable) on the same terms
105
+ as human-generated recommendations. The recommendation must be
106
+ evaluated against the customer's investment profile. The firm cannot
107
+ escape suitability review by saying the AI generated it.
108
+
109
+ Production implication: any recommendation pipeline that includes an
110
+ AI-generation step must include a suitability-evaluation step before
111
+ the recommendation reaches the customer. The "AI-suggested + rep
112
+ delivers" pattern only complies if the rep performs the suitability
113
+ review; "AI-suggested + auto-delivered" requires the suitability check
114
+ to be in the automation.
115
+
116
+ ### Rule 2090 — Know Your Customer
117
+
118
+ **The standard.** Firms must use reasonable diligence to know
119
+ essential facts about every customer.
120
+
121
+ **How it applies to AI.** AI tools that condition responses on
122
+ customer data — personalized chatbots, individualized risk-assessment
123
+ agents — must use customer data that satisfies Rule 2090's diligence
124
+ standard. Don't feed a customer-facing AI a customer profile the firm
125
+ hasn't reasonably verified.
126
+
127
+ ### Rule 4511 — books and records
128
+
129
+ **The standard.** Member firms must make and preserve books and
130
+ records as required by SEA Rules 17a-3 and 17a-4 and applicable FINRA
131
+ rules.
132
+
133
+ **How it applies to AI.** AI inputs and outputs that constitute
134
+ communications with customers are records subject to Rule 4511's
135
+ preservation requirements. That means:
136
+
137
+ - Chatbot conversations (full transcripts) must be preserved.
138
+ - AI-generated email content (the actual text sent) must be preserved.
139
+ - Where the AI tool was used in a regulated activity, the prompts and
140
+ outputs must be retrievable in response to FINRA or SEC inquiry.
141
+
142
+ Rule 4511 incorporates SEA Rule 17a-4(b)(4)'s 3-year retention period
143
+ for communications, with WORM (write-once, read-many) format
144
+ requirements for the first 2 years. Production AI tools need a
145
+ recording layer that satisfies WORM and retention obligations.
146
+
147
+ ### Rule 3220 — gifts and gratuities
148
+
149
+ **The standard.** $100/year per recipient cap on gifts; non-cash
150
+ compensation rules apply to promotional items.
151
+
152
+ **How it applies to AI.** AI-generated promotional materials, branded
153
+ giveaways, and content marketing fall under Rule 3220 standards if
154
+ delivered with associated gifts or non-cash compensation. The Notice
155
+ flags this primarily as a reminder; in practice it applies to firms
156
+ running AI-generated marketing campaigns alongside gift programs.
157
+
158
+ ## Third-party vendor responsibility
159
+
160
+ The most consequential clarification in Notice 24-09 is that **member
161
+ firm obligations persist when the AI tool is operated by a third-party
162
+ vendor**. Buying a chatbot from a vendor does not transfer Rule 3110
163
+ supervision or Rule 2210 communication standards to the vendor. The
164
+ firm remains responsible.
165
+
166
+ What this means in production:
167
+
168
+ - **Pre-deployment vendor due diligence.** Before deploying a
169
+ third-party AI tool, the firm must evaluate the vendor's controls,
170
+ including model accuracy, data handling, output review mechanisms,
171
+ and incident response.
172
+ - **Ongoing oversight.** The firm must monitor vendor performance and
173
+ output quality on an ongoing basis — not just at procurement time.
174
+ - **Written agreement coverage.** Vendor contracts should include
175
+ audit rights, data-handling provisions, and incident notification
176
+ obligations. The firm cannot meet Rule 3110 with a contract that
177
+ doesn't permit visibility into the vendor's AI tool operation.
178
+ - **Records access.** The firm must be able to produce records
179
+ generated by the vendor's tool in response to FINRA or SEC inquiry,
180
+ on the firm's regular response timeline.
181
+
182
+ The "vendor pattern" most at risk: a firm uses a SaaS AI chatbot
183
+ hosted entirely by the vendor, with no per-message logging into the
184
+ firm's systems and no audit rights in the contract. This is a Rule
185
+ 3110 violation independent of any specific output.
186
+
187
+ ## Where the SEC layers on top
188
+
189
+ FINRA member firms registered as broker-dealers also face SEC
190
+ obligations that overlap with Notice 24-09's scope. Two to be aware of:
191
+
192
+ - **SEC Staff Bulletin on AI/PDA conflicts of interest (July 2023).**
193
+ The SEC's Division of Examinations and Division of Trading and
194
+ Markets issued joint guidance on conflicts of interest arising from
195
+ AI and predictive data analytics use by broker-dealers and
196
+ investment advisers. The bulletin emphasizes that firms must
197
+ identify, disclose, and address conflicts created by AI/PDA tools.
198
+ - **SEC Proposed Rule on Predictive Data Analytics (Rel. No.
199
+ 34-97990, July 2023).** Would require broker-dealers and
200
+ investment advisers using PDA in investor-facing activities to
201
+ identify and address conflicts of interest associated with the
202
+ technology. Status: proposed; not finalized as of 2026-05-08.
203
+ Firms should monitor for finalization.
204
+ - **Investment Advisers Act fiduciary duty.** For dual-registered
205
+ firms, the IAA fiduciary duty applies to AI-driven advice on the
206
+ same terms as human-driven advice.
207
+
208
+ ## State-level overlays to be aware of
209
+
210
+ - **NYDFS October 2024 cybersecurity / AI guidance.** Applies to
211
+ NYDFS-licensed entities (NY-licensed insurers, banks, money
212
+ transmitters, virtual currency licensees). Covers AI-related
213
+ cybersecurity risks; firms must address AI tool risks under their
214
+ 23 NYCRR 500 cybersecurity programs.
215
+ - **NAIC Model Bulletin on AI use by insurers (December 2023).**
216
+ Adopted in form by multiple states. Applies to insurer use of AI;
217
+ not directly to broker-dealers but relevant for firms with
218
+ cross-affiliated insurance operations.
219
+
220
+ ## Common compliance failure patterns
221
+
222
+ - **WSPs that don't mention AI.** A firm has deployed an AI chatbot
223
+ but its written supervisory procedures don't address AI tool use,
224
+ vendor oversight, or hallucination risk. Rule 3110 deficiency on
225
+ inspection.
226
+ - **No principal review of AI-generated retail communications.** AI
227
+ produces customer-facing content that goes out without principal
228
+ pre-approval under Rule 2210(b)(1)(A).
229
+ - **Records gap.** AI chatbot conversations are stored only in the
230
+ vendor's system, with no copy in the firm's WORM-compliant records
231
+ store.
232
+ - **Hallucination tolerance.** A firm deploys an AI tool that
233
+ occasionally states market facts that are wrong, treating it as
234
+ acceptable error. Rule 2210's "not misleading" standard is
235
+ violated by every such output.
236
+ - **Suitability gap on AI-suggested actions.** An AI tool suggests
237
+ trades or portfolio changes; the rep delivers them without an
238
+ individual suitability evaluation against the customer's profile.
239
+ - **Vendor opacity.** Firm cannot produce AI tool inputs or outputs
240
+ on demand because the vendor's system doesn't expose them.
241
+
242
+ ## How plainstamp helps
243
+
244
+ `plainstamp` ships a `us-finra-rn-24-09-ai-customer-communications`
245
+ rule that returns the live disclosure-element checklist, plain-
246
+ language and formal-language disclosure templates suitable for
247
+ inclusion in AI-generated customer communications, citation back to
248
+ all six FINRA rules + RN 24-09, and a `last_verified` date. Lookup:
249
+
250
+ ```bash
251
+ npx plainstamp lookup --jurisdiction us \
252
+ --channel live-chat \
253
+ --use-case financial-services
254
+ ```
255
+
256
+ Returns the FINRA rule alongside the CFPB AI adverse-action rule and
257
+ any other federal financial-services rules. For broker-dealer
258
+ operations in California or other state-regulated environments, layer
259
+ state-jurisdiction queries to capture the additional state overlays.
260
+
261
+ ## The minimum viable compliance posture
262
+
263
+ If your firm is starting from zero on Notice 24-09 compliance, ship
264
+ these five artifacts in order:
265
+
266
+ 1. **AI-tool inventory.** A maintained list of every AI tool in use
267
+ in the firm's securities business, with owner, vendor (if any),
268
+ purpose, and customer-facing flag.
269
+ 2. **WSP update.** WSPs that explicitly address AI tool use under
270
+ each of Rules 2210, 3110, 2111, 2090, 4511, and 3220, plus
271
+ hallucination / bias / data-privacy / IP risk.
272
+ 3. **Records pipeline.** AI tool inputs and outputs flowing into the
273
+ firm's existing WORM-compliant records store, with the same
274
+ retention rules as other customer communications.
275
+ 4. **Principal review workflow.** AI-generated retail communications
276
+ reviewed by a qualified principal under Rule 2210 before delivery.
277
+ 5. **Vendor due diligence file.** Where third-party AI tools are
278
+ used, a documented due-diligence file with audit rights, data
279
+ handling, incident response, and ongoing-monitoring evidence.
280
+
281
+ Then layer the higher-fidelity work — output-quality monitoring,
282
+ hallucination-rate metrics, conflict-of-interest analysis — onto the
283
+ higher-risk tools first.
284
+
285
+ ## Source-of-truth links
286
+
287
+ - **FINRA Regulatory Notice 24-09** ([finra.org](https://www.finra.org/rules-guidance/notices/24-09))
288
+ - **FINRA Rule 2210 (Communications with the Public)** ([finra.org](https://www.finra.org/rules-guidance/rulebooks/finra-rules/2210))
289
+ - **FINRA Rule 3110 (Supervision)** ([finra.org](https://www.finra.org/rules-guidance/rulebooks/finra-rules/3110))
290
+ - **FINRA Rule 2111 (Suitability)** ([finra.org](https://www.finra.org/rules-guidance/rulebooks/finra-rules/2111))
291
+ - **FINRA Rule 2090 (Know Your Customer)** ([finra.org](https://www.finra.org/rules-guidance/rulebooks/finra-rules/2090))
292
+ - **FINRA Rule 4511 (Books and Records)** ([finra.org](https://www.finra.org/rules-guidance/rulebooks/finra-rules/4511))
293
+ - **SEC Proposed Rule on PDA Conflicts (Rel. No. 34-97990)** ([sec.gov](https://www.sec.gov/rules-regulations/2023/07/s7-12-23))
294
+
295
+ `plainstamp` is maintained by an autonomous AI agent operating under
296
+ KS Elevated Solutions LLC. Accuracy reports, rule-update suggestions,
297
+ and security disclosures: [helpfulbutton140@agentmail.to](mailto:helpfulbutton140@agentmail.to).
298
+
299
+ ---
300
+
301
+ [`← Back to plainstamp`](https://plainstamp.pages.dev/)
@@ -0,0 +1,268 @@
1
+ # HHS Section 1557 (Patient Care Decision Support Tools): a builder's guide
2
+
3
+ > **Informational only — not legal advice.** Verify against the cited
4
+ > regulator-published text and consult counsel for production deployments.
5
+ > See `AI-DISCLOSURE.md` in this package.
6
+
7
+ If your healthcare organization deploys an AI/ML clinical decision-support
8
+ tool — sepsis risk scores, discharge risk models, prior-auth scoring, AI
9
+ triage chatbots, anything that informs a care decision — and the
10
+ organization receives any federal financial assistance (Medicare,
11
+ Medicaid, federally-qualified health center funding, etc.), HHS Section
12
+ 1557's **Patient Care Decision Support Tool (PCDST) nondiscrimination
13
+ rule** applies to you. The rule has been enforceable since **May 1, 2025**
14
+ and is one of the most concrete federal AI compliance regimes operating
15
+ today. This guide covers what it requires, who is covered, what counts
16
+ as compliance, and the elements that catch builders off guard.
17
+
18
+ ## What 45 CFR § 92.210 actually requires
19
+
20
+ On May 6, 2024, the U.S. Department of Health and Human Services Office
21
+ for Civil Rights (HHS OCR) published a final rule (89 Fed. Reg. 37522)
22
+ implementing Section 1557 of the Affordable Care Act (42 U.S.C. § 18116).
23
+ The rule, codified at 45 CFR Part 92 and effective in stages with PCDST
24
+ enforcement starting May 1, 2025, imposes nondiscrimination obligations
25
+ on covered entities' use of "patient care decision support tools" — a
26
+ deliberately broad category that **includes AI/ML-based clinical
27
+ decision support**.
28
+
29
+ A covered entity must:
30
+
31
+ 1. **Identify uses of PCDSTs** in its health programs and activities that
32
+ employ input variables or factors that measure race, color, national
33
+ origin, sex, age, or disability.
34
+ 2. **Mitigate the risk of discrimination** resulting from each such tool's
35
+ use.
36
+
37
+ Both obligations are framed as "reasonable efforts" — OCR has stated in
38
+ commentary that what is reasonable scales with the entity's size, resources,
39
+ and the tool's risk profile. But documentation of those efforts is essential.
40
+
41
+ Penalties: loss of federal financial assistance, OCR-imposed corrective
42
+ action plans, potential private right-of-action discrimination claims,
43
+ and reputational fallout. OCR has historically taken Section 1557 seriously
44
+ in enforcement.
45
+
46
+ ## What's a "PCDST" — and why it sweeps in basically every clinical AI
47
+
48
+ OCR's definition of patient care decision support tool is broad on
49
+ purpose:
50
+
51
+ > *"any automated or non-automated tool, mechanism, method, technology,
52
+ > or combination thereof used by a covered entity to support clinical
53
+ > decision-making in its health programs or activities."*
54
+
55
+ This explicitly includes:
56
+
57
+ - **AI/ML clinical decision support** tools (the central focus of OCR's
58
+ commentary).
59
+ - **Rule-based scoring algorithms** (e.g., MEWS, NEWS, qSOFA, CHA₂DS₂-VASc).
60
+ - **Tools that consume race, sex, age, etc. as input variables** — the
61
+ Epic Sepsis Model, the Beth Israel Deaconess Discharge Risk Score, and
62
+ many commonly-deployed risk scores.
63
+ - **Tools that produce clinical scores** even where the underlying
64
+ computation is non-AI. Statistical models count.
65
+ - **Triage and routing tools** that affect access to clinical resources.
66
+
67
+ The "non-automated" inclusion is significant: paper-based scoring sheets
68
+ that a clinician uses to allocate care also count. The rule is not
69
+ specific to digital tools.
70
+
71
+ Three definitional gotchas:
72
+
73
+ - **"Used by a covered entity to support clinical decision-making."** A
74
+ tool merely available in the EHR but never actually consulted in a
75
+ clinical decision is arguably not in scope. A tool that's part of any
76
+ routine workflow — even informally — is in scope.
77
+ - **"Input variables or factors that measure race, color, national origin,
78
+ sex, age, or disability."** This is broader than just having a literal
79
+ "race" field. Tools that use ZIP code (proxy for race), insurance type
80
+ (proxy for income/national origin), or chronic condition counts (proxy
81
+ for disability) are within the identification obligation.
82
+ - **OCR's "reasonable efforts" standard scales but doesn't disappear.**
83
+ A small rural clinic doesn't have the same compliance burden as a
84
+ major academic medical center, but both must do something.
85
+
86
+ ## Who is a "covered entity"
87
+
88
+ Section 1557 applies broadly to any health program or activity that
89
+ receives federal financial assistance. In practice this includes:
90
+
91
+ - **Most healthcare providers** that participate in Medicare or Medicaid
92
+ (effectively almost all hospitals, most physician practices, most
93
+ long-term care facilities).
94
+ - **Federally-qualified health centers** and their clinical operations.
95
+ - **Health insurers in HHS-administered marketplaces** (and many
96
+ Medicaid managed care organizations).
97
+ - **HHS-administered programs** themselves (Indian Health Service, etc.).
98
+ - **Any program receiving federal grants** with health-related components.
99
+
100
+ Three exclusions to know about:
101
+
102
+ - **ERISA self-funded employer health plans** that don't otherwise
103
+ receive federal financial assistance are typically outside Section 1557
104
+ (though they may have parallel obligations under ERISA + state law).
105
+ - **Cash-only or fully-private practices** that decline all federal
106
+ funding may be outside Section 1557 (rare; most providers participate
107
+ in Medicare).
108
+ - **Federal contractors providing non-health services** — not in scope
109
+ even if their contractor receives federal money.
110
+
111
+ ## What "reasonable efforts" actually looks like
112
+
113
+ OCR commentary and informal guidance suggest a **risk-tiered approach**:
114
+
115
+ **Higher-risk tools (more documentation expected):**
116
+ - Tools that explicitly use race, sex, age, or disability as input
117
+ variables.
118
+ - Tools used in life-threatening contexts (sepsis prediction, organ
119
+ transplant risk).
120
+ - Tools that affect resource allocation across patients (ICU bed
121
+ triage, transplant priority).
122
+
123
+ **Lower-risk tools (lighter documentation acceptable):**
124
+ - Tools that don't use protected-class variables.
125
+ - Tools that surface information without producing a ranking or score.
126
+ - Tools whose output is one of many factors in a clinician's
127
+ unstructured judgment.
128
+
129
+ Concrete documentation to maintain for each PCDST:
130
+
131
+ 1. **Tool inventory entry** — name, vendor, purpose, deployment date,
132
+ input variables (with notation of any protected-class factors), use
133
+ cases, decision contexts.
134
+ 2. **Mitigation documentation** — what the entity has done to identify
135
+ and mitigate the risk of discriminatory output. Examples: vendor's
136
+ bias-audit report, internal performance comparison across protected
137
+ classes, threshold adjustments, monitoring dashboards.
138
+ 3. **Designation** — the Civil Rights Coordinator (a Section 1557 §
139
+ 92.7 requirement) is responsible for PCDST nondiscrimination.
140
+ 4. **Periodic review** — at least annual review of the tool's
141
+ performance, documented.
142
+
143
+ ## The patient-facing element (most builders miss this)
144
+
145
+ The PCDST rule's primary obligation is *governance-side* — identification
146
+ and mitigation. But where the entity exposes AI-informed decisions to
147
+ patients (or where notice-of-availability obligations under § 92.11 apply),
148
+ a **patient-facing notice** that automated tools may inform clinical
149
+ decisions is also expected. The notice typically lives in:
150
+
151
+ - The Section 1557 notice of nondiscrimination (printed and posted
152
+ per § 92.10).
153
+ - Patient-facing materials about specific decisions (denial letters,
154
+ triage explanations).
155
+
156
+ Plain-language template:
157
+
158
+ > *"Notice — Use of Decision-Support Tools in Your Care: Some clinical
159
+ > decisions in your care may be informed by automated decision-support
160
+ > tools, including artificial-intelligence and machine-learning systems.
161
+ > These tools assist your healthcare team and do not replace the
162
+ > judgment of a licensed clinician. You have the right to discuss any
163
+ > care decision with your provider. If you believe you have experienced
164
+ > discrimination on the basis of race, color, national origin, sex, age,
165
+ > or disability in connection with these tools or any other aspect of
166
+ > your care, please contact our Civil Rights Coordinator at [contact]
167
+ > or file a complaint with the HHS Office for Civil Rights at
168
+ > https://www.hhs.gov/ocr/."*
169
+
170
+ ## How Section 1557 stacks with other rules
171
+
172
+ Section 1557 is the federal floor for healthcare AI nondiscrimination.
173
+ Builders deploying AI/ML clinical tools at scale need to layer:
174
+
175
+ - **California SB 1120 (Physicians Make Decisions Act)** — adds a
176
+ *procedural* requirement: AI used in utilization review for medical
177
+ necessity must be reviewed by a licensed physician considering the
178
+ enrollee's clinical circumstances. Effective January 1, 2025.
179
+ California-specific.
180
+ - **FDA Predetermined Change Control Plans (FD&C Act § 515C, December
181
+ 2024 final guidance)** — applies to AI/ML medical devices that have
182
+ been cleared/authorized by FDA. Adds device-labeling AI/ML disclosure
183
+ obligations.
184
+ - **HIPAA Privacy Rule (45 CFR Part 164)** — separate privacy regime.
185
+ Section 1557 doesn't change HIPAA; both apply.
186
+ - **State medical-board rules** on AI in scope of practice (Texas,
187
+ several others have specific scope-of-practice rules for AI).
188
+ - **EU AI Act + GDPR Art. 22** — for any care delivered to EU residents,
189
+ including telehealth.
190
+ - **NIST AI RMF + healthcare-sector profile** — voluntary but widely
191
+ treated as a benchmark by hospital AI committees.
192
+
193
+ ## Common compliance pitfalls
194
+
195
+ - **Treating "vendor said the model was bias-audited" as enough.** OCR
196
+ commentary expects the covered entity to do its own due diligence;
197
+ vendor audits are an input, not a substitute.
198
+ - **Forgetting non-AI tools.** The rule covers any decision-support
199
+ tool, not just AI. Rule-based scoring tools that use protected-class
200
+ variables are within scope.
201
+ - **Documenting only the highest-risk tools.** OCR expects an
202
+ identification process for *all* PCDSTs, even if most have minimal
203
+ mitigation documentation.
204
+ - **No designated Civil Rights Coordinator with PCDST awareness.** The
205
+ Coordinator role under § 92.7 needs to know about the entity's AI/ML
206
+ tools; siloing AI governance from CRC creates compliance gaps.
207
+ - **Skipping the patient-facing language** under the assumption that
208
+ PCDST obligations are purely governance. Where AI informs decisions
209
+ exposed to patients, notice is expected.
210
+ - **Annual review never happens.** Documentation that the tool's
211
+ performance is monitored and reviewed is part of the "reasonable
212
+ efforts" standard.
213
+
214
+ ## How plainstamp helps
215
+
216
+ `plainstamp` ships an `us-hhs-section-1557-pcdst-2024` rule that
217
+ returns the live disclosure-element checklist for the PCDST regime,
218
+ plain-language and formal-language patient-facing notices, citation
219
+ back to 45 CFR § 92.210 + the Federal Register source URL, and a
220
+ `last_verified` date. Lookup:
221
+
222
+ ```bash
223
+ npx plainstamp lookup --jurisdiction us \
224
+ --channel ai-generated-content \
225
+ --use-case healthcare
226
+ ```
227
+
228
+ Returns the Section 1557 PCDST rule. For California-operating entities,
229
+ also query `--jurisdiction us-ca` to layer on SB 1120's
230
+ physician-review requirement.
231
+
232
+ For multi-jurisdiction systems, query each state's healthcare
233
+ jurisdiction in parallel — the disclosure copy must satisfy each
234
+ applicable layer.
235
+
236
+ ## The minimum viable compliance posture
237
+
238
+ If your organization is starting from zero on PCDST nondiscrimination,
239
+ ship these four artifacts in order:
240
+
241
+ 1. **PCDST inventory** — a spreadsheet/database of every clinical
242
+ decision-support tool in use, with input variables and protected-
243
+ class flags.
244
+ 2. **Civil Rights Coordinator briefing** — your CRC reads the inventory
245
+ and signs off that mitigation efforts are documented for each tool.
246
+ 3. **Patient-facing notice** — added to the entity's Section 1557
247
+ nondiscrimination notice and to patient-facing materials about
248
+ AI-informed decisions.
249
+ 4. **Annual review schedule** — calendar entry for next-year review
250
+ of each tool's performance and mitigation.
251
+
252
+ Then, layer the higher-fidelity work — vendor diligence, performance
253
+ testing, bias audits — onto the higher-risk tools first.
254
+
255
+ ## Source-of-truth links
256
+
257
+ - **45 CFR § 92.210 (PCDST nondiscrimination)** ([ecfr.gov](https://www.ecfr.gov/current/title-45/subtitle-A/subchapter-A/part-92/subpart-C/section-92.210))
258
+ - **HHS OCR final rule, May 6, 2024 (89 Fed. Reg. 37522)** ([federalregister.gov](https://www.federalregister.gov/documents/2024/05/06/2024-08711/nondiscrimination-in-health-programs-and-activities))
259
+ - **Section 1557 of the ACA (42 U.S.C. § 18116)** ([uscode.house.gov](https://uscode.house.gov/view.xhtml?req=granuleid:USC-prelim-title42-section18116&num=0&edition=prelim))
260
+ - **HHS OCR Section 1557 program page** ([hhs.gov/ocr](https://www.hhs.gov/civil-rights/for-providers/laws-regulations-guidance/laws/section-1557/index.html))
261
+
262
+ `plainstamp` is maintained by an autonomous AI agent operating under
263
+ KS Elevated Solutions LLC. Accuracy reports, rule-update suggestions,
264
+ and security disclosures: [helpfulbutton140@agentmail.to](mailto:helpfulbutton140@agentmail.to).
265
+
266
+ ---
267
+
268
+ [`← Back to plainstamp`](https://plainstamp.pages.dev/)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "plainstamp",
3
- "version": "0.7.1",
3
+ "version": "0.7.3",
4
4
  "description": "AI disclosure compliance assistant — generates legally-grounded AI disclosure text per (jurisdiction × channel × use-case) and tracks regulatory updates. Operated by an autonomous AI agent under KS Elevated Solutions LLC.",
5
5
  "type": "module",
6
6
  "license": "MIT",