plainstamp 0.7.0 → 0.7.2

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,23 @@ 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.2] — 2026-05-08
20
+
21
+ ### Documentation
22
+
23
+ - 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.
24
+ - README documents the parallel JSON-over-HTTP API on the same Worker (`/jurisdictions`, `/rules`, `/lookup`, `/validate`) for clients that don't speak MCP.
25
+ - 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.
26
+
27
+ No code changes; npm publish refreshes the README rendered on npmjs.com.
28
+
29
+ ## [0.7.1] — 2026-05-08
30
+
31
+ ### Fixed (cross-runtime compatibility)
32
+
33
+ - New `setBundledRules(parsed)` export: allows non-Node consumers (Cloudflare Workers, Deno Deploy, browsers) to pre-load the bundled rules object explicitly, avoiding the `node:fs` + `import.meta.url` path that fails in those environments. The recommended pattern is to import the JSON directly: `import rulesJson from "plainstamp/rules/seed.json"; setBundledRules(rulesJson);`. Once the override is set, all of `disclosuresFor`, `executeMcpTool`, `getRuleById`, `listJurisdictions`, etc. work unchanged.
34
+ - The Node fs path is unchanged for Node consumers; this is a strictly additive fix.
35
+
19
36
  ## [0.7.0] — 2026-05-08
20
37
 
21
38
  ### Added (transport-independent MCP tool module)
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
 
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { lookup, generateDisclosureText, validateDisclosure, } from "./lookup.js";
2
- export { loadBundledRules, loadRulesFromPath } from "./rules-loader.js";
2
+ export { loadBundledRules, loadRulesFromPath, setBundledRules, } from "./rules-loader.js";
3
3
  export { computeCoverageMatrix, renderCoverageMarkdown, renderCoverageCsv, type CoverageMatrix, type CoverageCell, } from "./coverage.js";
4
4
  export type { DisclosureRuleT, RuleSetT, LookupQueryT, LookupResultT, ChannelT, UseCaseT, SeverityT, JurisdictionIdT, DisclosureElementT, } from "./schema.js";
5
5
  export { Channel, UseCase, Severity, JurisdictionId, LookupQuery, DisclosureElement, DisclosureRule, RuleSet, } from "./schema.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACxE,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,EACjB,KAAK,cAAc,EACnB,KAAK,YAAY,GAClB,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,eAAe,EACf,QAAQ,EACR,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,eAAe,EACf,kBAAkB,GACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,OAAO,EACP,OAAO,EACP,QAAQ,EACR,cAAc,EACd,WAAW,EACX,iBAAiB,EACjB,cAAc,EACd,OAAO,GACR,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,QAAQ,EACR,cAAc,EACd,KAAK,iBAAiB,EACtB,KAAK,aAAa,GACnB,MAAM,gBAAgB,CAAC;AAIxB,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEhF;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,YAAY,GAAG,aAAa,EAAE,CAEnE;AAED,2EAA2E;AAC3E,wBAAgB,iBAAiB,IAAI,MAAM,EAAE,CAK5C;AAED,uDAAuD;AACvD,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAGnE;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,YAAY,EACnB,aAAa,EAAE,MAAM;;;;;IAKtB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,EACjB,KAAK,cAAc,EACnB,KAAK,YAAY,GAClB,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,eAAe,EACf,QAAQ,EACR,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,eAAe,EACf,kBAAkB,GACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,OAAO,EACP,OAAO,EACP,QAAQ,EACR,cAAc,EACd,WAAW,EACX,iBAAiB,EACjB,cAAc,EACd,OAAO,GACR,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,QAAQ,EACR,cAAc,EACd,KAAK,iBAAiB,EACtB,KAAK,aAAa,GACnB,MAAM,gBAAgB,CAAC;AAIxB,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEhF;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,YAAY,GAAG,aAAa,EAAE,CAEnE;AAED,2EAA2E;AAC3E,wBAAgB,iBAAiB,IAAI,MAAM,EAAE,CAK5C;AAED,uDAAuD;AACvD,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAGnE;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,YAAY,EACnB,aAAa,EAAE,MAAM;;;;;IAKtB"}
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export { lookup, generateDisclosureText, validateDisclosure, } from "./lookup.js";
2
- export { loadBundledRules, loadRulesFromPath } from "./rules-loader.js";
2
+ export { loadBundledRules, loadRulesFromPath, setBundledRules, } from "./rules-loader.js";
3
3
  export { computeCoverageMatrix, renderCoverageMarkdown, renderCoverageCsv, } from "./coverage.js";
