> ## Documentation Index
> Fetch the complete documentation index at: https://aspex.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# How Aspex reasons

> Every conclusion is a deterministic function of local data. This page names the model and the code paths, so you can reproduce any finding.

Nothing in Aspex is a black box. Two builds over the same state are byte-identical, and every conclusion says which of three kinds it is.

## The three kinds of statement

|                       | Comes from                                           | Example                                           |
| --------------------- | ---------------------------------------------------- | ------------------------------------------------- |
| **Capability**        | A tool in a live tool list, or a line in your config | `filesystem` can read files under `/Users/steven` |
| **Attack path**       | A composition of two capabilities                    | file read reaching `~/.ssh` + open egress = AP001 |
| **Observed behavior** | Your clients' own logs                               | `read_file` was called at 14:02 in session `a3f2` |

A path never claims it was walked. An observation never claims intent. Keeping these apart is the whole design. [Capabilities & attack paths →](/concepts/capabilities-and-attack-paths) · [Observed vs inferred →](/concepts/observed-vs-inferred)

## The environment

An **Environment** (`internal/agentenv`) is the normalized state of one machine's agent setup: agents (clients), MCP servers with their tools, lifecycle hooks, skills, instruction files, and what follows from them: fingerprints, derived resources, destinations, attack paths and the blast radius.

```
discover ─► inspect ─► attackpath (capabilities + evidence + compositions)
                             │
   hooks, skills, instructions ─► agentenv (one deterministic Environment)
                                        │
        lock · verify · diff · explain · tighten · bom · mcp · explore · history · watch
                                        │
                     trace (logs) ─► killchain · provenance ─► explore
```

Everything downstream of `agentenv` consumes the same model, so a capability reads the same in a lockfile, a PR comment, an explain answer and the MCP tool.

## The trust boundary

The boundary Aspex reasons about is **the agent's context**. Anything that enters it (a prompt, a pasted document, a fetched page, an issue body, a tool result) can carry an instruction; anything the agent can do, an instruction can ask for. This is why the first hop of every attack path is "instruction from a prompt, document, or tool result", and why ingress capabilities matter: they widen who can write into the context.

## Persistence

An agent's own configuration, hooks, skills, instruction files and memory are what future sessions trust, so writes to them are first-class. A writable root is resolved to the **agent-state files** it reaches (`~/.claude.json`, `.mcp.json`, `~/.claude/settings.json` hooks, `CLAUDE.md`, `.cursorrules`, memory, shell startup files) and whether writing them executes code at the next session start. AP003 covers ingress plus such a write; MCP200 flags the writable half alone; `aspex scan hooks` judges the commands hooks run; `lock` / `verify` detect any change.

## Change

`agentenv.Compare(before, after)` classifies each change as **informational**, **security-relevant** or **suspicious**, based on content (the injection patterns from `rules.ClassifyText`) and on capability deltas, and reports attack paths added or removed and blast radius before and after. A tool-description change is security-significant even when the executable did not change; that is the rug-pull case. [Change detection →](/tools/change-detection)

## Reproducing a finding

* **Static:** `aspex scan --no-exec --json` on the same configs yields the same `attackPaths` and `blastRadius`; `aspex lock --no-exec --stdout` yields the same lockfile.
* **Live:** tool lists come from the servers; `aspex lock` captures them so a later `verify` shows exactly which description or schema changed.
* **Scenarios:** `testdata/corpus/scenarios/*.yaml` state truth and expectation for whole environments; `aspex scan corpus test` runs them. Adding a scenario is how to report a disagreement with Aspex's reasoning. [Corpus →](/reference/corpus)
