# idio

Classical-language, human-readable identifiers with >32-bit entropy using Latin and Ancient Greek lexemes. Designed for enterprise-grade uniqueness while keeping outputs memorable and ASCII-only.

## Why idio?
- Uses cryptographically secure randomness (`secrets.SystemRandom`).
- Exceeds 32 bits of entropy by composing two grammar-conformant segments.
- Deterministic grammar drawn from AGENT.md: three patterns mixing Latin adjectives/nouns and Greek nouns/modifiers.
- Pure-Python, zero dependencies.

## Installation

```bash
pip install idio
# or locally
pip install .
```

## Usage

```python
from idio import generate_identifier, generate_segment, entropy_bits

# Default: two segments to exceed 32 bits, domain-safe with hyphens and dots
identifier = generate_identifier()
print(identifier)  # e.g., "unicus-nomen-onoma.idion-sema-signum"

# Single segment (useful for display, but ~18.9 bits with bundled lists)
segment = generate_segment()

# Entropy budget for your configuration
bits = entropy_bits(segments=2)
print(f"{bits:.2f} bits")
```

### Subdomain-safe format
By default, words are joined with `-` and segments with `.` to produce valid DNS
labels (e.g., `normalis-gradus-kosmos.perfectus-signum-onoma`). If you prefer the
original underscore format, pass `word_separator="_"` (and optionally
`segment_separator="--"`).

### Patterns (all supported)
- M1: `<latin_adjective>-<latin_noun>-<greek_noun>`
- M2: `<greek_modifier>-<greek_noun>-<latin_noun>`
- M3: `<latin_noun>-<latin_adjective>-<greek_noun>`

`generate_identifier` joins segments with `.` by default to keep each label comfortably
under DNS's 63-character limit and avoid underscores. If you want the original spec's
format, pass `word_separator="_"` and `segment_separator="--"`.

### Entropy math
Current bundled lists are roughly: ~75 Latin adjectives, ~3.5k Latin nouns, ~900 Greek nouns, and 11 Greek modifiers.
- Combinations per pattern set per segment: on the order of `5e8`
- Bits per segment: approximately `29 bits`
- Default identifier (2 segments): approximately `58 bits`

Add more words (≤100 per list) or more segments if you need an even larger space.

## API surface
- `generate_identifier(segments=2, patterns=None, bank=DEFAULT_BANK, word_separator="-", segment_separator=".")`
- `generate_segment(pattern=None, bank=DEFAULT_BANK, word_separator="-")`
- `entropy_bits(segments=2, patterns=Pattern, bank=DEFAULT_BANK)`
- `IdioGenerator` class if you want to own the RNG or word bank.

## Wordlists
All lexemes are ASCII transliterations with no diacritics, chosen to stay abstract, technical, and non-mythological per the spec in `AGENT.md`.

## Development

```bash
python -m venv .venv && source .venv/bin/activate
pip install -e .[dev]
pytest
```

## License

MIT License © Causum
