Skip to main content

TraceLayer

Agent-native software traceability: intent, implementation, verification, provenance, and evidence as a deterministic graph.

CI PyPI version Python uv License

Marker protocol · Relationships · Concepts · Policy · Hooks · Evidence · Security

TraceLayer makes the why of software traversable. One-line trace:v1 markers declare the semantic relationships that cannot be derived — which work item produced a behavior, which requirement it satisfies, which tests intend to verify it. The engine derives everything else: AST symbol attachment, Git provenance, revision fingerprints, staleness, and runtime evidence. The result is a continuously verified trace graph that agents and reviewers can query instead of loading the whole repository.

Quickstart

Install once per machine, then let TraceLayer handle the rest:

uv tool install tracelayer            # pipx install tracelayer also works
trace install --agent claude-code --global --yes   # one-time: skill + hooks for your agent

Zero-ceremony per-repo bootstrap (Ambient mode): nothing else is needed. When you start working in a repository, the hooks initialize .trace/ silently on their first fire, and the agent bootstraps traced tasks straight from your prose — you never type a TraceLayer ID:

you:  "Build a program that scans for node_modules over 2 GB..."
agent: trace task bootstrap --prompt "<your request>"   (internal machinery)
       ...work, spec, requirements, plan auto-created; hooks enforce per-boundary traces
agent: "Done — WORK finalized after tests + evidence."

Explicit per-repo setup is still available when you want it (config, invariant, skill + hooks for every detected agent, .mcp.json):

cd your-repo
trace init                            # full bootstrap: config, invariant, skill + hooks, .mcp.json
trace index --all                     # builds the trace graph
trace verify --all                    # policy check (exit 0 = pass)
trace context <trace-id>              # why does this exist, what verifies it

Trace a behavior by adding one line above it:

# trace:v1 id=impl.demo satisfies=REQ-1
def do_the_thing(): ...

then trace index --all again. Staleness, evidence, hooks, and the CI gate all build on this. Running trace outside a configured repository prints the trace init / trace install next steps.

Ambient mode in one paragraph

The user speaks only prose. At every UserPromptSubmit the prompt hook resolves the request deterministically: a strong match activates the existing work + its requirements + plan automatically; new intent records a pending bootstrap, so the first code mutation is gated on trace task bootstrap --prompt "<request>" (or a richer --json bundle) before any implementation exists. A behavior-change intake (trace task intake --kind behavior-change <WORK> --requirements REQ-x) blocks implementation edits until the requirement text actually changes. The authoring gate suggests qualified marker IDs (impl.<scope>.<name>), lists candidate requirements when several are active, and auto-injects markers into Write input (single-requirement, unambiguous) — Edits are denied with the plan, never rewritten. On completion the Stop hook runs a safe finalizer: work becomes done only under merge-grade policy (requirement ancestry, verifying test, passed evidence, no stale blockers), and mutation receipts are bound to the commit that contains the work.

How it works

flowchart LR
    A[trace:v1 markers] --> B[Marker parser]
    B --> C[AST symbol attachment]
    C --> D[SQLite trace graph]
    D --> E[Git provenance]
    E --> F[Fingerprints and staleness]
    F --> G[Policy evaluation]
    D --> H[Query engine]
    H --> I[context / why / impact / search]
    G --> J[Verify gate]
    J --> K[Hook engine]
    K --> L[Agent context and Stop gate]
    L --> M[CI merge gate]

Markers are the authoring notation; the graph is the product. Paths, line numbers, commit SHAs, and test results are derived — never written into markers — so trace identity survives refactors and evidence can never silently go stale.

Capabilities

