Skip to content
Back to skills

2701 3 Audit Log 68374b0d

ASecurity

**The `GraphExecutor`'s "killer feature" is the structured history log it generates. This is not just a `print` statement; it's a forensic trail.** For complex agent workflows, you need detailed provenance. **Lár delivers:** 1. **Immutability**: Every step is a discrete event. 2. **Causality**: We log the *exact state change* (`state_diff`) that caused the new reality. 3. **Reproducibility**: Replaying these events with the same seed guarantees the same outcome.

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
developmentpythonnodeapi

Works with

  • api

Security analysis

A100/100

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 2701-3-audit-log_68374b0d --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 2701 3 Audit Log 68374b0d?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 2701 3 Audit Log 68374b0d
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-2701-3-audit-log-68374b0d/badge)](https://www.skillsdirectory.com/skills/tools-only-2701-3-audit-log-68374b0d)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md


# The Event-Sourced Audit Log

**The `GraphExecutor`'s "killer feature" is the structured history log it generates. This is not just a `print` statement; it's a forensic trail.**

For complex agent workflows, you need detailed provenance.

**Lár delivers:**
1.  **Immutability**: Every step is a discrete event.
2.  **Causality**: We log the *exact state change* (`state_diff`) that caused the new reality.
3.  **Reproducibility**: Replaying these events with the same seed guarantees the same outcome.

## The "Event Sourcing" Model

To be infinitely scalable, `lar` (as of v2.0) does not log the entire state at every step. That is slow and expensive.

Instead, it logs **"events" (state diffs)**.

The `GraphExecutor` `yields` a `step_log` object for each step. This log is a small, efficient JSON object:
```json
{
  "step": 0,
  "node": "LLMNode",
  "outcome": "success",
  
  "state_before": {
    "task": "What is the capital of France?"
  },
  
  "state_diff": {
    "added": {
      "plan": "TEXT"
    },
    "removed": {},
    "modified": {}
  },

  "run_metadata": {
    "prompt_tokens": 42,
    "output_tokens": 1,
    "total_tokens": 43
  }
}
```

**What This Log Tells You**

- `step` **&** `node`: Where you are in the graph.

- `outcome`: What happened ("success" or "error").

- `state_before`: A "snapshot" of the agent's entire memory before this node ran.

- `state_diff`: The "**killer feature.**" This is the exact change the node made to the state. You can see it `added` the `"plan": "TEXT" key`.

- `run_metadata`: The **cost audit**. You can see this single `LLMNode` step cost 43 tokens.

When your agent fails, the "glass box" gives you a perfect record:
```json
{
  "step": 3,
  "node": "LLMNode",
  "outcome": "error",
  "error": "429 LLMNode failed after 3 retries.",
  "state_before": { ... },
  "state_diff": { ... },
  "run_metadata": {}
}
```

This is the `lar` difference. You don't have to guess why it failed. Your log tells you the exact node, the exact error, and the exact state it failed with.

---

## New in v1.3.0: Modular Observability

**Lár now separates logging and tracking into dedicated, injectable components:**

### AuditLogger

Manages the audit trail with GxP-compliant JSON persistence.

**Default usage:**
```python
executor = GraphExecutor(log_dir="my_logs")
# AuditLogger created automatically
history = executor.logger.get_history()
```

**Advanced (custom injection):**
```python
from lar import AuditLogger

custom_logger = AuditLogger(log_dir="compliance_logs")
executor = GraphExecutor(logger=custom_logger)

# Direct access to audit history
for step in custom_logger.get_history():
    print(f"Step {step['step']}: {step['node']} - {step['outcome']}")
```

### TokenTracker

Aggregates token usage across models and workflows.

**Default usage:**
```python
executor = GraphExecutor()
summary = executor.tracker.get_summary()
print(f"Total tokens: {summary['total_tokens']}")
print(f"By model: {summary['tokens_by_model']}")
```

**Advanced (shared tracker for cost aggregation):**
```python
from lar import TokenTracker

# Share one tracker across multiple executors
shared_tracker = TokenTracker()

executor1 = GraphExecutor(log_dir="workflow1", tracker=shared_tracker)
executor2 = GraphExecutor(log_dir="workflow2", tracker=shared_tracker)

# Run both workflows
executor1.run(agent1, state1)
executor2.run(agent2, state2)

# Get aggregated cost
total = shared_tracker.get_summary()
print(f"Total cost across both workflows: {total['total_tokens']} tokens")
```

**See full example:** `examples/patterns/16_custom_logger_tracker.py`

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.