Skip to main content

cendor-acttrace

A tamper-evident, append-only record of every AI decision — what model, what context, what it cost, which tools, and who signed off — mapped to control templates and exportable as an evidence pack. No database, no infra: integrity comes from a hash chain, not a server.

Detect and prove: 20 categories of secrets, PII & special-category data — block / warn / redact in one line, offline — every decision in a hash chain you can verify without a server.

PyPI license · pip install cendor-acttrace

Using an AI coding assistant? npx @cendor/init (TS) / uvx cendor-init (Python) wires it up — or point it at cendor.ai/docs/for-ai-assistants.

from cendor.core import instrument
from cendor.acttrace import AuditLog

client = instrument(OpenAI())
audit = AuditLog(system="loan_triage", risk_tier="high", signing_key="…")  # auto-subscribes

with audit.decision(input=application, actor="agent") as d:
    resp = client.chat.completions.create(model="gpt-4o", messages=msgs)  # auto-logged
    d.record(model="gpt-4o", prompt_id="triage@v3")          # cost/context captured for free
    d.human_oversight(reviewer="ops@bank", action="approved")

audit.export("evidence_q3.jsonl", framework="eu_ai_act")     # evidence pack (also nist_rmf)
acttrace verify evidence_q3.jsonl --key "…"   # re-walks the chain + checks signatures; non-zero if broken

Highlights

  • Offline detection engine + policy — a validator-gated Detector registry spanning secrets, PII, financial, government-ID, free-text credentials, and GDPR special-category data (20 categories), plus a Policy that maps each to allow · flag · redact · block. Regex + local checksums (Luhn / IBAN mod-97 / Verhoeff / ABA) — no model, no network, no account. Presets: Policy.default() / gdpr() / pci() / strict().
from cendor.acttrace import scan, redact, Policy

scan("card 4111 1111 1111 1111 for alice@example.com")     # -> [Finding(credit_card…), Finding(email…)]
cleaned, findings = redact({"note": "ping alice@example.com"}, Policy.default())
# cleaned == {"note": "ping <redacted>"} — findings report counts, never the raw value

audit = AuditLog(system="triage", policy=Policy.gdpr())    # special-category → block, PII → redact
  • Enforce + record in one lineguard(policy, audit=…) returns a dual-shape interceptor (1.5.0): install it on core's seam yourself, or use it as a context manager (with guard(...):) that installs/removes itself around the block. It enforces the policy (block a disallowed call before it runs, redact-before-send, or flag) and acttrace records the decision as a tamper-evident policy_flag. Recorder and enforcer stay separate — core is what stops the call. resolve_findings() exports the per-category action resolution for composers.
from cendor.core.instrument import add_interceptor
from cendor.acttrace import AuditLog, Policy, guard, PolicyViolation

audit = AuditLog(system="support_bot", risk_tier="high", signing_key="ops-key")
add_interceptor(guard(Policy.gdpr(), audit=audit))         # a special-category call is blocked + recorded
  • Auto-populating — construct an AuditLog and it subscribes to the bus: every LLM/tool call, plus cost (tokenguard) and context decisions (contextkit) on the same stream, becomes an entry — no per-call wiring.
  • Bounded memory for long-running logsAuditLog(path="audit.jsonl", max_entries=N) caps the in-memory entry ring so a multi-day agent doesn't grow memory per event. The file stays the complete, verifiable chain (verify()/export() read it), evicted_from_memory counts what left memory, and the default (None) is unbounded. Bound together with path=.
  • Tamper-evident hash chainverify() catches edits, reordering, and tail-truncation. The pack's _meta head+count catch truncation, but that header is only authenticated when the log is HMAC-signed and you verify(key=…) — the header itself is signed, so a rewritten _meta fails. Without a key it's an unauthenticated in-file check, so pass an out-of-band expected_head= (captured from log.head at write time) for an authoritative completeness guarantee. Each entry is optionally HMAC-signed too.
  • Decisions & oversightdecision() groups a unit of work; d.record(...) and d.human_oversight(reviewer, action) capture Art. 14-style sign-off.
  • Compliance evidence packsexport(framework=…) annotates control IDs for EU AI Act, ISO/IEC 42001, GDPR, and NIST AI RMF (starting templates, not certified mappings), and a _meta.summary (counts of decisions, oversight, flags by action/severity) gives a reviewer the at-a-glance read first. PII redaction on by default (swap in redactor=).
  • Opt-in extras, defaults unchangedenable_locale_pack("uk", "in") (UK NINO, India Aadhaar — Verhoeff-checked), enable_entropy_detector() (high-entropy generic secrets — noisy), and NER-backed name/address redaction via pip install "cendor-acttrace[ner]" (Microsoft Presidio, still offline). All strictly opt-in — the zero-extra install stays pure-regex.
  • Auto-flag by policy — every auto-captured entry is scanned against the full registry, and each detection appends a policy_flag with its resolved action (redacted / flagged / blocked), severity, and category — so "we removed / flagged / blocked this" is in the hash chain, not silent (flag_on_redact=True by default; a custom redactor= owns its own flagging). Detection scrubs the record; block on core's interceptor seam is the pre-send control.
  • Policy flags (validation)audit.flag(reason, action="blocked", …) records a tamper-evident policy_flag (and returns the chained entry) when your pre-flight guard refuses input that shouldn't be processed — so the refusal is auditable, not just the calls that ran:
