Skip to main content

LATTICE

Ledgered Agent Traces for Transparent, Inspectable Collaborative Execution

Python 3.10+ Tests License: MIT Version

Accountability layer for multi-agent AI systems. Every agent decision becomes a content-addressed, cryptographically signed claim in a DAG you can trace backward from any conclusion to raw evidence.

Read the Paper (PDF) | Changelog | Examples


LATTICE is not an agent framework. It is the accountability layer that sits underneath any agent framework, or raw Python functions.

The Problem

Multi-agent AI systems produce conclusions, but cannot explain why. When Agent X says "this domain is malicious," there is no audit trail showing what evidence it used, how confident it was, or whether that conclusion survives scrutiny.

In OSINT, security research, and regulated industries, an unverifiable claim is worse than no claim.

The Solution

Conclusion -> "domain is malicious" (conf: 0.75, eff: 0.70, agent: reporter)
    +-- "bulletproof hosting detected" (conf: 0.80, agent: analyzer)
        +-- "resolves to 198.51.100.42" (conf: 0.99, agent: harvester)
        |   +-- [evidence: nslookup output]
        +-- "registered via ShadyRegistrar, Panama" (conf: 0.95, agent: harvester)
            +-- [evidence: WHOIS record]

Every node is content-addressed (SHA-256), cryptographically signed (Ed25519), and stored in SQLite. Walk backward from any conclusion to raw evidence. Verify nothing was tampered with. Detect inflated confidence automatically.

Features

  • Content-addressed claims -- SHA-256 hashes make every claim tamper-evident
  • Ed25519 signatures -- every claim is cryptographically bound to its originating agent
  • Backward traceability -- walk from any conclusion to raw evidence
  • Effective confidence -- min-propagation ensures weak evidence cannot hide behind strong conclusions
  • Revocation waterfall -- revoking a claim propagates compromise status to all downstream dependents
  • Zero-friction monitoring -- @lattice_monitor instruments any function without changing its behavior
  • Cycle detection -- DAG acyclicity enforced at insertion time
  • Audit -- flags unsupported claims, low confidence, broken references, and inflated confidence
  • Local dashboard -- FastAPI + D3.js visualization, no external dependencies
  • CLI -- Rich terminal interface for all operations
  • 89 tests across all modules

Install

git clone https://github.com/thunderstornX/lattice.git
cd lattice
pip install -e .                    # Core library (no dashboard)
pip install -e ".[dashboard]"       # With local web dashboard
pip install -e ".[dev]"             # With dev/test dependencies

Quick Start

import lattice

store = lattice.init(":memory:")

# Register agents
harvester = store.agent("harvester", role="collector")
analyzer = store.agent("analyzer", role="analyst")

# Store raw evidence
eid = store.evidence("nslookup example.com -> 93.184.216.34")

# Create signed claims backed by evidence
dns_claim = harvester.claim(
    assertion="example.com resolves to 93.184.216.34",
    evidence=[eid],
    confidence=0.99,
    method="tool:nslookup",
)

# Build derived conclusions referencing other claims
conclusion = analyzer.claim(
    assertion="example.com hosted on Edgecast infrastructure",
    evidence=[dns_claim.claim_id],
    confidence=0.85,
    method="llm:analysis",
)

# Trace backward from any conclusion
chain = store.trace(conclusion.claim_id)
for claim in chain:
    print(f"  [{claim.agent_id}] {claim.assertion}")

# Check effective confidence (min across ancestor chain)
eff = store.effective_confidence(conclusion.claim_id)
print(f"  Effective confidence: {eff}")

# Audit for issues (unsupported, low confidence, inflated, broken refs)
issues = store.audit()

# Verify all cryptographic signatures
results = store.verify()

Auto-Instrumentation

Wrap any function with @lattice_monitor to auto-generate signed claims:

from lattice import lattice_monitor

@lattice_monitor(harvester, method="tool:nslookup")
def dns_lookup(domain: str) -> dict:
    """DNS lookup for {domain}"""
    result = subprocess.run(["nslookup", domain], capture_output=True, text=True)
    return {"output": result.stdout}

# Calling dns_lookup("example.com") automatically:
# 1. Runs the function
# 2. Stores the return value as raw Evidence
# 3. Creates a signed Claim with "DNS lookup for example.com"
# 4. Links the claim to the evidence in the DAG
# 5. Returns the original output unchanged

