# Meshulash Guard

## What This Is

A Python client SDK (`meshulash-guard`) that gives developers a clean, type-safe interface to the Meshulash security engine. Developers install the package, configure scanners with predefined label enums and actions, and scan text — the SDK translates their configuration into guardline specs, sends them to the security server (on-prem or cloud), and returns structured results. Accompanied by a documentation site built with MkDocs Material, hosted on the team's own domain.

## Core Value

Developers can protect their LLM applications from PII leakage, toxic content, jailbreaks, and cyber threats with a single `pip install` and a few lines of Python — no knowledge of the underlying engine required.

## Requirements

### Validated

(None yet — ship to validate)

### Active

- [ ] SDK core: Guard class with server_url + api_key, scan_input() method, HTTP client
- [ ] Translation layer: BaseScanner contract with to_guardline_spec() that converts developer config to server guardline format
- [ ] PIIScanner with scoped PIILabel enum (53 canonical labels across identity, contact, financial, credentials, technical, temporal, organizational)
- [ ] TopicScanner with scoped TopicLabel enum (TC head hidden from developer, SDK maps labels to heads internally)
- [ ] ToxicityScanner with scoped ToxicityLabel enum (maps to hate_speech TC head)
- [ ] CyberScanner with scoped CyberLabel enum (maps to cysecbench TC head)
- [ ] JailbreakScanner with scoped JailbreakLabel enum (maps to upcoming jailbreak TC head)
- [ ] Action enum: REPLACE (redact with placeholders), BLOCK (hard stop), LOG (pass-through)
- [ ] Condition enum: ANY, ALL, K_OF, CONTEXTUAL (maps to server gating conditions)
- [ ] Structured result type: status, processed_text, placeholders, level, per-scanner breakdown, risk_categories
- [ ] Placeholder cache / vault: session-scoped storage of placeholder dictionaries, deanonymize() method for restoring originals in LLM responses (client-side, no server round-trip)
- [ ] Risk bundle support: PII, PHI, PCI, SECRETS, TECH as predefined label groups
- [ ] BaseNormalizer contract: defined in v1 for extensibility, server-side normalizer registry comes in v2
- [ ] scan_input() and scan_output() method signatures: both defined from v1, output scanning implemented in v2
- [ ] Python package: pyproject.toml, pip-installable, semantic versioning
- [ ] Server: new /api/security/scan endpoint accepting JSON body with text + guardline_specs inline
- [ ] Server: per-scanner result breakdown in response body
- [ ] Server: JSON content-type support (current server only accepts multipart/form-data)
- [ ] Documentation site: MkDocs + Material theme, hosted on custom domain
- [ ] Documentation: installation guide, quickstart, scanner reference (each scanner + its labels), actions, conditions, result handling, deanonymize workflow
- [ ] Documentation: component reference for what the engine detects and how (validators, detection sources per label)

### Out of Scope

- REST API documentation — existing API is being deprecated, SDK is the primary interface
- Engine logic in the SDK — all ML, NER, regex, validation runs server-side
- File scanning via SDK — server supports PDF scanning but SDK won't expose it in v1
- Output scanning implementation — method signature defined, actual scanning is v2
- Normalizer implementation — BaseNormalizer contract defined, server normalizer registry is v2
- Streaming support — scanning streaming LLM responses is future work
- OAuth / JWT auth in SDK — API key only for v1
- Custom regex via SDK — developers can't define custom regex patterns in v1

## Context

- The security engine already exists at AIM/security-server with a mature 5-stage pipeline: Recognize → Validate → Score → Gate → Act
- 53 canonical labels in the label registry with regex patterns, NER model support, and 16+ validators
- 5 TC classification heads: topic, emotion, hate_speech, cysecbench, jailbreak (coming soon)
- 4 gating conditions: any, all, k_of, contextual_analysis
- The current server fetches guardline configs from a backend database per-request — the SDK needs a new endpoint where guardline_specs are sent inline with the request
- The server currently only accepts multipart/form-data — needs JSON support for SDK text scanning
- Guardlines are the server's core configuration unit — the SDK's entire translation layer maps scanner configs to this format
- Validators (Luhn, phone format, email format, entropy, etc.) run automatically per label — not configurable in v1
- Normalizers are minimal (whitespace only) and run by default — normalizer registry is v2
- Placeholder format: [LABEL_NAME-HASH] (e.g., [EMAIL_ADDRESS-A1B2])
- Design reference document: SDK_DESIGN.md in repo root

## Constraints

- **Architecture**: SDK is a client library (HTTP wrapper), not an engine extraction — server does all heavy compute
- **Auth**: API key + server address model, supporting both on-prem and cloud deployments
- **Compatibility**: Must work with the existing security server pipeline — translation layer produces guardline_specs the server already understands
- **Python**: Package target TBD based on server's Python version (server uses 3.13)
- **Extensibility**: BaseScanner and BaseNormalizer contracts must make adding new components trivial (new class + label enum)
- **TC heads hidden**: Developers never see TC head names — they pick labels, SDK maps to heads internally
- **Labels scoped to scanners**: Each scanner owns its label enum, no global label imports

## Key Decisions

| Decision | Rationale | Outcome |
|----------|-----------|---------|
| SDK is HTTP client wrapper, not engine extraction | Server stays as-is, engine has one home in AIM, on-prem customers keep their deployment model | — Pending |
| Translation layer (scanner config → guardline_specs) | Leverages existing server pipeline without modification to core engine logic | — Pending |
| Labels scoped to scanners, not global | Better DX — developer imports PIILabel from PIIScanner, not from a giant global enum | — Pending |
| TC heads hidden from developer | Simpler API — developer picks labels, SDK handles head routing | — Pending |
| MkDocs + Material for docs | Same stack as LLM Guard, Python-native, mkdocstrings for API reference, free hosting | — Pending |
| Placeholder cache client-side | Deanonymize doesn't need a server round-trip, placeholders are just string replacement | — Pending |
| BaseNormalizer contract in v1, implementation in v2 | Establishes extensibility pattern early, normalizer registry on server is a larger effort | — Pending |
| scan_input() / scan_output() signatures in v1, output scanning in v2 | Method signatures establish the pattern, output scanning needs server-side output endpoint | — Pending |

---
*Last updated: 2026-02-26 after initialization*
