# PyFulmen v0.1.2 Release Notes

**Release Date**: October 16, 2025
**Release Type**: Feature Release - Foundry Expansion & Infrastructure Improvements
**Milestone**: Foundry Phase 2E + Phase 3 Complete, ADR Infrastructure Established

---

## 🎯 Release Overview

PyFulmen v0.1.2 expands the Foundry module with **country code support** and **MIME magic number detection**, achieving full gofulmen v0.1.1 API parity. This release also establishes **architectural governance** through a comprehensive ADR system and implements **version propagation infrastructure** for maintainable version management.

**Key Capabilities**:

- **ISO 3166-1 Country Codes**: Triple-index catalog with O(1) lookups, case-insensitive matching
- **MIME Magic Number Detection**: Content-based type identification with BOM handling and stream support
- **Architectural Governance**: Two-tier ADR system (local + ecosystem decisions)
- **Version Propagation**: Policy-driven VERSION → pyproject.toml sync automation
- **Infrastructure Improvements**: Bootstrap symlink fix, enhanced Makefile targets

This release prioritizes:

- **Cross-Language Parity**: 100% behavioral alignment with gofulmen v0.1.1
- **Developer Experience**: Automated version management, symlink tracking for local development
- **Architectural Transparency**: Documented decision-making with promotion paths
- **Enterprise Quality**: 95%+ test coverage, 520+ tests passing

---

## ✨ Major Features

### Country Code Support (Phase 2E)

Complete ISO 3166-1 country code implementation with full gofulmen v0.1.1 API parity.

#### Country Model

**Location**: `src/pyfulmen/foundry/catalog.py:110-132`

```python
class Country(FulmenCatalogModel):
    """ISO 3166-1 country representation."""
    alpha2: str          # Two-letter code (e.g., "US")
    alpha3: str          # Three-letter code (e.g., "USA")
    numeric: str         # Numeric code (e.g., "840")
    name: str            # Common name (e.g., "United States")
    official_name: Optional[str] = None  # Official name if different
```

#### Triple-Index Catalog

**Implementation**: Lazy-loaded precomputed indexes for O(1) lookups

- **Alpha-2 Index**: Fast lookups by two-letter codes (`US`, `CA`, `JP`)
- **Alpha-3 Index**: Three-letter code lookups (`USA`, `CAN`, `JPN`)
- **Numeric Index**: Numeric code lookups with zero-padding (`840`, `076`)

**Performance**: O(1) lookups, computed once on first access

#### Convenience Functions

**Location**: `src/pyfulmen/foundry/__init__.py:49-97`

1. **validate_country_code(code)**: Three-lookup strategy
   - Tries Alpha-2 → Alpha-3 → Numeric (with zero-padding)
   - Case-insensitive: `"us"` → `"US"`, `"usa"` → `"USA"`
   - Returns `True` if valid, `False` otherwise

2. **get_country(alpha2)**: Lookup by Alpha-2 code
   - Direct index access for primary lookups
   - Returns `Country` object or `None`

3. **get_country_by_alpha3(alpha3)**: Lookup by Alpha-3 code
   - Case-insensitive matching
   - Returns `Country` object or `None`

4. **get_country_by_numeric(numeric)**: Lookup by numeric code
   - Automatic zero-padding: `"76"` → `"076"` (Brazil)
   - Returns `Country` object or `None`

5. **list_countries()**: Enumerate all countries
   - Returns list of all `Country` objects in catalog

#### Sample Data

**Catalog**: 5 sample countries from Crucible

- United States (US, USA, 840)
- Canada (CA, CAN, 124)
- Japan (JP, JPN, 392)
- Germany (DE, DEU, 276)
- Brazil (BR, BRA, 076)

#### Testing

**Coverage**: 32 comprehensive tests

- Model validation tests
- Catalog index tests (Alpha-2, Alpha-3, Numeric)
- Convenience function tests
- Case-insensitive matching tests
- Zero-padding canonicalization tests
- Integration tests

**Location**: `tests/foundry/test_catalog.py:213-405`

### MIME Magic Number Detection (Phase 3)

Content-based MIME type identification with full gofulmen v0.1.1 API parity.

#### Core Detection Function

**Location**: `src/pyfulmen/foundry/mime_detection.py:17-78`