Area What TraceLayer provides
Protocol One-line versioned trace:v1 grammar, typed semantic edges, stable IDs, deterministic type inference, generated schema docs
Indexing Full and changed-scope indexing, Markdown/YAML artifact extraction, fence-aware marker scanning, honest file-level degradation for unsupported languages
Symbols Tree-sitter attachment for Python, TypeScript, JavaScript, Go, Rust, and Java — markers attach to symbols, never line numbers
Graph SQLite materialized index with declared, structural (contains), and observed (executed) provenance; FTS5 search; bounded traversal
Provenance Git-derived first-seen/last-modified history, rename tracking, changed-line ranges, dirty-tree status — no commit IDs in source
Staleness Requirement/implementation fingerprints, upstream-change propagation, review states, historical evidence preservation
Policy Four profiles (minimal/standard/strict/safety-critical) across five lifecycles, scoped expiring waivers, deterministic TL-rule registry
Query UX context, why, impact, search, graph (tree/mermaid/DOT/JSON/JSONL), status, doctor, report pr
Hooks Session start, prompt context, pre-mutation block-once guard, post-mutation guidance, batch summary, fail-closed Stop gate
Evidence JUnit/Cobertura/normalized ingestion, revision binding, L0–L3 proof levels, per-test Python coverage adapter
Migration CodeOps scan/plan/apply with deterministic classification, Scry detection, doctor diagnostics with rename suggestions
Audit Bounded deterministic audit packages for an independent semantic reviewer — no LLM required for the engine itself

Usage

Install

uv tool install tracelayer            # PyPI; pipx install tracelayer also works
trace --help

From a local checkout: uv tool install .. From the repository directly: uv tool install git+https://github.com/carterlasalle/tracelayer.git.

Homebrew

Formula lives in the homebrew-tap tap (source: contrib/brew/tracelayer.rb):

brew install carterlasalle/tap/tracelayer

After each release, bump the formula (PyPI sdist URL + sha256):

contrib/brew/bump.sh        # latest version on PyPI
contrib/brew/bump.sh 0.1.2  # specific version

The brew formula installs both trace and tracelayer; tracelayer never collides with macOS /usr/bin/trace.

Note: macOS ships a built-in trace (/usr/bin/trace, Apple Instruments), and some shells put /usr/bin ahead of ~/.local/bin — which then shadows this project's binary. Both executables are installed, so use tracelayer where a collision bites (tracelayer init, tracelayer verify); it has no system counterpart. Check with which trace / which tracelayer.

The first time you run trace outside a configured repository it prints next steps: trace init to enable traceability in the current repo, or trace install to install the skill and hooks into your agent harnesses globally. Set TRACE_NO_HINT=1 to silence that message (e.g. in CI).

Publishing

tracelayer is published to PyPI on version tags via trusted publishing (no tokens stored in CI). Publish a release with:

git tag v0.1.0 && git push origin v0.1.0

Manual publish from a checkout: uv build && uv publish. See .github/workflows/release.yml for the one-time PyPI trusted-publisher setup.

Prerequisites

  • Python 3.12+
  • uv (dependency management is uv-only; no pip)
uv sync
uv run trace --help

Trace an existing repository:

uv run trace init --root <repo>          # writes .trace/trace.toml + policy.toml
uv run trace index --root <repo> --all
uv run trace verify --root <repo> --all
uv run trace context --root <repo> <trace-id>

Run the full development baseline:

uv run pytest
uv run ruff check .
uv run trace docs generate --check

Architecture

TraceLayer is a single Python package with deliberately narrow module boundaries:

src/tracelayer/
  cli.py                   Typer CLI; business logic lives in modules
  engine.py                Indexing pipeline, verify, staleness, TraceRepository API
  config.py                trace.toml / policy.toml models and loading
  diagnostics.py           TL-rule registry; every failure carries remediation
  protocol/                Marker grammar, parser, ID rules, ontology, generated schema
  discovery/               File enumeration, ignore logic, monorepo scopes
  artifacts/               Markdown, YAML, and generic file-level extraction
  symbols/                 Tree-sitter parsers and marker-to-symbol attachment
  graph/                   Node/edge models, SQLite store, migrations, traversal, fingerprints
  git/                     Provenance, history, diff-range mapping (argv-array subprocess only)
  evidence/                JUnit, Cobertura, normalized JSON, freshness, proof levels
  policy/                  Profiles, lifecycle, waivers, deterministic rule functions
  query/                   context, why, impact, search
  hooks/                   Event handlers and file-backed session state
  audit/                   Bounded semantic-audit packages and external auditor adapter
  migration/               CodeOps and Scry importers

