Metadata-Version: 2.4
Name: astrict
Version: 2.0.0
Summary: Hierarchical static analysis engine that captures tribal knowledge, enforces business logic, and prevents AI-generated code violations using AST analysis.
Author-email: saadparast <saadparast@users.noreply.github.com>
License: Elastic License 2.0
Project-URL: Homepage, https://github.com/saadparast/astrict
Project-URL: Documentation, https://docs.astrict.dev
Project-URL: Repository, https://github.com/saadparast/astrict
Project-URL: Issues, https://github.com/saadparast/astrict/issues
Project-URL: Changelog, https://github.com/saadparast/astrict/releases
Keywords: static-analysis,ast,tree-sitter,linter,security,tribal-knowledge,code-review,compliance,ai-code-safety,devtools,ci-cd
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Topic :: Software Development :: Testing
Classifier: Topic :: Security
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Operating System :: OS Independent
Classifier: Environment :: Console
Classifier: Framework :: Pytest
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: tree-sitter>=0.25.0
Requires-Dist: tree-sitter-python>=0.21.0
Requires-Dist: tree-sitter-javascript>=0.21.0
Requires-Dist: tree-sitter-typescript>=0.21.0
Requires-Dist: tree-sitter-java>=0.21.0
Requires-Dist: tree-sitter-go>=0.21.0
Requires-Dist: tree-sitter-rust>=0.21.0
Requires-Dist: tree-sitter-cpp>=0.21.0
Requires-Dist: tree-sitter-c>=0.21.0
Requires-Dist: ruamel.yaml>=0.18.0
Requires-Dist: typer>=0.12.0
Requires-Dist: rich>=13.0.0
Requires-Dist: click>=8.1.0
Requires-Dist: pygls>=1.3.0
Requires-Dist: gitpython>=3.1.0
Requires-Dist: pydantic>=2.0.0
Provides-Extra: dev
Requires-Dist: pytest>=7.4.0; extra == "dev"
Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
Requires-Dist: mypy>=1.5.0; extra == "dev"
Requires-Dist: black>=23.0.0; extra == "dev"
Requires-Dist: ruff>=0.1.0; extra == "dev"
Requires-Dist: pre-commit>=3.5.0; extra == "dev"
Provides-Extra: docs
Requires-Dist: mkdocs-material>=9.0.0; extra == "docs"
Requires-Dist: mkdocstrings[python]>=0.24.0; extra == "docs"
Dynamic: license-file

# 🛡️ Astrict

**Your team's memory, automated.**

