# CLAUDE.md — promocrypt-core
> **Core Rust library for promotional code generation and validation**
---
## CRITICAL RULES
### 1. DOCUMENTATION FIRST (MANDATORY)
**Before making ANY code changes:**
1. **Update docs/ files FIRST** - Any logical changes, new features, or modifications require updating the relevant documentation files BEFORE writing code
2. **Update README.md** - Ensure README reflects current state, no outdated information
3. **Verify consistency** - Check that docs match the actual implementation
**This is REQUIRED. Users must never encounter outdated documentation or be unaware of changes.**
### 2. Core is the Foundation
All other projects (CLI, PHP, PG) depend on this library. Changes here affect the entire ecosystem:
- **Breaking changes** require coordination across all projects
- **New features** must be exposed via FFI for other projects to use
- **API changes** must update docs/api.md and docs/ffi.md
### 3. Security Requirements
- **Never panic** in public functions - always return `Result`
- **Never log secrets** - no machineID or secret_key in error messages
- **Never weaken encryption** - maintain AES-256-GCM, Argon2id standards
- **Always validate input** - alphabet, code length, positions
### 4. Two-Key System
Maintain strict separation:
- **machineID** → read-only access (validation, info)
- **secret** → full access (generation, modification)
### 5. Backward Compatibility
- .bin files must remain compatible across versions
- Version byte (offset 8) indicates format version
- Support reading older formats
---
## Quick Reference
```rust
// Create
let bin = BinFile::create(path, secret, config)?;
// Open read-only (validation)
let bin = BinFile::open_readonly(path)?;
// Open full access (generation)
let mut bin = BinFile::open_with_secret(path, secret)?;
// Validate
let result = bin.validate(code);
let valid = bin.is_valid(code);
// Generate
let code = bin.generate()?;
let codes = bin.generate_batch(count)?;
// Generate at counter (parallel)
let start = bin.reserve_counter_range(count)?;
let codes = bin.generate_batch_at(start, count)?;
```
---
## Project Structure
```
core/
├── src/
│ ├── lib.rs # Public API exports
│ ├── error.rs # Error types, ValidationResult
│ ├── alphabet.rs # Alphabet handling
│ ├── damm.rs # Damm check digit algorithm
│ ├── format.rs # Code formatting (prefix/suffix/separator)
│ ├── generator.rs # HMAC-SHA256 code generation
│ ├── validator.rs # Code validation
│ ├── secret.rs # Secret configuration
│ ├── machine_id.rs # Hardware ID collection
│ ├── encryption.rs # AES-256-GCM, Argon2id
│ ├── binary_file.rs # .bin format handling
│ ├── counter.rs # Counter modes
│ ├── audit.rs # Audit trail
│ └── ffi/ # C-compatible FFI
├── docs/
│ ├── architecture.md # Component layers, flows
│ ├── binary-format.md # .bin file specification
│ ├── security.md # Two-key system, encryption
│ ├── counter-modes.md # File, inbin, manual modes
│ ├── api.md # Rust public API
│ ├── ffi.md # C-compatible interface
│ ├── errors.md # Error types and handling
│ └── testing.md # Test requirements
└── tests/
```
---
## Documentation Index
| [docs/architecture.md](docs/architecture.md) | Component layers, operation flows, module structure |
| [docs/binary-format.md](docs/binary-format.md) | .bin file structure, encrypted data, history records |
| [docs/security.md](docs/security.md) | Two-key encryption, machine ID, key derivation |
| [docs/counter-modes.md](docs/counter-modes.md) | File, inbin, manual, external counter modes |
| [docs/api.md](docs/api.md) | Complete Rust API reference |
| [docs/ffi.md](docs/ffi.md) | C-compatible FFI for other languages |
| [docs/errors.md](docs/errors.md) | Error types, recovery actions |
| [docs/testing.md](docs/testing.md) | Test requirements, benchmarks |
---
## Key Concepts
### Binary File Format (.bin)
- Magic: "PROMOCRY" (8 bytes)
- Version: 0x02
- Two encrypted keys: machine_encrypted + secret_encrypted
- Encrypted config block (name, alphabet, keys, audit)
- Optional mutable section (for in-bin counter)
### Check Position (Index-Based)
| `0` | Start |
| `-1` | End (default) |
| `4` | Index 4 |
| `-3` | 3rd from end |
### Counter Modes
| `file` | .counter file | Multi-process |
| `inbin` | Inside .bin | Single-file |
| `manual` | None | DB counter |
| `external` | Consumer | PostgreSQL |
### Performance Targets
| validate() | < 10μs |
| generate() | < 100μs |
| generate_batch(100k) | < 5s |
---
## Build & Test
```bash
# Build
cargo build --release
# Test
cargo test
# With FFI
cargo build --release --features ffi
# Benchmark
cargo bench
```