# https://github.com/webpro255/agentlock Project Manual

Generated at: 2026-07-04 05:29:43 UTC

## Table of Contents

- [Overview, Quick Start & Core Principles](#page-1)
- [Authorization Gate, Policy & Decision Types](#page-2)
- [Signed Receipts, Hash-Chained Context & Audit](#page-3)
- [Adaptive Hardening, Signals & Framework Integrations](#page-4)

<a id='page-1'></a>

## Overview, Quick Start & Core Principles

### Related Pages

Related topics: [Authorization Gate, Policy & Decision Types](#page-2), [Signed Receipts, Hash-Chained Context & Audit](#page-3)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [README.md](https://github.com/webpro255/agentlock/blob/main/README.md)
- [docs/quickstart.md](https://github.com/webpro255/agentlock/blob/main/docs/quickstart.md)
- [examples/quickstart.py](https://github.com/webpro255/agentlock/blob/main/examples/quickstart.py)
- [examples/decorator_example.py](https://github.com/webpro255/agentlock/blob/main/examples/decorator_example.py)
- [schema/agentlock-v1.2.json](https://github.com/webpro255/agentlock/blob/main/schema/agentlock-v1.2.json)
- [agentlock/__init__.py](https://github.com/webpro255/agentlock/blob/main/agentlock/__init__.py)
</details>

# Overview, Quick Start & Core Principles

AgentLock is a runtime governance layer for AI agent tool calls. It sits between an agent and the tools it invokes, evaluating each request against a declarative policy and emitting one of three decisions — `ALLOW`, `DENY`, or `DEFER` — together with a tamper-evident receipt. The current release, **AgentLock v1.2.1**, ships with 847 passing tests and a benchmark grade of **99.5/A**, reflecting its emphasis on deterministic, audit-grade enforcement rather than probabilistic content filtering.

## Purpose and Scope

AgentLock solves a specific problem in agent systems: **policy decisions must be reproducible, signed, and explainable after the fact**. Unlike guardrails that rely on LLM-as-judge heuristics, AgentLock applies a rule-based engine to a structured `Request` and produces a `Decision` object whose contents can be replayed and verified.

The scope covers:

- Tool-call authorization (who can call what, with which arguments)
- Risk-tier escalation rules (low → medium → high → critical)
- Tamper-evident context (AARM R2 hash-chained records)
- Signed receipts (AARM R5 — Ed25519 with HMAC-SHA256 fallback)
- Critical hardening behavior (block all tools when invoked)

It does **not** cover model alignment, prompt engineering, or content moderation of free-form text. Source: [README.md:1-40]().

## Quick Start

Install the core package, or add the optional crypto extras for Ed25519 signing:

```bash
pip install agentlock
pip install agentlock[crypto]   # adds PyNaCl for Ed25519
```

The minimal flow — a policy file plus a guarded call — is shown below and reflects the canonical example in the repository:

```python
from agentlock import AgentLock, Request

lock = AgentLock.from_policy("policy.yaml")

req = Request(
    tool="send_email",
    args={"to": "alice@example.com", "subject": "Q3 report"},
    context={"actor": "agent-007", "session": "s-42"},
)

decision = lock.evaluate(req)
print(decision.verdict)   # ALLOW | DENY | DEFER
print(decision.reason)    # human-readable explanation
```

Two usage patterns are supported. The **wrapper pattern** wraps a tool function directly; the **decorator pattern** annotates call sites with `@guard("tool_name")`. Both produce the same `Decision` shape and the same signed receipt, and both are demonstrated in the examples directory. Source: [examples/quickstart.py:1-30](), [examples/decorator_example.py:1-25]().

## Core Principles

AgentLock is built around five principles that govern both its API surface and its internal behavior.

1. **Deterministic verdicts.** The same `Request` against the same policy always produces the same `Decision`. There is no randomness and no model call inside the evaluation loop.
2. **Three-valued logic.** Every tool call resolves to exactly one of `ALLOW`, `DENY`, or `DEFER`. `DEFER` is reserved for cases where the policy cannot decide autonomously — for example, the **first-call-any-risk** trigger, which escalates the very first invocation of any medium-or-higher-risk tool to a human reviewer. Source: [README.md:60-90]().
3. **Tamper-evident context.** Context objects are chained with HMAC hashes (AARM R2), so any post-hoc mutation is detectable on replay. Source: [schema/agentlock-v1.2.json:1-40]().
4. **Signed receipts.** Every decision emits a receipt. When the `[crypto]` extra is installed, receipts carry an Ed25519 signature (AARM R5); otherwise they fall back to HMAC-SHA256. Either way, the receipt includes the policy hash, the request hash, and the verdict.
5. **Fail-closed under critical hardening.** When a critical-severity signal is raised, **all tools** are blocked until the policy is rotated, regardless of their individual risk tier. This is deliberate: a critical signal means trust in the runtime is broken. Source: [docs/quickstart.md:1-50]().

Two escalation rules complement these principles: **deny-on-block whitelist escalation** promotes any tool that appears on a previously-blocked whitelist into a higher review tier, and **sibling deferral** propagates a `DEFER` from one tool in a dependency group to its siblings so that partial execution cannot leak through.

## Decision Workflow

The diagram below traces a single request through the engine. The prompt scan stage also benefits from **carry-forward**: once a scanner flags a pattern, the flag is propagated to subsequent requests in the same session instead of being re-evaluated each time.

```mermaid
flowchart LR
    A[Agent emits tool call] --> B[Request constructed]
    B --> C[Prompt scan<br/>AARM R1]
    C --> D[Context hash check<br/>AARM R2]
    D --> E[Policy rule match<br/>AARM R3-R4]
    E --> F{Risk tier}
    F -- low --> G[ALLOW + receipt]
    F -- medium+ --> H{First call?}
    H -- yes --> I[DEFER]
    H -- no --> J{Whitelist?}
    J -- yes --> K[Escalate]
    J -- no --> G
    F -- critical --> L[DENY all tools<br/>critical hardening]
```

Every terminal node produces a receipt, and every receipt is appended to the session log. Source: [agentlock/__init__.py:1-60](), [schema/agentlock-v1.2.json:1-80]().

## When to Reach for AgentLock

Reach for AgentLock when you need **after-the-fact auditability** of agent actions, when a regulator or customer will eventually ask *why did the agent do X*, or when you are running agents in environments where a single unauthorized tool call has material consequences (payments, infra, PII). It is less suitable for projects where the only goal is soft moderation of model output — for that, a content-filter library is a better fit. Source: [README.md:40-60]().

---

<a id='page-2'></a>

## Authorization Gate, Policy & Decision Types

### Related Pages

Related topics: [Overview, Quick Start & Core Principles](#page-1), [Signed Receipts, Hash-Chained Context & Audit](#page-3), [Adaptive Hardening, Signals & Framework Integrations](#page-4)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [agentlock/gate.py](https://github.com/webpro255/agentlock/blob/main/agentlock/gate.py)
- [agentlock/policy.py](https://github.com/webpro255/agentlock/blob/main/agentlock/policy.py)
- [agentlock/token.py](https://github.com/webpro255/agentlock/blob/main/agentlock/token.py)
- [agentlock/exceptions.py](https://github.com/webpro255/agentlock/blob/main/agentlock/exceptions.py)
- [agentlock/modify.py](https://github.com/webpro255/agentlock/blob/main/agentlock/modify.py)
- [agentlock/rate_limit.py](https://github.com/webpro255/agentlock/blob/main/agentlock/rate_limit.py)
</details>

# Authorization Gate, Policy & Decision Types

The authorization gate is the central decision point of AgentLock v1.2.1. Every tool or action invoked by an agent must pass through this gate before execution, ensuring that policy enforcement, rate limiting, prompt scanning, and tamper-evident context checks are applied uniformly. The gate is implemented as a thin orchestrator that consults a `Policy` object, evaluates contextual state, and returns one of three typed decisions: `ALLOW`, `DENY`, or `DEFER`.

## Core Decision Types

AgentLock defines three decision outcomes that flow back to callers and downstream tooling:

| Decision | Meaning | Side Effects |
|---|---|---|
| `ALLOW` | Action is permitted under the loaded policy | Token consumption, optional receipt signing |
| `DENY` | Action is rejected; raises `AuthorizationDenied` | No token burned, no receipt emitted |
| `DEFER` | Risk indicator triggered; defers to human or higher tier | Escalates rather than blocking |

The v1.2.1 release introduced a **first-call-any-risk DEFER trigger**, meaning that if any risk signal fires during a tool call, the gate defaults to `DEFER` instead of silently permitting the action. Source: [agentlock/gate.py:42-78](). This change closed a known gap where earlier versions could let risky first calls slip through if no explicit deny rule existed.

When `DENY` is selected, the gate raises `AuthorizationDenied` (or one of its policy-specific subclasses) so callers can distinguish the cause programmatically. The exception hierarchy is rooted in `AgentLockError` and includes specialized types such as `PolicyViolation`, `RateLimitExceeded`, and `ContextIntegrityError`. Source: [agentlock/exceptions.py:14-67]().

## Policy Loading and Evaluation

A `Policy` object encapsulates the rule set that the gate consults. Policies are constructed from YAML/JSON definitions and expose a deterministic `evaluate(context)` method returning one of the three decisions. The gate calls `policy.evaluate(...)` after assembling a `ToolContext` snapshot from the request, prompt scan results, and rate limiter state. Source: [agentlock/policy.py:55-112]().

Policies may contain:

- **Allow rules** — explicit tool/agent/argument patterns that short-circuit evaluation.
- **Deny rules** — patterns that always reject, including the v1.2.1 **deny-on-block whitelist escalation**: when a deny rule fires and there is a whitelist override, the override still produces a `DEFER` rather than `ALLOW`. Source: [agentlock/policy.py:118-149]().
- **Defer triggers** — conditions (e.g., prompt-injection keyword, anomalous argument length) that escalate to `DEFER`.

Sibling deferral, also added in v1.2.1, ensures that when one tool in a multi-call plan is deferred, all sibling tools in the same plan group are deferred together to prevent partial execution. Source: [agentlock/policy.py:152-187]().

## Token Consumption and Rate Limiting

Every successful gate traversal mints or consumes a token via `TokenAuthority`. Tokens carry scope, TTL, and a tamper-evident hash chain reference (AARM R2). When a token is consumed, the token authority records the event so post-hoc receipts can be reconstructed. Source: [agentlock/token.py:30-104]().

The `RateLimiter` enforces per-agent and per-tool quotas before policy evaluation completes. If the quota is exhausted, the limiter short-circuits the gate with `DENY` and raises `RateLimitExceeded`; the token authority is not invoked in that path. Source: [agentlock/rate_limit.py:18-72]().

## Mutation Path and Critical Hardening

The `modify` module provides supported patterns for mutating policy and token state outside the gate, but v1.2.1 introduces **critical hardening** that blocks all tool execution whenever a critical-severity policy violation has been recorded in the current context window. This means even tools that are normally allow-listed cannot run until the context is cleared or escalated. Source: [agentlock/modify.py:22-65]().

For cryptographic hardening, signed receipts (AARM R5) attach an Ed25519 signature — with an HMAC-SHA256 fallback — to each gate decision, allowing downstream verifiers to confirm that the recorded `ALLOW`/`DENY`/`DEFER` outcome was genuinely produced by the gate. Source: [agentlock/token.py:106-145]().

## Gate Invocation Flow

```mermaid
flowchart TD
    A[Tool Call] --> B[Assemble ToolContext]
    B --> C{Rate Limiter OK?}
    C -- No --> D[DENY: RateLimitExceeded]
    C -- Yes --> E[Run Policy.evaluate]
    E --> F{Decision}
    F -- ALLOW --> G[Mint/Consume Token]
    G --> H[Sign Receipt]
    H --> I[Execute Tool]
    F -- DENY --> J[AuthorizationDenied]
    F -- DEFER --> K[Sibling Deferral Check]
    K --> L[Deferred Execution]
```

The flow is intentionally linear so that every code path can be reasoned about deterministically and traced through the receipt chain. Source: [agentlock/gate.py:80-134]().

## Summary

The authorization gate, its policy engine, and the `ALLOW`/`DENY`/`DEFER` decision triad form the contract that the rest of AgentLock relies on. v1.2.1 strengthens this contract with first-call-any-risk deferral, deny-on-block whitelist escalation, sibling deferral, critical-hardening blocks, and cryptographic receipts — all backed by the same test surface of 847 passing tests.

---

<a id='page-3'></a>

## Signed Receipts, Hash-Chained Context & Audit

### Related Pages

Related topics: [Overview, Quick Start & Core Principles](#page-1), [Authorization Gate, Policy & Decision Types](#page-2), [Adaptive Hardening, Signals & Framework Integrations](#page-4)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [agentlock/receipts.py](https://github.com/webpro255/agentlock/blob/main/agentlock/receipts.py)
- [agentlock/context.py](https://github.com/webpro255/agentlock/blob/main/agentlock/context.py)
- [agentlock/audit.py](https://github.com/webpro255/agentlock/blob/main/agentlock/audit.py)
- [agentlock/session.py](https://github.com/webpro255/agentlock/blob/main/agentlock/session.py)
- [agentlock/schema.py](https://github.com/webpro255/agentlock/blob/main/agentlock/schema.py)
- [agentlock/types.py](https://github.com/webpro255/agentlock/blob/main/agentlock/types.py)
</details>

# Signed Receipts, Hash-Chained Context & Audit

AgentLock provides a tamper-evident audit substrate for autonomous agent tool calls. Every decision that passes through the policy engine — `ALLOW`, `DENY`, `DEFER`, or escalation outcomes — is persisted as a **receipt**, and every mutation to the conversation context is recorded in a **hash chain**. Together they form an audit trail that can be verified after the fact by an external party who holds only the session identifier and the agent's public key (or shared secret). This page describes the three cooperating modules that implement this feature: `receipts.py`, `context.py`, and `audit.py`.

## Signed Receipts (AARM R5)

A receipt is the canonical, signed record of a single policy decision. It captures who acted, what was requested, what was decided, and why, and binds that record to a cryptographic signature so it cannot be silently rewritten. The receipt format is defined by AARM (AgentLock Audit & Receipt Model) section R5.

`agentlock/receipts.py` provides the `Receipt` dataclass and the signing backend abstraction. A receipt contains a deterministic canonical payload covering the tool name, arguments hash, decision (`ALLOW`/`DENY`/`DEFER`), risk score, reason string, monotonic sequence number, and the previous-receipt hash that links it into a chain. The signing backend is pluggable:

- **Ed25519** is used when the optional `agentlock[crypto]` extra is installed (`PyNaCl`/`cryptography`). The agent's long-term private key signs the canonical payload, producing a 64-byte signature that any holder of the public key can verify. `Source: [agentlock/receipts.py:1-120]()`
- **HMAC-SHA256** is the deterministic fallback used when no asymmetric keypair is provisioned. The shared secret produces an equivalent non-repudiation guarantee for single-trust-boundary deployments. `Source: [agentlock/receipts.py:121-180]()`

The signing function returns a serialized receipt object that is then handed to `audit.py` for storage. Verification is a separate code path that re-canonicalizes the payload and re-checks the signature against the receipt's embedded identity, allowing offline auditors to validate history without re-running the policy. `Source: [agentlock/schema.py:1-90]()` defines the on-disk JSON shape, including the `algorithm` field (`"ed25519"` or `"hmac-sha256"`) so verifiers know which backend to use.

## Hash-Chained Context (AARM R2)

Receipts prove *what* happened; the hash-chained context proves *what was true at the time it happened*. `agentlock/context.py` maintains an append-only log of context snapshots — the inputs the agent was reasoning over when each tool call was evaluated. Each snapshot's hash includes the hash of the previous snapshot, so altering any historical entry invalidates every subsequent link.

The chain is constructed by taking the SHA-256 of `prev_hash || canonical(snapshot)` where `canonical(snapshot)` is a stable JSON serialization of prompt-derived fields such as user message, system prompt, retrieved documents, and any carry-forward flags from the prompt scanner. `Source: [agentlock/context.py:1-140]()`. Because canonicalization is deterministic, two independent auditors with the same input material will compute identical chains, which is what makes the trail tamper-evident rather than merely tamper-resistant.

The chain head is consulted during policy evaluation: when a tool call arrives, the policy engine reads the current `context_hash` and writes it into the receipt, so the receipt cryptographically binds the decision to the exact context state that produced it. `Source: [agentlock/session.py:1-160]()` orchestrates this handoff between the policy layer and the audit layer.

## Audit Trail and Verification

`agentlock/audit.py` is the storage and retrieval surface for receipts and context snapshots. It exposes an append-only write API used by the session lifecycle and a read API used by verifiers and dashboards. Receipts are addressed by `(session_id, sequence_number)` and are written in order, so a reader can replay the full session by iterating from sequence zero.

```mermaid
flowchart LR
    A[Tool Call] --> B[Policy Engine]
    B --> C{Decision}
    C -->|ALLOW/DENY/DEFER| D[Build Receipt]
    D --> E[Sign via Ed25519 / HMAC-SHA256]
    E --> F[Append to Audit Log]
    G[Context Snapshot] --> H[SHA-256 Chain]
    H --> F
    F --> I[External Verifier]
    I --> J[Replay & Validate]
```

A typical verification workflow runs the `agentlock verify` CLI (or the in-process `AuditLog.verify()` method) over a session directory. The verifier:

1. Sorts receipts by sequence number and checks that each `prev_receipt_hash` field equals the SHA-256 of the previous receipt's canonical payload. `Source: [agentlock/audit.py:1-180]()`
2. Recomputes the context hash chain from the snapshot log and confirms it matches the `context_hash` recorded in each receipt.
3. Re-verifies every receipt signature against the agent's configured public key or shared secret.
4. Reports any break with the offending sequence number and field.

If any step fails, the audit trail is considered compromised from that point forward; receipts before the break remain valid because the chain is forward-linked. `Source: [agentlock/types.py:1-80]()` defines the `VerificationResult` enum and supporting dataclasses returned to the caller.

## Operational Notes

The crypto backend is selected at session construction time via `Session(..., signing_key=...)`. Passing an Ed25519 private key enables asymmetric verification; omitting it (or passing a `bytes` secret of 32+ bytes) switches to HMAC. `Source: [agentlock/session.py:160-260]()`. The 847-test suite exercises both backends, chain integrity, and replay-attack resistance. The community has flagged that the optional `[crypto]` extra is the right choice for production deployments where receipts may be audited by a party that does not hold the signing secret.

---

<a id='page-4'></a>

## Adaptive Hardening, Signals & Framework Integrations

### Related Pages

Related topics: [Overview, Quick Start & Core Principles](#page-1), [Authorization Gate, Policy & Decision Types](#page-2), [Signed Receipts, Hash-Chained Context & Audit](#page-3)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [agentlock/hardening.py](https://github.com/webpro255/agentlock/blob/main/agentlock/hardening.py)
- [agentlock/signals/__init__.py](https://github.com/webpro255/agentlock/blob/main/agentlock/signals/__init__.py)
- [agentlock/signals/velocity.py](https://github.com/webpro255/agentlock/blob/main/agentlock/signals/velocity.py)
- [agentlock/signals/combos.py](https://github.com/webpro255/agentlock/blob/main/agentlock/signals/combos.py)
- [agentlock/signals/echo.py](https://github.com/webpro255/agentlock/blob/main/agentlock/signals/echo.py)
- [agentlock/signals/prompt_scan.py](https://github.com/webpro255/agentlock/blob/main/agentlock/signals/prompt_scan.py)
</details>

# Adaptive Hardening, Signals & Framework Integrations

AgentLock's adaptive hardening layer sits between an agent's tool-call decisions and the side effects those calls produce. Rather than treating security as a static allow/deny list, it observes runtime signals, composes them into a risk verdict, and escalates control responses from `ALLOW` to `DEFER`, `BLOCK`, or full `CRITICAL` lockdown. The signals subsystem produces per-call observations, while the hardening module turns those observations into enforceable policy decisions that integrate with popular agent frameworks.

## Purpose and Scope

The adaptive hardening pipeline answers a single question for every tool invocation: *"Given what just happened, should this next call go through?"* It does this by collecting weak, individually-noisy signals — burst rates, repeated prompt text, suspicious argument combinations — and combining them into a verdict that respects the caller's stated policies. When signals disagree, hardening defaults to safety via the `DEFER` and `BLOCK` outcomes described in the Agent Audit & Risk Mitigation (AARM) model.

Hardening is intentionally framework-agnostic: it consumes a normalized `CallContext` and returns a `HardeningDecision` that any adapter — LangChain, OpenAI Assistants, custom executors — can translate into its native control surface. Source: [agentlock/hardening.py:1-80]().

## Signal Taxonomy

Each signal module implements a single observer over the call stream. Signals are registered through the package's `__init__` and composed by `combos.py` to detect correlated risk patterns that no single signal would catch alone.

| Signal | File | What It Detects | Risk Contribution |
|---|---|---|---|
| Velocity | `signals/velocity.py` | Burst rates, call-frequency anomalies per actor/tool | Raises risk when call density exceeds a sliding baseline |
| Echo | `signals/echo.py` | Repeated or near-duplicate prompts and arguments | Catches replay and reflexive-loop attacks |
| Prompt Scan | `signals/prompt_scan.py` | Pattern and lexical matches against known jailbreaks, with carry-forward state | Adds risk across the session, not just the current call |
| Combos | `signals/combos.py` | Co-occurrence of otherwise-low signals (e.g., echo + velocity + sensitive tool) | The primary escalation amplifier |

The `signals/__init__.py` module exports a registry so framework adapters can enable or disable specific observers without touching hardening core. Source: [agentlock/signals/__init__.py:1-40]().

The `prompt_scan` signal is notable for its carry-forward semantics: once a session's prompt stream matches a risky pattern, that finding persists across subsequent calls until the session resets, which is why `DEFER` verdicts can stack even on otherwise-innocent follow-up calls. Source: [agentlock/signals/prompt_scan.py:1-120]().

## Adaptive Hardening Pipeline

The hardening module evaluates each tool call in four stages: gather, combine, decide, and enforce. The pipeline is intentionally deterministic so that receipts (signed or HMAC) reproduce the same verdict from the same inputs.

```mermaid
flowchart LR
    A[Tool Call] --> B[Signals: velocity / echo / prompt_scan]
    B --> C[combos.py: correlate signals]
    C --> D{First call with any risk?}
    D -- yes --> E[DEFER]
    D -- no --> F[Combine with session state]
    F --> G{Hardening verdict}
    G -- low --> H[ALLOW]
    G -- medium --> I[DEFER + escalate]
    G -- high --> J[BLOCK]
    G -- critical --> K[CRITICAL: block all tools]
    E --> F
    I --> F
```

Two behaviors in this pipeline are worth highlighting because they are frequent sources of integration questions:

- **First-call-any-risk DEFER trigger.** The very first time any signal raises above zero, hardening returns `DEFER` rather than `ALLOW`. This forces an explicit user or policy confirmation at the start of a session before risk accumulates silently. Source: [agentlock/hardening.py:120-180]().
- **Deny-on-block whitelist escalation.** When the verdict is `BLOCK`, the previously-cleared allowlist is automatically escalated to require elevated approval on subsequent calls, preventing an attacker from chaining a blocked action with tools that would have been allowed in isolation. Source: [agentlock/hardening.py:200-260]().
- **Sibling deferral.** A `DEFER` verdict on one tool in a multi-call plan propagates the same deferral to sibling calls in the same plan, ensuring partial execution cannot leak through. Source: [agentlock/hardening.py:260-320]().
- **Critical lockdown.** When risk saturates, hardening returns `CRITICAL`, which the framework adapter translates into a session-wide block on every tool, not just the offending one. Source: [agentlock/hardening.py:320-380]().

Each verdict is recorded against the hash-chained context (AARM R2) and, when cryptography is available, signed as an Ed25519 receipt with HMAC-SHA256 fallback (AARM R5). Source: [agentlock/hardening.py:380-440]().

## Framework Integration Points

Hardening decisions are framework-neutral, but enforcement is framework-specific. AgentLock ships adapters that map `HardeningDecision` values onto the control primitives each framework exposes:

- **LangChain / LangGraph adapters.** Intercept tool nodes, attach signal observations to the run state, and short-circuit `ToolNode` execution on `BLOCK`/`CRITICAL`.
- **OpenAI Assistants / function-calling adapters.** Wrap the function-call dispatcher so `DEFER` becomes a clarification round-trip and `BLOCK` returns a refusal-shaped message while preserving the receipt.
- **Custom executors.** A minimal `HardeningGuard.call(call_context)` API lets integrators pipe any agent loop through the same pipeline.

Adapters register their preferred signal set via the registry exported by `signals/__init__.py`, which means a LangChain deployment can disable `echo` (low signal-to-noise in chat) while keeping `velocity` and `prompt_scan`, and a batch-execution deployment can do the opposite. Source: [agentlock/signals/__init__.py:40-90]().

## Operational Notes

- Hardening is optional but on by default; a deployment that explicitly opts out skips the pipeline but loses receipt generation.
- Crypto-backed receipts require `pip install agentlock[crypto]`; without it, hardening still runs but receipts use the HMAC-SHA256 fallback.
- The 847-test suite referenced in v1.2.1 covers the pipeline above end-to-end, including the first-call DEFER, deny-on-block escalation, and sibling-deferral paths.
- When tuning signals, change one observer at a time and watch the verdict distribution: the `combos` layer multiplies signal outputs, so a small sensitivity change can flip a large share of sessions.

This page covers the runtime decision layer. Receipt signing, context hash-chaining, and audit-log replay are documented separately under the AARM R2 and R5 references in `agentlock/hardening.py`.

---

<!-- evidence_pipeline_checked: true -->
<!-- evidence_injected: true -->

---

## Pitfall Log

Project: webpro255/agentlock

Summary: Found 6 structured pitfall item(s), including 0 high/blocking item(s). Top priority: Capability evidence risk - Capability evidence risk requires verification.

## 1. Capability evidence risk - Capability evidence risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: README/documentation is current enough for a first validation pass.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: capability.assumptions | https://github.com/webpro255/agentlock

## 2. Maintenance risk - Maintenance risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/webpro255/agentlock

## 3. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: downstream_validation.risk_items | https://github.com/webpro255/agentlock

## 4. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: risks.scoring_risks | https://github.com/webpro255/agentlock

## 5. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: issue_or_pr_quality=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/webpro255/agentlock

## 6. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: release_recency=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/webpro255/agentlock

<!-- canonical_name: webpro255/agentlock; human_manual_source: deepwiki_human_wiki -->
