Skip to main content

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, GHCR containers, package-index ownership transfer, and additional package-manager channels are preview, planned, 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
Agent Validation Lab Local-proof Development-only eval group, scenario fixtures, no-model CI lanes
MCP, policy, OpenTelemetry, service, Postgres, cloud/Kubernetes fixtures Preview Optional extras and local fixture tests
GitHub release artifacts and attestations Alpha-supported / External-validation-required v0.1.0a5 GitHub Release is published with 13 release assets; 0.1.0a6 is the next prepared hardening release
PyPI/TestPyPI package publication Alpha-supported PyPI latest is 0.1.0a5; 0.1.0a6 is prepared but not published until owner approval
GHCR container publication Preview / external-validation-required Anonymous GHCR registry and GitHub package checks did not expose a public image on 2026-06-23; release workflow prepares digest capture, signing, and attestations after publication
Homebrew tap, 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 PyPI Evaluation

Prerequisites:

  • Python 3.12, 3.13, or 3.14
  • uv

Run the public-alpha package from PyPI after the owner-approved 0.1.0a6 publication. Because 0.1.0a6 is a prerelease, uvx needs an explicit prerelease flag:

uvx --prerelease allow --from actionlineage==0.1.0a6 actionlineage version
uvx --prerelease allow --from actionlineage==0.1.0a6 actionlineage demo run --output-dir /tmp/actionlineage-demo
uvx --prerelease allow --from actionlineage==0.1.0a6 actionlineage journal verify /tmp/actionlineage-demo/evidence.jsonl

The demo requires no model API key, cloud account, or external service. The PyPI path needs internet access to install the package; the demo itself is deterministic and local after installation.

The demo writes artifacts under /tmp/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.

If you cloned the repository for development, install the full local test environment and run the same demo through the checkout:

uv sync --locked --all-extras
make demo

Repository demo artifacts are written under build/actionlineage-demo/. To generate a deterministic SVG overview from those demo artifacts, run:

make demo-map

That writes build/actionlineage-demo/demo-evidence-map.svg and build/actionlineage-demo/demo-evidence-map.json. The SVG is an onboarding aid derived from incident.json; the canonical evidence remains evidence.jsonl.

Inspect repository-generated 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 python scripts/generate_demo_evidence_map.py \
  --demo-dir build/actionlineage-demo \
  --check

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_dispatched with downstream_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.

Agent Validation Lab

The Agent Validation Lab is a development-only evaluation surface for testing tool-using agents against ActionLineage evidence requirements. It lives under evals/, is not packaged as an ActionLineage runtime dependency, and does not change the v1alpha1 event schema.

It provides scenario fixtures, no-model replay, scorer output, provenance, artifact audits, Docker-backed local receiver scenarios, and optional scheduled live-model lanes for maintainers. Pull-request validation remains secret-free and no model response is treated as authoritative product evidence.

Run the deterministic no-model lab locally from a repository checkout:

PYTHONPATH=evals uv run --group eval python -m actionlineage_evals validate-scenarios
PYTHONPATH=evals uv run --group eval python -m actionlineage_evals coverage --strict
PYTHONPATH=evals uv run --group eval python -m actionlineage_evals run \
  --scenario-path evals/scenarios \
  --artifact-root build/evals/local \
  --mode scripted \
  --model-adapter scripted
PYTHONPATH=evals uv run --group eval python -m actionlineage_evals summarize \
  build/evals/local \
  --format markdown

See evals/README.md, docs/AGENT_VALIDATION_EVIDENCE.md, docs/AGENT_VALIDATION_ARCHITECTURE.md, docs/AGENT_VALIDATION_THREAT_MODEL.md, and docs/AGENT_VALIDATION_PLAN.md.

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.0a6"),
    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

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.

actionlineage 0.1.0a6 is the next corrective public-alpha hardening version prepared from this source tree. PyPI and the GitHub Release currently publish 0.1.0a5; the already published 0.1.0a5 PyPI long description cannot be changed in place, so corrected package text appears with the next owner-approved upload. The release workflow is prepared to publish preview GHCR images for version tags, capture the OCI digest, and sign/attest that digest, while Homebrew and additional package-manager channels remain gated on external setup and validation. See docs/PACKAGE_MANAGERS.md.

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


Download files

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

Source Distribution

actionlineage-0.1.0a6.tar.gz (620.3 kB view details)

Uploaded Source

Built Distribution

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

actionlineage-0.1.0a6-py3-none-any.whl (142.6 kB view details)

Uploaded Python 3

File details

Details for the file actionlineage-0.1.0a6.tar.gz.

File metadata

  • Download URL: actionlineage-0.1.0a6.tar.gz
  • Upload date:
  • Size: 620.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for actionlineage-0.1.0a6.tar.gz
Algorithm Hash digest
SHA256 acb85c786573071bc3a13efa3db84b2b0499c78f0534e9caf87106376e7b5f8f
MD5 b25b050869eb12878d8b35955a6d8390
BLAKE2b-256 ca8210c11e489042bac46b5d6068669923a85db55069d1c97bc96ef21c626b4c

See more details on using hashes here.

Provenance

The following attestation bundles were made for actionlineage-0.1.0a6.tar.gz:

Publisher: release.yml on VectorTrace-Labs/ActionLineage

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

File details

Details for the file actionlineage-0.1.0a6-py3-none-any.whl.

File metadata

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

File hashes

Hashes for actionlineage-0.1.0a6-py3-none-any.whl
Algorithm Hash digest
SHA256 5214c77f330c3e6426e4ee6db58103b37c17c071b8667ac586275aa74639017b
MD5 5ec9c98a54ffa9ca9f906ff7fb999f6b
BLAKE2b-256 797c8c0320baaf9423f918f284f299ddef2ebb9d211515cd5adaae183e6180ee

See more details on using hashes here.

Provenance

The following attestation bundles were made for actionlineage-0.1.0a6-py3-none-any.whl:

Publisher: release.yml on VectorTrace-Labs/ActionLineage

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

Supported by

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