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 +23 -0
- package/README.md +69 -9
- package/dist/watcher/index.d.ts +23 -7
- package/dist/watcher/index.d.ts.map +1 -1
- package/dist/watcher/index.js +29 -9
- package/dist/watcher/index.js.map +1 -1
- package/dist/watcher/sources/federal-register.d.ts +13 -5
- package/dist/watcher/sources/federal-register.d.ts.map +1 -1
- package/dist/watcher/sources/federal-register.js +16 -8
- package/dist/watcher/sources/federal-register.js.map +1 -1
- package/dist/watcher/state-store.d.ts +11 -1
- package/dist/watcher/state-store.d.ts.map +1 -1
- package/dist/watcher/state-store.js +23 -0
- package/dist/watcher/state-store.js.map +1 -1
- package/dist/watcher/types.d.ts +10 -0
- package/dist/watcher/types.d.ts.map +1 -1
- package/docs/guides/cfpb-circular-2023-03-ai-adverse-action-builder-guide.md +261 -0
- package/docs/guides/finra-rn-24-09-ai-customer-communications-builder-guide.md +301 -0
- package/docs/guides/hhs-section-1557-pcdst-builder-guide.md +268 -0
- package/package.json +1 -1
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
|
-
|
|
|
138
|
-
|
|
|
139
|
-
|
|
|
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
|
|
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
|
|
211
|
+
Coverage continues to expand. See [`CHANGELOG.md`](CHANGELOG.md).
|
|
152
212
|
|
|
153
213
|
## Disclaimers
|
|
154
214
|
|
package/dist/watcher/index.d.ts
CHANGED
|
@@ -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
|
|
9
|
-
* report, and updates the
|
|
10
|
-
* (newly fetched ids). Source fetch failures are caught and reported
|
|
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
|
|
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"}
|
package/dist/watcher/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
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
|
|
17
|
-
* report, and updates the
|
|
18
|
-
* (newly fetched ids). Source fetch failures are caught and reported
|
|
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
|
|
22
|
-
const state =
|
|
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
|
-
|
|
71
|
+
await opts.stateStore.write(state);
|
|
66
72
|
return { run_at: now, sources: sourceReports };
|
|
67
73
|
}
|
|
68
|
-
|
|
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":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/watcher/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,OAAkB,EAAE,IAAc;IAC7D,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,GAAG,GAAc,EAAE,CAAC;IAC1B,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,IAIzC;IACC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;IAC3C,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrC,MAAM,aAAa,GAAsB,EAAE,CAAC;IAE5C,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;QACvE,IAAI,QAAQ,GAAc,EAAE,CAAC;QAC7B,IAAI,MAA0B,CAAC;QAC/B,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QAClC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAI,GAAa,CAAC,OAAO,CAAC;QAClC,CAAC;QAED,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,aAAa,CAAC,IAAI,CAAC;gBACjB,SAAS,EAAE,MAAM,CAAC,EAAE;gBACpB,WAAW,EAAE,MAAM,CAAC,WAAW;gBAC/B,EAAE,EAAE,KAAK;gBACT,KAAK,EAAE,MAAM;gBACb,YAAY,EAAE,EAAE;gBAChB,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM;aAC7B,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,MAAM,WAAW,GAAG,YAAY,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACtD,aAAa,CAAC,IAAI,CAAC;YACjB,SAAS,EAAE,MAAM,CAAC,EAAE;YACpB,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,EAAE,EAAE,IAAI;YACR,YAAY,EAAE,WAAW;YACzB,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM;SAClD,CAAC,CAAC;QAEH,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClC,KAAK,MAAM,CAAC,IAAI,QAAQ;gBAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC3C,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;gBACzB,IAAI,EAAE,CAAC,GAAG,MAAM,CAAC;gBACjB,SAAS,EAAE,GAAG;aACf,CAAC;QACJ,CAAC;IACH,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAErD,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC;AACjD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAKhC;IACC,MAAM,WAAW,GAIb;QACF,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,UAAU,EAAE,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC;KACzC,CAAC;IACF,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS;QAAE,WAAW,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAChE,OAAO,mBAAmB,CAAC,WAAW,CAAC,CAAC;AAC1C,CAAC;AAUD,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,13 +1,21 @@
|
|
|
1
1
|
import type { Source } from "../types.js";
|
|
2
2
|
/**
|
|
3
|
-
* Federal Register source. Fetches recent rules
|
|
4
|
-
* a search term (default:
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
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
|
|
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
|
|
4
|
-
* a search term (default:
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
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 (
|
|
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
|
-
|
|
20
|
-
|
|
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
|
|
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;
|
|
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"}
|
package/dist/watcher/types.d.ts
CHANGED
|
@@ -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.
|
|
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",
|