Metadata-Version: 2.5
Name: tacit-deid
Version: 0.3.0
Summary: Client-side clinical de-identification SDK: turns a real consultation transcript into a de-identified boundary artifact that can safely leave your infrastructure.
Project-URL: Homepage, https://tacitintelligence.co
Project-URL: Documentation, https://docs.tacitintelligence.co/deid
Project-URL: Changelog, https://docs.tacitintelligence.co/deid/changelog
Author-email: "Tacit Intelligence Co." <support@tacitintelligence.co>
License-Expression: Apache-2.0
License-File: DATA_LICENSES.md
License-File: LICENSE
License-File: NOTICE
Keywords: clinical,de-identification,healthcare,phi,privacy,transcripts
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Healthcare Industry
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
Classifier: Topic :: Security
Classifier: Typing :: Typed
Requires-Python: >=3.13
Requires-Dist: pydantic>=2.9
Requires-Dist: pyyaml>=6
Provides-Extra: bedrock
Requires-Dist: boto3>=1.35; extra == 'bedrock'
Provides-Extra: detector
Requires-Dist: click>=8.1; extra == 'detector'
Requires-Dist: faker>=30; extra == 'detector'
Requires-Dist: presidio-analyzer>=2.2; extra == 'detector'
Requires-Dist: presidio-anonymizer>=2.2; extra == 'detector'
Requires-Dist: spacy>=3.8; extra == 'detector'
Provides-Extra: gliner
Requires-Dist: gliner>=0.2; extra == 'gliner'
Provides-Extra: llm
Requires-Dist: instructor>=1.5; extra == 'llm'
Requires-Dist: litellm>=1.50; extra == 'llm'
Provides-Extra: pdf
Requires-Dist: pypdf>=5; extra == 'pdf'
Provides-Extra: transport
Requires-Dist: httpx>=0.27; extra == 'transport'
Description-Content-Type: text/markdown

# tacit-deid

Client-side clinical de-identification. Runs inside your own infrastructure, turns a real
consultation transcript into a de-identified **boundary artifact** (a demographic shell, a
timeline of clinical beats, aggregate lexical statistics, and an audit log), and hands only that
artifact to Tacit. The transcript, the audio, and the local ledger never leave your boundary.

- Every model call goes to an endpoint you allow by name; anything else fails closed.
- The artifact carries an opaque token, never your record identifier, and is sealed with a
  digest so a change after sealing is detectable on either side.
- An identifier the detectors miss is caught by a judge loop that runs to a fixpoint, and a
  record it cannot clean is refused: nothing crosses.

Apache-2.0. The bundled base-rate tables carry their own terms; see `DATA_LICENSES.md`.

## Install

```bash
pip install "tacit-deid[detector,llm,transport]"
python -m spacy download en_core_web_lg     # one-time, for the Stage-0 detector
```

Extras: `detector` (Presidio and spaCy), `llm` (LiteLLM and instructor for the extractor and the
judge), `transport` (sending to Tacit), `bedrock` (AWS credentials via boto3), `gliner` (an
optional on-demand model detector), `pdf` (reading `.pdf` inputs). Python 3.13 or newer.

## Run

`tacit_deid.yaml` names your in-boundary model and the hosts it may call. Credentials are read
from disk by your provider's SDK, never stored here.

```yaml
model: bedrock/us.anthropic.claude-sonnet-4-6
allowed_endpoint_hosts:
  - amazonaws.com
region: us-east-1
boundary_k: 11
```

```bash
tacit-deid inspect consult.json                                   # what a run would do; no model call
tacit-deid run consult.json --config tacit_deid.yaml --out artifact.json
tacit-deid run consults/ --config tacit_deid.yaml --out-dir artifacts/   # a whole batch, one manifest
tacit-deid send artifact.json --key-file .env.local              # TACIT_API_URL and TACIT_API_KEY
```

Inputs: plain text, JSON in the common speech-to-text shapes, JSON Lines, WebVTT and SubRip,
CSV and TSV, Word, PDF, a directory, or a zip. `inspect` reports what it resolved before any
model is built.

As a library: `from tacit_deid import deidentify, load_config, run_canary` and the rest of
`tacit_deid.__all__`.

## When it refuses

`deidentify` returns `DeidResult(crossed=False, refusal_reason=...)` when the judge loop cannot
clean the transcript within its round cap or the demographic shell fails singling-out. Nothing
crossed and nothing was sent. Do not retry with a weaker configuration; re-run only after a
change that removes the cause (a fixed transcript, a better model, or a `keep` entry for a
value wrongly treated as an identifier). The local ledger under `runs/` names every judge round
and holds real identifiers; it must not leave your boundary.

## Documentation and security

The full guide (inputs, configuration, the artifact contract, what Tacit does with an artifact,
ceilings, and the security model) is on the documentation site named in this package's
metadata. Security reports: see `SECURITY.md` in the source repository, or the contact on the
documentation site.
