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 External-validation-required v0.1.0a5 tag and GitHub Release object are owner-gated; v0.1.0a4 did not produce release artifacts
PyPI/TestPyPI package publication Alpha-supported 0.1.0a5 is the corrective release-prep version; 0.1.0a3 fresh install/demo smoke passed; 0.1.0a4 was not published
GHCR container publication Preview Tag-gated release workflow path
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 or newer
  • uv

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

uvx --prerelease allow --from actionlineage==0.1.0a5 actionlineage version
uvx --prerelease allow --from actionlineage==0.1.0a5 actionlineage demo run --output-dir /tmp/actionlineage-demo
uvx --prerelease allow --from actionlineage==0.1.0a5 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.0a5"),
    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.0a5 is the corrective public-alpha release-prep version for PyPI and TestPyPI Trusted Publishing. The v0.1.0a4 tag exists but did not complete release artifact upload, package publication, or GitHub Release creation; the v0.1.0a5 tag, package upload, GitHub Release object, and hosted release-artifact page remain owner-gated until release. The release workflow is prepared to publish preview GHCR images for version tags, 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.0a5.tar.gz (590.4 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.0a5-py3-none-any.whl (137.5 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: actionlineage-0.1.0a5.tar.gz
  • Upload date:
  • Size: 590.4 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.0a5.tar.gz
Algorithm Hash digest
SHA256 a2a9faf3ebf80d940be6281cda91d2b2b28f68ddb0c3a7f599bee67fac1033c4
MD5 50b087ee8075fdd8d1144263b1ac30d0
BLAKE2b-256 e3c6f0743210243287fa003d481afefa597a24300ccc286cc282ec07a9a3cdb9

See more details on using hashes here.

Provenance

The following attestation bundles were made for actionlineage-0.1.0a5.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.0a5-py3-none-any.whl.

File metadata

  • Download URL: actionlineage-0.1.0a5-py3-none-any.whl
  • Upload date:
  • Size: 137.5 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.0a5-py3-none-any.whl
Algorithm Hash digest
SHA256 1835ec37566b0b9dd33d16eaf9767660c3fdaf999900ce9f26769989b1ca7101
MD5 888097f7624ade1ba4d9de1e9d5a28b9
BLAKE2b-256 18932475e2317febcfb63be5333d5b12df3a278830676fe60a4acb1a52d5c588

See more details on using hashes here.

Provenance

The following attestation bundles were made for actionlineage-0.1.0a5-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