Every module is independently testable; the CLI is a thin shell over the engine.

Safety model

TraceLayer sits in the coding-agent control loop, so correctness is fail-closed by construction:

  • Declared claims are never displayed as proven: a test -> exercises -> implementation claim stays unproven until observed execution evidence exists (proof levels L0–L3).
  • Derived facts cannot be declared: paths, SHAs, test results, and structural/observed edges are rejected in markers.
  • Ambiguity is a diagnostic, never a silent guess: detached markers, unresolved targets, and duplicate IDs are deterministic TL failures with remediation.
  • Staleness preserves history: changing a requirement marks downstream review-required; it never deletes evidence.
  • Repository text is untrusted data: hooks inject bounded, sanitized summaries; subprocess calls use argv arrays; no shell=True.
  • Policy can weaken only deliberately: enforcement-file changes surface as TL063 warnings; waivers are scoped, owned, and expiring.
  • CI and the Stop gate run the same engine as the CLI — there is no separate enforcement code path.

Documentation

Document Purpose
Concepts Three truths, the trace graph, stable IDs, staleness
Marker protocol Generated normative trace:v1 syntax and placement rules
Relationships Generated semantic/structural/observed edge semantics
Policy Profiles, lifecycles, waivers, and the TL-rule catalog
Hooks Event model, block-once semantics, injection safety
Evidence JUnit/Cobertura ingestion and proof levels L0–L3
Migration CodeOps scan/plan/apply workflow
Security Threat model and mitigations
Large repositories Incremental indexing, monorepo scopes, performance targets
Architecture decisions ADR-0001 through ADR-0008

Installing the agent skill

The canonical skill (canonical layout: SKILL.md + README.md + references/) lives in skills/traceability/ and is bundled with the installed package. Install it with trace install:

trace install --list                     # detect agents and install state
trace install --agent claude-code        # project scope (.claude/skills)
trace install --agent claude-code --global --yes   # ~/.claude/skills
trace install --yes                      # all detected agents, non-interactive

Hooks install for every agent: JSON-merged settings for claude-code (.claude/settings.json) and codex (.codex/hooks.json); file-based hook configs for pi (.pi/hooks.json + wrapper), omp (.omp/hook/hooks.yaml + extension gate), and opencode (opencode.json) — each with an activation note (e.g. pi install npm:@hsingjui/pi-hooks, /hooks-trust in omp). The engine contract is shared across harnesses; enforcement strength is harness-dependent (Claude Code and OMP gate Write/Edit/Bash and finalize on Stop; Codex gates Bash only; Pi/OpenCode/Hermes are best-effort or CI/manual — see the master spec §74). Where a harness cannot intercept, CI merge-grade verification and trace task finish remain authoritative. After upgrading the tool, refresh installed copies with tracelayer update (or trace install --update). The same skill is installable through the skills.sh ecosystem:

npx skills add carterlasalle/tracelayer --agent claude-code

For existing repositories, trace init copies the skill into .agents/skills/traceability/ and installs hooks for every detected agent (project scope — all files land in the repo; --no-skill opts out). The same folder is ready for skill registries (e.g. skills.sh, anthropics/skills) — it follows the standard layout and links references directly from SKILL.md. Use trace install for global (user-level) agent installs.

Web UI: trace graph (markers only)

trace web spawns a local web UI with a 3D force-directed graph of the trace graph — see what connects to what, and why, through the markers:

trace web            # http://127.0.0.1:8765/ (opens the browser)
trace web --port 9000 --no-open

Nodes are colored by type (requirement/decision/plan/work/implementation/ test/docs), edges are the declared marker relationships (satisfies, verifies, exercises, work, implements, ...) — never structural derivations. Click a node to inspect its upstream intent, downstream dependents, and verification status; filter with the search box. The server is stdlib-only and binds localhost by default.