Options: confidence=0.9, evidence_ids=[...] to link upstream claims, capture_evidence=False to skip evidence storage.

Overhead: 0.24 ms per instrumented call (see benchmarks).

Effective Confidence

LATTICE computes the effective confidence of every claim: the minimum confidence across the claim and all of its ancestors. A conclusion cannot hide behind a high stated confidence if its evidence chain contains a weak link.

# Stated confidence is 0.95, but an ancestor has 0.6
eff = store.effective_confidence(conclusion.claim_id)
# Returns 0.6 -- the real floor

# Audit catches the mismatch automatically
issues = store.audit()
# -> "inflated_confidence: Stated 0.95 but effective 0.60"

Min-propagation is correct under worst-case correlation between evidence sources, making it a defensible choice for adversarial and security contexts.

Revocation Waterfall

When evidence is invalidated, revoke it and LATTICE propagates compromise status through the entire dependency graph:

# Revoke a claim (only the signer or governance can do this)
result = store.revoke_claim(bad_claim.claim_id, agent_id="harvester", reason="Source retracted")

print(f"Directly revoked: {result.revoked_claim_id}")
print(f"Downstream compromised: {result.compromised_claim_ids}")
print(f"Total affected: {result.total_affected}")

# Check any claim's status
store.get_claim_status(some_claim_id)  # -> "VALID", "REVOKED", or "COMPROMISED"

Original claims and signatures are never modified. Revocation is stored separately, preserving the complete historical record.

CLI

lattice init ./my-investigation       # Initialize
lattice agents -d ./my-investigation  # List agents
lattice claims -d ./my-investigation  # List claims (shows effective confidence)
lattice trace <claim_id> -d .         # Trace backward
lattice audit -d .                    # Audit for issues
lattice verify -d .                   # Verify all signatures
lattice stats -d .                    # Summary statistics
lattice export out.json -d .          # Export to JSON
lattice revoke <id> --agent bot -d .  # Revoke a claim
lattice revocations -d .             # List revocations
lattice dashboard -d .                # Launch local web dashboard

Dashboard

Local web dashboard (FastAPI + D3.js, no CDN dependencies):

lattice dashboard -d ./my-investigation
# -> http://127.0.0.1:8420

Force-directed DAG visualization with color-coded nodes (valid/revoked/compromised/evidence). Click any node to see full details: claim ID, assertion, agent, confidence, effective confidence, signature verification status, and revocation info.

Architecture

+--------------------------------------------------+
|         YOUR AGENTS (any framework)              |
|  CrewAI / LangGraph / raw Python / shell scripts |
+------------------------+-------------------------+
                         |  store.agent() / .claim()
                         v
+--------------------------------------------------+
|              LATTICE CORE                        |
|                                                  |
|  +----------+  +----------+  +--------------+   |
|  |Claim DAG |  | Evidence |  |   Agent      |   |
|  | (SQLite) |  |  Store   |  |  Registry    |   |
|  +----------+  +----------+  +--------------+   |
|                                                  |
|  +--------------+  +-----------+  +----------+  |
|  | DAG Traversal|  | Effective |  | Signature|  |
|  | + Audit      |  | Confidence|  | Verify   |  |
|  +--------------+  +-----------+  +----------+  |
|                                                  |
|  +--------------+  +-----------+                 |
|  | Revocation   |  | Runtime   |                 |
|  | Waterfall    |  | Monitor   |                 |
|  +--------------+  +-----------+                 |
+------------------------+-------------------------+
                         |
          +--------------+--------------+
          v              v              v
+----------------+ +------------+ +----------+
| CLI (Rich)     | | Dashboard  | | JSON     |
| trace/audit/   | | (FastAPI + | | Export   |
| verify/stats   | |  D3.js)    | |          |
+----------------+ +------------+ +----------+

Performance

Benchmarked on Intel Xeon E5-2676 v3, 2GB RAM, SSD, Ubuntu 20.04 (see benchmarks/):

Operation Time
Evidence storage 0.009 ms
Claim creation + signing 0.68 ms
Trace (100-claim chain) 1.36 ms
Effective confidence (single) 1.30 ms
Effective confidence (bulk, 100) 2.44 ms
Audit (100 claims) 4.01 ms
Verify all signatures (100) 43.33 ms
Instrumentation overhead per call 0.24 ms