from cendor.core.instrument import add_interceptor, MISS

def guard(call):                                    # your pre-flight policy guard
    if my_policy_disallows(call):                   # YOUR rule
        audit.flag("special-category data", action="blocked")   # acttrace records the refusal
        raise PolicyViolation("blocked")            # your guard enforces it
    return MISS

add_interceptor(guard)   # the blocked call never reaches the bus — flag() is its only record

Produces evidence to support compliance — not legal advice, not a guarantee. Control mappings are starting templates for your compliance team.

See docs/acttrace.md · CHANGELOG. Part of the Cendor stack — github.com/cendorhq/cendor-libs. Powered by PowerAI Labs. Apache-2.0; provided "as is", without warranty — use at your own risk (LICENSE §7–8).

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cendor_acttrace-1.8.0.tar.gz (72.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cendor_acttrace-1.8.0-py3-none-any.whl (48.5 kB view details)

Uploaded Python 3

File details

Details for the file cendor_acttrace-1.8.0.tar.gz.

File metadata

  • Download URL: cendor_acttrace-1.8.0.tar.gz
  • Upload date:
  • Size: 72.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for cendor_acttrace-1.8.0.tar.gz
Algorithm Hash digest
SHA256 c92b48cdb55a6fe0605f2ede95dd65067df584b88bd62f96a337ab3c1566b420
MD5 fdefbce8b93f4dd7bccaccc2b6920996
BLAKE2b-256 fad2416d725d234c3ae2a099f8dd1341a609fe787779bebfb689da2bfa67785a

See more details on using hashes here.

Provenance

The following attestation bundles were made for cendor_acttrace-1.8.0.tar.gz:

Publisher: release.yml on cendorhq/cendor-libs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cendor_acttrace-1.8.0-py3-none-any.whl.

File metadata

  • Download URL: cendor_acttrace-1.8.0-py3-none-any.whl
  • Upload date:
  • Size: 48.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for cendor_acttrace-1.8.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6c5e0ba549c44223b78ffbdba475124b63af8bce580ec4142d971becbf014d0c
MD5 63c000c08cd77ddfbf191a01492c420a
BLAKE2b-256 beaee4dcd5a134acd1c5575d883853d115955658375257b2daf81b9164bc3bbd

See more details on using hashes here.

Provenance

The following attestation bundles were made for cendor_acttrace-1.8.0-py3-none-any.whl:

Publisher: release.yml on cendorhq/cendor-libs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

1.14.0

2 files

1.13.1

2 files

1.13.0

2 files

1.12.0

2 files

1.11.0

2 files

1.10.1

2 files

1.10.0

2 files

1.9.0

2 files

This release

1.8.0 This release

2 files

1.7.0

2 files

1.6.0

2 files

1.5.0

2 files

1.4.2

2 files

1.4.1

2 files

1.4.0

2 files

1.3.0

2 files

1.2.2

2 files

1.2.1

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page