```python
def detect_mime_type(data: bytes) -> Optional[str]:
    """
    Detect MIME type from raw bytes using magic number detection.

    Features:
    - BOM stripping (UTF-8, UTF-16 LE/BE)
    - Leading whitespace trimming
    - Format detection: JSON, XML, YAML, CSV, text
    - Returns None for binary/unknown content
    """
```

**Supported Formats**:

- **JSON**: Objects `{...}` and arrays `[...]`
- **XML**: `<?xml` declarations
- **YAML**: `key: value` patterns
- **CSV**: 2+ commas per line
- **Plain Text**: >80% printable characters

#### Streaming Detection

**Location**: `src/pyfulmen/foundry/mime_detection.py:81-118`

```python
def detect_mime_type_from_reader(
    reader: BinaryIO,
    max_bytes: int = 512
) -> Tuple[Optional[str], BinaryIO]:
    """
    Detect MIME type from reader while preserving read position.

    Returns:
    - Detected MIME type (or None)
    - ChainedReader wrapping original reader

    ChainedReader preserves consumed bytes for continued reading.
    """
```

**ChainedReader Pattern**: Enables detection without disrupting stream consumption

#### File Detection

**Location**: `src/pyfulmen/foundry/mime_detection.py:121-141`

```python
def detect_mime_type_from_file(path: str) -> Optional[str]:
    """
    Detect MIME type from file path.

    Reads first 512 bytes and delegates to detect_mime_type().
    """
```

#### BOM Handling

Automatic byte order mark detection and stripping:

- **UTF-8 BOM**: `EF BB BF`
- **UTF-16 LE BOM**: `FF FE`
- **UTF-16 BE BOM**: `FE FF`

#### Golden Fixtures

**Location**: `tests/fixtures/foundry/mime/`

Cross-language test fixtures for parity verification:

- `valid-json-object.json` - JSON object detection
- `valid-json-array.json` - JSON array detection
- `valid-xml.xml` - XML declaration
- `valid-yaml.yaml` - YAML key-value
- `valid-csv.csv` - CSV comma detection
- `valid-text.txt` - Plain text
- `binary-unknown.bin` - Binary content (returns None)
- `json-with-utf8-bom.json` - BOM stripping

#### Testing

**Coverage**: 83 comprehensive tests

- Core detection tests (30 tests)
- Streaming detection tests (26 tests)
- File detection tests (13 tests)
- Golden fixture tests (8 tests)
- Edge case tests (6 tests)

**Location**: `tests/foundry/test_mime_detection.py`

**Parity**: 100% gofulmen v0.1.1 behavioral compliance (28/28 features)

### ADR Infrastructure

Comprehensive architectural decision record system for governance and transparency.

#### Two-Tier ADR System

**Local ADRs** (`docs/development/adr/`):

- Python-specific implementation decisions
- Local to pyfulmen repository
- Promotion path to ecosystem when cross-language impact identified

**Ecosystem ADRs** (`docs/crucible-py/architecture/decisions/`):

- Cross-language architectural patterns
- Synced from Crucible SSOT
- Binding across gofulmen, pyfulmen, tsfulmen

#### Local ADR Infrastructure

**Location**: `docs/development/adr/`

```
docs/development/adr/
├── README.md           # Index and promotion process
├── template.md         # ADR template
├── ADR-0001-*.md      # FulmenCatalogModel populate_by_name=True
├── ADR-0002-*.md      # validate_country_code() Three-Lookup Strategy
└── ADR-0003-*.md      # Country Catalog Preview Status
```

**ADR-0001**: FulmenCatalogModel populate_by_name Configuration

- **Decision**: Enable Pydantic's `populate_by_name=True` for field aliases
- **Rationale**: Enables camelCase → snake_case mapping for Crucible integration
- **Impact**: Python-specific Pydantic configuration detail

**ADR-0002**: validate_country_code() Three-Lookup Strategy

- **Decision**: Alpha-2 → Alpha-3 → Numeric fallback sequence
- **Rationale**: Maximum flexibility while maintaining performance
- **Impact**: Documented algorithm for cross-language implementation

**ADR-0003**: Country Catalog Preview Status

- **Decision**: Explicit "preview" status for 5-country sample catalog
- **Rationale**: Clear communication about maturity and future expansion
- **Impact**: User expectation management

#### Ecosystem ADRs (Synced from Crucible)

**Location**: `docs/crucible-py/architecture/decisions/`