Full scalability curves and case study results in the paper.

Core Concepts

Claim

The fundamental unit. Content-addressed (SHA-256), cryptographically signed (Ed25519):

Claim(
    claim_id="a1b2c3...",     # SHA-256 of canonical content
    agent_id="harvester",     # Who made this claim
    assertion="domain -> IP", # What is claimed
    evidence=["e1", "c2"],    # Supporting claim/evidence IDs
    confidence=0.99,          # 0.0 to 1.0
    method="tool:nslookup",   # How it was derived
    signature="d4e5f6...",    # Ed25519 signature
)

Evidence

Content-addressed raw data (tool output, API responses, etc.). Claims reference evidence by hash.

DAG

Claims reference other claims and evidence, forming a Directed Acyclic Graph:

  • Leaf nodes = raw evidence
  • Intermediate nodes = derived analysis
  • Root nodes = final conclusions

Cycle detection is enforced at insertion time.

Dependencies

Minimal by design:

  • Python 3.10+
  • cryptography -- Ed25519 signatures
  • click -- CLI
  • rich -- terminal formatting
  • fastapi + uvicorn -- local dashboard
  • sqlite3 -- storage (stdlib)

Security Notes

LATTICE is designed for single-user, local investigations:

  • Private keys are stored in plaintext in the SQLite database. Acceptable for local use with appropriate file permissions. Do not share the database file.
  • No key rotation in v1.x. If an agent keypair is compromised, register a new agent.
  • The database is a local file with no access control beyond filesystem permissions.

For multi-user or networked deployments, additional encryption and access control would be needed (planned for future versions).

Running Tests

pip install -e ".[dev]"
pytest

89 tests covering: content addressing, signatures, DAG traversal, revocation waterfall, cycle detection, effective confidence, inflated confidence audit, CLI, dashboard API, and runtime monitoring.

Examples

See examples/ for:

  • basic_usage.py -- Minimal two-agent demo
  • osint_investigation.py -- Full three-agent OSINT pipeline

Benchmarks

PYTHONPATH=. python3 benchmarks/run_benchmarks.py

Six experiments: scalability curves, operation profiling, revocation waterfall performance, effective confidence scaling, instrumentation overhead, and OSINT pipeline case study. Results saved to benchmarks/results.json.

Research

LATTICE formalizes concepts from:

  • W3C PROV -- Data provenance standard
  • Structured Analytic Techniques -- Intelligence community tradecraft
  • Content-addressed storage -- Git, IPFS, Merkle DAGs
  • Runtime verification -- Lightweight monitoring of multi-agent behavior

To our knowledge, no existing tool combines content-addressing + cryptographic signatures + effective confidence propagation + revocation waterfall + agent attribution in a single protocol for AI systems.

License

MIT -- see LICENSE.

Author

Ali Murtaza Bhutto -- @thunderstornX -- ORCID: 0009-0007-2787-943X

Metadata

Release files for lattice-core 1.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for lattice-core 1.2.1
File Size Uploaded
lattice_core-1.2.1.tar.gz 40.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for lattice-core 1.2.1
File Interpreter ABI Platform
lattice_core-1.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 74.5 kB

Release files / lattice_core-1.2.1.tar.gz

Download URL lattice_core-1.2.1.tar.gz
Size 40.8 kB
Tags Source
SHA-256 checksum
How to use checksums
bfb681dc5182d1e1181d0e71b49cc3150fd7b25dbc7b2f83ec1ecaa4585b64c4
BLAKE2b-256 checksum
How to use checksums
5a07ad4c10c591448cd91151bc2aef70587f24cde6d264f11e20a78f226dedae
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.8.10

Release files / lattice_core-1.2.1-py3-none-any.whl

Download URL lattice_core-1.2.1-py3-none-any.whl
Size 33.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
83941579644c03fab925258b4d2b7a61d5febc2a1abefcbe56ccf4fa38384b50
BLAKE2b-256 checksum
How to use checksums
8644336e5c275cb511966414e5149ff307233176ec9df4ca5da73e8421c8c17b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.8.10

Release history Release notifications | RSS feed

This release

1.2.1 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page