Metadata-Version: 2.4
Name: allela
Version: 0.1.1
Summary: Operational Flight Recorder for AI — tamper-evident, DigiCert co-signed decision attestation
License-Expression: Apache-2.0
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: cryptography>=41.0
Requires-Dist: asn1crypto>=1.5
Requires-Dist: rfc8785>=0.1.2
Provides-Extra: api
Requires-Dist: fastapi[standard]>=0.110; extra == "api"
Dynamic: license-file

# Allela SDK

Tamper-evident, DigiCert co-signed attestation for AI decisions.

## Install

From this folder:

    pip install -e .

## Quickstart

```python
import allela

allela.configure(
    tenant_id="acme_corp",
    model_provider="anthropic",
    model_id="claude-sonnet-4-6",
    model_version="20250929",
)

@allela.trace(system_prompt="You are a credit risk assistant.")
def make_credit_decision(applicant_profile: str) -> str:
    return call_your_llm(applicant_profile)  # your existing AI call, unchanged

result = make_credit_decision("Applicant: income $60,000, requesting $10,000 loan.")
# `result` is returned immediately — attestation happens on a background
# thread and does not add latency to your function call.

# Before your process exits, flush any in-flight attestations:
allela.shutdown()
```

## Verifying a decision later

```python
result = allela.reconcile(
    event_id="evt_...",
    raw_input="Applicant: income $60,000, requesting $10,000 loan.",
    raw_output="APPROVED: Low risk profile.",
)
print(result["path"])
```

`result["path"]` is one of:

- `FULL_INTEGRITY_VERIFICATION`: the stored record is intact and your data matches it.
- `TAMPER_DETECTED`: the stored record is intact, but your data doesn't match it (`mismatched_fields` says which).
- `DATA_UNAVAILABLE_AT_SOURCE`: the stored record is intact; no data was supplied to compare.
- `LEDGER_RECORD_INVALID`: the stored record failed its signature or root-hash check (`failed_checks` says which), so it can't be trusted and nothing was compared.
- `NOT_FOUND`: no event with that ID.

`result["timestamp_imprint_matches"]` only confirms that the stored
timestamp token covers this record's hash. It does not yet verify the
timestamp authority's signature or certificate chain.

## What gets stored

Only cryptographic hashes and metadata (model ID/version, timestamps,
a hash of the system prompt) — never your raw input/output text. See
the Decision Event Schema (`v1/decision-event.json`) for the exact shape.

## Important: call `allela.shutdown()` before exiting

Because attestation runs on a background worker so it never blocks your
application, an attestation that's still in flight when your process
exits abruptly could be lost. Call `allela.shutdown()` (which flushes
the queue) during your application's graceful shutdown sequence.

`shutdown()` waits at most `timeout` seconds (default 30; pass `None` to
wait indefinitely) and returns `True` if every attestation was written,
or `False` if the timeout expired with some still pending — in which
case a warning is logged with the count.

## License

Apache License 2.0 — see `LICENSE`.