4
4
  export { Channel, UseCase, Severity, JurisdictionId, LookupQuery, DisclosureElement, DisclosureRule, RuleSet, } from "./schema.js";
5
5
  export { mcpTools, executeMcpTool, } from "./mcp-tools.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACxE,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,GAGlB,MAAM,eAAe,CAAC;AAYvB,OAAO,EACL,OAAO,EACP,OAAO,EACP,QAAQ,EACR,cAAc,EACd,WAAW,EACX,iBAAiB,EACjB,cAAc,EACd,OAAO,GACR,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,QAAQ,EACR,cAAc,GAGf,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,MAAM,IAAI,QAAQ,EAAE,kBAAkB,IAAI,UAAU,EAAE,MAAM,aAAa,CAAC;AAGnF;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,KAAmB;IAChD,OAAO,QAAQ,CAAC,gBAAgB,EAAE,EAAE,KAAK,CAAC,CAAC;AAC7C,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,iBAAiB;IAC/B,MAAM,KAAK,GAAG,gBAAgB,EAAE,CAAC;IACjC,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,KAAK;QAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AACzB,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,WAAW,CAAC,EAAU;IACpC,MAAM,KAAK,GAAG,gBAAgB,EAAE,CAAC;IACjC,OAAO,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;AAC9C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CACxC,KAAmB,EACnB,aAAqB;IAErB,MAAM,KAAK,GAAG,gBAAgB,EAAE,CAAC;IACjC,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC1C,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC;AAClE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,GAGlB,MAAM,eAAe,CAAC;AAYvB,OAAO,EACL,OAAO,EACP,OAAO,EACP,QAAQ,EACR,cAAc,EACd,WAAW,EACX,iBAAiB,EACjB,cAAc,EACd,OAAO,GACR,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,QAAQ,EACR,cAAc,GAGf,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,MAAM,IAAI,QAAQ,EAAE,kBAAkB,IAAI,UAAU,EAAE,MAAM,aAAa,CAAC;AAGnF;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,KAAmB;IAChD,OAAO,QAAQ,CAAC,gBAAgB,EAAE,EAAE,KAAK,CAAC,CAAC;AAC7C,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,iBAAiB;IAC/B,MAAM,KAAK,GAAG,gBAAgB,EAAE,CAAC;IACjC,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,KAAK;QAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AACzB,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,WAAW,CAAC,EAAU;IACpC,MAAM,KAAK,GAAG,gBAAgB,EAAE,CAAC;IACjC,OAAO,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;AAC9C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CACxC,KAAmB,EACnB,aAAqB;IAErB,MAAM,KAAK,GAAG,gBAAgB,EAAE,CAAC;IACjC,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC1C,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC;AAClE,CAAC"}
@@ -1,8 +1,30 @@
1
1
  import { type RuleSetT } from "./schema.js";
2
2
  /**
3
- * Loads and validates the bundled seed rules. Throws on schema violation
4
- * an invalid rules file is a hard failure because the product's correctness
5
- * depends on it.
3
+ * Provide the bundled rules object explicitly. Useful in environments
4
+ * where `import.meta.url`-based filesystem reads are unavailable or
5
+ * unreliable (Cloudflare Workers, Deno Deploy, browsers): the caller
6
+ * imports `plainstamp/rules/seed.json` directly and hands the parsed
7
+ * object to this function before any other plainstamp lookup.
8
+ *
9
+ * Idempotent. Calling with `null` clears the override.
10
+ *
11
+ * @example
12
+ * import rulesJson from "plainstamp/rules/seed.json";
13
+ * import { setBundledRules, executeMcpTool } from "plainstamp";
14
+ * setBundledRules(rulesJson);
15
+ */
16
+ export declare function setBundledRules(rules: unknown | null): void;
17
+ /**
18
+ * Loads and validates the bundled seed rules. If `setBundledRules()`
19
+ * has been called, returns that override. Otherwise reads from the
20
+ * package's `rules/seed.json` file via `node:fs` + `import.meta.url`.
21
+ *
22
+ * Throws on schema violation — an invalid rules file is a hard
23
+ * failure because the product's correctness depends on it.
24
+ *
25
+ * In non-Node environments (Workers, browsers), `import.meta.url` may
26
+ * not resolve to a usable path; in that case, callers MUST set the
27
+ * override via `setBundledRules()` before any lookup.
6
28
  */
