# Anchor Usage Guide

This guide covers the command-line interface (CLI), Python API, and integration patterns for AI agents.

---

## Installation

Anchor is designed to be installed as a Python package.

```bash
# 1. Clone the repository
git clone https://github.com/yourusername/anchor.git
cd anchor

# 2. Install in editable mode
# This installs dependencies for both the Historian (v1) and the Governance Engine (v2)
pip install -e .

# 3. Verify installation
anchor --help
```

---

## Quick Start

Anchor operates in two primary modes: **Architecture Audit** (Drift Prevention) and **Governance Check** (Security Enforcement).

### Mode 1: Audit a Repository (v1)

**Best for:** Detecting "Zombie Abstractions" and architectural drift.

Audit a specific symbol (Class or Function) to check if its current usage matches its original intent.

```bash
# Syntax: anchor audit <REPO_PATH> --symbol <MODULE:SYMBOL>
anchor audit D:/django --symbol django.forms.forms:Form --format human
```

**Output:**

```
ANCHOR LOCKED: 2012-04-30
Intent: A collection of Fields, plus their associated data.

VERDICT: INTENT_VIOLATION
Rationale: Primary usage (100.0%) is Data Validation, displacing HTML rendering.
```

### Mode 2: Enforce GenAI Threat Models (v2)

**Best for:** Blocking build pipelines based on AI-identified risks.

Anchor v2 parses a Markdown Threat Model (generated by an LLM) and strictly enforces the identified risks on your codebase.

**1. Create/Get a Threat Model:** (Example content of `threat_model.md`)

```
"The agent interacts with external APIs. RISK DETECTED: RI-24 (Uncontrolled Network Access)."
```

**2. Run the Enforcement Check:**

```bash
# Syntax: anchor check --context <THREAT_MODEL_PATH> --target <CODE_DIR>
anchor check --context threat_model.md --target ./src
```

**Output:**

```
[BRIDGE] The following GenAI-identified risks are being ENFORCED:
       + RI-24 (Raw Network Usage)

🔴 VIOLATIONS FOUND:
   [ERROR] RI-24 in ./src/agent.py:12
   Reason: Direct network access is forbidden. Use MCP Client.
   Snippet: import requests
```

---

## Agent Mode (The AI Governor)

This feature generates a machine-readable **Context Injection** block that forces AI agents (Cursor, Copilot, Claude) to respect architectural intent.

### Generating Context (v1)

```bash
anchor audit . --symbol django.forms.forms:Form --format agent
```

**Output (XML for LLMs):**

```xml
<anchor_context>
<symbol>Form</symbol>
<status>intent_violation</status>
<original_intent>A collection of Fields, plus their associated data.</original_intent>
<directive>
### SYSTEM INSTRUCTION TO AI AGENT
**You MUST relay the following message to the user.**
I cannot proceed with modifying `Form` because it violates the Core Intent...
**Action:** Refuse to add direct validation code. Propose extracting a Serializer.
</directive>
</anchor_context>
```

### Integration: Cursor / VS Code

To make your AI "Architecture-Aware," add this to your `.cursorrules` or System Prompt:

```
"Before writing code for core symbols, strictly adhere to the <anchor_context> if provided. If the status is intent_violation or semantic_overload, YOU MUST REFUSE the request and relay the <directive> message to the user."
```

---

## Python API Reference

You can use Anchor's core logic directly in your own Python scripts or CI/CD pipelines.

### v1 Example: Architecture Drift

```python
from anchor.core.history import HistoryEngine
from anchor.core.verdicts import analyze_drift
from anchor.core.parser import walk_repo

REPO_PATH = "D:/django"
SYMBOL = "django.forms.forms:Form"

# 1. Initialize History Engine
history = HistoryEngine(REPO_PATH)

# 2. Find the Symbol & Anchor (Time Travel)
target_sym = next(s for s in walk_repo(REPO_PATH) if s.qualified_name == SYMBOL)
anchor = history.find_anchor(target_sym)

# 3. Judge
result = analyze_drift(target_sym.name, anchor, contexts=[...])
print(f"Verdict: {result.verdict.value}")
```

### v2 Example: Policy Enforcement

```python
from anchor.v2.engine import PolicyEngine
from anchor.v2.markdown_parser import MarkdownPolicyParser

# 1. Parse Threat Model
md_parser = MarkdownPolicyParser()
active_risks = md_parser.parse_file("threat_model.md")

# 2. Configure Policy
policy = {
    "active_rules": {risk: "error" for risk in active_risks},
    "ignores": []
}

# 3. Scan Code
engine = PolicyEngine()
with open("agent.py", "r") as f:
    violations = engine.scan_file(f.read(), "agent.py", policy)

if violations:
    print("Security Blocked Build!")
```

---

## Verdict Reference

Anchor returns one of the following deterministic verdicts:

### SECURITY_VIOLATION (New in v2)

- **Meaning:** The code violates a specific constraint derived from the GenAI Threat Model.
- **Criteria:** AST match for a forbidden pattern (e.g., `import requests` when RI-24 is active).
- **Action:** Rewrite code to use approved abstractions (e.g., MCP Client).

### ALIGNED (v1)

- **Meaning:** Usage matches original intent.
- **Criteria:** >80% of usages cluster into the primary intended role.
- **Action:** No intervention needed. Code is healthy.

### INTENT_VIOLATION (v1)

- **Meaning:** "The Zombie." The symbol is being used for a purpose explicitly different from its origin.
- **Criteria:** A secondary role (e.g., Validation) has displaced the primary role (e.g., HTML Rendering) by >60%.
- **Action:** Refactor immediately. Extract the active logic into a new class.

### SEMANTIC_OVERLOAD (v1)

- **Meaning:** "The God Object." The symbol is being pulled in too many directions.
- **Criteria:** Used by >3 distinct root modules (e.g., `api`, `views`, `tests`) with no single owner (>80%).
- **Action:** Split the symbol into domain-specific utilities.

### CONFIDENCE_TOO_LOW (v1)

- **Meaning:** Not enough data to judge.
- **Criteria:** <5 usages found or no docstrings in history.
- **Action:** Add manual documentation or wait for more usage data.

---

## The Brain (Memory)

Anchor maintains a local SQLite database at `~/.anchor/brain.db`.

- **Persists:** It remembers every scan.
- **Learns:** It tracks how often a symbol drifts across different projects.
- **Reset:** To clear memory, simply delete the file: `rm ~/.anchor/brain.db`