invar-cli 1.0.0

The Unchanging Key for Changing Data - Generate immutable structural state roots for cryptographic cache keys
# Invar Design Document

## Overview

| Property | Description |
|----------|-------------|
| **Name** | Invar |
| **Tagline** | The Unchanging Key for Changing Data |
| **Purpose** | Generate immutable structural state roots from arbitrary input data |
| **Output** | 64-character (32-byte) hex string representing a structural Distinction ID |

## Core Concept

The Invar Key is analogous to a **crystal**: the most deterministic, stable arrangement of a raw substance.

**Properties:**
- If input data changes by even a single byte, the resulting key changes completely
- If input data is identical, the generated key is guaranteed to be identical
- Directory hashing is order-independent (consistent across file systems)

## Architecture

### Technology Stack

- **Language**: Rust
- **Core Engine**: [koru-lambda-core]https://crates.io/crates/koru-lambda-core - Distinction Calculus implementation
- **CLI Framework**: clap
- **File Walking**: ignore crate (same as ripgrep)
- **File Watching**: notify crate

### Core Algorithm

The key generation process:

1. Initialize the root Distinction (D0)
2. Iterate over every byte of input data
3. For each byte `b`:
   - Convert to canonical Distinction using 8-step binary path encoding
   - Synthesize with running root: `D_root = synthesize(D_root, D_byte)`
4. Return final D_root ID as 64-character hex string

### Directory Hashing

For directories, Invar:

1. Walks the directory tree using the `ignore` crate
2. Respects `.gitignore` and `.invarignore` patterns by default
3. Sorts entries by path for cross-platform consistency
4. For each file:
   - Includes normalized relative path in the hash
   - Includes file contents
   - Separates path and content with null byte

This ensures:
- Order independence (regardless of file system ordering)
- Path awareness (renaming a file changes the key)
- Cross-platform consistency (normalized path separators)

## CLI Commands

### Primary Commands

| Command | Alias | Description |
|---------|-------|-------------|
| `gen` | `g` | Generate Invar key from input data |
| `check` | `c` | Verify data produces expected key |
| `watch` | `w` | Monitor file/directory for changes |

### Input Sources (mutually exclusive)

| Option | Description |
|--------|-------------|
| `--file <PATH>` | Read from file |
| `--data <STRING>` | Read from command-line string |
| `--directory <PATH>` | Hash directory recursively |
| *(stdin)* | Default when no source specified |

### Output Conventions

- **stdout**: Primary result only (key or JSON)
- **stderr**: All logs, warnings, and error messages
- **Exit codes**: 0 = success, non-zero = failure

## Feature Summary

| Feature | Description |
|---------|-------------|
| File hashing | Single file to key |
| Directory hashing | Recursive, order-independent |
| Streaming mode | O(1) memory for large files |
| Watch mode | Real-time change monitoring |
| .gitignore support | Respects git ignore patterns |
| .invarignore support | Custom ignore patterns for Invar |
| JSON output | Structured output with metadata |
| Verification | Check data against expected key |

## Design Principles

1. **Determinism**: Same input always produces same output
2. **Precision**: Byte-level sensitivity to changes
3. **Simplicity**: Minimal CLI with clear semantics
4. **Integration**: Clean integration with build systems and CI/CD
5. **Performance**: Streaming support for large files