- **ADR-0002**: Triple-Index Catalog Strategy (foundational pattern)
- **ADR-0003**: Progressive Logging Profiles (SIMPLE/STRUCTURED/ENTERPRISE)
- **ADR-0004**: Schema-Driven Config Hydration (three-layer config)
- **ADR-0005**: CamelCase to Language Convention Mapping (field aliases)

**Documentation**: +2,000 lines of architectural decision records

### Version Propagation Infrastructure

Policy-driven VERSION management with automatic pyproject.toml synchronization.

#### Version Policy Configuration

**Location**: `.goneat/version-policy.yaml`

```yaml
# Version scheme configuration
version:
  scheme: semver # Semantic versioning (MAJOR.MINOR.PATCH)
  allow_extended: true # Enable prerelease identifiers and build metadata

# Propagation rules for package manager files
propagation:
  defaults:
    include:
      - pyproject.toml # Primary package manager for Python
    exclude:
      - "**/node_modules/**"
      - "docs/**"
      - "tests/**"
      - ".venv/**"
    backup:
      enabled: true # Create .bak files before changes
      retention: 5 # Keep last 5 backups

  targets:
    pyproject.toml:
      mode: project # Use [project] section (not [tool.poetry])

  workspace:
    strategy: single-version # All files use root VERSION

# Safety guards
guards:
  required_branches:
    - main # Allow on main branch
    - "release/*" # Allow on release branches
  disallow_dirty_worktree: false # Allow with uncommitted changes for testing
```

**Schema**: `schemas/crucible-py/config/goneat/v1.0.0/version-policy.schema.yaml`

#### Makefile Integration

**Enhanced Targets**:

```makefile
# Print current version
make version

# Set specific version (auto-propagates)
make version-set VERSION=x.y.z

# Bump version (auto-propagates)
make version-bump-patch
make version-bump-minor
make version-bump-major
make version-bump-calver

# Manual propagation
make version-propagate
```

**Workflow**: VERSION file → goneat version propagate → pyproject.toml [project] section

**Single Source of Truth**: VERSION file is authoritative, all other files sync from it

---

## 🔧 Implementation Fixes

### Bootstrap Symlink Fix

**Fixed**: `type:link` tools now create symlinks instead of copies

**Issue**: Bootstrap script was copying tools instead of symlinking for `type:link` installations, causing stale binaries that don't reflect source rebuilds.

**Location**: `scripts/bootstrap.py:210-220`

**Before**:

```python
shutil.copy(source_path, dest_path)  # Creates a copy
```

**After**:

```python
if dest_path.exists() or dest_path.is_symlink():
    dest_path.unlink()  # Remove existing file/symlink
os.symlink(source_path, dest_path)  # Create symlink
```

**Impact**:

- `bin/goneat` now auto-tracks `../goneat/dist/goneat` without re-bootstrap
- No more stale binaries after local goneat rebuilds
- Proper development workflow for local tool integration

**Addresses**: Pitfall 6 from Fulmen Helper Library Standard (lines 166-174)

### Makefile Version Command Fix

**Fixed**: `version-set` target now uses correct goneat command

**Issue**: Makefile was calling non-existent `goneat version sync` command

**Location**: `Makefile:134`

**Before**:

```makefile
@bin/goneat version sync --version $(VERSION)
```

**After**:

```makefile
@bin/goneat version set $(VERSION)
@$(MAKE) version-propagate
```

**Impact**: `make version-set VERSION=x.y.z` now works correctly and auto-propagates

---

## 📊 Quality Metrics

### Test Coverage

- **Country Code Tests**: 32 tests, all passing
- **MIME Detection Tests**: 83 tests, all passing
- **Total Tests**: 520+ tests, all passing
- **Coverage**: 95%+ maintained on foundry module

### Code Quality

- ✅ Ruff linting: All checks passing
- ✅ Ruff formatting: Code formatted consistently
- ✅ Type hints: Full type coverage maintained
- ✅ Documentation: Complete and validated

### Cross-Language Parity

- ✅ Country Code API: 100% gofulmen v0.1.1 parity
- ✅ MIME Detection API: 100% gofulmen v0.1.1 parity (28/28 features)
- ✅ Golden Fixtures: All 8 fixtures passing

---

## 🚀 Getting Started

### Country Code Lookups

