Vendor-neutral evidence and detection plane for tool-using agents
Project description
ActionLineage
Know what the agent did, and show what changed.
ActionLineage is an alpha-stage, vendor-neutral evidence and detection plane for tool-using agents. It correlates agent intent, delegated identity, tool execution, and independently observed side effects into investigation-ready local evidence.
The central rule is simple: a successful tool response is an acknowledgement, not proof of a side effect. ActionLineage records requested, authorized, dispatched, acknowledged, observed, verified, unverified, timed-out, conflicting, and not-dispatched outcomes as separate facts.
Current Maturity
This repository is a public alpha. Core evidence recording is usable for local evaluation and fixture-backed integration work, but service deployments, external adapters, cloud observers, containers, package-index publication, and attested release artifacts are preview or external-validation surfaces until they are externally validated.
| Surface | Maturity | Evidence |
|---|---|---|
| Event envelope, redaction, local journal, SQLite projection | Alpha-supported | Unit, compatibility, projection, and security tests |
| Deterministic verified/unverified/conflicting/not-dispatched demo | Alpha-supported | make demo, demo tests, contract validation |
| Case export, graph export, grounded summary, static console | Alpha-supported | Projection and console tests |
| Lineage Contracts, sequence detections, Lineage Lab | Local-proof | Contract, detection, and replay tests |
| MCP, policy, OpenTelemetry, service, Postgres, cloud/Kubernetes fixtures | Preview | Optional extras and local fixture tests |
| Package-index publication, attested artifacts, external audits, production history | Planned or external-validation-required | See docs/DECISIONS_REQUIRED.md |
Full claim mapping lives in docs/QUALITY_SCORECARD.md.
Five-Minute Local Evaluation
Prerequisites:
- Python 3.13 or newer
uvmakefor convenience targets
Install all optional extras used by the test suite:
uv sync --locked --all-extras
Run the deterministic local demo:
make demo
The demo requires no model API key, cloud account, external service, or internet
access. It writes artifacts under build/actionlineage-demo/:
evidence.jsonl: canonical append-only local journal.projection.sqlite: rebuildable query projection.timeline.json: compact event-order summary.incident.json: machine-readable incident export.
Inspect the evidence:
uv run actionlineage journal verify build/actionlineage-demo/evidence.jsonl
uv run actionlineage projection timeline \
build/actionlineage-demo/projection.sqlite \
--trace-id trace_demo_evidence_plane
uv run actionlineage projection summarize \
build/actionlineage-demo/projection.sqlite \
--trace-id trace_demo_evidence_plane
uv run actionlineage projection export-case \
build/actionlineage-demo/projection.sqlite \
build/actionlineage-demo/case \
--trace-id trace_demo_evidence_plane
uv run actionlineage projection export-console \
build/actionlineage-demo/projection.sqlite \
build/actionlineage-demo/console.html \
--trace-id trace_demo_evidence_plane
uv run actionlineage contract validate \
contracts/examples/outbound-http.json \
build/actionlineage-demo/evidence.jsonl
Open build/actionlineage-demo/console.html in a browser to review the static
timeline, event details, graph, verification matrix, and case context.
The stricter contracts/examples/restricted-exfiltration.json contract is a
design example for detection coverage; it is not the five-minute demo contract.
What The Demo Shows
The default scenario emits a deterministic local journal that includes:
- a recorded human intent and agent run;
- a verified file-read side effect corroborated by a local filesystem observer;
- an acknowledged HTTP send that remains unverified because acknowledgement is not side-effect evidence;
- a conflicting receiver observation represented as
side_effect.conflict_detected; - a policy-denied shell-like request represented as
tool.execution.not_dispatchedwithdownstream_forwarded=false.
Evidence Lifecycle
| State | Meaning |
|---|---|
agent.intent.recorded |
A human, service, scheduler, or agent initiated a run. |
tool.execution.requested |
An agent or adapter requested a tool invocation. |
tool.execution.authorized |
An optional policy or approval path allowed the request. |
tool.execution.dispatched |
The request crossed the tool boundary. |
tool.execution.acknowledged |
The tool or adapter returned a response. |
side_effect.observed |
A named observer recorded resource or environment evidence. |
side_effect.verified |
Corroborating evidence supports the subject event. |
side_effect.unverified |
Evidence is insufficient or only self-reported. |
side_effect.timed_out |
Observation or verification did not complete in time. |
side_effect.conflict_detected |
Evidence sources disagree and both sides are retained. |
tool.execution.not_dispatched |
A request was blocked, denied, or not sent downstream. |
Verification requires independent or explicitly identified corroborating evidence. Missing observations are reported as missing observations only.
Architecture
flowchart LR
Client["Agent / client"] --> Adapter["Optional adapter"]
Adapter --> Journal["Append-only local journal"]
Adapter --> Tool["Tool runtime"]
Tool --> Adapter
Observer["Observer adapters"] --> Journal
Verifier["Verification helpers"] --> Journal
Journal --> Projection["Rebuildable projection"]
Projection --> Timeline["Timeline, export, console"]
Journal --> Contracts["Lineage Contracts"]
Journal --> Lab["Lineage Lab"]
Journal --> Exporters["Optional exporters"]
Core packages do not import MCP, OpenTelemetry, model-provider SDKs, FastAPI, or cloud SDKs. Those surfaces live behind optional adapter or service boundaries.
How This Differs
| Tooling category | Main focus | ActionLineage difference |
|---|---|---|
| Distributed tracing | Request flow and latency | Adds evidence status, side-effect verification, and investigation exports |
| Agent gateway | Mediation or policy enforcement | Treats enforcement as optional adapter behavior |
| Guardrail | Preventing or blocking actions | Preserves evidence, uncertainty, and conflicts even when no block occurs |
| SIEM/logging | Event collection and search | Adds causal evidence links and telemetry contract validation |
Python API Example
from datetime import UTC, datetime
from pathlib import Path
from actionlineage import (
Classification,
Correlation,
EvidenceNormalizer,
EvidenceRecord,
EvidenceSourceKind,
EventType,
FixedClock,
FixedIdGenerator,
LocalJournal,
NormalizedAction,
NormalizedResource,
Principal,
PrincipalType,
ResourceType,
Sensitivity,
Source,
ToolIdentity,
import_evidence_batch,
verify_journal,
)
journal_path = Path("build/example/evidence.jsonl")
journal = LocalJournal(journal_path)
normalizer = EvidenceNormalizer(
correlation=Correlation(trace_id="trace_example", run_id="run_example"),
source=Source(component="example_adapter", instance_id="local", version="0.1.0a2"),
principal=Principal(principal_id="agent_example", principal_type=PrincipalType.AGENT),
classification=Classification(sensitivity=Sensitivity.INTERNAL),
clock=FixedClock(datetime(2026, 1, 1, tzinfo=UTC)),
id_generator=FixedIdGenerator(("evt_example_001", "evt_example_002")),
)
intent = EvidenceRecord(
idempotency_key="example-intent-001",
source_kind=EvidenceSourceKind.LOCAL_FUNCTION,
event_type=EventType.AGENT_INTENT_RECORDED,
payload={"intent": {"summary": "Read a workspace report"}},
sort_key="000",
)
action = EvidenceRecord.from_action(
idempotency_key="example-action-001",
source_kind=EvidenceSourceKind.LOCAL_FUNCTION,
sort_key="001",
action=NormalizedAction(
action_type="read",
tool_identity=ToolIdentity(
name="safe_file_read",
descriptor_hash="sha256:example_descriptor",
adapter="local",
),
resources=(
NormalizedResource(
resource_type=ResourceType.FILE,
identifier="demo://workspace/report.txt",
),
),
),
)
result = import_evidence_batch([intent, action], normalizer=normalizer, journal=journal)
assert result.ok
assert verify_journal(journal_path).ok
See docs/API_REFERENCE.md for alpha-supported public imports and preview API boundaries.
CLI Highlights
uv run actionlineage version
uv run actionlineage demo run --output-dir build/actionlineage-demo
uv run actionlineage journal verify build/actionlineage-demo/evidence.jsonl
uv run actionlineage projection timeline build/actionlineage-demo/projection.sqlite --trace-id trace_demo_evidence_plane
uv run actionlineage projection explain-event build/actionlineage-demo/projection.sqlite evt_demo_11
uv run actionlineage projection export-incident build/actionlineage-demo/projection.sqlite --trace-id trace_demo_evidence_plane
uv run actionlineage projection export-graph build/actionlineage-demo/projection.sqlite --trace-id trace_demo_evidence_plane
uv run actionlineage projection export-desktop-bundle build/actionlineage-demo/projection.sqlite build/actionlineage-demo/desktop --trace-id trace_demo_evidence_plane
uv run actionlineage contract validate contracts/examples/outbound-http.json build/actionlineage-demo/evidence.jsonl
See docs/CLI_REFERENCE.md for the full command reference.
Documentation Map
- Maturity model: supported, preview, planned, and external validation labels.
- Quality scorecard: public claim-to-evidence map.
- Architecture: component boundaries and runtime flow.
- Threat model: assets, adversaries, trust boundaries, and claim language.
- Acceptance tests: executable release criteria.
- Data model: event envelope and payload conventions.
- Schema reference:
v1alpha1event schema. - Compatibility: supported journal and schema policy.
- Tutorial: local demo walkthrough.
- Investigation workflow: timelines, summaries, graph, and case bundles.
- Console: static analyst UI and desktop bundle export.
- Journal integrity: anchors, archive manifests, recovery, and limits.
- Lineage Contracts: telemetry requirements as code.
- Detection Lab: replay, mutation, minimization, and scorecards.
- Observers: local, fixture, cloud, Kubernetes, and external sensor evidence.
- Integrations: exporters and optional ecosystem adapters.
- Operations: service mode, health, storage, and deployment notes.
- Release checklist: public release gates.
- Publishing: GitHub release workflow, artifact attestations, and Trusted Publishing setup.
- Decisions required: owner and external gates.
Packages and Extras
The repository currently ships as one Python distribution with optional extras:
uv sync --locked # core
uv sync --locked --extra adapters
uv sync --locked --extra service
uv sync --locked --all-extras
Core dependencies are intentionally small: Pydantic and Typer. Optional extras hold MCP, OpenTelemetry, SQLAlchemy, FastAPI, JWT, and related integration dependencies.
Security Model In One Paragraph
ActionLineage is not a sandbox, model guardrail, DLP engine, or universal proof system. It records redacted, structured, causally linked evidence and verifies local journal consistency under documented trust assumptions. When a report says an outcome is verified, it means the named evidence source corroborated it within the stated limitations. When no observation exists, the system reports that no observation was recorded.
Development
uv sync --locked --all-extras
uv run ruff check .
uv run ruff format --check .
uv run mypy src
uv run pytest
uv run python scripts/check_claims_language.py .
uv run python scripts/secret_scan.py .
uv run pip-audit
Before release, also run:
uv run python scripts/generate_sbom.py --output build/actionlineage-sbom.json
uv run python scripts/generate_release_provenance.py \
--dist-dir dist \
--output build/actionlineage-release-provenance.json
uv build
License
Apache License 2.0. See LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file actionlineage-0.1.0a2.tar.gz.
File metadata
- Download URL: actionlineage-0.1.0a2.tar.gz
- Upload date:
- Size: 303.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3ab6056d08d458e983c691946507e904532c312df907f79d1cb744d1885b87d1
|
|
| MD5 |
c3bc7f21c6725dec4f4b7f75fae92086
|
|
| BLAKE2b-256 |
2c2eb7893f8e910a6b320e2eb66e97fac46dc96d6ba334f54fd5577e6f6f0eae
|
Provenance
The following attestation bundles were made for actionlineage-0.1.0a2.tar.gz:
Publisher:
release.yml on VectorTrace-Labs/ActionLineage
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
actionlineage-0.1.0a2.tar.gz -
Subject digest:
3ab6056d08d458e983c691946507e904532c312df907f79d1cb744d1885b87d1 - Sigstore transparency entry: 1912507922
- Sigstore integration time:
-
Permalink:
VectorTrace-Labs/ActionLineage@ac97c901412576a93c4d9ac7a621ceafbb5c4d12 -
Branch / Tag:
refs/tags/v0.1.0a2 - Owner: https://github.com/VectorTrace-Labs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ac97c901412576a93c4d9ac7a621ceafbb5c4d12 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file actionlineage-0.1.0a2-py3-none-any.whl.
File metadata
- Download URL: actionlineage-0.1.0a2-py3-none-any.whl
- Upload date:
- Size: 134.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
45b2e81267b92ea69687ab9a0dfb1b2e32ffca4e1263eeea53d84ae00f0ab0d0
|
|
| MD5 |
6b7e8bc29667d894c63e1e077d1905f9
|
|
| BLAKE2b-256 |
de8571b6705cdf953360ca793c69d9bb8492ea3d8b99da1b1ed0cdbf0f8e7836
|
Provenance
The following attestation bundles were made for actionlineage-0.1.0a2-py3-none-any.whl:
Publisher:
release.yml on VectorTrace-Labs/ActionLineage
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
actionlineage-0.1.0a2-py3-none-any.whl -
Subject digest:
45b2e81267b92ea69687ab9a0dfb1b2e32ffca4e1263eeea53d84ae00f0ab0d0 - Sigstore transparency entry: 1912508172
- Sigstore integration time:
-
Permalink:
VectorTrace-Labs/ActionLineage@ac97c901412576a93c4d9ac7a621ceafbb5c4d12 -
Branch / Tag:
refs/tags/v0.1.0a2 - Owner: https://github.com/VectorTrace-Labs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ac97c901412576a93c4d9ac7a621ceafbb5c4d12 -
Trigger Event:
workflow_dispatch
-
Statement type: