DCL Core
Tamper-evident record chain + multi-party consensus primitives for AI agent audit systems. Part of the Deterministic Commitment Layer / Leibniz Layer™ ecosystem by Fronesis Labs.
Why a free package for a paid protocol
DCL's paid layer is the evaluation — running an agent's output through a policy and getting a verdict, via x402 micropayments in USDC on Base. Verification of a chain you already have is a different problem, and gating it behind a paywall would defeat the point of an audit trail. If you can't independently check that a record wasn't edited without paying the party who might have edited it, it isn't really independent verification.
So: the protocol is open. dcl-core is the reference implementation for Python; @fronesis-labs/dcl-sdk is the equivalent for TypeScript/JavaScript, byte-for-byte compatible.
This is a clean-history consolidation: the single-agent chain logic
previously duplicated inside dcl-webhook, and the multi-agent consensus
logic from dcl-v2, unified into one module with two known issues fixed.
What changed vs the previous implementations
1. ChainState.verify() now detects content tampering
The chain logic previously embedded in dcl-webhook/dcl_core.py only
checked that prev_hash pointers linked correctly between rows. It never
recomputed a row's hash from its own stored fields. That meant a party with
direct database access could edit verdict, confidence, or reason on
an existing row — without touching tx_hash/prev_hash — and verify()
would still report the chain as clean. This defeated the core tamper-evident
claim.
verify() here recomputes each row's hash from all of its stored fields
and compares it against the stored tx_hash. Editing any field now breaks
verification. See tests/test_fixes.py::test_detects_content_tamper_not_just_link_break.
2. Super-Hash consensus no longer uses XOR
dcl-v2's original formula was H*_t = hash(h_t1 ⊕ h_t2 ⊕ ... ⊕ h_tM).
XOR is commutative and reversible: a party submitting last (or able to
observe the running combination) can solve for a contribution that forces
the final Super-Hash to any target value, without breaking any hash
function — cheap arithmetic forgery, not a cryptographic break.
compute_super_hash() instead sorts contributions by party ID and hashes
their length-prefixed concatenation. Order no longer matters (no
last-mover advantage) and the XOR-forgery trick no longer works. See
tests/test_fixes.py::test_super_hash_xor_forgery_no_longer_trivial.
Structure
dcl_core/
├── __init__.py
├── chain.py ChainState — append-only chain, content-hash verify()
├── consensus.py ConsensusRound, compute_super_hash — multi-party consensus
├── seal.py format_seal() — human-readable "Verified by..." seal, mirrors dcl-sdk's seal.ts
└── verify.py verify_chain() — standalone offline chain verification, mirrors dcl-sdk's verify.ts
tests/
└── test_fixes.py Regression tests for both fixes above
Quick start
pip install -e .
python -m pytest tests/ -v
from dcl_core import ChainState
chain = ChainState("audit.db")
tx_hash, idx = chain.append(
verdict="COMMIT", input_hash="0xabc...", policy_hash="0xdef...",
agent_id="agent-1", reason="policy checks passed", confidence=0.95,
task_type="generation",
)
clean, bad_index, reason = chain.verify()
from dcl_core import ConsensusRound, verify_super_hash
round_ = ConsensusRound(expected_parties={"org-a", "org-b", "org-c"})
round_.submit("org-a", h_a)
round_.submit("org-b", h_b)
round_.submit("org-c", h_c)
super_hash, contributions = round_.seal()
assert verify_super_hash(contributions, super_hash)
Scope
This repo publishes the protocol layer only — record format, hash-chain verification, and consensus combination. Scoring/policy engines (behavioral fingerprinting, epistemic validation thresholds, reputation weighting) stay in separate, closed modules that build on top of this.
License
Apache License 2.0 — see LICENSE.
Metadata
Release files for dcl-core 0.3.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| dcl_core-0.3.1.tar.gz | 14.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| dcl_core-0.3.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 26.8 kB
Release files / dcl_core-0.3.1.tar.gz
| Download URL | dcl_core-0.3.1.tar.gz |
|---|---|
| Size | 14.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e93ee49ff23453ac0474d34510897660508375e15f20b2486fcd76eb791fb7e0
|
|
BLAKE2b-256 checksum How to use checksums |
bc659ca51c5cb945d26d80ade4ff908e9270bf8872ce8984e318f761389076ff
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.3
|
Release files / dcl_core-0.3.1-py3-none-any.whl
| Download URL | dcl_core-0.3.1-py3-none-any.whl |
|---|---|
| Size | 12.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0c8bb9a49e590bbc2b676457a7624f3896d61286a541a974375d7c27da5f45e8
|
|
BLAKE2b-256 checksum How to use checksums |
dfdc64935e119f1df7fb181adfe4fafd0620477c4704dd455e5ec6ebb1bc64e2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.3
|