```python
from pyfulmen.foundry import (
    validate_country_code,
    get_country,
    get_country_by_alpha3,
    get_country_by_numeric,
    list_countries
)

# Validate country codes (case-insensitive, flexible format)
validate_country_code("US")     # True (Alpha-2)
validate_country_code("usa")    # True (Alpha-3, case-insensitive)
validate_country_code("840")    # True (Numeric)
validate_country_code("76")     # True (Numeric with zero-padding → "076")

# Get country details
us = get_country("US")
print(us.name)          # "United States"
print(us.alpha3)        # "USA"
print(us.numeric)       # "840"

# Alternative lookup methods
us = get_country_by_alpha3("USA")
us = get_country_by_numeric("840")

# List all countries
countries = list_countries()
print(len(countries))   # 5 (sample catalog)
```

### MIME Type Detection

```python
from pyfulmen.foundry import (
    detect_mime_type,
    detect_mime_type_from_reader,
    detect_mime_type_from_file
)

# Detect from bytes
data = b'{"key": "value"}'
mime = detect_mime_type(data)
print(mime)  # "application/json"

# Detect from file
mime = detect_mime_type_from_file("data.json")
print(mime)  # "application/json"

# Detect from reader (stream-safe)
with open("data.json", "rb") as f:
    mime, reader = detect_mime_type_from_reader(f)
    print(mime)  # "application/json"
    # reader is ChainedReader wrapping f, preserves consumed bytes
    content = reader.read()  # Can continue reading
```

### Version Management

```bash
# Check current version
make version

# Bump patch version (0.1.2 → 0.1.3, auto-propagates)
make version-bump-patch

# Set specific version (auto-propagates)
make version-set VERSION=v0.2.0

# Manual propagation (if needed)
make version-propagate
```

---

## 📝 Known Limitations

### Country Catalog

- **5 Sample Countries**: Full 250+ country catalog will come in future Crucible sync
- Current catalog sufficient for testing and validation

### Version Propagation

- **Policy Required**: `.goneat/version-policy.yaml` must be present
- **Branch Guards**: Can be adjusted in policy file for local development

---

## 🔄 Migration Guide

### From v0.1.1 to v0.1.2

**No breaking changes** - this release is fully backward compatible.

### New Features

1. **Country Code Support**: New API, additive only

   ```python
   # New functionality in v0.1.2
   from pyfulmen.foundry import validate_country_code, get_country

   if validate_country_code("US"):
       country = get_country("US")
       print(country.name)
   ```

2. **MIME Detection**: New API, additive only

   ```python
   # New functionality in v0.1.2
   from pyfulmen.foundry import detect_mime_type

   mime = detect_mime_type(b'{"key": "value"}')
   print(mime)  # "application/json"
   ```

3. **Version Management**: Enhanced workflow

   ```bash
   # Old workflow (still works)
   echo "0.1.3" > VERSION
   sed -i 's/version = "0.1.2"/version = "0.1.3"/' pyproject.toml

   # New workflow (recommended)
   make version-set VERSION=0.1.3  # Auto-propagates
   ```

4. **Bootstrap**: Symlink tracking

   ```bash
   # After upgrade, re-run bootstrap to get symlinks
   make bootstrap

   # Verify symlink
   ls -la bin/goneat
   # Should show: bin/goneat -> ../goneat/dist/goneat
   ```

---

## 🤝 Contributors

**Generated by**: PyFulmen Architect (@pyfulmen-architect) using [Claude Code](https://claude.ai/code)
**Supervised by**: @3leapsdave (Dave Thompson)
**Agentic Attribution**: All commits follow FulmenHQ agentic attribution standards

---

## 📚 Additional Resources

- **Repository**: [pyfulmen](https://github.com/fulmenhq/pyfulmen) (internal)
- **Foundry Documentation**: `src/pyfulmen/foundry/README.md`
- **ADR Index**: `docs/development/adr/README.md`
- **Standards**: `docs/crucible-py/standards/` for FulmenHQ ecosystem standards
- **Maintainers**: See `MAINTAINERS.md` for project governance

---

## 🎯 Next Steps

### v0.1.3+ (Planned)

Additional ecosystem utilities:

- Additional Crucible catalog features
- Expanded documentation
- Additional cross-language coordination

### v0.2.0 (Planned)

Enterprise complete milestone:

- Full enterprise logging implementation
- Complete progressive interface features
- Cross-language compatibility verified
- Comprehensive documentation and examples
- Production-ready for FulmenHQ ecosystem

---

**Release**: v0.1.2
**Date**: October 16, 2025
**Status**: ✅ Released
