Producer profile
How ComplyEdge writes its ADCR records
Every ADCR record and export ComplyEdge produces names this page as its producer_id. It is the profile ADCR 0.1.0 asks a producer to publish (PRF-01): what a reader needs to check a record without asking us. The same profile, as the JSON document the reference verifier reads with --profile, is at /producer-profile/profile.json. Its classes list is empty: no class is claimed.
1. Rulebook version and classes
Records carry rulebook: https://complyedge.io/rulebook/0.1.0 and record_version: complyedge-adcr-1, the version of the mapping from a stored row to an ADCR record. The classes this producer is built to meet are Record, Law, Chain and Export. Oversight and Rights are not claimed. The account holder's review of a flag is recorded as an oversight record (section 6); measured with the reference verifier, Oversight is met for those reviews, under the same conditions as the classes above. Rights is not met: the product does not collect the notice, decision mode and explanation fields it needs.
No conformance claim is made on this page. An export of your records meets Record, Law, Chain and Export only when all of the following hold, and the reference verifier names each one that does not:
- • every decision in the range was checked with
decision_contextnaming the deciding system's version, the purpose and the data categories, which only you know; - • no decision names a
subject: a decision about a person needs the Rights fields, which are not recorded; - • the account keeps records for 184 days, 7 years or 11 years, the retention classes the profile defines (section 4);
- • every record in the range was written after the chain began, and no timestamp failed in it;
- • every rule that fired is approved (the rule set page shows which are; see section 7).
2. Clock
occurred_at is read from the API host clock (AWS Lambda, UTC) when the decision is made. The record joins the chain when it is written, so two requests answered at the same time can reach the chain in the opposite order of their times. The declared tolerance, clock_source.tolerance_ms: 301000, is the longest a request can run (300 seconds) plus one second for the hosts' clocks. A record that is earlier than the one before it by more than that is reported by the verifier as backdated.
3. Chain and timestamps
- • Chain:
sha256-chain-1, one chain per account, written in the same transaction as the record (CHN-02, CHN-03). That is integrity of the sequence, not attribution. Records are not signed, and no qualified electronic seal is applied. Each hourly anchor statement carries a ComplyEdge origin signature (CHN-05, ECDSA P-256), checkable with the public key itskey_refnames: origin-p256.spki for the US region, origin-p256-eu.spki for the EU region. EU-region anchors written before 25 October 2026 name the US key inkey_refbut were signed with the EU key: check any anchor withregion: eu-central-1against origin-p256-eu.spki. An origin signature is attribution only, not an eIDAS Art 35(2) seal. - • Timestamps: every hour, in both regions, the newest chain position of each account that moved is timestamped by Sectigo (eIDAS-qualified) as an RFC 3161 token over the anchor statement (account, chain algorithm, hash, position; no record content). An export is also timestamped at the newest position when the last timestamp is older than an hour. A qualified time stamp dates the head; it is not a ComplyEdge seal.
- • Each timestamp, its token and the provider address are stored write-once (section 5) and travel in the Enterprise export.
- • A write or a timestamp that fails is recorded as an
event_type: logging_failurerecord on the same chain.
4. Retention classes
| retention.class | Meaning |
|---|---|
| retention-184d | The default. The record is erased 184 days after it was written; retention.erase_after is that date. 184 days holds six months from any start date (REC-20), so this class is declared high_risk: true. |
| retention-2557d | An Enterprise account that keeps records 7 years. Declared high_risk: true. |
| retention-4018d | An Enterprise account that keeps records 11 years. Declared high_risk: true. |
Legal holds: Enterprise accounts place or lift a hold with POST /v1/audit/legal-hold. That writes a chained legal_hold record (listed in this profile) and suspends DynamoDB expiry for the covered chain sequence numbers until the hold is lifted. Outside a hold, erasure still happens by expiry, by closing the account, or by destroying the account key on request, as the DPO pack describes.
5. Every copy, and when it is gone
| Copy | Kept for |
|---|---|
| Audit record | The account's retention period (section 4) |
| Write-once archive of each change | Locked 180 days, deleted after 400 days |
| Timestamps (anchors) | Locked at least 400 days, longer when the account's retention is longer; deleted after 3,660 days |
| Database point-in-time recovery | 35 days |
| Weekly backups | 210 days |
| The account key (encrypted, on the account's settings record) | Until the account is closed or the key is destroyed on request; a backup taken before the destruction holds it for up to 210 days more |
After the key is destroyed, the copies that remain still verify as a chain, but their commitments and pseudonyms can no longer be linked to any text or person.
6. Event types and reason codes
Event types: decision, logging_failure (with failure_kind write_failed or anchor_failed) oversight, legal_hold, contest, notice, incident, opt_out, classification and fallback. These ten are the event_types in profile.json; no other event type is written.
An oversight record is written when the account holder finishes the review of a flag in the dashboard: accepted with reason code layer2.reviewed_violation, or disregarded with layer2.reviewed_compliant. Sending a flag to legal counsel writes no record. The record names the decision it reviewed (proposal_ref), the reviewer as a pseudonym, reviewer_role: account_holder, the dashboard page of the flag (inputs_ref) and the review authority statement (authority_ref). Review notes stay on the flag and are never written to the record.
OVS-03, OVS-04 and OVS-05 do not apply: no record identifies a person from biometric data, no record is written for a decision the law reserves to a human, and no oversight evaluation or per-reviewer count is kept.
| Reason code | Meaning |
|---|---|
| classifier_match | A semantic classifier matched the rule it names |
| llm_layer2_block, LLM_LAYER2_BLOCK | The optional model review refused the request |
| llm_fallback_block, LLM_FALLBACK_BLOCK | The model review could not decide and the request was refused |
| LLM_LAYER2_UNAVAILABLE | The required model review did not answer; the request was refused |
| LLM_SPEND_COUNTER_UNAVAILABLE | The counter that caps model spend was unavailable; the request was refused |
| OPA_UNNAMED_VIOLATION, OPA_UNNAMED_VIOLATION_<PACKAGE> (one per policy package: ARTICLE5, ARTICLE50, GPAI, ARTICLE6, HIGHRISK, PROMPT_SECURITY, DATA_PROTECTION, US_CORPUS) | The rule engine refused without naming a rule |
| fallback_block | With fallback.kind: degraded: the engine could not complete the check and refused the request |
| layer2_plan, layer2_budget, layer2_unavailable | With fallback.kind: skipped: the model review was requested but not run, because the plan does not include it, the account's model spend cap was reached, or the review model was not available |
| law_enforcement_refused, dataset_operation_refused | An exemption was claimed and not accepted |
| layer2.reviewed_violation, layer2.reviewed_compliant | On an oversight record: the account holder reviewed a flag and found a violation, or found the output compliant |
| confirmer_cleared, injection_check_clear | The model review cleared a rule the engine had matched, and, for a prompt security rule, the injection check found no instruction aimed at an AI in the text |
7. The rule set
Each decision record names the rules that were loaded by rule_set.digest, and rule_set.index_url is https://complyedge.io/rule-set/<digest>/. That page lists every rule in the set, and each rule's own page shows its provision, citation, condition and approval. A page is published for every digest a record has named. Once a record names a digest, the list of rules on its page and each rule's own content never change; only the site menu around them can.
8. How to read a ComplyEdge record
- •
account_idanddeploying_partyare your account.deciding_system.idis theagent_idyou sent; itsversionis the one you sent indecision_context.checkeris ComplyEdge: the rule set label, the engine path and, when it ran, the review model. - •
verdictandaction: a refused request isdeny/blocked; an allowed one isallow/passed, orallow/flaggedwhen it was sent on to the model review.native_resultkeeps the stored value (block,allow,flag). - •
rules_firedholds only rules from the rule set, each with its version, provision and approval. What the engine reported that is not a rule goes toreason_codesand, in full, tocomplyedge.non_rule_findings. - •
commitments:hmac-sha256-1is HMAC-SHA-256 under your account key overcommitment:followed by the checked text. Records written before the keyed hash was deployed carry a plain SHA-256 instead, which is not a commitment. Check a text against a record withPOST /v1/audit/verify. - • People and exchange identifiers are
p1:pseudonyms: HMAC-SHA-256 under the same key over the field name (user_id,session_id,subject,correlation_idorreviewer), a colon and the value, first 32 hex characters, with the key version beside them. - •
complyedgeholds every stored attribute ADCR has no field for, so the chain covers the whole stored row. - • A record with no
chainobject carrieschain_status: pre_chain: it was written before the chain existed and nothing about it is claimed. - • Get the export with
GET /v1/audit/export?start_date=…&end_date=…&format=adcr(the timestamps are included on Enterprise) and check it with the reference verifier.