MCP server (optional adapter)

trace mcp exposes the query surface and the verify gate as MCP tools over stdio, so any MCP-capable agent can connect directly. It is deterministic, local, and optional — the skill + CLI + hooks remain the canonical interface (the spec marks MCP as never required). trace init and trace install (project scope) register it automatically in .mcp.json (merged, other servers preserved; trace init --no-mcp opts out).

Connect Claude Code:

claude mcp add tracelayer -- uv run tracelayer mcp

Or add a project-level .mcp.json for any MCP client (written automatically by trace init / trace install):

{
  "mcpServers": {
    "tracelayer": { "command": "tracelayer", "args": ["mcp"] }
  }
}

Tools: status, search, context, why, impact, verify, index. index refreshes the graph from the repository (changed scope by default); the rest are read-only. Results are JSON text.

Contributing

TraceLayer uses protected, squash-only pull requests with required checks. Read CONTRIBUTING.md before making changes. Run uv run trace docs generate --check when editing protocol documentation and trace verify --changed before proposing a merge — this repository traces itself.

License

Apache License 2.0 — see LICENSE.

Metadata

Release files for tracelayer 0.2.40

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

Source distribution (sdist)

Source distribution for tracelayer 0.2.40
File Size Uploaded
tracelayer-0.2.40.tar.gz 633.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for tracelayer 0.2.40
File Interpreter ABI Platform
tracelayer-0.2.40-py3-none-any.whl Python 3 none any Details

Total release size: 1.2 MB

Release files / tracelayer-0.2.40.tar.gz

Download URL tracelayer-0.2.40.tar.gz
Size 633.2 kB
Tags Source
SHA-256 checksum
How to use checksums
e54931a60678f1eb430ddf1f3763d335433ecf1c97f8a0ebbc20dceeefe95892
BLAKE2b-256 checksum
How to use checksums
0916201c058cff72526d173b6e8ea9594cd3347a7e9dab81d48739a2b498659b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.

Transparency log

Release files / tracelayer-0.2.40-py3-none-any.whl

Download URL tracelayer-0.2.40-py3-none-any.whl
Size 569.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6217fc0d566e6d67d04d8a4faf2859a68942062a5c4c331ebae9f74530683d98
BLAKE2b-256 checksum
How to use checksums
f9015f9856b650a24ecb71246247807a3ad8edd494bebef575f43a21d860ca28
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.

Transparency log

Release history Release notifications | RSS feed

0.9.1

2 release files

0.9.0

2 release files

0.8.4

2 release files

0.8.3

2 release files

0.8.2

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.7

2 release files

0.7.6

2 release files

0.7.5

2 release files

0.7.4

2 release files

0.7.3

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

This release

0.2.40 This release

2 release files

0.2.39

2 release files

0.2.38

2 release files

0.2.37

2 release files

0.2.36

2 release files

0.2.35

2 release files

0.2.34

2 release files

0.2.33

2 release files

0.2.32

2 release files

0.2.31

2 release files

0.2.30

2 release files

0.2.29

2 release files

0.2.28

2 release files

0.2.27

2 release files

0.2.26

2 release files

0.2.25

2 release files

0.2.24

2 release files

0.2.23

2 release files

0.2.22

2 release files

0.2.21

2 release files

0.2.20

2 release files

0.2.19

2 release files

0.2.18

2 release files

0.2.17

2 release files

0.2.16

2 release files

0.2.15

2 release files

0.2.14

2 release files

0.2.13

2 release files

0.2.12

2 release files

0.2.11

2 release files

0.2.10

2 release files

0.2.9

2 release files

0.2.8

2 release files

0.2.7

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.16

2 release files

0.1.15

2 release files

0.1.14

2 release files

0.1.13

2 release files

0.1.12

2 release files

0.1.11

2 release files

0.1.10

2 release files

0.1.9

2 release files

0.1.8

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

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