[![PyPI](https://img.shields.io/pypi/v/astrict)](https://pypi.org/project/astrict/)
[![License](https://img.shields.io/badge/License-Elastic%202.0-blue)](LICENSE)
[![Python](https://img.shields.io/badge/Python-3.11+-blue)](https://python.org)

---

Astrict is a **hierarchical static analysis engine** that captures tribal knowledge, enforces business logic, and prevents AI-generated code violations using AST analysis.

Unlike traditional linters that focus on syntax, Astrict encodes **your team's hard-won lessons**: the outage that happened at 3 AM, the architectural decision from Q3 planning, the performance bottleneck that cost $50K.

**Every rule has an author. Every violation explains the history. Every enforcement teaches the team.**

## Why Astrict?

Most production failures aren't caused by invalid syntax — they're caused by **valid code that should never have been allowed**:

- 💰 Floating-point arithmetic used for money (AI tools love generating this)
- 🔑 Secrets hardcoded into source code
- ⏱️ HTTP requests without timeouts (caused a $50K outage)
- 🏗️ Architectural rules enforced only by convention

These rules are documented informally and enforced inconsistently. **Astrict makes them explicit, enforceable, and non-ignorable.**

## Key Features

### 🏛️ Hierarchical Authority
Rules are organized by who wrote them and how critical they are:

| Layer | Owner | Enforcement | Example |
|-------|-------|-------------|---------|
| **GLOBAL** | Security Team | 🚫 BLOCK | No hardcoded secrets |
| **TEAM** | Tech Lead | ⚠️ WARN | No requests without timeout |
| **PERSONAL** | Developer | 💡 NUDGE | Remind me to write tests |

Higher authority always wins. Lower layers can never override higher mandates.

### 🧠 Tribal Knowledge Capture
Every rule carries its story:
- **Author:** Who wrote this rule (accountability)
- **Rationale:** Why it exists (learning)
- **Incident:** What outage caused it (prevention)
- **Decision PR:** What team discussion led to it (context)

### 🤖 AI Code Safety
Catches common mistakes in AI-generated code:
- Float for money → Use Decimal
- `console.log` with passwords → Use proper logger
- SQL string concatenation → Use parameterized queries
- Missing timeouts → Always specify

### 🌐 Multi-Language
Python (full), JavaScript/TypeScript (partial), Go/Java (basic). Severity is **capped by detection confidence** — Astrict never blocks a build on uncertain detection.

### ⚡ AST-Based Detection
Uses Tree-sitter for semantic analysis, not fragile regex. Deterministic, explainable, and fast.

## Quick Start

```bash
# Install
pip install astrict

# Initialize in your project
cd my-project
astrict init

# Scan
astrict scan

# Scan with full context (author, incident, rationale)
astrict scan --verbose
```

## Example Output

```
🛡️  Astrict — Scanning project...

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🚫 BLOCKING VIOLATIONS (1)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  global.no-float-money
  File: src/payments.py:45
  Author: security@company.com
  🚫 CRITICAL: Float used for financial value!
  🤖 AI Code Safety Rule — Common in AI-generated code

  Fix: Use Decimal
    from decimal import Decimal
    price = Decimal("10.99")

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚠️  WARNINGS (1)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  team.no-requests-without-timeout
  File: src/api.py:123
  Author: @senior-backend-dev
  Incident: 2024-03-15 outage
  ⚠️ HTTP request without timeout detected!
  🔥 This caused the 2024-03-15 production outage

  ❌ Build FAILED
```

## How Astrict Differs

| Feature | Semgrep | SonarQube | **Astrict** |
|---------|---------|-----------|-------------|
| Security rules | ✅ Strong | ✅ Good | ✅ Good |
| **Tribal knowledge** | ❌ None | ❌ None | ✅ **Core feature** |
| **Incident linking** | ❌ None | ❌ None | ✅ **Built-in** |
| **Author attribution** | ❌ None | ❌ None | ✅ **Every rule** |
| **AI code safety** | ❌ None | ❌ None | ✅ **Built-in** |
| Rule hierarchy | ❌ Flat | ❌ Flat | ✅ **GLOBAL>TEAM>PERSONAL** |
| Personal rules | ❌ No | ❌ No | ✅ **Git-ignored** |

## Integrations

### VS Code Extension
Real-time analysis with rich hover tooltips showing rule context.
```
Install "Astrict" from VS Code Marketplace
```

### GitHub Actions
```yaml
- uses: saadparast/astrict-action@v2
  with:
    fail-on-block: 'true'
    post-pr-comment: 'true'
```

### Pre-commit Hook
```yaml
repos:
  - repo: https://github.com/saadparast/astrict
    rev: v2.0.0
    hooks:
      - id: astrict-scan
```

## Writing Rules

### Incident-Driven Rule (from a production failure)
```yaml
- metadata:
    id: "team.no-requests-without-timeout"
    author: "@senior-dev"
    created: "2024-03-16"
    incident: "2024-03-15-prod-hang"
    rationale: |
      On March 15, a requests.get() without timeout hung for
      30 minutes and took down production. Cost: $50K.
  layer: TEAM
  severity: WARN
  pattern:
    type: ai_pattern
    ai_tool_patterns:
      - "requests\\.(get|post)\\([^)]*(?!timeout)[^)]*\\)"
  message: |
    ⚠️ HTTP request without timeout!
    🔥 This caused the 2024-03-15 outage.
    Fix: requests.get(url, timeout=10)
```

### AI Code Safety Rule
```yaml
- metadata:
    id: "global.no-float-money"
    author: "security@company.com"
    rationale: "AI tools generate float for money. $0.1 + $0.2 ≠ $0.3"
    tags: ["ai-safety", "finance"]
  layer: GLOBAL
  severity: BLOCK
  pattern:
    type: ai_pattern
    target_matches: "price|salary|balance|amount"
    ai_tool_patterns:
      - "(?i)(price|amount)\\s*=\\s*\\d+\\.\\d+"
    correct_pattern: "from decimal import Decimal; price = Decimal('10.99')"
  message: |
    🚫 Float used for financial value!
    🤖 AI tools commonly generate this mistake.
    Fix: Use Decimal
```

## Project Structure
```
your-project/
├── .astrict/
│   ├── global.yaml    # Security rules (BLOCK) — committed
│   ├── team.yaml      # Tribal knowledge (WARN) — committed
│   └── personal.yaml  # Your habits (NUDGE) — git-ignored
└── src/
```

## CLI Commands

| Command | Description |
|---------|-------------|
| `astrict scan` | Scan project for violations |
| `astrict init` | Initialize .astrict/ directory |
| `astrict explain <rule-id>` | Show full rule context |
| `astrict validate` | Validate rule files |
| `astrict audit --output report.json` | Generate compliance report |
| `astrict langs` | Show supported languages |

## License

Elastic License 2.0 — see [LICENSE](LICENSE)

---

**Built by [@saadparast](https://github.com/saadparast)**

*Turn your outages into rules. Your team's memory, automated.* 🛡️
