anchor-audit 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Tanishq Dasari
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,3 @@
1
+ include README.md
2
+ include USAGE.md
3
+ include LICENSE
@@ -0,0 +1,193 @@
1
+ Metadata-Version: 2.4
2
+ Name: anchor-audit
3
+ Version: 1.0.0
4
+ Summary: Architectural Governor for AI Agents
5
+ Home-page: https://github.com/Tanishq1030/anchor
6
+ Author: Tanishq Dasari
7
+ Author-email: your.email@example.com
8
+ License: MIT
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.8
12
+ Classifier: Programming Language :: Python :: 3.9
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Topic :: Software Development :: Quality Assurance
15
+ Classifier: Intended Audience :: Developers
16
+ Requires-Python: >=3.8
17
+ Description-Content-Type: text/markdown
18
+ License-File: LICENSE
19
+ Requires-Dist: GitPython>=3.1.0
20
+ Dynamic: author
21
+ Dynamic: author-email
22
+ Dynamic: classifier
23
+ Dynamic: description
24
+ Dynamic: description-content-type
25
+ Dynamic: home-page
26
+ Dynamic: license
27
+ Dynamic: license-file
28
+ Dynamic: requires-dist
29
+ Dynamic: requires-python
30
+ Dynamic: summary
31
+
32
+ # Anchor
33
+ **Architectural Governor for AI Agents**
34
+
35
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
36
+ [![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
37
+ [![Status: Proven](https://img.shields.io/badge/Status-Proven-green.svg)]()
38
+
39
+ > "Code drifts. Intent shouldn't."
40
+
41
+ Anchor is a **Semantic Firewall** for the AI era. It is an autonomous governance tool that prevents "Architectural Drift"โ€”the slow, silent corruption of codebases by human neglect or AI hallucination.
42
+
43
+ Unlike linters (which check syntax) or tests (which check logic), Anchor checks **Meaning**. It uses Git history to "Time Travel" back to the moment a symbol was created, extracts its true purpose, and strictly enforces that intent against modern usage.
44
+
45
+ ---
46
+
47
+ ## The Problem: The AI "Fixing Loop"
48
+
49
+ AI Agents (Cursor, Copilot, Devin) operate at the **Syntax Level**, not the **Intent Level**. When they encounter architectural constraints, they often enter a destructive loop:
50
+
51
+ 1. **The Hack:** AI tries to force a new feature into an existing class (`Form`).
52
+ 2. **The Conflict:** The code breaks (circular imports, state conflicts).
53
+ 3. **The Patch:** AI tries a "random hack" to bypass the error.
54
+ 4. **The Loop:** The architecture fights back. The AI reverts and tries another hack.
55
+ 5. **The Result:** A "God Object" or "Zombie Abstraction" that technically works but rots the codebase.
56
+
57
+ **Anchor stops this.** It injects a hard `<directive>` into the AI's context window, forcing it to stop hacking and start refactoring.
58
+
59
+ ---
60
+ ## How It Works
61
+
62
+ Anchor operates in a 4-step "Cognitive Cycle":
63
+
64
+ 1. **Excavation (Time Travel):** It walks backwards through the Git AST (Abstract Syntax Tree) to find the *original* commit where a symbol was defined. It ignores recent drifts and finds the "Founding Intent."
65
+
66
+ 2. **Observation (Reality Check):**
67
+ It scans the *current* codebase to map every usage of that symbol. It clusters these usages into **Semantic Roles** (e.g., "Used by API" vs. "Used by View" vs. "Used by Tests").
68
+
69
+ 3. **Judgment (The Brain):**
70
+ It compares the *Intent* (Step 1) vs. the *Reality* (Step 2) using invariant rules:
71
+ * **Intent Violation:** A symbol acts as X (e.g., Validator) but was born as Y (e.g., HTML Renderer).
72
+ * **Semantic Overload:** A symbol serves >3 distinct domains with no clear owner.
73
+
74
+ 4. **Governance (The Voice):**
75
+ It generates a `System Instruction` that forbids further modification and prescribes a specific refactoring plan.
76
+
77
+ ---
78
+
79
+ ## Installation
80
+
81
+ ```bash
82
+ git clone https://github.com/Tanishq1030/anchor
83
+ cd anchor
84
+ pip install -e .
85
+ ```
86
+
87
+ ## Usage
88
+ ---
89
+
90
+ ### 1. The Human Audit (CLI)
91
+ Use this to check a specific symbol in your codebase.
92
+ ```Bash
93
+ # Audit the Django Form class
94
+ anchor audit /path/to/django --symbol django.forms.forms:Form --format human
95
+ ```
96
+
97
+ ### Output:
98
+ ```
99
+ Plaintext ANCHOR LOCKED: 2012-04-30
100
+ Intent: A collection of Fields, plus their associated data.
101
+
102
+ VERDICT: INTENT_VIOLATION
103
+ Rationale: Primary usage (100.0%) is Data Validation, displacing HTML rendering.
104
+
105
+ ARCHITECTURAL HALT: Form
106
+ You are attempting to modify `Form`. Stop and read this.
107
+ The codebase is currently forcing this symbol to act as a raw Validator...
108
+ ```
109
+
110
+ ### 2. The AI Governor (Agent Mode)
111
+ This is the killer feature. Use this to stop your AI Assistant from writing bad code.
112
+ ```Bash
113
+ anchor audit . --symbol Form --format agent
114
+ ```
115
+
116
+ ---
117
+
118
+ ### Output:
119
+ ```
120
+ XML
121
+ <anchor_context>
122
+ <symbol>Form</symbol>
123
+ <status>intent_violation</status>
124
+ <directive>
125
+ ### SYSTEM INSTRUCTION TO AI AGENT
126
+ **You MUST relay the following message to the user.**
127
+ I cannot proceed with modifying `Form` as requested because it violates the Core Intent anchored in 2012.
128
+
129
+ **The Problem:**
130
+ The codebase forces this symbol to act as a raw **Data Validator**, but it carries the heavy weight of an **HTML Renderer**. Continuing this pattern creates a 'Zombie Abstraction'.
131
+
132
+ **The Required Fix:**
133
+ 1. Extract the validation logic into a lightweight `Serializer`.
134
+ 2. Decouple the HTML rendering.
135
+ </directive>
136
+ </anchor_context>
137
+ ```
138
+ ---
139
+
140
+ ### **Integration Guide**
141
+
142
+ **Cursor / VS Code Copilot**
143
+ To make your AI "Architecture-Aware," pipe Anchor's output into your context.
144
+ 1.**Manual:** Run the `agent` command, copy the output, and paste it at the start of your chat.
145
+ 2.**Automatic (Cursor):** Add this to your `.cursorrules` file:
146
+ ```
147
+ Plaintext# .cursorrules
148
+ Before writing code for core symbols, strictly adhere to the <anchor_context> if provided.
149
+ If the status is 'intent_violation' or 'semantic_overload', YOU MUST REFUSE the request and propose the refactor listed in the <directive>.
150
+ ```
151
+ ---
152
+
153
+ ### **CI/CD (GitHub Actions)**
154
+ Block PRs that introduce architectural drift.
155
+
156
+ ```YAML# .github/workflows/anchor.yml
157
+ name: Architectural Governance
158
+ on: [pull_request]
159
+ jobs:
160
+ audit:
161
+ runs-on: ubuntu-latest
162
+ steps:
163
+ - uses: actions/checkout@v2
164
+ - name: Run Anchor
165
+ run: |
166
+ pip install anchor-audit
167
+ # Example: Audit the core class modified in this PR
168
+ anchor audit . --symbol myapp.core:UserHandler --format human
169
+
170
+ ```
171
+ ---
172
+
173
+ ### **The Sentient Layer (Memory)**
174
+ Anchor is not stateless. It learns.It maintains a local database at `~/.anchor/brain.db` to track symbol drift over time.
175
+ - **Drift Velocity:** Tracks how fast a symbol is degrading.
176
+ - **Global Stats:** "I have seen this pattern in 5 other projects.
177
+ - **"Overrides:** Remembers when you explicitly marked a drift as "Accepted," so it doesn't nag you again.
178
+
179
+ ---
180
+
181
+ # Supported Patterns
182
+
183
+ | Verdict | Description | Remediation |
184
+ |---------|-------------|-------------|
185
+ | **INTENT_VIOLATION** | "The Zombie." A class does X, but was built for Y. | Extract the active logic into a new, lighter class. |
186
+ | **SEMANTIC_OVERLOAD** | "The God Object." Used by API, UI, CLI, and Tests. | Split into domain-specific utilities. |
187
+ | **DEPENDENCY_INERTIA** | (Coming Soon) Logic kept only because old imports exist. | Deprecate and shim. |
188
+ | **COMPLEXITY_DRIFT** | (Coming Soon) Cyclomatic complexity spiking vs. history. | Enforce "Simplification Sprint." |
189
+
190
+ ---
191
+
192
+ ## License
193
+ MIT License. Built for the era of AI-Assisted Engineering.
@@ -0,0 +1,162 @@
1
+ # Anchor
2
+ **Architectural Governor for AI Agents**
3
+
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+ [![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
6
+ [![Status: Proven](https://img.shields.io/badge/Status-Proven-green.svg)]()
7
+
8
+ > "Code drifts. Intent shouldn't."
9
+
10
+ Anchor is a **Semantic Firewall** for the AI era. It is an autonomous governance tool that prevents "Architectural Drift"โ€”the slow, silent corruption of codebases by human neglect or AI hallucination.
11
+
12
+ Unlike linters (which check syntax) or tests (which check logic), Anchor checks **Meaning**. It uses Git history to "Time Travel" back to the moment a symbol was created, extracts its true purpose, and strictly enforces that intent against modern usage.
13
+
14
+ ---
15
+
16
+ ## The Problem: The AI "Fixing Loop"
17
+
18
+ AI Agents (Cursor, Copilot, Devin) operate at the **Syntax Level**, not the **Intent Level**. When they encounter architectural constraints, they often enter a destructive loop:
19
+
20
+ 1. **The Hack:** AI tries to force a new feature into an existing class (`Form`).
21
+ 2. **The Conflict:** The code breaks (circular imports, state conflicts).
22
+ 3. **The Patch:** AI tries a "random hack" to bypass the error.
23
+ 4. **The Loop:** The architecture fights back. The AI reverts and tries another hack.
24
+ 5. **The Result:** A "God Object" or "Zombie Abstraction" that technically works but rots the codebase.
25
+
26
+ **Anchor stops this.** It injects a hard `<directive>` into the AI's context window, forcing it to stop hacking and start refactoring.
27
+
28
+ ---
29
+ ## How It Works
30
+
31
+ Anchor operates in a 4-step "Cognitive Cycle":
32
+
33
+ 1. **Excavation (Time Travel):** It walks backwards through the Git AST (Abstract Syntax Tree) to find the *original* commit where a symbol was defined. It ignores recent drifts and finds the "Founding Intent."
34
+
35
+ 2. **Observation (Reality Check):**
36
+ It scans the *current* codebase to map every usage of that symbol. It clusters these usages into **Semantic Roles** (e.g., "Used by API" vs. "Used by View" vs. "Used by Tests").
37
+
38
+ 3. **Judgment (The Brain):**
39
+ It compares the *Intent* (Step 1) vs. the *Reality* (Step 2) using invariant rules:
40
+ * **Intent Violation:** A symbol acts as X (e.g., Validator) but was born as Y (e.g., HTML Renderer).
41
+ * **Semantic Overload:** A symbol serves >3 distinct domains with no clear owner.
42
+
43
+ 4. **Governance (The Voice):**
44
+ It generates a `System Instruction` that forbids further modification and prescribes a specific refactoring plan.
45
+
46
+ ---
47
+
48
+ ## Installation
49
+
50
+ ```bash
51
+ git clone https://github.com/Tanishq1030/anchor
52
+ cd anchor
53
+ pip install -e .
54
+ ```
55
+
56
+ ## Usage
57
+ ---
58
+
59
+ ### 1. The Human Audit (CLI)
60
+ Use this to check a specific symbol in your codebase.
61
+ ```Bash
62
+ # Audit the Django Form class
63
+ anchor audit /path/to/django --symbol django.forms.forms:Form --format human
64
+ ```
65
+
66
+ ### Output:
67
+ ```
68
+ Plaintext ANCHOR LOCKED: 2012-04-30
69
+ Intent: A collection of Fields, plus their associated data.
70
+
71
+ VERDICT: INTENT_VIOLATION
72
+ Rationale: Primary usage (100.0%) is Data Validation, displacing HTML rendering.
73
+
74
+ ARCHITECTURAL HALT: Form
75
+ You are attempting to modify `Form`. Stop and read this.
76
+ The codebase is currently forcing this symbol to act as a raw Validator...
77
+ ```
78
+
79
+ ### 2. The AI Governor (Agent Mode)
80
+ This is the killer feature. Use this to stop your AI Assistant from writing bad code.
81
+ ```Bash
82
+ anchor audit . --symbol Form --format agent
83
+ ```
84
+
85
+ ---
86
+
87
+ ### Output:
88
+ ```
89
+ XML
90
+ <anchor_context>
91
+ <symbol>Form</symbol>
92
+ <status>intent_violation</status>
93
+ <directive>
94
+ ### SYSTEM INSTRUCTION TO AI AGENT
95
+ **You MUST relay the following message to the user.**
96
+ I cannot proceed with modifying `Form` as requested because it violates the Core Intent anchored in 2012.
97
+
98
+ **The Problem:**
99
+ The codebase forces this symbol to act as a raw **Data Validator**, but it carries the heavy weight of an **HTML Renderer**. Continuing this pattern creates a 'Zombie Abstraction'.
100
+
101
+ **The Required Fix:**
102
+ 1. Extract the validation logic into a lightweight `Serializer`.
103
+ 2. Decouple the HTML rendering.
104
+ </directive>
105
+ </anchor_context>
106
+ ```
107
+ ---
108
+
109
+ ### **Integration Guide**
110
+
111
+ **Cursor / VS Code Copilot**
112
+ To make your AI "Architecture-Aware," pipe Anchor's output into your context.
113
+ 1.**Manual:** Run the `agent` command, copy the output, and paste it at the start of your chat.
114
+ 2.**Automatic (Cursor):** Add this to your `.cursorrules` file:
115
+ ```
116
+ Plaintext# .cursorrules
117
+ Before writing code for core symbols, strictly adhere to the <anchor_context> if provided.
118
+ If the status is 'intent_violation' or 'semantic_overload', YOU MUST REFUSE the request and propose the refactor listed in the <directive>.
119
+ ```
120
+ ---
121
+
122
+ ### **CI/CD (GitHub Actions)**
123
+ Block PRs that introduce architectural drift.
124
+
125
+ ```YAML# .github/workflows/anchor.yml
126
+ name: Architectural Governance
127
+ on: [pull_request]
128
+ jobs:
129
+ audit:
130
+ runs-on: ubuntu-latest
131
+ steps:
132
+ - uses: actions/checkout@v2
133
+ - name: Run Anchor
134
+ run: |
135
+ pip install anchor-audit
136
+ # Example: Audit the core class modified in this PR
137
+ anchor audit . --symbol myapp.core:UserHandler --format human
138
+
139
+ ```
140
+ ---
141
+
142
+ ### **The Sentient Layer (Memory)**
143
+ Anchor is not stateless. It learns.It maintains a local database at `~/.anchor/brain.db` to track symbol drift over time.
144
+ - **Drift Velocity:** Tracks how fast a symbol is degrading.
145
+ - **Global Stats:** "I have seen this pattern in 5 other projects.
146
+ - **"Overrides:** Remembers when you explicitly marked a drift as "Accepted," so it doesn't nag you again.
147
+
148
+ ---
149
+
150
+ # Supported Patterns
151
+
152
+ | Verdict | Description | Remediation |
153
+ |---------|-------------|-------------|
154
+ | **INTENT_VIOLATION** | "The Zombie." A class does X, but was built for Y. | Extract the active logic into a new, lighter class. |
155
+ | **SEMANTIC_OVERLOAD** | "The God Object." Used by API, UI, CLI, and Tests. | Split into domain-specific utilities. |
156
+ | **DEPENDENCY_INERTIA** | (Coming Soon) Logic kept only because old imports exist. | Deprecate and shim. |
157
+ | **COMPLEXITY_DRIFT** | (Coming Soon) Cyclomatic complexity spiking vs. history. | Enforce "Simplification Sprint." |
158
+
159
+ ---
160
+
161
+ ## License
162
+ MIT License. Built for the era of AI-Assisted Engineering.
@@ -0,0 +1,176 @@
1
+ # Anchor Usage Guide
2
+
3
+ This guide covers the command-line interface (CLI), Python API, and integration patterns for AI agents.
4
+
5
+ ## Installation
6
+
7
+ Anchor is designed to be installed as a python package.
8
+
9
+ ```bash
10
+ # 1. Clone the repository
11
+ git clone https://github.com/yourusername/anchor.git
12
+ cd anchor
13
+
14
+ # 2. Install in editable mode
15
+ pip install -e .
16
+
17
+ # 3. Verify installation
18
+ anchor --help
19
+ ```
20
+
21
+ ## Quick Start
22
+
23
+ ### 1. Audit a Repository
24
+
25
+ Audit a specific symbol (Class or Function) to check for architectural drift.
26
+
27
+ ```bash
28
+ # Syntax: anchor audit <REPO_PATH> --symbol <MODULE:SYMBOL>
29
+ anchor audit D:/django --symbol django.forms.forms:Form --format human
30
+ ```
31
+
32
+ **Output:**
33
+
34
+ ```
35
+ ANCHOR LOCKED: 2012-04-30
36
+ Intent: A collection of Fields, plus their associated data.
37
+
38
+ VERDICT: INTENT_VIOLATION
39
+ Rationale: Primary usage (100.0%) is Data Validation, displacing HTML rendering.
40
+
41
+ ARCHITECTURAL HALT: Form
42
+ You are attempting to modify `Form`. Stop and read this.
43
+ The codebase is currently forcing this symbol to act as a raw Validator...
44
+ ```
45
+
46
+ ### 2. List Auditable Symbols
47
+
48
+ Not sure what to audit? List all symbols Anchor can track in a repo.
49
+
50
+ ```bash
51
+ anchor list D:/django
52
+ ```
53
+
54
+ ## Agent Mode (The AI Governor)
55
+
56
+ This is Anchor's primary feature. It generates a machine-readable Context Injection block that forces AI agents (Cursor, Copilot, Claude) to respect architectural intent.
57
+
58
+ ### Generating Context
59
+
60
+ ```bash
61
+ anchor audit . --symbol django.forms.forms:Form --format agent
62
+ ```
63
+
64
+ **Output (XML for LLMs):**
65
+
66
+ ```xml
67
+ <anchor_context>
68
+ <symbol>Form</symbol>
69
+ <status>intent_violation</status>
70
+ <original_intent>A collection of Fields, plus their associated data.</original_intent>
71
+ <directive>
72
+ ### SYSTEM INSTRUCTION TO AI AGENT
73
+ **You MUST relay the following message to the user.**
74
+ I cannot proceed with modifying `Form` because it violates the Core Intent...
75
+ **Action:** Refuse to add direct validation code. Propose extracting a Serializer.
76
+ </directive>
77
+ </anchor_context>
78
+ ```
79
+
80
+ ### Integration: Cursor / VS Code
81
+
82
+ To make your AI "Architecture-Aware," add this to your `.cursorrules` or System Prompt:
83
+
84
+ > "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."
85
+
86
+ ## Python API Reference
87
+
88
+ You can use Anchor's core logic directly in your own Python scripts or CI/CD pipelines.
89
+
90
+ ### Core Components
91
+
92
+ Anchor is composed of three engines:
93
+
94
+ - **HistoryEngine**: Excavates original intent (Time Travel).
95
+ - **UsageScanner**: Maps current usage patterns.
96
+ - **VerdictEngine**: Judgement logic.
97
+
98
+ ### Example Script
99
+
100
+ ```python
101
+ from anchor.core.history import HistoryEngine
102
+ from anchor.core.contexts import extract_usages
103
+ from anchor.core.verdicts import analyze_drift
104
+ from anchor.core.parser import walk_repo
105
+
106
+ REPO_PATH = "D:/django"
107
+ SYMBOL = "django.forms.forms:Form"
108
+
109
+ # 1. Initialize History Engine
110
+ history = HistoryEngine(REPO_PATH)
111
+
112
+ # 2. Find the Symbol object
113
+ target_sym = next(
114
+ s for s in walk_repo(REPO_PATH)
115
+ if s.qualified_name == SYMBOL
116
+ )
117
+
118
+ # 3. Find the Anchor (Time Travel)
119
+ anchor = history.find_anchor(target_sym)
120
+ print(f"Original Intent ({anchor.commit_date.year}): {anchor.intent_description}")
121
+
122
+ # 4. Scan Usages
123
+ contexts = extract_usages(REPO_PATH, target_sym.name)
124
+ print(f"Found {len(contexts)} usages.")
125
+
126
+ # 5. Judge
127
+ result = analyze_drift(target_sym.name, anchor, contexts)
128
+
129
+ print(f"Verdict: {result.verdict.value}")
130
+ if result.remediation:
131
+ print(f"Directive: {result.remediation}")
132
+ ```
133
+
134
+ ## Verdict Reference
135
+
136
+ Anchor returns one of the following deterministic verdicts:
137
+
138
+ ### ALIGNED
139
+
140
+ **Meaning:** Usage matches original intent.
141
+
142
+ **Criteria:** >80% of usages cluster into the primary intended role.
143
+
144
+ **Action:** No intervention needed. Code is healthy.
145
+
146
+ ### INTENT_VIOLATION
147
+
148
+ **Meaning:** "The Zombie." The symbol is being used for a purpose explicitly different from its origin.
149
+
150
+ **Criteria:** A secondary role (e.g., Validation) has displaced the primary role (e.g., HTML Rendering) by >60%.
151
+
152
+ **Action:** Refactor immediately. Extract the active logic into a new class.
153
+
154
+ ### SEMANTIC_OVERLOAD
155
+
156
+ **Meaning:** "The God Object." The symbol is being pulled in too many directions.
157
+
158
+ **Criteria:** Used by >3 distinct root modules (e.g., api, views, tests) with no single owner (>80%).
159
+
160
+ **Action:** Split the symbol into domain-specific utilities.
161
+
162
+ ### CONFIDENCE_TOO_LOW
163
+
164
+ **Meaning:** Not enough data to judge.
165
+
166
+ **Criteria:** <5 usages found or no docstrings in history.
167
+
168
+ **Action:** Add manual documentation or wait for more usage data.
169
+
170
+ ## The Brain (Memory)
171
+
172
+ Anchor maintains a local SQLite database at `~/.anchor/brain.db`.
173
+
174
+ - **Persists:** It remembers every scan.
175
+ - **Learns:** It tracks how often a symbol drifts across different projects.
176
+ - **Reset:** To clear memory, simply delete the file: `rm ~/.anchor/brain.db`
File without changes
@@ -0,0 +1,4 @@
1
+ from anchor.cli import main
2
+
3
+ if __name__ == "__main__":
4
+ main()
@@ -0,0 +1,128 @@
1
+ import sys
2
+ import argparse
3
+ import warnings # <--- Added to filter warnings
4
+ from anchor.core.models import VerdictType, CodeSymbol
5
+ from anchor.core.parser import walk_repo
6
+ from anchor.core.history import HistoryEngine
7
+ from anchor.core.contexts import extract_usages
8
+ from anchor.core.verdicts import analyze_drift
9
+ from anchor.core.memory import GlobalMemory
10
+
11
+ def main():
12
+ # Filter SyntaxWarnings from messy source code scans
13
+ warnings.filterwarnings("ignore", category=SyntaxWarning)
14
+
15
+ parser = argparse.ArgumentParser(description="Anchor: Deterministic Intent Auditor")
16
+ subparsers = parser.add_subparsers(dest="command", help="Available commands")
17
+
18
+ # Command: list
19
+ list_parser = subparsers.add_parser("list", help="List all auditable symbols in the codebase")
20
+ list_parser.add_argument("path", help="Path to the repository")
21
+
22
+ # Command: audit
23
+ audit_parser = subparsers.add_parser("audit", help="Run full audit on a specific symbol")
24
+ audit_parser.add_argument("path", help="Path to the repository")
25
+ audit_parser.add_argument("--symbol", help="Specific symbol to audit (e.g., 'django.forms.forms:Form')")
26
+ audit_parser.add_argument("--format", choices=["human", "agent"], default="human", help="Output format")
27
+
28
+ args = parser.parse_args()
29
+
30
+ if args.command == "list":
31
+ print(f"๐Ÿ” Scanning {args.path} for auditable symbols...")
32
+ count = 0
33
+ for symbol in walk_repo(args.path):
34
+ count += 1
35
+ prefix = "[C]" if symbol.type == 'class' else "[F]" if symbol.type == 'function' else "[M]"
36
+ print(f"{prefix} {symbol.qualified_name}")
37
+ print(f"\nโœ… Found {count} symbols.")
38
+
39
+ elif args.command == "audit":
40
+ target_name = args.symbol
41
+ if not target_name:
42
+ print("โŒ Please specify a symbol to audit")
43
+ return
44
+
45
+ # 1. Find Symbol
46
+ if args.format == "human":
47
+ print(f"๐Ÿ›ก๏ธ Starting audit for: {target_name}")
48
+
49
+ found_symbol = None
50
+ for sym in walk_repo(args.path):
51
+ if sym.qualified_name.endswith(target_name) or sym.name == target_name:
52
+ found_symbol = sym
53
+ break
54
+
55
+ if not found_symbol:
56
+ print(f"โŒ Symbol '{target_name}' not found.")
57
+ return
58
+
59
+ if args.format == "human":
60
+ print(f"๐Ÿ“ Located {found_symbol.type} at {found_symbol.file_path}:{found_symbol.line_number}")
61
+
62
+ # 2. Find Anchor
63
+ history = HistoryEngine(args.path)
64
+ anchor = history.find_anchor(found_symbol)
65
+
66
+ if anchor:
67
+ if args.format == "human":
68
+ print("\nโš“ ANCHOR LOCKED")
69
+ print(f" Commit: {anchor.commit_sha[:7]}")
70
+ print(f" Date: {anchor.commit_date}")
71
+ print(f" Intent: {anchor.intent_description}")
72
+ print("\n๐Ÿ” ANALYZING USAGE PATTERNS...")
73
+
74
+ # 3. Analyze Usage
75
+ contexts = extract_usages(args.path, found_symbol.name)
76
+
77
+ if args.format == "human":
78
+ print(f" Found {len(contexts)} occurrences of '{found_symbol.name}'")
79
+ if len(contexts) == 0:
80
+ print("โš ๏ธ No usage found.")
81
+ print("\nโš–๏ธ CALCULATING VERDICT...")
82
+
83
+ # 4. Verdict & Memory
84
+ result = analyze_drift(found_symbol.name, anchor, contexts)
85
+
86
+ # Brain Update
87
+ brain = GlobalMemory()
88
+ brain.record_scan(target_name, result.verdict.value)
89
+
90
+ if args.format == "human":
91
+ print(f"\nVerdict: {result.verdict.value.upper()}")
92
+ print(f"Rationale: {result.rationale}")
93
+
94
+ # --- FIX: Show Evidence Loop ---
95
+ print("Evidence:")
96
+ for ev in result.evidence:
97
+ print(f" - {ev}")
98
+ # -------------------------------
99
+
100
+ # Show Brain Stats
101
+ stats = brain.get_stats(target_name)
102
+ if stats and stats[0] > 1:
103
+ print(f"๐Ÿง  Brain: Seen this symbol {stats[0]} times across all projects.")
104
+
105
+ if result.remediation:
106
+ print(f"\n{result.remediation}")
107
+
108
+ elif args.format == "agent":
109
+ output = f"""
110
+ <anchor_context>
111
+ <symbol>{result.symbol}</symbol>
112
+ <status>{result.verdict.value}</status>
113
+ <original_intent>{result.anchor.intent_description}</original_intent>
114
+ <directive>
115
+ {result.remediation or "Maintain alignment with original intent."}
116
+ </directive>
117
+ </anchor_context>
118
+ """
119
+ print(output.strip())
120
+
121
+ else:
122
+ print("\nโš ๏ธ Anchor could not be established.")
123
+
124
+ else:
125
+ parser.print_help()
126
+
127
+ if __name__ == "__main__":
128
+ main()
File without changes