Metadata-Version: 2.4
Name: clinicsentry
Version: 0.3.0
Summary: Framework-agnostic compliance middleware for clinical AI agents (HIPAA, FDA TPLC, IEC 62304).
Project-URL: Homepage, https://github.com/aakash1411/clinicsentry
Project-URL: Repository, https://github.com/aakash1411/clinicsentry
Project-URL: Documentation, https://github.com/aakash1411/clinicsentry/tree/main/docs
Project-URL: Changelog, https://github.com/aakash1411/clinicsentry/blob/main/CHANGELOG.md
Project-URL: Issues, https://github.com/aakash1411/clinicsentry/issues
Author: ClinicSentry Contributors
License: Apache-2.0
License-File: LICENSE
License-File: NOTICE
Keywords: agents,fda,guardrails,healthcare,hipaa,iec62304,llm,samd
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Healthcare Industry
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Security
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: cryptography>=41.0
Requires-Dist: pydantic>=2.0
Requires-Dist: pyyaml>=6.0
Provides-Extra: adk
Requires-Dist: google-adk>=0.1; extra == 'adk'
Provides-Extra: all
Requires-Dist: fhir-resources>=7.0; extra == 'all'
Requires-Dist: hl7apy>=1.3; extra == 'all'
Requires-Dist: opentelemetry-api>=1.27; extra == 'all'
Requires-Dist: opentelemetry-sdk>=1.27; extra == 'all'
Requires-Dist: presidio-analyzer>=2.2; extra == 'all'
Requires-Dist: presidio-anonymizer>=2.2; extra == 'all'
Requires-Dist: prometheus-client>=0.20; extra == 'all'
Requires-Dist: pydicom>=2.4; extra == 'all'
Provides-Extra: claude
Requires-Dist: anthropic>=0.40; extra == 'claude'
Provides-Extra: cloud-kms
Requires-Dist: azure-identity>=1.15; extra == 'cloud-kms'
Requires-Dist: azure-keyvault-keys>=4.8; extra == 'cloud-kms'
Requires-Dist: boto3>=1.34; extra == 'cloud-kms'
Requires-Dist: google-cloud-kms>=2.20; extra == 'cloud-kms'
Provides-Extra: crewai
Requires-Dist: crewai>=0.80; extra == 'crewai'
Provides-Extra: dashboard
Requires-Dist: fastapi>=0.110; extra == 'dashboard'
Requires-Dist: jinja2>=3.1; extra == 'dashboard'
Requires-Dist: uvicorn>=0.27; extra == 'dashboard'
Provides-Extra: dev
Requires-Dist: bandit>=1.7; extra == 'dev'
Requires-Dist: freezegun>=1.4; extra == 'dev'
Requires-Dist: hypothesis>=6.100; extra == 'dev'
Requires-Dist: mutmut<3.0,>=2.5; extra == 'dev'
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pip-audit>=2.7; extra == 'dev'
Requires-Dist: pip-licenses>=4.4; extra == 'dev'
Requires-Dist: pre-commit>=3.7; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest-cov>=4.1; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: respx>=0.20; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Requires-Dist: testcontainers[postgres]>=4.0; extra == 'dev'
Provides-Extra: dicom
Requires-Dist: pydicom>=2.4; extra == 'dicom'
Provides-Extra: docs
Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
Requires-Dist: mkdocstrings[python]>=0.24; extra == 'docs'
Provides-Extra: fhir
Requires-Dist: fhir-resources>=7.0; extra == 'fhir'
Provides-Extra: hl7
Requires-Dist: hl7apy>=1.3; extra == 'hl7'
Provides-Extra: hsm
Requires-Dist: python-pkcs11>=0.7; extra == 'hsm'
Provides-Extra: langgraph
Requires-Dist: langchain-core>=0.3; extra == 'langgraph'
Requires-Dist: langgraph>=0.2; extra == 'langgraph'
Provides-Extra: mcp
Requires-Dist: mcp>=0.9; extra == 'mcp'
Provides-Extra: metrics
Requires-Dist: prometheus-client>=0.20; extra == 'metrics'
Provides-Extra: nlp-medical
Requires-Dist: scispacy>=0.5; extra == 'nlp-medical'
Requires-Dist: spacy>=3.7; extra == 'nlp-medical'
Provides-Extra: ocr
Requires-Dist: pytesseract>=0.3; extra == 'ocr'
Provides-Extra: openai-agents
Requires-Dist: openai-agents>=0.1; extra == 'openai-agents'
Provides-Extra: otel
Requires-Dist: opentelemetry-api>=1.27; extra == 'otel'
Requires-Dist: opentelemetry-exporter-otlp>=1.27; extra == 'otel'
Requires-Dist: opentelemetry-sdk>=1.27; extra == 'otel'
Provides-Extra: pdf
Requires-Dist: weasyprint>=60.0; extra == 'pdf'
Provides-Extra: phi
Requires-Dist: presidio-analyzer>=2.2; extra == 'phi'
Requires-Dist: presidio-anonymizer>=2.2; extra == 'phi'
Provides-Extra: postgres
Requires-Dist: alembic>=1.13; extra == 'postgres'
Requires-Dist: asyncpg>=0.29; extra == 'postgres'
Requires-Dist: sqlalchemy>=2.0; extra == 'postgres'
Provides-Extra: s3
Requires-Dist: boto3>=1.34; extra == 's3'
Provides-Extra: test
Requires-Dist: freezegun>=1.4; extra == 'test'
Requires-Dist: hypothesis>=6.100; extra == 'test'
Requires-Dist: pytest-asyncio>=0.23; extra == 'test'
Requires-Dist: pytest-cov>=4.1; extra == 'test'
Requires-Dist: pytest>=8.0; extra == 'test'
Requires-Dist: respx>=0.20; extra == 'test'
Description-Content-Type: text/markdown