7
29
  export declare function loadBundledRules(): RuleSetT;
8
30
  /** Loads rules from an arbitrary path. Useful for tests and for callers that maintain their own rules feed. */
@@ -1 +1 @@
1
- {"version":3,"file":"rules-loader.d.ts","sourceRoot":"","sources":["../src/rules-loader.ts"],"names":[],"mappings":"AAGA,OAAO,EAAW,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAIrD;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,QAAQ,CAK3C;AAED,+GAA+G;AAC/G,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAIxD"}
1
+ {"version":3,"file":"rules-loader.d.ts","sourceRoot":"","sources":["../src/rules-loader.ts"],"names":[],"mappings":"AAGA,OAAO,EAAW,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAIrD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,GAAG,IAAI,CAE3D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,IAAI,QAAQ,CAO3C;AAED,+GAA+G;AAC/G,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAIxD"}
@@ -2,13 +2,40 @@ import { readFileSync } from "node:fs";
2
2
  import { fileURLToPath } from "node:url";
3
3
  import { dirname, join } from "node:path";
4
4
  import { RuleSet } from "./schema.js";
5
- const here = dirname(fileURLToPath(import.meta.url));
5
+ let bundledRulesOverride = null;
6
6
  /**
7
- * Loads and validates the bundled seed rules. Throws on schema violation
8
- * an invalid rules file is a hard failure because the product's correctness
9
- * depends on it.
7
+ * Provide the bundled rules object explicitly. Useful in environments
8
+ * where `import.meta.url`-based filesystem reads are unavailable or
9
+ * unreliable (Cloudflare Workers, Deno Deploy, browsers): the caller
10
+ * imports `plainstamp/rules/seed.json` directly and hands the parsed
11
+ * object to this function before any other plainstamp lookup.
12
+ *
13
+ * Idempotent. Calling with `null` clears the override.
14
+ *
15
+ * @example
16
+ * import rulesJson from "plainstamp/rules/seed.json";
17
+ * import { setBundledRules, executeMcpTool } from "plainstamp";
18
+ * setBundledRules(rulesJson);
19
+ */
20
+ export function setBundledRules(rules) {
21
+ bundledRulesOverride = rules === null ? null : RuleSet.parse(rules);
22
+ }
23
+ /**
24
+ * Loads and validates the bundled seed rules. If `setBundledRules()`
25
+ * has been called, returns that override. Otherwise reads from the
26
+ * package's `rules/seed.json` file via `node:fs` + `import.meta.url`.
27
+ *
28
+ * Throws on schema violation — an invalid rules file is a hard
29
+ * failure because the product's correctness depends on it.
30
+ *
31
+ * In non-Node environments (Workers, browsers), `import.meta.url` may
32
+ * not resolve to a usable path; in that case, callers MUST set the
33
+ * override via `setBundledRules()` before any lookup.
10
34
  */
11
35
  export function loadBundledRules() {
36
+ if (bundledRulesOverride !== null)
37
+ return bundledRulesOverride;
38
+ const here = dirname(fileURLToPath(import.meta.url));
12
39
  const path = join(here, "..", "rules", "seed.json");
13
40
  const raw = readFileSync(path, "utf-8");
14
41
  const parsed = JSON.parse(raw);
@@ -1 +1 @@
1
- {"version":3,"file":"rules-loader.js","sourceRoot":"","sources":["../src/rules-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAiB,MAAM,aAAa,CAAC;AAErD,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAErD;;;;GAIG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;IACpD,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/B,OAAO,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC;AAED,+GAA+G;AAC/G,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/B,OAAO,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC"}
1
+ {"version":3,"file":"rules-loader.js","sourceRoot":"","sources":["../src/rules-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAiB,MAAM,aAAa,CAAC;AAErD,IAAI,oBAAoB,GAAoB,IAAI,CAAC;AAEjD;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,eAAe,CAAC,KAAqB;IACnD,oBAAoB,GAAG,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AACtE,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB;IAC9B,IAAI,oBAAoB,KAAK,IAAI;QAAE,OAAO,oBAAoB,CAAC;IAC/D,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACrD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;IACpD,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/B,OAAO,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC;AAED,+GAA+G;AAC/G,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/B,OAAO,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC"}
@@ -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"}
@@ -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.0",
3
+ "version": "0.7.2",
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",