# ClinicSentry

> **Framework-agnostic compliance middleware for clinical AI agents**

ClinicSentry is an open-source Python library that wraps any AI agent
framework (LangGraph, CrewAI, Google ADK, OpenAI Agents SDK, Claude SDK, MCP,
A2A) and enforces clinical-domain guardrails — without requiring changes to
your existing agent code.

> **⚠️ Important disclaimers**
>
> - ClinicSentry is **not a medical device** and is not FDA-cleared or
>   CE-marked. Its controls *align with* HIPAA, FDA TPLC draft guidance, and
>   IEC 62304 — alignment is not certification, and using this library does
>   not make your system compliant by itself.
> - The default detectors catch **structured identifiers** (SSN, MRN, phone,
>   email, dates, …) deterministically. **Person-name detection requires the
>   optional NER extras** (`pip install 'clinicsentry[phi]'`); its recall on
>   real clinical text is not yet characterized on a public benchmark.
> - Read [RESPONSIBLE_USE.md](RESPONSIBLE_USE.md) before any deployment that
>   touches real PHI or influences patient care.

## Four Orthogonal Controls

| Module | What it does | Regulatory alignment |
|--------|-------------|---------------------|
| **PHI Firewall** | Detect, redact, and track PHI across agents | HIPAA §164.502(b), §164.312 |
| **Clinical Escalation Router** | Risk-tier actions; route uncertain decisions to humans | IEC 62304 §9, FDA TPLC §III.B |
| **Regulatory Audit Trail** | Tamper-evident HMAC-signed hash chain of every event | 21 CFR Part 11, HIPAA §164.312(b) |
| **MedDevice Mode** | IEC 62304 Class A/B/C enforcement, dose-range checks, emergency stop | IEC 62304 §5.1/§8, EU AI Act |

## Install

```bash
pip install clinicsentry            # core
pip install 'clinicsentry[all]'     # everything (Presidio, FHIR, OTEL, cloud KMS, …)
```

**Extras:** `[postgres]`, `[cloud-kms]`, `[otel]`, `[dashboard]`, `[all]`

## Quick Example

```python
from clinicsentry import ClinicSentry, ClinicalRiskTier

guard = ClinicSentry(framework="my-agent")

# 1. Scan input for PHI
scan = guard.firewall.scan(
    {"note": "Patient Jane Doe (MRN 12345678), SSN 123-45-6789"},
    origin_agent="intake",
)
print(scan.redacted)  # PHI replaced with [REDACTED:MRN], [REDACTED:SSN]

# 2. Register actions with risk tiers
@guard.register_action(
    tier=ClinicalRiskTier.ADVISORY,
    description="Summarize a clinical note",
    required_fields={"note"},
)
def summarize(payload: dict) -> str:
    return f"Summary ({len(payload['note'])} chars)"

# 3. Evaluate — router decides: proceed / escalate / block
decision = guard.evaluate_action(
    "summarize",
    output_text="Summary of visit note",
    reasoning_text="High confidence, structured input",
    provided_fields={"note"},
)
print(decision.action, decision.confidence)

# 4. End session → regulatory compliance report
report = guard.end_session(intended_use="clinical summarization")
print(report.compliance_attestation)
```

Or let the context manager guarantee the session boundary — `SESSION_END` is
audited even if your pipeline raises:

```python
with ClinicSentry(framework="my-agent") as guard:
    ...  # scans, evaluations, tool calls
# report available as guard.last_report
```

## Risk Tiers

| Tier | Behavior | Example |
|------|----------|---------|
| `INFORMATIONAL` | Auto-proceed; audit logged | "How do I use my device?" |
| `ADVISORY` | Proceed with annotation; confidence score visible | Triage patients by glucose trends |
| `INTERVENTIONAL` | **Auto-blocked**; routed to human reviewer | Adjust insulin dosing parameters |

Unregistered actions **escalate by default** (fail closed) — see
`escalation.on_unregistered_action` in the [policy reference](docs/policy.md).

## Fail-Safe by Default

- **Adversarial PHI detection** on the production scan path: homoglyphs,
  zero-width characters, full-width forms, percent-encoding, and
  base64-encoded payloads are normalized with exact offset mapping, then
  redacted in the original text (ADR-0016). Plain-ASCII inputs take a
  no-overhead fast path (~0.7 ms p95 on 3 KB notes, pure Python, no extra
  LLM calls).
- **Whole-payload coverage**: strings, dicts (keys included), lists, tuples,
  sets, UTF-8 bytes, FHIR/HL7/DICOM; nesting deeper than
  `phi_firewall.max_depth` is redacted wholesale rather than erroring.
- **Tamper-evident auditing** under concurrency: thread-safe gapless
  sequencing, plus tail-truncation detection on `verify()`.
- **Strict policy loading**: typo'd keys and out-of-range values raise
  `PolicyError` at startup instead of silently disabling enforcement;
  `CLINICSENTRY_*` env overrides for containerized deployments.
- **MedDevice guardrails**: undeclared dose parameters and non-finite values
  fail validation; rate limits use a true rolling 1-hour window.

## CLI

```bash
clinicsentry demo                                    # seeded demo session
clinicsentry scan "Patient SSN 123-45-6789"          # one-shot PHI scan
clinicsentry verify ./audit.sqlite --secret <hex>    # verify audit chain
clinicsentry report ./audit.sqlite --session <id>    # compliance report
clinicsentry policy-validate examples/policy.yaml    # validate policy file
```

## Bundled Compliance Frameworks

| Framework | Key rules |
|-----------|-----------|
| **HIPAA** | PHI redacted, audit signed, chain integrity, minimum necessary |
| **FDA TPLC** | Session boundaries, no sequence gaps, postmarket data capture |
| **IEC 62304** | Agent traceability, chain integrity, interventional escalation |
| **EU AI Act** | Transparency, human oversight |

All four are checked automatically by `clinicsentry report`.

## Production Stack

```bash
# Postgres audit + S3 + OTEL + Grafana dashboard
docker compose -f deploy/compose/docker-compose.yml up
```

Open <http://localhost:3000> (Grafana) or <http://localhost:9001> (MinIO).

## Documentation

- [Quickstart](docs/quickstart.md) — install and run in < 5 minutes
- [Adapters](docs/adapters.md) — supported agent frameworks
- [Regulatory Mapping](docs/regulatory-mapping.md) — controls → regulation clauses
- [Threat Model](THREAT_MODEL.md) — STRIDE analysis
- [API Reference](docs/api.md)

## Status, Versioning, and Support

**v0.3.0** — pre-1.0 software ([per-module status](STATUS.md)). SemVer: breaking
changes only in minor releases until 1.0, always flagged in the
[CHANGELOG](CHANGELOG.md) with migration notes. Only the latest minor release
receives security fixes ([security policy](SECURITY.md) — PHI-detection
bypasses are treated as vulnerabilities, reported privately).

- Bugs and feature requests: GitHub issues (templates provided).
- Conduct: [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md).
- Contributing: [CONTRIBUTING.md](CONTRIBUTING.md) and [CONVENTIONS.md](CONVENTIONS.md).

## How It Compares

| | ClinicSentry | NeMo Guardrails / Guardrails AI | Presidio |
|---|---|---|---|
| Clinical regulatory mapping (HIPAA / FDA TPLC / IEC 62304) | built-in, rule DSL | generic rails | none |
| Tamper-evident audit chain | HMAC hash chain | logging only | none |
| Risk-tiered human escalation | built-in | build your own | none |
| Extra LLM calls on hot path | **zero** | often 1+ per check | zero |
| PHI detection | regex + adversarial normalization (+ optional Presidio/NER) | delegate | NER engine |

Presidio is a complementary *detector* (we wrap it via `[phi]`); rails
frameworks are complementary *conversation shapers*. ClinicSentry is the
compliance enforcement and evidence layer between your agent and the world.

## License

Apache-2.0. See [LICENSE](LICENSE) and [NOTICE](NOTICE). Apache-2.0 permits
commercial use, modification, and redistribution — including inside
proprietary products.
